diff --git a/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/SupercamCalibrationTargets.pdf b/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/SupercamCalibrationTargets.pdf new file mode 100644 index 0000000..7528108 Binary files /dev/null and b/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/SupercamCalibrationTargets.pdf differ diff --git a/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/vanesm-finalprojectdraftF24.Rmd b/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/vanesm-finalprojectdraftF24.Rmd new file mode 100755 index 0000000..f0feaf0 --- /dev/null +++ b/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/vanesm-finalprojectdraftF24.Rmd @@ -0,0 +1,440 @@ +--- +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, ***ADD*** + +# 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. + +_Give a highlevel overview of the major finding. What questions were your trying to address, what approaches did you employ, and what happened?_ + + +## 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)) +``` + +## 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="LIBS ternary Plot With Reference Samples", + 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() +``` + +```{r} +kablelibstern<-cbind(point=libs.tern$num,"Description"=libs.tern$cluster) +kablelibstern<-kablelibstern[1:22,] + +kable(kablelibstern) +``` + +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 2, 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. + + +# 4.0 Finding 1: 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) + +## 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. + + +## 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 reccommendation 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") +``` + +## 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 + +libs.tern.dist<-libs.tern[libs.tern$Distance <= meters, ] + +ggtern(libs.tern.dist, ggtern::aes(x=x,y=y,z=z)) + + geom_point(data=libs.tern.dist,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") + +meters<- 7 + +libs.tern.dist<-libs.tern[libs.tern$Distance <= meters, ] + +ggtern(libs.tern.dist, ggtern::aes(x=x,y=y,z=z)) + + geom_point(data=libs.tern.dist,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") +``` + +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="Column-Scaled Heatmap of Means and Medians of LIBS data within 7m of PIXL Abrasion") +pheatmap(libs.heatmap[,2:9],scale="none",cluster_rows=F,cluster_cols=F,main="Unscaled Heatmap of Means and Medians of LIBS data within 7m of PIXL Abrasion") +``` +When looking at the heatmap, we can see more differences between the abrasions than are visible on the ternary plot. + +## 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. + +# 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 + +```{r} +citation("geosphere") +citation("ggtern") +``` + + + diff --git a/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/vanesm-finalprojectdraftF24.html b/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/vanesm-finalprojectdraftF24.html new file mode 100644 index 0000000..8e71f10 --- /dev/null +++ b/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/vanesm-finalprojectdraftF24.html @@ -0,0 +1,2135 @@ + + + + + + + + + + + + + + + +Data Analytics Research Individual Final Project Report + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+
+ +
+ + + + + + + +
+

DAR Project and Group Members

+
    +
  • Project name: Mars
  • +
  • Project team members: Charlotte Peterson, +ADD
  • +
+
+
+

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.

+

Give a highlevel overview of the major finding. What questions +were your trying to address, what approaches did you employ, and what +happened?

+
+

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))
+
+
+

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="LIBS ternary Plot With Reference Samples",
+       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
+

+
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
+

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 2, +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.

+
+
+
+

4.0 Finding 1: 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. +
+
+
+

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.

+
+
+

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 reccommendation 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")
+
+
+

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
+
+libs.tern.dist<-libs.tern[libs.tern$Distance <= meters, ]
+
+ggtern(libs.tern.dist, ggtern::aes(x=x,y=y,z=z)) +
+  geom_point(data=libs.tern.dist,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")
+

+
meters<- 7
+
+libs.tern.dist<-libs.tern[libs.tern$Distance <= meters, ]
+
+ggtern(libs.tern.dist, ggtern::aes(x=x,y=y,z=z)) +
+  geom_point(data=libs.tern.dist,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")
+

+

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="Column-Scaled Heatmap of Means and Medians of LIBS data within 7m of PIXL Abrasion")
+

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

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

+
+
+

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.

+
+
+
+

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
  • +
+
citation("geosphere")
+
## To cite package 'geosphere' in publications use:
+## 
+##   Hijmans R (2024). _geosphere: Spherical Trigonometry_. R package
+##   version 1.5-20, <https://CRAN.R-project.org/package=geosphere>.
+## 
+## A BibTeX entry for LaTeX users is
+## 
+##   @Manual{,
+##     title = {geosphere: Spherical Trigonometry},
+##     author = {Robert J. Hijmans},
+##     year = {2024},
+##     note = {R package version 1.5-20},
+##     url = {https://CRAN.R-project.org/package=geosphere},
+##   }
+
citation("ggtern")
+
## To cite ggtern in publications use:
+## 
+##   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>.
+## 
+## A BibTeX entry for LaTeX users is
+## 
+##   @Article{,
+##     title = {{ggtern}: Ternary Diagrams Using {ggplot2}},
+##     author = {Nicholas E. Hamilton and Michael Ferry},
+##     journal = {Journal of Statistical Software, Code Snippets},
+##     year = {2018},
+##     volume = {87},
+##     number = {3},
+##     pages = {1--17},
+##     doi = {10.18637/jss.v087.c03},
+##   }
+
+ + + +
+
+ +
+ + + + + + + + + + + + + + + + diff --git a/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/vanesm-finalprojectdraftF24.nb.html b/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/vanesm-finalprojectdraftF24.nb.html new file mode 100644 index 0000000..edcd804 --- /dev/null +++ b/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/vanesm-finalprojectdraftF24.nb.html @@ -0,0 +1,2497 @@ + + + + + + + + + + + + + + + +Data Analytics Research Individual Final Project Report + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + +
+

DAR Project and Group Members

+ +
+
+

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:

+ +

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:

+ +
+
+

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.

+

Give a highlevel overview of the major finding. What questions +were your trying to address, what approaches did you employ, and what +happened?

+
+

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))
+ + + +
+
+

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="LIBS ternary Plot With Reference Samples",
+       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 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
+ + +

+ + + + + + +
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
+ + + + + + +

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 2, +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.

+
+
+
+

4.0 Finding 1: 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. +
+
+
+

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.

