# HG changeset patch # User lecorguille # Date 1519821853 18000 # Node ID b147b17759a6ea287c701ce7b4e9e3a478108a12 # Parent 4f06e1796334cf22bc9fb1a7be95ff4b71004c64 planemo upload for repository https://github.com/workflow4metabolomics/anova commit 28838bb8dafd6d286157db77f181ed8a1b586664 diff -r 4f06e1796334 -r b147b17759a6 README.rst --- a/README.rst Thu Oct 26 09:30:56 2017 -0400 +++ b/README.rst Wed Feb 28 07:44:13 2018 -0500 @@ -2,6 +2,14 @@ Changelog/News -------------- +**Version 1.2.0 23/02/2018** + +- Fix for bug in multiple testing correction when more than one factor. +- Adding results in variable metadata file instead of putting it in data matrix +- Adding mean calculation +- Converting filtered output into a pdf file with Venn diagram and boxplots + a "selected.var" column +- New dependency : R package 'venn' + **Version 1.1.4 04/04/2016** diff -r 4f06e1796334 -r b147b17759a6 abims_anova.r --- a/abims_anova.r Thu Oct 26 09:30:56 2017 -0400 +++ b/abims_anova.r Wed Feb 28 07:44:13 2018 -0500 @@ -3,7 +3,7 @@ # date: 06-06-2012 # update: 18-02-2014 -# **Authors** Gildas Le Corguille ABiMS - UPMC/CNRS - Station Biologique de Roscoff - gildas.lecorguille|at|sb-roscoff.fr +# **Authors** Gildas Le Corguille ABiMS - UPMC/CNRS - Station Biologique de Roscoff - gildas.lecorguille|at|sb-roscoff.fr # abims_anova.r version 20140218 @@ -11,25 +11,35 @@ # function avova -anova = function (file, sampleinfo, mode="column", condition=1, interaction=F, method="BH", threshold=0.01, selection_method="intersection", sep=";", dec=".", outputdatapvalue="anova.data.output", outputdatafiltered="anova.datafiltered.output") { - - +anova = function (file, sampleinfo, varinfo, mode="column", condition=1, interaction=F, method="BH", threshold=0.01, selection_method="intersection", sep=";", dec=".", outputdatapvalue="anova.data.output", outputdatasignif="anova.datasignif.output") { + + if (sep=="tabulation") sep="\t" if (sep=="semicolon") sep=";" if (sep=="comma") sep="," anova_formula_operator = "+" if (interaction) anova_formula_operator = "*" - + # -- import -- - data=read.table(file, header = TRUE, row.names=1, sep = sep, quote="\"", dec = dec, fill = TRUE, comment.char="",na.strings = "NA") - + data=read.table(file, header = TRUE, row.names=1, sep = sep, quote="\"", dec = dec, fill = TRUE, comment.char="",na.strings = "NA", check.names=FALSE) + if (mode == "row") data=t(data) - + sampleinfoTab=read.table(sampleinfo, header = TRUE, row.names=1, sep = sep, quote="\"") rownames(sampleinfoTab) = make.names(rownames(sampleinfoTab)) - + varinfoTab=read.table(varinfo, header = TRUE, sep = sep, quote="\"") + if(sum(colnames(data)!=varinfoTab[,1])!=0){ # if ID not exactly identical + if(sum(colnames(data)[order(colnames(data))]!=varinfoTab[order(varinfoTab[,1]),1])==0){ + # reorder data matrix to match variable metadata order + data = data[,match(varinfoTab[,1],colnames(data))] + }else{ + stop(paste0("\nVariables' ID do not match between your data matrix and your variable", + "metadata file. \nPlease check your data.")) + } + } + # -- group -- match_data_sampleinfoTab = match(rownames(data),rownames(sampleinfoTab)) if (sum(is.na(match_data_sampleinfoTab)) > 0) { @@ -41,10 +51,10 @@ write(head(rownames(sampleinfoTab)), stderr()) quit("no",status=10) } - - + + # -- anova -- - + # formula grps=list() anova_formula_s = "data ~ " @@ -60,16 +70,16 @@ anova_formula = as.formula(anova_formula_s) - + # anova manovaObjectList = manova(anova_formula) manovaList = summary.aov(manovaObjectList) - + # condition renaming manovaRownames = gsub(" ","",rownames(manovaList[[1]])) manovaNbrPvalue = length(manovaRownames)-1 manovaRownames = manovaRownames[-(manovaNbrPvalue+1)] - + for (i in 1:length(condition)) { manovaRownames = sub(paste("grps\\[\\[",i,"\\]\\]",sep=""),condition[i],manovaRownames) anova_formula_s = sub(paste("grps\\[\\[",i,"\\]\\]",sep=""),condition[i],anova_formula_s) @@ -77,45 +87,94 @@ # log cat("\nanova_formula",anova_formula_s,"\n") - + # p-value aovPValue = sapply(manovaList,function(x){x[-(manovaNbrPvalue+1),5]}) if(length(condition) == 1) aovPValue = t(aovPValue) rownames(aovPValue) = paste("pvalue_",manovaRownames,sep="") - + # p-value adjusted if(length(condition) == 1) { aovAdjPValue = t(p.adjust(aovPValue,method=method)) } else { - aovAdjPValue = apply(aovPValue,2,p.adjust, method=method) + aovAdjPValue = t(apply(aovPValue,1,p.adjust, method=method)) } - rownames(aovAdjPValue) = paste("pvalueadjusted.",method,".",manovaRownames,sep="") - + rownames(aovAdjPValue) = paste("pval.",method,".",manovaRownames,sep="") + # selection colSumThreshold = colSums(aovAdjPValue <= threshold) if (selection_method == "intersection") { - datafiltered = data[,colSumThreshold == nrow(aovAdjPValue )] + datafiltered = data[,colSumThreshold == nrow(aovAdjPValue ), drop=FALSE] } else { - datafiltered = data[,colSumThreshold != 0] + datafiltered = data[,colSumThreshold != 0, drop=FALSE] } - + selected.var = rep("no",ncol(data)) + selected.var[colnames(data)%in%colnames(datafiltered)] = "yes" + #data=rbind(data, aovPValue, aovAdjPValue) - data=rbind(data, aovAdjPValue) + varinfoTab=cbind(varinfoTab, round(t(aovAdjPValue),10), selected.var) + + # group means + for (i in 1:length(condition)) { + for(j in levels(grps[[i]])){ + subgp = rownames(sampleinfoTab[which(sampleinfoTab[,condition[i]]==j),]) + modmean = colMeans(data[which(rownames(data)%in%subgp),],na.rm=TRUE) + varinfoTab=cbind(varinfoTab, modmean) + colnames(varinfoTab)[ncol(varinfoTab)] = paste0("Mean_",condition[i],".",j) + } + } + colnames(varinfoTab) = make.unique(colnames(varinfoTab)) - - if (mode == "row") { - data=t(data) - datafiltered=t(datafiltered) + # pdf for significant variables + pdf(outputdatasignif) + ### Venn diagram + if(nrow(aovAdjPValue)>5){ + pie(100,labels=NA,main=paste0("Venn diagram only available for maximum 5 terms\n", + "(your analysis concerns ",nrow(aovAdjPValue)," terms)\n\n", + "Number of significant variables relatively to\nyour chosen threshold and ", + "selection method: ",ncol(datafiltered)),cex.main=0.8) + }else{ + vennlist = list(NULL) + names(vennlist) = rownames(aovAdjPValue)[1] + if(length(colnames(aovAdjPValue))==0){colnames(aovAdjPValue)=varinfoTab[,1]} + for(i in 1:nrow(aovAdjPValue)){ + vennlist[[rownames(aovAdjPValue)[i]]]=colnames(aovAdjPValue[i,which(aovAdjPValue[i,]<=threshold),drop=FALSE]) + } + if(length(vennlist)==0){ pie(100,labels=NA,main="No significant ions was found.") + }else{ library(venn) ; venn(vennlist, zcolor="style", cexil=2, cexsn=1.5) } } - + ### Boxplot + par(mfrow=c(2,2),mai=rep(0.5,4)) + data <- as.data.frame(data) + for(i in 1:nrow(aovAdjPValue)){ + factmain = gsub(paste0("pval.",method,"."),"",rownames(aovAdjPValue)[i]) + factsignif = aovAdjPValue[i,which(aovAdjPValue[i,]<=threshold),drop=FALSE] + if((ncol(factsignif)!=0)&(factmain%in%colnames(sampleinfoTab))){ + for(j in 1:ncol(factsignif)){ + varsignif = gsub(" Response ","",colnames(factsignif)[j]) + boxplot(as.formula(paste0("data$",varsignif," ~ sampleinfoTab$",factmain)), + main=paste0(factmain,"\n",varsignif), col="grey", mai=7) + } + } + } + dev.off() + + # summary for significant variables + cat("\n\n- - - - - - - number of significant variables - - - - - - -\n\n") + for(i in 1:nrow(aovAdjPValue)){ + cat(rownames(aovAdjPValue)[i],"-", + sum(aovAdjPValue[i,]<=threshold),"significant variable(s)\n") + } + cat("\nIf some of your factors are missing here, this may be due to\neffects", + "not estimable; your design may not be balanced enough.\n") + # -- output / return -- - write.table(data, outputdatapvalue, sep=sep, quote=F, col.names = NA) - write.table(datafiltered, outputdatafiltered, sep=sep, quote=F, col.names = NA) - - # log + write.table(varinfoTab, outputdatapvalue, sep=sep, quote=F, row.names=FALSE) + + # log cat("\nthreshold:",threshold,"\n") - cat("result:",nrow(datafiltered),"/",nrow(data),"\n") - + cat("result:",ncol(datafiltered),"/",ncol(data),"\n\n") + quit("no",status=0) } @@ -127,6 +186,3 @@ listArguments = parseCommandArgs(evaluate=FALSE) do.call(anova, listArguments) - - - diff -r 4f06e1796334 -r b147b17759a6 abims_anova.xml --- a/abims_anova.xml Thu Oct 26 09:30:56 2017 -0400 +++ b/abims_anova.xml Wed Feb 28 07:44:13 2018 -0500 @@ -1,9 +1,10 @@ - - + + N-way anova. With ou Without interactions - + r-batch + r-venn @@ -11,39 +12,40 @@ -Rscript $__tool_directory__/abims_anova.r file '$input' sampleinfo '$sampleinfo' mode '$mode' +Rscript $__tool_directory__/abims_anova.r file '$input' sampleinfo '$sampleinfo' varinfo '$varinfo' mode '$mode' condition "c('$condition_1' #for $i, $s in enumerate( $conditions ) ,'${s.condition}' #end for )" -interaction $interaction -method $method -threshold $threshold -selection_method $selection_method -sep '$sep' -dec '$dec' -outputdatapvalue '$dataMatrixPValue' -outputdatafiltered '$dataMatrixFiltered' - +interaction $interaction +method $method +threshold $threshold +selection_method $selection_method +sep '$sep' +dec '$dec' +outputdatapvalue '$varMetaPValue' +outputdatasignif '$dataSignif' + - - + + + - + - + - + @@ -53,9 +55,9 @@ - - - + + + @@ -70,20 +72,21 @@ - + - - + + - + + @@ -93,8 +96,8 @@ - - + + @@ -102,7 +105,8 @@ .. class:: infomark -**Authors** Gildas Le Corguille ABiMS - UPMC/CNRS - Station Biologique de Roscoff - gildas.lecorguille|at|sb-roscoff.fr +**Authors** Gildas Le Corguille ABiMS - UPMC/CNRS - Station Biologique de Roscoff - gildas.lecorguille|at|sb-roscoff.fr +Melanie Petera - PFEM ; INRA ; MetaboHUB --------------------------------------------------- @@ -123,14 +127,15 @@ Input files ----------- -+---------------------------+------------+ -| Parameter : num + label | Format | -+===========================+============+ -| 1 : Data Matrix file | Tabular | -+---------------------------+------------+ -| 2 : Sample Metadata file | Tabular | -+---------------------------+------------+ - ++----------------------------+------------+ +| Parameter : num + label | Format | ++============================+============+ +| 1 : Data Matrix file | Tabular | ++----------------------------+------------+ +| 2 : Sample Metadata file | Tabular | ++----------------------------+------------+ +| 3 : Variable Metadata file | Tabular | ++----------------------------+------------+ ------------ @@ -141,118 +146,28 @@ ***.anova_pvalue.tabular** - | A tabular file which represents for each metabolite (row), the value of the intensity in each sample (column) + two columns (aovPValue and aovAdjPValue). - -***.anova_filtered.tabular** - - | The tabular file xset.anova_pvalue.tabular containing only the metabolites that have been filtered by aovAdjPValue. - - ------- - -.. class:: infomark + | Your variable metadata file completed with columns of p-values, result of selection method and means of subgroups. -The outputs ***.anova_filtered.tabular** or ***.anova_pvalue.tabular** are tabular files. You can continue your analysis using it in the following tools: - - | PCA - | Hierarchical Clustering +***.anova_signif.pdf** - - ---------------------------------------------------- - ---------------- -Working example ---------------- + | A pdf file containing a Venn diagram and boxplots of significant variables. -Input files ------------ - -**>A part of an example of Data Matrix file input** - +------ -+--------+------------------+----------------+ -| Name | Bur-eH_FSP_12 | Bur-eH_FSP_24 | -+========+==================+================+ -|M202T601| 91206595.7559783 |106808979.08546 | -+--------+------------------+----------------+ -|M234T851| 27249137.275504 |28824971.3177926| -+--------+------------------+----------------+ +.. class:: infomark -**>A part of an example of Sample Metadata file input** - - -+---------------------------+------------+------------+------------+ -| Sample name | class | time | batch | -+===========================+============+============+============+ -| Bur-eH_FSP_12 | Bur-eH | 12 | 1 | -+---------------------------+------------+------------+------------+ -| Bur-eH_FSP_24 | Bur-eH | 24 | 1 | -+---------------------------+------------+------------+------------+ -| Bur-NI_FSP_12 | Bur-NI | 12 | 2 | -+---------------------------+------------+------------+------------+ -| Bur-NI_FSP_24 | Bur-NI | 24 | 2 | -+---------------------------+------------+------------+------------+ - -Parameters ----------- +The outputs ***.anova_filtered.tabular** is a tabular file. You can continue your analysis using it in the following tools: - | Mode -> **row** - | column name of condition -> **class** - | Separator of columns: -> **tabulation** - | Decimal separator -> **.** - | PValue adjusted method -> **BH** - | Threshold -> **0.001** - - + | Generic_filter + | Hierarchical Clustering -Output files ------------- - -**Part of an example of xset.anova_filtered.tabular:** - -.. image:: anova_pvalue.png - -**Part of an example of xset.anova_pvalue.tabular:** - -.. image:: anova_filtered.png --------------------------------------------------- - ---------------------------- -Position in workflow4metabo ---------------------------- -**Upstream tools** - -+---------------------------+----------------------------------------+--------+------------------------+ -| Name | Output file | Format | parameter | -+===========================+========================================+========+========================+ -|CAMERA.annotateDiffreport |xset.annotatediffreport.data_matrix.tsv | Tabular| Data table file | -+---------------------------+----------------------------------------+--------+------------------------+ -|xcms.xcmsSet |sample_info.tab | Tabular| sample info table file | -+---------------------------+----------------------------------------+--------+------------------------+ - - -**Downstream tools** - -+---------------------------+---------------------------------------------------------+--------+ -| Name | Output file | Format | -+===========================+=========================================================+========+ -|PCA |xset.anova_pvalue.tabular OR xset.anova_filtered.tabular | Tabular| -+---------------------------+---------------------------------------------------------+--------+ -|Hierarchical Clustering |xset.anova_pvalue.tabular OR xset.anova_filtered.tabular | Tabular| -+---------------------------+---------------------------------------------------------+--------+ - - -**General schema of the metabolomic workflow** - -.. image:: anova_workflow.png - diff -r 4f06e1796334 -r b147b17759a6 static/images/anova_filtered.png Binary file static/images/anova_filtered.png has changed diff -r 4f06e1796334 -r b147b17759a6 static/images/anova_pvalue.png Binary file static/images/anova_pvalue.png has changed diff -r 4f06e1796334 -r b147b17759a6 static/images/anova_workflow.png Binary file static/images/anova_workflow.png has changed diff -r 4f06e1796334 -r b147b17759a6 test-data/dataMatrix.tsv_anova_filtered.tabular --- a/test-data/dataMatrix.tsv_anova_filtered.tabular Thu Oct 26 09:30:56 2017 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ - HU_017 HU_028 HU_034 HU_051 HU_060 HU_078 HU_091 HU_093 HU_099 HU_110 HU_130 HU_134 HU_138 HU_149 HU_152 HU_175 HU_178 HU_185 HU_204 HU_208 -HMDB00208 747080 13420742 595872 1172376 7172632 3143654 4059767 1433702 5593888 5402629 2477288 3346077 4230072 7621236 8960828 10335722 7037373 1574738 3359238 2540044 -HMDB00512 53304 319783 280560 85009 1333877 556003 590779 209285 342532 198512 569970 525240 246282 1140422 542345 1171008 827723 222953 438839 85554 diff -r 4f06e1796334 -r b147b17759a6 test-data/dataMatrix.tsv_anova_pvalue.tabular --- a/test-data/dataMatrix.tsv_anova_pvalue.tabular Thu Oct 26 09:30:56 2017 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ - HU_017 HU_028 HU_034 HU_051 HU_060 HU_078 HU_091 HU_093 HU_099 HU_110 HU_130 HU_134 HU_138 HU_149 HU_152 HU_175 HU_178 HU_185 HU_204 HU_208 pvalueadjusted.BH.age pvalueadjusted.BH.gender -HMDB03193 76043 412165 44943 27242 436566 173175 242549 57066 559869 3732 339188 471368 262271 127285 451270 212500 79673 NA 891129 43907 0.740856975457218 0.740856975457218 -HMDB01101 30689 6877586 52217 3158 10789748 229568 4763576 3878773 976436 831937 608298 1605075 72021 442510 1107705 1464339 31250 2724553 72900 32742 0.347623051099051 0.234554902330543 -HMDB10348 47259 544877 60885 34582 529874 168264 176500 76457 610110 16262 279156 524468 451573 591487 433529 161069 214392 13781 1580343 39315 0.720303175717481 0.720303175717481 -HMDB59717 357351 1030464 301983 67604 306862 1028110 1530493 270027 1378535 289677 808334 1132813 871209 895435 715190 1563158 784738 146195 994336 239030 0.252979062487671 0.517822514350462 -HMDB00822 483755 579287 1132413 157113 1577570 1469735 1085454 477909 814755 245417 610681 763706 2406336 827531 992508 569605 355321 150259 1334200 271010 0.808532959173048 0.808532959173048 -HMDB13189 2644620 727587 1661412 619181 136278 2755434 593863 837865 3526136 2003278 1608814 3446611 1941527 113937 3132404 2893445 2092753 1034666 1517319 841661 0.329174238111018 0.329174238111018 -HMDB00299 250551 1046138 456162 159386 1013302 808657 614370 250403 768004 242085 504108 1014041 1362408 1057660 1110050 566050 411886 142233 1992420 284775 0.995859884733937 0.995859884733937 -HMDB00191 560002 771533 575790 392284 888498 785428 645785 591569 960658 910201 639437 1092885 1409045 2292023 1246459 1945577 710519 773384 1061418 622898 0.15341384456659 0.15341384456659 -HMDB00518 34236 58249 85944 NA 342102 129886 175800 13154 230242 NA 440223 315368 10657 419508 48673 28361 514579 23108 867108 73831 0.439012867631325 0.596200901535843 -HMDB00715 1252089 2547452 905408 371059 4983588 5140022 2658555 814523 2558923 859466 4184204 3865723 3236644 2615560 3820724 3577833 2295288 625924 7517724 1341900 0.814406453193777 0.814406453193777 -HMDB01032 2569205 26023086 1604999 430453 8103558 26222916 257139 675754 59906109 263055 31151730 18648127 14989438 1554658 20249262 5588731 871010 15920 9120781 44276 0.288354536353544 0.288354536353544 -HMDB00208 747080 13420742 595872 1172376 7172632 3143654 4059767 1433702 5593888 5402629 2477288 3346077 4230072 7621236 8960828 10335722 7037373 1574738 3359238 2540044 0.659785284053633 0.00376251274734483 -HMDB04824 374028 1144386 539206 178517 1046190 959381 605191 310260 1253319 477259 477995 825691 1157093 1089284 1411802 1020206 782673 346761 1824553 387811 0.646714644805001 0.646714644805001 -HMDB00512 53304 319783 280560 85009 1333877 556003 590779 209285 342532 198512 569970 525240 246282 1140422 542345 1171008 827723 222953 438839 85554 0.13976111393526 0.0491480895853803 -HMDB00251 368600 616555 94936 622468 180988 293988 352855 767894 268331 167246 310918 1248919 577184 10985 335711 403815 80614 63393 454489 616061 0.565910223149305 0.565910223149305 diff -r 4f06e1796334 -r b147b17759a6 test-data/dataMatrix.tsv_anova_signif.pdf Binary file test-data/dataMatrix.tsv_anova_signif.pdf has changed diff -r 4f06e1796334 -r b147b17759a6 test-data/variableMetadata.tsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/variableMetadata.tsv Wed Feb 28 07:44:13 2018 -0500 @@ -0,0 +1,16 @@ +variables numHMDB +HMDB03193 03193 +HMDB01101 01101 +HMDB10348 10348 +HMDB59717 59717 +HMDB00822 00822 +HMDB13189 13189 +HMDB00299 00299 +HMDB00191 00191 +HMDB00518 00518 +HMDB00715 00715 +HMDB01032 01032 +HMDB00208 00208 +HMDB04824 04824 +HMDB00512 00512 +HMDB00251 00251 diff -r 4f06e1796334 -r b147b17759a6 test-data/variableMetadata.tsv_anova_pvalue.tabular --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/variableMetadata.tsv_anova_pvalue.tabular Wed Feb 28 07:44:13 2018 -0500 @@ -0,0 +1,16 @@ +variables numHMDB pval.BH.age pval.BH.gender selected.var Mean_age.20-30 Mean_age.30-40 Mean_age.40-50 Mean_age.50-60 Mean_age.60-70 Mean_gender.F Mean_gender.M +HMDB03193 3193 0.7937753308 0.7855401401 no 270572 392525.5 279004.4 135576.75 161111 199371.111111111 311760.1 +HMDB01101 1101 0.7449065381 0.4721949521 no 530010.25 647011.75 1923248.66666667 3888168.75 2397413 2430552.8 1228955.3 +HMDB10348 10348 0.780857123 0.8311190489 no 279384 653013.75 291703.666666667 170869.5 195446 257916.8 397501.5 +HMDB59717 59717 0.7449065381 0.7855401401 no 600089.75 1065315.75 761023.666666667 292137.25 1157615.5 603835.3 867319.1 +HMDB00822 822 0.8085329592 0.7855401401 no 558846.5 835504.25 975513 858327.25 720387.5 572562.1 1057894.4 +HMDB13189 13189 0.7449065381 0.5606315068 no 2029845.5 1533378.75 2091740.83333333 1159708.25 1343308 1359519 2053360.1 +HMDB00299 299 0.780857123 0.9958598847 no 580553.75 1030059.5 770671.333333333 490488 513128 603356.5 802112.4 +HMDB00191 191 0.7449065381 0.4721949521 no 805574.75 1484613.75 898712.833333333 741514.5 678152 1055337.6 832201.7 +HMDB00518 518 0.7449065381 0.7855401401 no 117582 438800 95250.6666666667 147066.666666667 345189.5 188551.375 230261.8 +HMDB00715 715 0.780857123 0.8725783427 no 2023151.5 4473830.25 2777975.66666667 1890746.25 2476921.5 2303879.4 3213381.5 +HMDB01032 1032 0.7449065381 0.5606315068 no 20157525 11853975 14744782 2661841.5 564074.5 6314400.9 16514619.8 +HMDB00208 208 0.780857123 0.0282188456 yes 4566784 5948371 4410393.83333333 3651208.75 5548570 6523832 2898663.8 +HMDB04824 4824 0.780857123 0.7855401401 no 807862.25 1103009.5 801223.333333333 593228.75 693932 788488.9 832671.7 +HMDB00512 512 0.7449065381 0.1843053359 no 263860 830059.75 320594.166666667 505558.5 709251 592718.6 381279.4 +HMDB00251 251 0.780857123 0.7855401401 no 460642.75 295051.75 528106.5 302766 216734.5 309783.6 473811.4