+
+
+

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 reccommendation 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")
+ + + +
+
+

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
+
+libs.tern.dist<-libs.tern[libs.tern$Distance <= meters, ]
+ + + + + + +
meters<- 100
+
+libs.tern.dist<-libs.tern[libs.tern$Distance <= meters, ]
+
+ggtern(libs.tern.dist, ggtern::aes(x=x,y=y,z=z)) +
+  geom_point(data=libs.tern.dist,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")
+ + +

+ + +

+meters<- 7
+
+libs.tern.dist<-libs.tern[libs.tern$Distance <= meters, ]
+
+ggtern(libs.tern.dist, ggtern::aes(x=x,y=y,z=z)) +
+  geom_point(data=libs.tern.dist,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")
+ + +

+ + + +

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="Column-Scaled Heatmap of Means and Medians of LIBS data within 7m of PIXL Abrasion")
+ + +

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

+ + + +

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

+
+
+

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.

+
+
+
+

Bibliography

+

Provide a listing of references and other sources.

+ + + + +
citation("geosphere")
+ + +
To cite package ‘geosphere’ in publications use:
+
+  Hijmans R (2024). _geosphere: Spherical Trigonometry_. R package version 1.5-20, <https://CRAN.R-project.org/package=geosphere>.
+
+A BibTeX entry for LaTeX users is
+
+  @Manual{,
+    title = {geosphere: Spherical Trigonometry},
+    author = {Robert J. Hijmans},
+    year = {2024},
+    note = {R package version 1.5-20},
+    url = {https://CRAN.R-project.org/package=geosphere},
+  }
+ + +
citation("ggtern")
+ + +
To cite ggtern in publications use:
+
+  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>.
+
+A BibTeX entry for LaTeX users is
+
+  @Article{,
+    title = {{ggtern}: Ternary Diagrams Using {ggplot2}},
+    author = {Nicholas E. Hamilton and Michael Ferry},
+    journal = {Journal of Statistical Software, Code Snippets},
+    year = {2018},
+    volume = {87},
+    number = {3},
+    pages = {1--17},
+    doi = {10.18637/jss.v087.c03},
+  }
+ + + + +
+ +
LS0tCnRpdGxlOiAiRGF0YSBBbmFseXRpY3MgUmVzZWFyY2ggSW5kaXZpZHVhbCBGaW5hbCBQcm9qZWN0IFJlcG9ydCIKYXV0aG9yOiAiTWFyZ28gVmFuRXNzZWxzdHluIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogMwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogbm8KICAgIHRoZW1lOiB1bml0ZWQKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgcGRmX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogJzMnCi0tLQojIERBUiBQcm9qZWN0IGFuZCBHcm91cCBNZW1iZXJzCgoqIFByb2plY3QgbmFtZTogTWFycwoqIFByb2plY3QgdGVhbSBtZW1iZXJzOiBDaGFybG90dGUgUGV0ZXJzb24sICoqKkFERCoqKgoKIyAwLjAgUHJlbGltaW5hcmllcy4KClRoaXMgcmVwb3J0IGlzIGdlbmVyYXRlZCBmcm9tIGFuIFIgTWFya2Rvd24gZmlsZSB0aGF0IGluY2x1ZGVzIGFsbCB0aGUgUiBjb2RlIG5lY2Vzc2FyeSB0byBwcm9kdWNlIHRoZSByZXN1bHRzIGRlc2NyaWJlZCBhbmQgZW1iZWRkZWQgaW4gdGhlIHJlcG9ydC4gIENvZGUgYmxvY2tzIGNhbiBiZSBzdXJwcmVzc2VkIGZyb20gb3V0cHV0IGZvciByZWFkYWJpbGl0eSB1c2luZyB0aGUgY29tbWFuZCBjb2RlIGB7UiwgIGVjaG89c2hvd31gIGluIHRoZSBjb2RlIGJsb2NrIGhlYWRlci4gSWYgYHNob3cgPC0gRkFMU0VgIHRoZSBjb2RlIGJsb2NrIHdpbGwgYmUgc3VycHJlc3NlZDsgaWYgYHNob3cgPC0gVFJVRWAgdGhlbiB0aGUgY29kZSB3aWxsIGJlIHNob3cuIAoKYGBge3J9CiMgU2V0IHRvIFRSVUUgdG8gZXhwYW5kIFIgY29kZSBibG9ja3M7IHNldCB0byBGQUxTRSB0byBjb2xsYXBzZSBSIGNvZGUgYmxvY2tzIApzaG93IDwtIFRSVUUKYGBgCgpFeGVjdXRpbmcgdGhpcyBSIG5vdGVib29rIHJlcXVpcmVzIHNvbWUgc3Vic2V0IG9mIHRoZSBmb2xsb3dpbmcgcGFja2FnZXM6CgoqIGBnZ3Bsb3QyYAoqIGB0aWR5dmVyc2VgCiogYGdndGVybmAKKiBga25pdHJgCiogYHBoZWF0bWFwYAoKVGhlc2Ugd2lsbCBiZSBpbnN0YWxsZWQgYW5kIGxvYWRlZCBhcyBuZWNlc3NhcnkgKGNvZGUgc3VwcHJlc3NlZCkuIAoKPCEtLSBUaGUgYGluY2x1ZGU9RkFMU0VgIG9wdGlvbiBwcmV2ZW50cyB5b3VyIGNvZGUgZnJvbSBiZWluZyBzaG93biBhdCBhbGwgLS0+CmBgYHtyLCBpbmNsdWRlPUZBTFNFfQojIFRoaXMgY29kZSB3aWxsIGluc3RhbGwgcmVxdWlyZWQgcGFja2FnZXMgaWYgdGhleSBhcmUgbm90IGFscmVhZHkgaW5zdGFsbGVkCiMgQUxXQVlTIElOU1RBTEwgWU9VUiBQQUNLQUdFUyBMSUtFIFRISVMhCmlmICghcmVxdWlyZSgiZ2dwbG90MiIpKSB7CiAgIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQogICBsaWJyYXJ5KGdncGxvdDIpCn0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgewogICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQogICBsaWJyYXJ5KHRpZHl2ZXJzZSkKfQppZiAoIXJlcXVpcmUoImdndGVybiIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygiZ2d0ZXJuIikKICBsaWJyYXJ5KGdndGVybikKfQppZighcmVxdWlyZSgia25pdHIiKSkgewogIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikKICBsaWJyYXJ5KGtuaXRyKQp9CmlmKCFyZXF1aXJlKCJwaGVhdG1hcCIpKXsKICBpbnN0YWxsLnBhY2thZ2VzKCJwaGVhdG1hcCIpCiAgbGlicmFyeShwaGVhdG1hcCkKfQpgYGAKCiMgMS4wIFByb2plY3QgSW50cm9kdWN0aW9uCgpUaGlzIHByb2plY3Qgb3V0bGluZXMgbXkgYW5hbHlzaXMgb2YgdGhlIE1hcnMgTElCUyBhbmQgUElYTCBkYXRhLiBJdCBsYXJnZWx5IHJldm9sdmVzIGFyb3VuZCBkYXRhIHByb2Nlc3NpbmcgYW5kIG9yZ2FuaXphdGlvbgoKIyAyLjAgT3JnYW5pemF0aW9uIG9mIFJlcG9ydAoKVGhpcyByZXBvcnQgaXMgb3JnYW5pemVkIGFzIGZvbGxvd3M6IAoKCiogU2VjdGlvbiAzLjAuICBGaW5kaW5nIDE6IEhlcmUgd2UgZGlzY3VzcyB0aGUgTElCUyBzY2N0IHRhcmdldHMgYW5kIHRoZSBpbXBvcnRhbmNlIG9mIGRpZmZlcmVudGlhdGluZyB0aGVtIGluIGZ1dHVyZSBhbmFseXNpcyAKCiogU2VjdGlvbiA0LjA6IEZpbmRpbmcgMjogSGVyZSB3ZSBkaXNjdXNzIHRoZSBjb25uZWN0aW9uIGJldHdlZW4gdGhlIExJQlMgYW5kIFBJWEwgZGF0YQoKKiBTZWN0aW9uIDUuMCBPdmVyYWxsIGNvbmNsdXNpb25zIGFuZCBzdWdnZXN0aW9ucyAKCiMgMy4wIEZpbmRpbmcgMTogVW5kZXJzdGFuZGluZyBMSUJTIFRhcmdldHMKCkkgcmVzZWFyY2hlZCB0aGUgbWVhbmluZyBiZWhpbmQgdGhlIExJQlMgdGFyZ2V0IG5hbWVzLCBhbmQgY2F0ZWdvcml6ZWQgdGhlIExJQlMgZGF0YSBpbnRvIGEgZmV3IG1ham9yIGNhdGVnb3JpZXMuIEkgY3JlYXRlZCBhIG5ldyBSZHMgZmlsZSB0aGF0IGluY2x1ZGVzIGEgY29sdW1uIGxhYmVsaW5nIGVhY2ggTElCUyBzYW1wbGUgd2l0aCBpdHMgY2F0ZWdvcnkuIAoKX0dpdmUgYSBoaWdobGV2ZWwgb3ZlcnZpZXcgb2YgdGhlIG1ham9yIGZpbmRpbmcuIFdoYXQgcXVlc3Rpb25zIHdlcmUgeW91ciB0cnlpbmcgdG8gYWRkcmVzcywgd2hhdCBhcHByb2FjaGVzIGRpZCB5b3UgZW1wbG95LCAgYW5kIHdoYXQgaGFwcGVuZWQ/XwoKCiMjIDMuMSBEYXRhLCBDb2RlLCBhbmQgUmVzb3VyY2VzCgpIZXJlIGlzIGEgbGlzdCAgZGF0YSBzZXRzLCBjb2RlcywgIHRoYXQgYXJlIHVzZWQgaW4geW91ciB3b3JrLiBBbG9uZyB3aXRoIGJyaWVmIGRlc2NyaXB0aW9uIGFuZCBVUkwgd2hlcmUgdGhleSBhcmUgbG9jYXRlZC4KCjEuIHN1cGVyY2FtX2xpYnNfbW9jX2xvYy5SZHMgaXMgdGhlIFJkcyBmaWxlIGNvbnRhaW5pbmcgdGhlIExJQlMgZGF0YSBbaHR0cHM6Ly9naXRodWIucnBpLmVkdS9EYXRhSU5DSVRFL0RBUi1NYXJzLUYyNC9ibG9iLzJmYmI5Yjc5ODhkNTM2NjU2YmIxMThhMGQ4ZTBiNjQ0MzkyY2EwOWEvRGF0YS9zdXBlcmNhbV9saWJzX21vY19sb2MuUmRzXShodHRwczovL2dpdGh1Yi5ycGkuZWR1L0RhdGFJTkNJVEUvREFSLU1hcnMtRjI0L2Jsb2IvMmZiYjliNzk4OGQ1MzY2NTZiYjExOGEwZDhlMGI2NDQzOTJjYTA5YS9EYXRhL3N1cGVyY2FtX2xpYnNfbW9jX2xvYy5SZHMpCgoyLiBsaWJzX3R5cGVkLlJkcyBpcyB0aGUgUmRzIGZpbGUgY29udGFpbmluZyB0aGUgTElCUyBkYXRhIGFzIHdlbGwgYXMgYSB0eXBlIGNvbHVtbiBjYXRlZ29yaXppbmcgZWFjaCBzYW1wbGUgW2h0dHBzOi8vZ2l0aHViLnJwaS5lZHUvRGF0YUlOQ0lURS9EQVItTWFycy1GMjQvYmxvYi8yZmJiOWI3OTg4ZDUzNjY1NmJiMTE4YTBkOGUwYjY0NDM5MmNhMDlhL1N0dWRlbnREYXRhL2xpYnNfdHlwZWQuUmRzXShodHRwczovL2dpdGh1Yi5ycGkuZWR1L0RhdGFJTkNJVEUvREFSLU1hcnMtRjI0L2Jsb2IvMmZiYjliNzk4OGQ1MzY2NTZiYjExOGEwZDhlMGI2NDQzOTJjYTA5YS9TdHVkZW50RGF0YS9saWJzX3R5cGVkLlJkcykKCjMuIFN1cGVyY2FtQ2FsaWJyYXRpb25UYXJnZXRzLnBkZiBpcyBhIHBkZiBjb250YWluaW5nIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjYWxpYnJhdGlvbiB0YXJnZXRzIHVzZWQgaW4gdGhlIExJQlMgZGF0YS4gW2h0dHBzOi8vZ2l0aHViLnJwaS5lZHUvRGF0YUlOQ0lURS9EQVItTWFycy1GMjQvYmxvYi9lMDJhMzAxMTk4ZTJlYzQ3ZTE2ODQ0ODYwMmVhY2U2YTZmN2UzZWFmL1N0dWRlbnROb3RlYm9va3MvQXNzaWdubWVudDA3X0RyYWZ0RmluYWxQcm9qZWN0Tm90ZWJvb2svU3VwZXJjYW1DYWxpYnJhdGlvblRhcmdldHMucGRmXShodHRwczovL2dpdGh1Yi5ycGkuZWR1L0RhdGFJTkNJVEUvREFSLU1hcnMtRjI0L2Jsb2IvZTAyYTMwMTE5OGUyZWM0N2UxNjg0NDg2MDJlYWNlNmE2ZjdlM2VhZi9TdHVkZW50Tm90ZWJvb2tzL0Fzc2lnbm1lbnQwN19EcmFmdEZpbmFsUHJvamVjdE5vdGVib29rL1N1cGVyY2FtQ2FsaWJyYXRpb25UYXJnZXRzLnBkZikKCjQuIHYxX2xpYnMuUmRzIGlzIHRoZSBSZHMgZmlsZSBjb250YWluaW5nIHRoZSBMSUJTIGRhdGEgYXMgd2VsbCBhcyBteSBjYXRlZ29yaXphdGlvbiB0aGF0IERvw7FhIHB1dCBpbnRvIGEgc3RhbmRhcmRpemVkIGZvcm1hdCBbaHR0cHM6Ly9naXRodWIucnBpLmVkdS9EYXRhSU5DSVRFL0RBUi1NYXJzLUYyNC9ibG9iLzJmYmI5Yjc5ODhkNTM2NjU2YmIxMThhMGQ4ZTBiNjQ0MzkyY2EwOWEvRGF0YS9zdXBlcmNhbV9saWJzX21vY19sb2MuUmRzXShodHRwczovL2dpdGh1Yi5ycGkuZWR1L0RhdGFJTkNJVEUvREFSLU1hcnMtRjI0L2Jsb2IvMmZiYjliNzk4OGQ1MzY2NTZiYjExOGEwZDhlMGI2NDQzOTJjYTA5YS9EYXRhL3N1cGVyY2FtX2xpYnNfbW9jX2xvYy5SZHMpCgoKSSB1c2VkIHRoZSBsaWJzIGRhdGFzZXQgd2l0aCB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uIGZlYXR1cmVzLCBkaXN0YW5jZXMsIGFuZCB0b3RhbHMgcmVtb3ZlZC4gSSBtYWRlIHN1cmUgdGhhdCBjZXJ0YWluIGNhdGVnb3JpZXMgd2VyZSBudW1lcmljIGFuZCBhZGRlZCBhIG5ldyAidHlwZSIgY29sdW1uLgoKVGhlbiwgSSBhZGRlZCBhIGRlc2NyaXB0aW9uIHRvIGVhY2ggc2NjdCAoY2FsaWJyYXRpb24pIHRhcmdldCBpbiB0aGUgdHlwZSBjb2x1bW4sIHdoaWNoIG5hbWVzIHRoZSBlYXJ0aCByZWZlcmVuY2UgYmFzZWQgb24gdGhlIHBkZiBsaW5rZWQgaW4gdGhpcyBzZWN0aW9uLiBGb3IgZXhhbXBsZSwgdGhlIHNjY3QgdGFyZ2V0IGNvbnRhaW5pbmcgIlBNSUZBMDMwNiIgd2FzIHR5cGVkICJPbGl2aW5lIgoKSSBhbHNvIGxhYmVsZWQgdGhlIHRhcmdldHMgd2l0aCAiYWVnaXMiIGluIHRoZWlyIG5hbWVzIHdpdGggQUVHSVMsIHRoZXNlIHNhbXBsZXMgY2FuIGJlIHVzZWQgdGhlIHNhbWUgYXMgdGhlIG90aGVyIE1hcnMgTElCUyBzYW1wbGVzLCBidXQgaXQgaXMgbm90ZWQgdGhhdCB0aGUgbWVhc3VyZW1lbnQgaXMgdGFrZW4gdXNpbmcgQUVHSVMsIHRoZSByb3ZlcidzIEFJLiBTbyBpbnN0ZWFkIG9mIHRoZSB0YXJnZXQgYmVpbmcgY2hvc2VuIGludGVudGlvbmFsbHkgYnkgYSBzY2llbnRpc3QsIGl0IGlzIGNob3NlbiBieSB0aGUgcm92ZXIgd2hlbiBpdCBoYXMgZXh0cmEgcmVzb3VyY2VzIHRvIHRha2UgYSBzYW1wbGUuCgpGcm9tIHRoZSBhbmFseXN0cyBub3RlYm9vaywgdGFyZ2V0cyB3aXRoICJzY2FtIiBpbiB0aGVpciBuYW1lcyBjb3JyZXNwb25kIHRvIHRhcmdldHMgb2Ygb3RoZXIgbWVhc3VyZW1lbnRzLCBJIHdlbnQgdGhyb3VnaCB0aGUgYW5hbHlzdHMgbm90ZWJvb2sgZm9yIHRoZXNlIHNhbXBsZXMgYW5kIGFkZGVkIHRoZSBvdGhlciBtZWFzdXJlbWVudHMgdGhhdCB3ZXJlIHRha2VuIGF0IHRoZSBzYW1lIHRhcmdldCBpbnRvIHRoZSB0eXBlIGNvbHVtbi4gRm9yIGV4YW1wbGUsIHRoZSAidmlsbGVwbGFuZV9zY2FtIiB0YXJnZXQgYWxzbyBoYWQgWkNhbSBtZWFzdXJlbWVudHMgdGFrZW4gYXQgdGhlIHNhbWUgdGFyZ2V0LCBzbyBJIHR5cGVkIGl0ICJaQ0FNLVNDQU0iCgpJIGxhYmVsZWQgdHdvIHRhcmdldHMgKCJzZWlfX19fX19fX19fX19fX19fXyIgYW5kICJuYWFraWhfX19fX19fX19fX19fXyIpLCAgd2l0aCBmdXJ0aGVyIGRlc2NyaXB0aW9ucyBiZWNhdXNlIHRoZSBhbmFseXN0cyBub3RlYm9vayBoYWQgY2xlYXIgZGVzY3JpcHRpb25zIG9mIHdoYXQgdGhlIHRhcmdldCB3YXMgaW50ZW5kZWQgdG8gYmUgc2FtcGxpbmcuIAoKQWxsIHJlbWFpbmluZyBzYW1wbGVzIGFyZSB0eXBlZCAib3RoZXIiLgoKYGBge3J9CmxpYnMuZGYgPC0gcmVhZFJEUygiL2FjYWRlbWljcy9NQVRQLTQ5MTAtRjI0L0RBUi1NYXJzLUYyNC9EYXRhL3N1cGVyY2FtX2xpYnNfbW9jX2xvYy5SZHMiKQoKI0Ryb3AgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBmZWF0dXJlcywgdGhlIHN1bSBvZiB0aGUgcGVyY2VudGFnZXMsIAojdGhlIGRpc3RhbmNlLCBhbmQgdGhlIHRvdGFsIGZyZXF1ZW5jaWVzCmxpYnMuZGYgPC0gbGlicy5kZiAlPiUgCiAgc2VsZWN0KCEoYyhkaXN0YW5jZV9tbSxUb3QuRW0uLFNpTzJfc3RkZXYsVGlPMl9zdGRldixBbDJPM19zdGRldixGZU9UX3N0ZGV2LAogICAgICAgICAgICAgTWdPX3N0ZGV2LE5hMk9fc3RkZXYsQ2FPX3N0ZGV2LEsyT19zdGRldixUb3RhbCkpKQoKIyBDb252ZXJ0IHRoZSBwb2ludHMgdG8gbnVtZXJpYwpsaWJzLmRmJHBvaW50IDwtIGFzLm51bWVyaWMobGlicy5kZiRwb2ludCkKdHlwZWRsaWJzPC1jYmluZChsaWJzLmRmWywxOjRdLCJ0eXBlIj0wLGxpYnMuZGZbNToxM10pCmBgYAoKYGBge3J9CnRhcmdldGxpc3Q8LWMoInRzcmljaDA0MDQiLCJMQ01CMDAwNiIsIkxDQTUzMDEwNiIsIlBNSUZTMDUwNSIsIlRBUEFHMDIwNiIsIlBNSU9SMDUwNyIsCiAgICAgICAgICAgICAgIlBNSUROMDMwMiIsIlBNSUZBMDMwNiIsIlBNSUFOMDEwNiIsIlBNSUVOMDYwMiIsIlRTRVJQMDEwMiIsIkxCSFZPMjA0MDYiLAogICAgICAgICAgICAgICJMSlNDMTAzMDQiLCJMQU5LRTAxMDEiLCJMU0lERTAxMDEiLCJMSk1OMTAxMDYiLCJOVEUwMTAzMDEiLCJOVEUwMjAxMDYiLAogICAgICAgICAgICAgICJOVEUwMzAxMDYiLCJOVEUwNDAxMDYiLCJOVEUwNTAzMDEiLCJTSEVSRzAyIiwiVElUQU5JVU0iLCJhZWdpcyIsCiAgICAgICAgICAgICAgImJ1enphcmRfcm9ja3Nfc2NhbSIsImFsZmFsZmFfMzc4X3NjYW0iLCJjaGluaWFrXzU2NV9zY2FtIiwKICAgICAgICAgICAgICAiZ2FyZGVfMjEwX3NjYW0iLCJndWlsbGF1bWVzXzE2OF9zY2FtIiwibW9udHBlemF0XzM1MF9zY2FtIiwibmFsdHNvc19zY2FtIiwKICAgICAgICAgICAgICAib3V6ZWxfZmFsbHNfNzkyX3NjYW0iLCJwb2xsb2NrX2tub2JfNTAxX3NjYSIsInJvc2Vfcml2ZXJfZmFsbHNfc2NhIiwKICAgICAgICAgICAgICAicm91Ymlvbl8xNjhfc2NhbSIsInZpbGxlcGxhbmVfc2NhbSIsImF0bW9fbW91bnRhaW5fNjM3X3NjIiwKICAgICAgICAgICAgICAiY3Jvc3N3aW5kX2xha2VfNjQxX3MiKQoKdHlwZWxpc3Q8LWMoIkJIVk8tMiBiYXNhbHQgYW5kIEsgc3VsZmF0ZSBtaXh0dXJlIiwiQ2hlcnQiLCJDYWxjaXRlIiwiRmVycm9zaWxpdGUiLAogICAgICAgICAgICAiRmx1b3JvLUNobG9yby1IeWRybyBBcGF0aXRlIiwiT3J0aG9jbGFzZSIsIkRpb3BzaWRlIiwiT2xpdmluZSIsIkFuZGVzaW5lIiwKICAgICAgICAgICAgIkVuc3RhdGl0ZSIsIlNlcnBlbnRpbmUvVGFsYyIsIkJIVk8tMiBzdGFuZGFyZCBiYXNhbHQiLCJNYXJzIHNvaWwgYW5hbG9nIiwKICAgICAgICAgICAgIkFua2VyaXRlIiwiU2lkZXJpdGUiLCJKTU4tMSBzdGFuZGFyZCBNbiBub2R1bGUiLAogICAgICAgICAgICAiQmFzYWx0IGRvcHBlZCBpbiBtaW5vciBlbGVtZW50cyAtIEN1LCBabiIsCiAgICAgICAgICAgICJCYXNhbHQgZG9wcGVkIGluIG1pbm9yIGVsZW1lbnRzIC0gTW4sIEJhLCBDciIsCiAgICAgICAgICAgICJCYXNhbHQgZG9wcGVkIGluIG1pbm9yIGVsZW1lbnRzIC0gWm4iLAogICAgICAgICAgICAiQmFzYWx0IGRvcHBlZCBpbiBtaW5vciBlbGVtZW50cyAtIExpLCBTciIsCiAgICAgICAgICAgICJCYXNhbHQgZG9wcGVkIGluIG1pbm9yIGVsZW1lbnRzIC0gTmkiLCJTaGVyZ290dGl0ZSIsIlRpdGFuaXVtIiwiQUVHSVMiLAogICAgICAgICAgICAiUElYTC1TQ0FNIiwiVklTSVItUmFtYW54Mi1aQ0FNLVNDQU0iLCJBVC1TQ0FNIiwiQVQtU0NBTSIsIlBJWEwtU0NBTSIsCiAgICAgICAgICAgICJQSVhMLVNDQU0iLCJQSVhMLVNDQU0iLCJBVC1TQ0FNIiwiWkNBTS1TQ0FNIiwiPy1TQ0FNIiwiWkNBTS1QSVhMLVNDQU0iLAogICAgICAgICAgICAiWkNBTS1TQ0FNIiwiWkNBTU1TLVNDQU0iLCJaQ0FNLVNDQU0iKQoKdGFyZ2V0dHlwZWQ8LWFzLmRhdGEuZnJhbWUoY2JpbmQodGFyZ2V0bGlzdCx0eXBlbGlzdCkscm93bmFtZXM9YygxKSkKCmZvcihpIGluIDE6MjMpewogIHR5cGVkbGliczwtdHlwZWRsaWJzICU+JQogICAgbXV0YXRlKHR5cGUgPSBpZmVsc2UoZ3JlcGwodGFyZ2V0dHlwZWRbaSwxXSx0YXJnZXQsaWdub3JlLmNhc2U9VCksCiAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0dHlwZWRbaSwyXSwgdHlwZSkpCn0KCmZvcihpIGluIDI0Om5yb3codGFyZ2V0dHlwZWQpKXsKICB0eXBlZGxpYnM8LXR5cGVkbGlicyAlPiUKICAgIG11dGF0ZSh0eXBlPSBpZmVsc2UoZ3JlcGwodGFyZ2V0dHlwZWRbaSwxXSwgdGFyZ2V0LGlnbm9yZS5jYXNlPVQpICYgdHlwZT09IjAiLAogICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0dHlwZWRbaSwyXSx0eXBlKSkKfQoKdHlwZWRsaWJzPC10eXBlZGxpYnMgJT4lCiAgbXV0YXRlKHR5cGU9aWZlbHNlKHR5cGU9PSIwIiwib3RoZXIiLHR5cGUpKSAlPiUKICBtdXRhdGUodHlwZT0gaWZlbHNlKHRhcmdldD09InNlaV9fX19fX19fX19fX19fX19fIiwgIm90aGVyIC0gZmluZSBzb2lsIix0eXBlKSkgJT4lCiAgbXV0YXRlKHR5cGU9IGlmZWxzZSh0YXJnZXQ9PSJuYWFraWhfX19fX19fX19fX19fXyIsICJvdGhlciAtIGNvYXJzZSBzb2lsIix0eXBlKSkKYGBgCgojIyAzLjIgQ29udHJpYnV0aW9uCgpUaGlzIHNlY3Rpb24gd2FzIHNvbGUgd29yaywgZXhjZXB0IGZvciBEb8OxYSdzIHN0YW5kYXJkaXphdGlvbiBvZiBteSBmaWxlIGludG8gdGhlIHYxX2xpYnMuUmRzIGF0IHRoZSBlbmQuIExhdGVyLCBpbiBteSB0ZXJuYXJ5IGRpYWdyYW1zLCBJIHVzZWQgdGhlIHNhbWUgc2VlZCBhbmQgbnVtYmVyIG9mIGNsdXN0ZXJzIGFzIEFhZGksIHNvIHRoYXQgbXkgY2x1c3RlcmluZyB3b3VsZCBtYXRjaCBoaXMuIAoKIyMgMy4zIE1ldGhvZHMgRGVzY3JpcHRpb24gCgpOb3csIHdlIHBsb3QgdGhlIGF2ZXJhZ2Ugb2YgZWFjaCBjYWxpYnJhdGlvbi9zY2N0IHRhcmdldCwgYWdhaW5zdCB0aGUgY2x1c3RlcmVkIG1hcnMgTElCUyBkYXRhLiBUaGUgTWFycyBkYXRhIGlzIHNlcGFyYXRlZCBmcm9tIHRoZSByZWZlcmVuY2UgZGF0YSwgd2UgcGxvdCB0aGUgcmVmZXJlbmNlIGRhdGEgb3ZlciB0aGUgTWFycyBkYXRhIHdpdGggbGFiZWxlZCBwb2ludHMgY29ycmVzcG9uZGluZyB0byB0aGUgdGFibGUgb2YgcmVmZXJlbmNlIHR5cGVzLiAKCmBgYHtyfQpsaWJzLm1hdHJpeCA8LSBhcy5tYXRyaXgobGlicy5kZlssNjoxM10pIAoKbGlicy50ZXJuIDwtIGFzLmRhdGEuZnJhbWUobGlicy5tYXRyaXgpICU+JQogIG11dGF0ZSh4PShTaU8yK0FsMk8zKS8xMDAseT0oRmVPVCtNZ08pLzEwMCx6PShDYU8rTmEyTytLMk8pLzEwMCkgJT4lCiAgc2VsZWN0KC1jKFNpTzIsQWwyTzMsRmVPVCxNZ08sQ2FPLE5hMk8sSzJPLFRpTzIpKQoKCmxpYnMudGVybjwtY2JpbmQobGlicy50ZXJuLCAidHlwZSI9dHlwZWRsaWJzJHR5cGUsICJ0YXJnZXQiPXR5cGVkbGlicyR0YXJnZXQsIAogICAgICAgICAgICAgICAgICJzaGFwZSI9dHlwZWRsaWJzJHR5cGUpCgpsaWJzLnRlcm48LWxpYnMudGVybiAlPiUgbXV0YXRlKHNoYXBlID0gaWZlbHNlKGdyZXBsKCJTQ0FNIiwgdHlwZSwgaWdub3JlLmNhc2U9VCksCiAgICAgICAgICAgICAgICAgICAgICAgIm90aGVyIiwgc2hhcGUpKSAlPiUKICBtdXRhdGUoc2hhcGUgPSBpZmVsc2UoZ3JlcGwoIm90aGVyIiwgdHlwZSwgaWdub3JlLmNhc2U9VCksCiAgICAgICAgICAgICAgICAgICAgICAgIm90aGVyIiwgc2hhcGUpKSAlPiUKICBtdXRhdGUoc2hhcGUgPSBpZmVsc2UoZ3JlcGwoInNjY3QiLCB0YXJnZXQsIGlnbm9yZS5jYXNlPVQpLCAic2NjdCIsIHNoYXBlKSkKCmxpYnMudGVybiRzaGFwZTwtYXMuZmFjdG9yKGxpYnMudGVybiRzaGFwZSkKYGBgCgoKVGhpcyBpcyBub3Qgc3BlY2lmaWMgYW5hbHlzaXMsIG1vcmVzbyBhIHJlY29tbWVuZGF0aW9uIHRoYXQgZm9yIGZ1dHVyZSB3b3JrLCB0aGUgc2NjdCB2YWx1ZXMgc2hvdWxkIGJlIHNlcGFyYXRlZCBmcm9tIHRoZSBhY3R1YWwgbWFycyBkYXRhLiBQcmV2aW91c2x5LCB3ZSBoYWQgYmVlbiBhbmFseXNpbmcgdGhlc2UgdGFyZ2V0cyBhcyBpZiB0aGV5IHdlcmUgbWFycyBkYXRhLCB3aGVuIGluIGZhY3QgdGhleSBzaG91bGQgYmUgdHJlYXRlZCBhcyByZWZlcmVuY2Ugb3IgY2FsaWJyYXRpb24gZGF0YS4gCgpXaGVuIGdyYXBoaW5nIHRoZSByZWZlcmVuY2UgcG9pbnRzIG9uIHRoZSB0ZXJuYXJ5IHBsb3QsIGdncmVwZWwgaGFzIGEgY29uZmxpY3Qgd2l0aCBnZ3Rlcm4sIHNvIEkgaGFkIHRvIG1hbnVhbGx5IGFkZCB3aGVyZSB0aGUgbGFiZWxzIHNob3VsZCBnby4gSWYgdGhpcyBpc3N1ZSB3aXRoIGdndGVybiBpcyBmaXhlZCBpbiB0aGUgZnV0dXJlLCB0aGlzIGNhbiBiZSBzaW1wbGlmaWVkIHRvIHVzZSBnZ3JlcGVsIGZvciB0aGUgbGFiZWxzLiAKCiMjIDMuNCBSZXN1bHQgYW5kIERpc2N1c3Npb24gCgpgYGB7cn0Kc2V0LnNlZWQoMTIzNCkKa208LWttZWFucyhsaWJzLnRlcm5bLDE6M10sNCkKCmxpYnMudGVybjwtYXMuZGF0YS5mcmFtZShjYmluZChsaWJzLnRlcm4sImNsdXN0ZXIiPWFzLmZhY3RvcihrbSRjbHVzdGVyKSkpCmBgYAoKYGBge3J9CmxpYnMudGVybi5vdGhlcjwtbGlicy50ZXJuW2xpYnMudGVybiRzaGFwZT09Im90aGVyIixdCmxpYnMudGVybi5zY2N0PC1saWJzLnRlcm5bbGlicy50ZXJuJHNoYXBlPT0ic2NjdCIsXQoKI2xpYnMuc2NjdC5hdmc8LWxpYnMudGVybi5zY2N0WywgbGFwcGx5KC5TRCwgYXZlcmFnZSksIGJ5PSB0YXJnZXRdCmxpYnMuc2NjdC5hdmc8LWFnZ3JlZ2F0ZShjYmluZCh4LHkseikgfiB0eXBlLCBkYXRhID0gbGlicy50ZXJuLnNjY3QsIEZVTiA9ICJtZWFuIikKbGlicy50ZXJuLm90aGVyPC1saWJzLnRlcm4ub3RoZXJbLGMoMSwyLDMsNyldCmxpYnMudGVybi5vdGhlcjwtY2JpbmQobGlicy50ZXJuLm90aGVyLCJ0eXBlIj0wKQpsaWJzLnNjY3QuYXZnPC1jYmluZChsaWJzLnNjY3QuYXZnWywyOjRdLCJjbHVzdGVyIj1saWJzLnNjY3QuYXZnJHR5cGUsInR5cGUiPTEpCmxpYnMudGVybjwtcmJpbmQobGlicy5zY2N0LmF2ZyxsaWJzLnRlcm4ub3RoZXIpCmBgYAoKYGBge3J9CmxpYnMudGVybjwtY2JpbmQobGlicy50ZXJuLCJudW0iPXJvd25hbWVzKGxpYnMudGVybiksImxlZ2VuZCI9MCkKYGBgCgpgYGB7cn0KbGlicy50ZXJuPC1saWJzLnRlcm4gJT4lIAogIG11dGF0ZShsZWdlbmQ9cGFzdGUobnVtLGNsdXN0ZXIsc2VwPSIgICIpKQpgYGAKCgpgYGB7cn0KbGlic3Rlcm48LWNiaW5kKGxpYnMudGVybix4ZW5kPTAseWVuZD0wLHplbmQ9MCkKbGlic3Rlcm48LWxpYnN0ZXJuJT4lIAogIG11dGF0ZSh4ZW5kPSBpZmVsc2UodHlwZT09IjEiLCB4LHhlbmQpKSAlPiUKICBtdXRhdGUoeWVuZD0gaWZlbHNlKHR5cGU9PSIxIiwgeSx5ZW5kKSkgJT4lCiAgbXV0YXRlKHplbmQ9IGlmZWxzZSh0eXBlPT0iMSIsIHosemVuZCkpCmBgYAoKYGBge3J9CmZvcihpIGluIGMoMSwxMCwxMSwxMywxNykpewogIGxpYnN0ZXJuW2ksODoxMF08LWMobGlic3Rlcm5baSwxXSswLjA2LGxpYnN0ZXJuW2ksMl0sbGlic3Rlcm5baSwzXS0wLjA2KQp9Cgpmb3IoaSBpbiBjKDcpKXsKICBsaWJzdGVybltpLDg6MTBdPC1jKGxpYnN0ZXJuW2ksMV0rMC4wOSxsaWJzdGVybltpLDJdLGxpYnN0ZXJuW2ksM10tMC4wOSkKfQoKZm9yKGkgaW4gYygxNSwyMCkpewogIGxpYnN0ZXJuW2ksODoxMF08LWMobGlic3Rlcm5baSwxXSxsaWJzdGVybltpLDJdKzAuMDUsbGlic3Rlcm5baSwzXS0wLjA1KQp9Cgpmb3IoaSBpbiBjKDMpKXsKICBsaWJzdGVybltpLDg6MTBdPC1jKGxpYnN0ZXJuW2ksMV0rMC4wMixsaWJzdGVybltpLDJdKzAuMDYsbGlic3Rlcm5baSwzXS0wLjA4KQp9Cgpmb3IoaSBpbiBjKDE0KSl7CiAgbGlic3Rlcm5baSw4OjEwXTwtYyhsaWJzdGVybltpLDFdLGxpYnN0ZXJuW2ksMl0tMC4wNSxsaWJzdGVybltpLDNdKzAuMDUpCn0KCmZvcihpIGluIGMoNCwxNiwxOSkpewogIGxpYnN0ZXJuW2ksODoxMF08LWMobGlic3Rlcm5baSwxXS0wLjA4LGxpYnN0ZXJuW2ksMl0rMC4wMixsaWJzdGVybltpLDNdKzAuMDYpCn0KCmZvcihpIGluIGMoMiw5KSl7CiAgbGlic3Rlcm5baSw4OjEwXTwtYyhsaWJzdGVybltpLDFdKzAuMDMsbGlic3Rlcm5baSwyXS0wLjA1LGxpYnN0ZXJuW2ksM10rMC4wMykKfQoKZm9yKGkgaW4gYyg2LDgsMTIsMTgsMjIpKXsKICBsaWJzdGVybltpLDg6MTBdPC1jKGxpYnN0ZXJuW2ksMV0tMC4wNixsaWJzdGVybltpLDJdLGxpYnN0ZXJuW2ksM10rMC4wNikKfQoKZm9yKGkgaW4gYyg1KSl7CiAgbGlic3Rlcm5baSw4OjEwXTwtYyhsaWJzdGVybltpLDFdLGxpYnN0ZXJuW2ksMl0tMC4wOSxsaWJzdGVybltpLDNdKzAuMDkpCn0KCmZvcihpIGluIGMoMjEpKXsKICBsaWJzdGVybltpLDg6MTBdPC1jKGxpYnN0ZXJuW2ksMV0tMC4wMyxsaWJzdGVybltpLDJdKzAuMDcsbGlic3Rlcm5baSwzXS0wLjAzKQp9CmBgYAoKYGBge3J9Cm52ID0gLTAuMDAgICNWZXJ0aWNhbCBBZGp1c3RtZW50CnBuID0gcG9zaXRpb25fbnVkZ2VfdGVybih5PW52LHg9LW52LHo9bnYpCgpnZ3Rlcm4obGlic3Rlcm4sIGdndGVybjo6YWVzKHg9eCx5PXksej16KSkgKwogIGdlb21fcG9pbnQoZGF0YT1zdWJzZXQobGlic3Rlcm4sdHlwZT09MCksYWVzKGNvbG9yPWNsdXN0ZXIpLGFscGhhPTAuNSkgKyAKICBnZW9tX3BvaW50KGRhdGE9c3Vic2V0KGxpYnN0ZXJuLHR5cGU9PTEpLGFlcygpKSsKICB0aGVtZV9yZ2J3KCkgKyAKICBsYWJzKHRpdGxlPSJMSUJTIHRlcm5hcnkgUGxvdCBXaXRoIFJlZmVyZW5jZSBTYW1wbGVzIiwKICAgICAgIHg9IlNpK0FsIiwKICAgICAgIHk9IkZlK01nIiwKICAgICAgIHo9IkNhK05hK0siKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikgKwogIGdlb21fdGV4dChwb3NpdGlvbj1wbixkYXRhPXN1YnNldChsaWJzdGVybix0eXBlPT0xKSwKICAgICAgICAgICAgYWVzKHg9eGVuZCx5PXllbmQsej16ZW5kLGxhYmVsPW51bSksY2hlY2tfb3ZlcmxhcD1UKSsKICBnZW9tX3NlZ21lbnQoYWVzKHg9eCx4ZW5kID0geGVuZCwgeSA9IHksIHllbmQ9eWVuZCwgej16LCB6ZW5kPXplbmQpLHNpemU9MC4zLAogICAgICAgICAgICAgICBkYXRhID0gc3Vic2V0KGxpYnN0ZXJuLHR5cGU9PTEpKSsKICB0aGVtZV9ub21hc2soKQpgYGAKCmBgYHtyfQprYWJsZWxpYnN0ZXJuPC1jYmluZChwb2ludD1saWJzLnRlcm4kbnVtLCJEZXNjcmlwdGlvbiI9bGlicy50ZXJuJGNsdXN0ZXIpCmthYmxlbGlic3Rlcm48LWthYmxlbGlic3Rlcm5bMToyMixdCgprYWJsZShrYWJsZWxpYnN0ZXJuKQpgYGAKCk9uZSBvZiB0aGUgcHJpbWFyeSByZXN1bHRzIG9mIGxvb2tpbmcgYXQgdGhpcyBncmFwaCBpcyB0aGF0IG1hbnkgb2YgdGhlIHBvaW50cyB0aGF0IHNlZW1lZCB0byBiZSBvdXRsaWVycyBmcm9tIHRoZSByZXN0IG9mIHRoZSBkYXRhIGFyZSBhY3R1YWxseSBjYWxpYnJhdGlvbiB0YXJnZXRzLiBUaGVyZSBhcmUgbXVjaCBmZXdlciBwb2ludHMgaW4gY2x1c3RlciAyLCBvdXIgc21hbGxlc3QgYW5kIG1vc3QgZGlzdGluY3QgY2x1c3Rlciwgd2hlbiB5b3UgY29uc2lkZXIgdGhhdCBzb21lIG9mIHRob3NlIG9yaWdpbmFsIHBvaW50cyBhcmUgYXZlcmFnZWQgaW50byB0aGUgcmVmZXJlbmNlIHBvaW50cyBmb3IgY2FsY2l0ZSBhbmQgRmxvdXJvLUNobG9yby1IeWRybyBBcGF0aXRlLgoKCiMgNC4wIEZpbmRpbmcgMTogTWF0Y2hpbmcgTElCUyBhbmQgUElYTCBEYXRhCgpNYXRjaGluZyB0aGUgTElCUyBhbmQgUElYTCBkYXRhIHVzaW5nIHRoZWlyIGxvbmdpdHVkZSBhbmQgbGF0aXR1ZGVzLiAKCiMjIDQuMSBEYXRhLCBDb2RlLCBhbmQgUmVzb3VyY2VzCgpIZXJlIGlzIGEgbGlzdCAgZGF0YSBzZXRzLCBjb2RlcywgIHRoYXQgYXJlIHVzZWQgaW4geW91ciB3b3JrLiBBbG9uZyB3aXRoIGJyaWVmIGRlc2NyaXB0aW9uIGFuZCBVUkwgd2hlcmUgdGhleSBhcmUgbG9jYXRlZC4KCjEuIE1hdGNoaW5nTElCU2FuZFBJWEwuUm1kIG91dGxpbmVzIGEgbG90IG9mIHRoZSB3b3JrIGJlaGluZCBtYXRjaGluZyB0aGUgTElCUyB0YXJnZXRzIHRvIFBJWEwgc2FtcGxlcy4gIFtodHRwczovL2dpdGh1Yi5ycGkuZWR1L0RhdGFJTkNJVEUvREFSLU1hcnMtRjI0L2Jsb2IvMThhNzQ0MGUyYjRkZTUwYTJiZTgyMjNhZGM5MzE5ZjMzZjA4MmYwOS9TdHVkZW50Tm90ZWJvb2tzL0Fzc2lnbm1lbnQwNS9NYXRjaGluZ0xJQlNhbmRQSVhMLlJtZF0oaHR0cHM6Ly9naXRodWIucnBpLmVkdS9EYXRhSU5DSVRFL0RBUi1NYXJzLUYyNC9ibG9iLzE4YTc0NDBlMmI0ZGU1MGEyYmU4MjIzYWRjOTMxOWYzM2YwODJmMDkvU3R1ZGVudE5vdGVib29rcy9Bc3NpZ25tZW50MDUvTWF0Y2hpbmdMSUJTYW5kUElYTC5SbWQpCgoyLiAgc3VwZXJjYW1fbGlic19tb2NfbG9jLlJkcyBpcyB0aGUgUmRzIGZpbGUgY29udGFpbmluZyB0aGUgTElCUyBkYXRhIFtodHRwczovL2dpdGh1Yi5ycGkuZWR1L0RhdGFJTkNJVEUvREFSLU1hcnMtRjI0L2Jsb2IvMmZiYjliNzk4OGQ1MzY2NTZiYjExOGEwZDhlMGI2NDQzOTJjYTA5YS9EYXRhL3N1cGVyY2FtX2xpYnNfbW9jX2xvYy5SZHNdKGh0dHBzOi8vZ2l0aHViLnJwaS5lZHUvRGF0YUlOQ0lURS9EQVItTWFycy1GMjQvYmxvYi8yZmJiOWI3OTg4ZDUzNjY1NmJiMTE4YTBkOGUwYjY0NDM5MmNhMDlhL0RhdGEvc3VwZXJjYW1fbGlic19tb2NfbG9jLlJkcykKCjMuIHNhbXBsZXNfcGl4bF93aWRlLlJkcyAgaXMgdGhlIFJkcyBmaWxlIGNvbnRhaW5pbmcgYWxsIG9mIHRoZSBQSVhMIGRhdGEgW2h0dHBzOi8vZ2l0aHViLnJwaS5lZHUvRGF0YUlOQ0lURS9EQVItTWFycy1GMjQvYmxvYi8xOGE3NDQwZTJiNGRlNTBhMmJlODIyM2FkYzkzMTlmMzNmMDgyZjA5L0RhdGEvc2FtcGxlc19waXhsX3dpZGUuUmRzXShodHRwczovL2dpdGh1Yi5ycGkuZWR1L0RhdGFJTkNJVEUvREFSLU1hcnMtRjI0L2Jsb2IvMThhNzQ0MGUyYjRkZTUwYTJiZTgyMjNhZGM5MzE5ZjMzZjA4MmYwOS9EYXRhL3NhbXBsZXNfcGl4bF93aWRlLlJkcykKCjIuIHBpeGxfc29sX2Nvb3JkaW5hdGVzLlJkcyBjb250YWlucyB0aGUgcGl4bCBkYXRhIHdpdGggdGhlIGNvb3JkaW5hdGVzIGFuZCBzb2wgbWV0YWRhdGEgYWRkZWQgZnJvbSB0aGUgYW5hbHlzdHMgbm90ZWJvb2sgW2h0dHBzOi8vZ2l0aHViLnJwaS5lZHUvRGF0YUlOQ0lURS9EQVItTWFycy1GMjQvYmxvYi9tYWluL1N0dWRlbnREYXRhL3BpeGxfc29sX2Nvb3JkaW5hdGVzLlJkc10oaHR0cHM6Ly9naXRodWIucnBpLmVkdS9EYXRhSU5DSVRFL0RBUi1NYXJzLUYyNC9ibG9iL21haW4vU3R1ZGVudERhdGEvcGl4bF9zb2xfY29vcmRpbmF0ZXMuUmRzKS4gCgo1LiBQSVhMX0xJQlNfQ29tYmluZWQuUmRzIGlzIHRoZSBmaW5hbCBwcm9kdWN0IG9mIGNvbWJpbmluZyB0aGUgTElCUyBhbmQgUElYTCBkYXRhIGNyZWF0ZWQgYnkgQ2hhcmxvdHRlIGFuZCBJLiBbaHR0cHM6Ly9naXRodWIucnBpLmVkdS9EYXRhSU5DSVRFL0RBUi1NYXJzLUYyNC9ibG9iL2UwMmEzMDExOThlMmVjNDdlMTY4NDQ4NjAyZWFjZTZhNmY3ZTNlYWYvU3R1ZGVudERhdGEvUElYTF9MSUJTX0NvbWJpbmVkLlJkc10oaHR0cHM6Ly9naXRodWIucnBpLmVkdS9EYXRhSU5DSVRFL0RBUi1NYXJzLUYyNC9ibG9iL2UwMmEzMDExOThlMmVjNDdlMTY4NDQ4NjAyZWFjZTZhNmY3ZTNlYWYvU3R1ZGVudERhdGEvUElYTF9MSUJTX0NvbWJpbmVkLlJkcykKCiMjIDQuMiBDb250cmlidXRpb24KCkkgd29ya2VkIHdpdGggQ2hhcmxvdHRlIFBldGVyc29uIG9uIHRoaXMgc2VjdGlvbiwgd2UgbWF0Y2hlZCB0aGUgTElCUyBhbmQgUElYTCBkYXRhIHRvZ2V0aGVyLiBUaGVuIEkgZ3JhcGhlZCB0aGUgdGVybmFyeSBwbG90IG9mIHRoZSBMSUJTIGRhdGEgY29sb3JlZCBieSBpdHMgY2xvc2VzdCBQSVhMIHNhbXBsZS4gCgoKIyMgNC4zIE1ldGhvZHMgRGVzY3JpcHRpb24gCgpGaXJzdCwgY29sdW1ucyB3aXRoIHRoZSBQSVhMIGNvb3JkaW5hdGVzIGFuZCBzb2wgd2VyZSBhZGRlZCB0byB0aGUgUElYTCBkYXRhLiBUaGlzIGluZm9ybWF0aW9uIHdhcyBmb3VuZCBmcm9tIHRoZSBhbmFseXN0J3Mgbm90ZWJvb2suIAoKVGhlIGZpbmFsIGl0ZXJhdGlvbiBvZiBjb21iaW5lZCBkYXRhIGlzIGNyZWF0ZWQgaW4gdGhlIE1hdGNoaW5nTElCU2FuZFBJWEwuUm1kIGZpbGUuIFRoZSByZXN1bHQgb2YgdGhhdCBmaWxlIGlzIHRoZSBQSVhMX0xJQlNfQ29tYmluZWQuUmRzLCB3aGljaCBjb250YWlucyBldmVyeSBtYXJzIExJQlMgc2FtcGxlLCBzbyB0aGUgc2NjdC9lYXJ0aCByZWZlcmVuY2Ugc2FtcGxlcyBhcmUgcmVtb3ZlZC4gRWFjaCBMSUJTIHNhbXBsZSBpcyBsaXN0ZWQgd2l0aCBpdHMgY2xvc2VzdCBQSVhMIHNhbXBsZSwgaWdub3JpbmcgdGhlIGF0bW9zcGhlcmljIHNhbXBsZSwgYW5kIHRoZWlyIGRpc3RhbmNlIGluIG1ldGVycy4gCgpUaGUgc2NjdC9lYXJ0aCByZWZlcmVuY2Ugc2FtcGxlcyB3ZXJlIHJlbW92ZWQgYmVjYXVzZSB0aGVpciBsb2NhdGlvbiBoYXMgbm90aGluZyB0byBkbyB3aXRoIHRoZWlyIGRhdGEsIHRoZSByb3ZlciBpcyB0YWtpbmcgYSBMSUJTIG1lYXN1cmVtZW50IG9mIHJlZmVyZW5jZSBtYXRlcmlhbHMgaXQgY2FycmllcyB3aXRoIGl0LiAKCkV2ZW4gdGhvdWdoIHNvbWUgb2YgdGhlIGRpc3RhbmNlcyBhcmUgZmFydGhlciB0aGFuIHdlIHdvdWxkIGNvbnNpZGVyIGNsb3NlIG9yIHVzZWZ1bCwgdWx0aW1hdGVseSwgd2UgY2hvc2Ugbm90IHRvIHJlbW92ZSBhbnkgZGF0YSBwb2ludHMgc28gdGhhdCBpbiB0aGUgZnV0dXJlIHBlb3BsZSBjYW4gbWFrZSB0aGVpciBvd24gY3V0b2ZmIG9mIHdoYXQgZGlzdGFuY2UgdGhleSBjb25zaWRlciB0byBiZSBzaWduaWZpY2FudCBvciByZWxldmFudC4gVGhlIHJlY2NvbW1lbmRhdGlvbiB3ZSB3b3VsZCBtYWtlIGlzIHRvIGNvbnNpZGVyIHBhaXJlZCBQSVhMIGFuZCBMSUJTIHNhbXBsZXMgdGhhdCBhcmUgd2l0aGluIDcgbWV0ZXJzIG9mIGVhY2ggb3RoZXIsIGFzIHRoYXQgaXMgY2xvc2UgdG8gdGhlIHJhbmdlIHdoZXJlIHRoZSBMSUJTIGxhc2VyIGNhbiByZWFjaC4gCgpgYGB7cn0KcGl4bGxpYnM8LXJlYWRSRFMoIi9hY2FkZW1pY3MvTUFUUC00OTEwLUYyNC9EQVItTWFycy1GMjQvU3R1ZGVudERhdGEvUElYTF9MSUJTX0NvbWJpbmVkLlJkcyIpCmBgYAoKIyMgNC40IFJlc3VsdCBhbmQgRGlzY3Vzc2lvbiAKClNpbmNlIHRoZSB3b3JrIG9mIG1hdGNoaW5nIHRoZSBMSUJTIGFuZCBQSVhMIGRhdGEgaGFzIGFscmVhZHkgYmVlbiBkb25lLCBpdCBpcyBlYXN5IHRvIGltcG9ydCB0aGUgY29tYmluZWQgUkRTIGFuZCBjb252ZXJ0IHRoYXQgZGF0YSBpbnRvIGEgZGF0YWZyYW1lIHRvIGJlIHVzZWQgZm9yIGEgdGVybmFyeSBkaWFncmFtCgpXZSBjYW4gZWFzaWx5IGNoYW5nZSB3aGF0IGRpc3RhbmNlIHdlIHdvdWxkIGxpa2UgdG8gdmlldwoKYGBge3J9CmxpYnMudGVybiA8LSBhcy5kYXRhLmZyYW1lKHBpeGxsaWJzKSAlPiUKICBtdXRhdGUoeD0oTElCUy5TaU8yK0xJQlMuQWwyTzMpLzEwMCx5PShMSUJTLkZlT1QrTElCUy5NZ08pLzEwMCx6PShMSUJTLkNhTytMSUJTLk5hMk8rTElCUy5LMk8pLzEwMCkKCmxpYnMudGVybjwtbGlicy50ZXJuWyxjKDYsNywxOSwyMCwyMSldCmBgYAoKCmBgYHtyfQptZXRlcnM8LSAxMDAKCmxpYnMudGVybi5kaXN0PC1saWJzLnRlcm5bbGlicy50ZXJuJERpc3RhbmNlIDw9IG1ldGVycywgXQoKZ2d0ZXJuKGxpYnMudGVybi5kaXN0LCBnZ3Rlcm46OmFlcyh4PXgseT15LHo9eikpICsKICBnZW9tX3BvaW50KGRhdGE9bGlicy50ZXJuLmRpc3QsYWVzKGNvbG9yPVBJWEwuQWJyYXNpb24sYWxwaGE9MC41KSkgKyAKICB0aGVtZV9yZ2J3KCkgKyAKICBsYWJzKHRpdGxlPXBhc3RlKCJNYXJzIExJQlMgRGF0YSBXaXRoaW4iLG1ldGVycywibWV0ZXJzIG9mIFBJWEwiLHNlcD0iICIpLAogICAgICAgeD0iU2krQWwiLAogICAgICAgeT0iRmUrTWciLAogICAgICAgej0iQ2ErTmErSyIpK3RoZW1lKGxlZ2VuZC5wb3NpdGlvbj0icmlnaHQiKSArIAogIGd1aWRlcyhhbHBoYT0ibm9uZSIpCgptZXRlcnM8LSA3CgpsaWJzLnRlcm4uZGlzdDwtbGlicy50ZXJuW2xpYnMudGVybiREaXN0YW5jZSA8PSBtZXRlcnMsIF0KCmdndGVybihsaWJzLnRlcm4uZGlzdCwgZ2d0ZXJuOjphZXMoeD14LHk9eSx6PXopKSArCiAgZ2VvbV9wb2ludChkYXRhPWxpYnMudGVybi5kaXN0LGFlcyhjb2xvcj1QSVhMLkFicmFzaW9uLGFscGhhPTAuNSkpICsgCiAgdGhlbWVfcmdidygpICsgCiAgbGFicyh0aXRsZT1wYXN0ZSgiTWFycyBMSUJTIERhdGEgV2l0aGluIixtZXRlcnMsIm1ldGVycyBvZiBQSVhMIixzZXA9IiAiKSwKICAgICAgIHg9IlNpK0FsIiwKICAgICAgIHk9IkZlK01nIiwKICAgICAgIHo9IkNhK05hK0siKSt0aGVtZShsZWdlbmQucG9zaXRpb249InJpZ2h0IikgKyAKICBndWlkZXMoYWxwaGE9Im5vbmUiKQpgYGAKCldlIGNhbiBzZWUgaGVyZSB0aGF0IHdoZW4gaW50ZXJwcmV0aW5nIHRoZSBMSUJTIGRhdGEgd2l0aGluIDcgbWV0ZXJzIG9mIGVhY2ggUElYTCBhYnJhc2lvbiwgdGhlIGRhdGEgaXMgbm90IHRpZ2h0bHkgY2x1c3RlcmVkLiBGb3IgdGhlIG1vc3QgcGFydCwgdGhlIGRhdGEgaXMganVzdCBhcyBzcHJlYWQgYXMgdGhlIGVudGlyZSBkYXRhLiAKCmBgYHtyfQpsaWJzLmhlYXRtYXA8LXBpeGxsaWJzCgpsaWJzLmhlYXRtYXA8LWxpYnMuaGVhdG1hcFtsaWJzLmhlYXRtYXAkRGlzdGFuY2UgPD0gNywgXQoKbGlicy5oZWF0bWFwLm1lYW48LWFnZ3JlZ2F0ZShjYmluZChMSUJTLlNpTzIsTElCUy5UaU8yLExJQlMuQWwyTzMsTElCUy5GZU9ULExJQlMuTWdPLExJQlMuQ2FPLExJQlMuTmEyTyxMSUJTLksyTykgfiBQSVhMLkFicmFzaW9uLCBkYXRhID0gbGlicy5oZWF0bWFwLCBGVU4gPSAibWVhbiIpCmxpYnMuaGVhdG1hcC5tZWQ8LWFnZ3JlZ2F0ZShjYmluZChMSUJTLlNpTzIsTElCUy5UaU8yLExJQlMuQWwyTzMsTElCUy5GZU9ULExJQlMuTWdPLExJQlMuQ2FPLExJQlMuTmEyTyxMSUJTLksyTykgfiBQSVhMLkFicmFzaW9uLCBkYXRhID0gbGlicy5oZWF0bWFwLCBGVU4gPSAibWVkaWFuIikKCmxpYnMuaGVhdG1hcC5tZWFuPC1jYmluZChsaWJzLmhlYXRtYXAubWVhbiwieCI9Im1lYW4iKQpsaWJzLmhlYXRtYXAubWVhbiRQSVhMLkFicmFzaW9uPC1hcy5jaGFyYWN0ZXIobGlicy5oZWF0bWFwLm1lYW4kUElYTC5BYnJhc2lvbikKbGlicy5oZWF0bWFwLm1lYW48LWxpYnMuaGVhdG1hcC5tZWFuICU+JQogIG11dGF0ZSh4PXBhc3RlKFBJWEwuQWJyYXNpb24seCxzZXA9IiAiKSkKcm93bmFtZXMobGlicy5oZWF0bWFwLm1lYW4pPC1saWJzLmhlYXRtYXAubWVhbiR4CgpsaWJzLmhlYXRtYXAubWVkPC1jYmluZChsaWJzLmhlYXRtYXAubWVkLCJ4Ij0ibWVkaWFuIikKbGlicy5oZWF0bWFwLm1lZCRQSVhMLkFicmFzaW9uPC1hcy5jaGFyYWN0ZXIobGlicy5oZWF0bWFwLm1lZCRQSVhMLkFicmFzaW9uKQpsaWJzLmhlYXRtYXAubWVkPC1saWJzLmhlYXRtYXAubWVkICU+JQogIG11dGF0ZSh4PXBhc3RlKFBJWEwuQWJyYXNpb24seCxzZXA9IiAiKSkKcm93bmFtZXMobGlicy5oZWF0bWFwLm1lZCk8LWxpYnMuaGVhdG1hcC5tZWQkeAoKbGlicy5oZWF0bWFwPC1yYmluZChsaWJzLmhlYXRtYXAubWVhbixsaWJzLmhlYXRtYXAubWVkKQpsaWJzLmhlYXRtYXA8LWxpYnMuaGVhdG1hcFtjKDEsNywyLDgsMyw5LDQsMTAsNSwxMSw2LDEyKSxdCgpwaGVhdG1hcChsaWJzLmhlYXRtYXBbLDI6OV0sc2NhbGU9ImNvbHVtbiIsY2x1c3Rlcl9yb3dzPUYsY2x1c3Rlcl9jb2xzPUYsbWFpbj0iQ29sdW1uLVNjYWxlZCBIZWF0bWFwIG9mIE1lYW5zIGFuZCBNZWRpYW5zIG9mIExJQlMgZGF0YSB3aXRoaW4gN20gb2YgUElYTCBBYnJhc2lvbiIpCnBoZWF0bWFwKGxpYnMuaGVhdG1hcFssMjo5XSxzY2FsZT0ibm9uZSIsY2x1c3Rlcl9yb3dzPUYsY2x1c3Rlcl9jb2xzPUYsbWFpbj0iVW5zY2FsZWQgSGVhdG1hcCBvZiBNZWFucyBhbmQgTWVkaWFucyBvZiBMSUJTIGRhdGEgd2l0aGluIDdtIG9mIFBJWEwgQWJyYXNpb24iKQpgYGAKV2hlbiBsb29raW5nIGF0IHRoZSBoZWF0bWFwLCB3ZSBjYW4gc2VlIG1vcmUgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGUgYWJyYXNpb25zIHRoYW4gYXJlIHZpc2libGUgb24gdGhlIHRlcm5hcnkgcGxvdC4gCgojIyA1LjUgQ29uY2x1c2lvbnMsIExpbWl0YXRpb25zLCAgYW5kIEZ1dHVyZSBXb3JrLgoKTW9yZSBhbmFseXNpcyBvZiB0aGUgTElCUyBkYXRhIGdyb3VwZWQgYnkgUElYTCBuZWVkcyB0byBiZSBkb25lLiBJIHRoaW5rIGEgUHJpbmNpcGxlIENvbXBvbmVudCBhbmFseXNpcyBjb3VsZCBiZSBpbnRlcmVzdGluZyB0byBoZWxwIHVzIHNlZSB3aGF0IGZhY3RvcnMgYnJlYWsgdXAgdGhlIGRpZmZlcmVudCBncm91cHMuIEkgYWxzbyB0aGluayBhIHNpbWlsYXJpdHkgYW5hbHlzaXMgd2l0aGluIHRoZSBncm91cHMgY291bGQgYmUgaW50ZXJlc3RpbmcuIAoKIyBCaWJsaW9ncmFwaHkKUHJvdmlkZSBhIGxpc3Rpbmcgb2YgcmVmZXJlbmNlcyBhbmQgb3RoZXIgc291cmNlcy4KCiogW0NvdXNpbjIxXSBDb3VzaW4sIEEuLCBTYXV0dGVyLCBWLiwgRmFicmUsIEMuLCBEcm9tYXJ0LCBHLiwgTW9udGFnbmFjLCBHLiwgRHJvdWV0LCBDLiwgTWVzbGluLCBQLiBZLiwgR2FzbmF1bHQsIE8uLCBCZXlzc2FjLCBPLiwgQmVybmFyZCwgUy4sIENsb3V0aXMsIEUuLCBGb3JuaSwgTy4sIEJlY2ssIFAuLCBGb3VjaGV0LCBULiwgSm9obnNvbiwgSi4gUi4sIExhc3VlLCBKLiwgT2xsaWxhLCBBLiBNLiwgRGUgUGFyc2V2YWwsIFAuLCBHb3V5LCBTLiwgJiBDYXJvbiwgQi4gKDIwMjEpLiBTdXBlckNhbSBjYWxpYnJhdGlvbiB0YXJnZXRzIG9uIGJvYXJkIHRoZSBwZXJzZXZlcmFuY2Ugcm92ZXI6IEZhYnJpY2F0aW9uIGFuZCBxdWFudGl0YXRpdmUgY2hhcmFjdGVyaXphdGlvbi4gU3BlY3Ryb2NoaW1pY2EgQWN0YSBQYXJ0IEI6IEF0b21pYyBTcGVjdHJvc2NvcHksIDEwNjM0MS4gaHR0cHM6Ly9kb2kub3JnLzEwLjEwMTYvai5zYWIuMjAyMS4xMDYzNDEKCmBgYHtyfQpjaXRhdGlvbigiZ2Vvc3BoZXJlIikKY2l0YXRpb24oImdndGVybiIpCmBgYAoKCgo=
+ + + +
+ + + + + + + + + + + + + + + + diff --git a/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/vanesm-finalprojectdraftF24.pdf b/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/vanesm-finalprojectdraftF24.pdf new file mode 100644 index 0000000..0de8c7f Binary files /dev/null and b/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/vanesm-finalprojectdraftF24.pdf differ