# Licence ----
#
# Copyright or © or Copr. CNRS 2020-2024
#
#
# This package is under
# The “Creative Commons Attribution-ShareAlike International License” version 4.0
# A copy of the License is available at
# http://www.r-project.org/Licenses/
# _________________________________________________________________________________
# Version 2024-06-18
#
#' @author "Philippe DUFRESNE, Théo DUBROCA"
#' @docType package
# Equation du 3 degrées
# résolution du 3 eme degre pour calcul mcFadden importé de ARMAG
# modifier suivant livre photocopié
# Fonction interne
EQUATION_DEGRE_3 <- function(A1, A2, A3)
{
Q <- (3*A2-A1*A1)/9
R <- (9*A1*A2-27*A3-2*A1*A1*A1)/54
D <- Q*Q*Q+R*R
# Discriminant équation du 3eme degre
if (D>0) {
S <- exp( log( R + sqrt(D) )/3)
if ( R>sqrt(D))
T1 <- exp(log( R - sqrt(D) )/3)
else
T1 <- -exp(log( -R + sqrt(D) )/3)
PZ1 <- S+ T1 -(A1/3)
# Les deux autres solutions sont complexes
PZ2 <- 0
PZ3 <- 0
}
else if (D==0) {
S <- exp( log(-Q/2)/3)
PZ1 <- 2*S-(A1/3)
PZ2 <- -S-(A1/3)
PZ3 <- -S-(A1/3)
}
else if (D<0) {
TETA <- acos( R/sqrt(-Q*Q*Q) )/3
U <- 2*sqrt(-Q)
PZ1 <- U*cos(TETA)-(A1/3);
PZ2 <- U*cos(TETA + 2/3*pi)-(A1/3)
PZ3 <- U*cos(TETA + 4/3*pi)-(A1/3)
}
rslt <- NULL
rslt$PZ1 <- as.numeric(PZ1)
rslt$PZ2 <- as.numeric(PZ2)
rslt$PZ3 <- as.numeric(PZ3)
return(rslt)
}
# Equation du 4 degrées
# résolution du 4 ème degre pour calcul mcFadden importé de ARMAG
# Fonction interne
EQUATION_DEGRE_4 <- function(B1, B2, B3, B4)
{
E3 <- EQUATION_DEGRE_3(-B2, B1*B3-4*B4, 4*B2*B4-B3*B3-B1*B1*B4)
TZ <- E3$PZ1
if (E3$PZ2>TZ)
TZ <- E3$PZ2
if (E3$PZ3>TZ)
TZ <- E3$PZ3
SQ <- sqrt(B1*B1/4-B2+TZ)
C1 <- B1/2-SQ
C2 <- TZ/2-(B1*TZ/2-B3)/(2*SQ)
if ((C1*C1-4*C2)>=0) {
PX1 <- (-C1+ sqrt(C1*C1-4*C2))/2
PX2 <- (-C1- sqrt(C1*C1-4*C2))/2
} else {
PX1 <- 0
PX2 <- 0
}
D1 <- B1/2+SQ
D2 <- TZ/2+(B1*TZ/2-B3)/(2*SQ)
if ((D1*D1-4*D2)>=0) { # une solution double
PX3 <- (-D1+ sqrt(D1*D1-4*D2))/2
PX4 <- (-D1- sqrt(D1*D1-4*D2))/2
}
else {
PX3 <- 0
PX4 <- 0
}
rslt <- NULL
rslt$PX1 <- as.numeric(PX1)
rslt$PX2 <- as.numeric(PX2)
rslt$PX3 <- as.numeric(PX3)
rslt$PX4 <- as.numeric(PX4)
return(rslt)
}
#' Calcul l'arc sinus d'un réel renvoie un angle entre -PI/2 et +PI/2
#' @return angle en radian
#' Fonction interne
n_arcsin <- function(x)
{
n <- NA
if ( abs(x) < 1) {
n <- atan(x/sqrt(1-x*x))
}
else {
if (x>=1)
{n <- pi/2}
else
{n <- -pi/2}
}
return(n)
}
#' Calcul l'arc cosinus d'un réel renvoie un angle entre 0 et +PI
#' @return angle en radian
#' Fonction interne
n_arccos <- function(x)
{
n <- NA
if (abs(x)<1)
n <- (pi/2-atan(x/sqrt(1-x*x)) )
else
if (x>=1)
n <- 0
else
n <- pi
return(n)
}
#' Calcul de l'angle D entre -pi <= angD < +3 pi retourne en radian
#' @return angle en radian
#' Fonction interne
angleD <- function(X, Y)
{
res <- NULL
for (i in 1:length(X)) {
if (X[i] == 0)
res <- c(res, sign(Y[i])*pi/2)
else {
if (X[i]<0)
res <- c(res, atan(Y[i]/X[i]) + pi)
else
res <- c(res, atan(Y[i]/X[i]) )
}
}
return(res)
}
#' Statistique de mcFadden sur l'inclinaison seule à partir des coordonées XYZ
#' @seealso \code{\link{stat.mcFadden}}, \code{\link{stat.fisher}}
#' @export
stat.mcFadden.XYZ <- function(TabX, TabY, TabZ)
{
N <- length(TabX)
VP <- to.polar(TabX, TabY, TabZ)
stat.mcFadden(inc, dec)
}
#' Statistique de mcFadden sur l'inclinaison seule à partir des coordonées I et D
#' @param Data liste des inclinaisons en degré ou une data.frame avec les variables $I et $D
#' @param dec liste des déclinaisons en degré
#' @param inc.absolue calcul avec la valeur absolue des inclinaisons
#' @return en degré, un data.frame "n", "imoy.McFadden", "imoy.McElhinny", "a95.mcFad", "a95.eqFish", "Kb", "Kssb", "imin", "imax", "dmin", "dmax"
#' @seealso \code{\link{stat.mcFadden.XYZ}}, \code{\link{stat.fisher}}
#' @references https://doi.org/10.1111/j.1365-246X.1990.tb05683.x
#' @export
stat.mcFadden <- function(Data, dec = NULL, inc.absolue = TRUE)
{
if (is.null(dec)) {
inc <- Data$I
dec <- Data$D
Dmin <- min(dec)
Dmax <- max(dec)
} else {
inc <- Data
Dmin <- min(dec)
Dmax <- max(dec)
}
if (inc.absolue)
inc <- abs(inc)
# Calcul des sommes
N <- length(inc)
if (N<=2) {
warning("length(inc) < 3")
return()
}
Imin <- min(inc)
Imax <- max(inc)
Imoy <- 0
# Passage en radian pour les calculs
i.rad <- as.numeric(inc*pi/180)
A <- sum(sin(i.rad))
B <- sum(cos(i.rad))
P <- 2*(N+2*B)/A
Q <- -6
R <- 2*(N-2*B)/A
S <- 1
E4 <- EQUATION_DEGRE_4(P, Q, R, S)
KJ <- N/(2*(N-A*sin(2*atan(E4$PX1))-B*cos(2*atan(E4$PX1))))
Imoy <- 2*atan(E4$PX1)
K <- KJ
KJ <- N/(2*(N-A*sin(2*atan(E4$PX2))-B*cos(2*atan(E4$PX2))))
if (KJ>K) {
Imoy <- 2*atan(E4$PX2)
K <- KJ
}
KJ <- N/(2*(N-A*sin(2*atan(E4$PX3))-B*cos(2*atan(E4$PX3))))
if (KJ>K) {
Imoy <- 2*atan(E4$PX3)
K <- KJ
}
KJ <- N/(2*(N-A*sin(2*atan(E4$PX4))-B*cos(2*atan(E4$PX4))))
if (KJ>K) {
Imoy <- 2*atan(E4$PX4)
K <- KJ
}
CFad <- sum(cos(i.rad-Imoy))
SFad <- sum(sin(i.rad-Imoy))
I.McElhinny <- Imoy /pi*180 # modif effectuée le 2017/01/25
imoy.McFadden <- (Imoy + (SFad/CFad) ) /pi*180
a95mcFadden <- 1 - ((SFad/CFad)^2)/2 - (qf(.95, 1, N-1)*(N-CFad)/(CFad*(N-1)))
a95mcFadden <- acos(a95mcFadden) /pi*180
Kssb <- (N-1)/2/(N-CFad)
# retour en degré #
return(data.frame( n= N, imoy.McFadden = imoy.McFadden, imoy.McElhinny = I.McElhinny,
a95.mcFad = a95mcFadden, a95.eqFish = 2.4477/sqrt(N*K)/pi*180,
Kb = K, Kssb = Kssb,
imin = Imin, imax = Imax, Dmin = Dmin, Dmax = Dmax))
}
#' Statistique de Fisher
#' modifié, pas de pondération calcul de A95 Vrai sans simplification tel que fisher 1953
#' @param Data liste des inclinaisons en degré ou une data.frame avec les variables $I et $D
#' @param dec liste des déclinaisons en degrés
#' @param aim liste des aimantations, facultatif
#' @param pfish pourcentage de confiance
#' @param inc.absolue calcul avec la valeur absolue des inclinaisons
#' @return en degrés
#' @seealso \code{\link{stat.mcFadden}}
#' @keywords fisher
#' @export
stat.fisher <- function (Data, dec = NULL, aim = NA, pfish = 0.95, inc.absolue = TRUE)
{
if (is.null(dec)) {
inc <- Data$I
dec <- Data$D
} else {
inc <- Data
dec <- dec
}
n <- length(inc)
if (length(dec) != n) {
return("length (dec) diff length(inc)")
}
if (is.na(aim) || length(aim) != n) {
# message("length(aim) diff length(inc)")
aim <- rep(1, n)
}
if (inc.absolue == TRUE)
inc <- abs(inc)
imin <- min(inc)
imax <- max(inc)
dmin <- min(dec)
dmax <- max(dec)
# Passage en radian pour les calculs
i.rad <- inc/180*pi
d.rad <- dec/180*pi
sx <- sum(aim*cos(i.rad)*cos(d.rad))
sy <- sum(aim*cos(i.rad)*sin(d.rad))
sz <- sum(aim*sin(i.rad))
sn <- sum(aim)
r <- sqrt(sx*sx+sy*sy+sz*sz)
imoy <- n_arcsin(sz/r)
dmoy <- angleD(sx,sy)
KF <- sn/(sn-r)
# Calcul de A95 Vrai sans simplification tel que fisher 1953
a95 <- exp( (1/(n-1))* log(1/(1-pfish)) )
a95 <- (a95 - 1 )*(n-r)/r
a95 <- acos(1-a95)
# correction du biais
KF <- ((n-1)/n) * KF
if (KF<10) {
delta <- log(1+ (1-pfish) * (exp(2*KF) -1) ) /KF
delta <- acos(delta-1)
} else {
delta <- log(1-pfish)/KF
delta <- acos(1 + delta)
}
# retour en degrés
return(data.frame(n = n, imoy =imoy/pi*180, dmoy = dmoy/pi*180, alpha=a95/pi*180, pfish = pfish, delta = delta/pi*180, KF = KF,
imin = imin, imax = imax, dmin = dmin, dmax = dmax))
}
#' Valeurs maximun d'un tracer lambert
#' Permet de trouver les valeurs minimales et maximales pour tracer un lambert
#' Fonction interne
find.extremum <- function(i.min = 0, i.max = 90, d.min = -90, d.max = 270)
{
d.seq <- seq( d.min, d.max, length.out = 300)
x1.seq <- sin(d.seq*pi/180 ) * (1 - (i.min-i.min)/(90-i.min))
x2.seq <- sin(d.seq*pi/180 ) * (1 - (i.max-i.min)/(90-i.min))
y1.seq <- cos(d.seq*pi/180 ) * (1 - (i.min-i.min)/(90-i.min))
y2.seq <- cos(d.seq*pi/180 ) * (1 - (i.max-i.min)/(90-i.min))
x.range <- range(x1.seq, x2.seq)
y.range <- range(y1.seq, y2.seq)
return(c(x.range = x.range, y.range = y.range))
}
# Transformation des mesures en coordonnées graphiques ----------------------
#' Valeur de X graphique pour I et D
#' Fonction interne
#' @param i inclinaison en degrés
#' @param d déclinaison en degrés
X <- function (i, d, ray=1, i.min = 0, box.range)
{
x <- sin(d*pi/180 ) * (1 - (abs(i)-i.min)/(90-i.min)) - (box.range[2] + box.range[1])/2
c <- NA
if ((box.range[2] - box.range[1]) > (box.range[4] - box.range[3]))
c <- box.range[2] - box.range[1]
else
c <- box.range[4] - box.range[3]
x /c *ray *2
}
#' Valeur de Y graphique pour I et D
#' Fonction interne
#' @param i inclinaison en degrés
#' @param d déclinaison en degrés
Y <- function(i, d, ray=1, i.min = 0, box.range)
{
y <- cos(d*pi/180 ) * (1 - (abs(i)-i.min)/(90-i.min)) - (box.range[4] + box.range[3])/2
c<-NA
if ((box.range[2] - box.range[1]) > (box.range[4] - box.range[3]))
c <- box.range[2] - box.range[1]
else
c <- box.range[4] - box.range[3]
y /c *ray *2
}
# Transformation de type de repère -----------------
## Conversion
#' Conversion de Degrés Minute Second en Degré Décimal
#' @param degre degrés entier
#' @param minute minute entière
#' @param second seconde en décimal
#' @seealso \code{\link{DD.to.DMS}}
#' @export
DMS.to.DD <- function(degre, minute, second = 0)
{
if (degre>=0) {
return(as.numeric(degre + minute/60 + second/3600) )
} else {
return(as.numeric(degre - minute/60 - second/3600) )
}
}
#' Conversion de Degré Décimal en Degrés Minute Second
#' @param degre degrés décimal
#' @seealso \code{\link{DMS.to.DD}}
#' @export
DD.to.DMS <- function(degre)
{
absDegre <- abs(degre)
res <- NULL
res$Degre <- floor(absDegre)
res$Minute <- floor((absDegre - res$Degre)*60)
res$Second <- ((absDegre - res$Degre)*60 - res$Minute)*60
if (degre<0)
res$Degre <- res$Degre*(-1)
return(res)
}
#' Convertie la déclinaison dans la convention AM
#' @param d déclinaison en degré
#' @return angle en degré en -90° et 270°
#' @export
D.AM <- function(d)
{
res <- d
if (d< (-90))
res <- 360 + d
if (d>270)
res <- d-360
return(res)
}
#' Convertie la déclinaison dans la convention paleomag
#' @param d déclinaison en degré
#' @return déclinaison entre 0 et 360°
#' @export
D.pal <- function(d)
{
if ( d>270)
return(d-360)
}
# Transformation de type de coordonnée ----
## to cartesian vector ----
#' Valeur de Y pour I et D
#' @param inc liste des inclinaisons en degré
#' @param des liste des déclinaisons en degré
#' @seealso \code{\link{to.cartesian}} , \code{\link{to.polar}}
#' @export
to.cartesian.Y <- function(inc, dec, aim =1)
{
as.numeric(aim*cos(inc/180*pi)*sin(dec/180*pi) )
}
#' Valeur de X pour I et D
#' @param inc liste des inclinaisons en degré
#' @param des liste des déclinaisons en degré
#' @seealso \code{\link{to.cartesian}} , \code{\link{to.polar}}
#' @export
to.cartesian.X <- function(inc, dec, aim=1)
{
as.numeric(aim*cos(inc/180*pi)*cos(dec/180*pi) )
}
#' Valeur de Z pour I et D
#' @param inc liste des inclinaisons en degré
#' @param des liste des déclinaisons en degré
#' @seealso \code{\link{to.cartesian}} , \code{\link{to.polar}}
#' @export
to.cartesian.Z <- function(inc, dec, aim=1)
{
as.numeric(aim*sin(inc/180*pi))
}
#' Valeur de X, Y et Z pour I et D
#' @param inc liste des inclinaisons en degrés
#' @param des liste des déclinaisons en degrés
#' @seealso \code{\link{to.polar}}
#' @export
to.cartesian <- function(inc, dec, aim=1)
{
res <- NULL
resT <- NULL
for (i in 1:length(inc)) {
res$X <- as.numeric( aim*cos(inc[i]/180*pi)*cos(dec[i]/180*pi) )
res$Y <- as.numeric( aim*cos(inc[i]/180*pi)*sin(dec[i]/180*pi) )
res$Z <- as.numeric( aim*sin(inc[i]/180*pi) )
res$I <- inc[i]
res$D <- dec[i]
res$F <- aim[i]
resT <- c(resT, res)
}
return( resT )
}
#' Coordonnées polaires pour X, Y et Z
#' @return I, D, F en degré
#' @seealso \code{\link{to.polar}} , \code{\link{cartesien}}
#' @export
to.polar <- function(X, Y, Z)
{ #en A/m
res <- NULL
resT <- NULL
for (i in 1:length(X)) {
res$X <- X[i]
res$Y <- Y[i]
res$Z <- Z[i]
aim <- as.numeric( sqrt(X[i]*X[i] + Y[i]*Y[i] + Z[i]*Z[i]) )
if ( aim== 0) {
res$I <- as.numeric( 0 )
res$D <- as.numeric( 0 )
} else {
res$I <- as.numeric( n_arcsin(Z[i]/aim) /pi*180 )
res$D <- as.numeric( angleD(X[i],Y[i]) /pi*180 )
}
res$F <- aim
resT <- c(resT, res)
}
return( resT )
}
# Calcul vecteur polaire ----
#' inclinaison pour X, Y et Z
#' @return angle en degré
#' @export
to.polar.I <- function(X, Y, Z)
{ #en A/m
res <- NULL
for (i in 1:length(X)) {
A <- as.numeric( sqrt(X[i]*X[i]+Y[i]*Y[i]+Z[i]*Z[i]) )
res <- c(res, n_arcsin(Z[i]/A)/pi*180)
}
return(res)
}
#' Déclinaison pour X, Y et Z
#' #' @return angle en degré
#' @export
to.polar.D <- function(X, Y, Z)
{ #en A/ms
res <- NULL
for (i in 1:length(X)) {
res <- c(res, angleD(X[i],Y[i])/pi*180)
}
return(res)
}
#' champs pour X, Y et Z
#' @export
to.polar.F <- function(X, Y, Z)
{ #en A/m
res <- NULL
for (i in 1:length(X)) {
res <- c(res, sqrt(X[i]*X[i]+Y[i]*Y[i]+Z[i]*Z[i]))
}
return(res)
}
# Trace des graphes ----
## Plot Lambert directionnel ID ----
#' lambert.ID.grid
#' Trace une grille dans le repère Lambert, fonctionne avec la fonction lambert()
#'
#' # Pour choisir les graduations
#' et pour paleomag : lab.pos$D = c(seq(270, 350, by=10), seq(0, 90, by=10))
#' Label.pos : doit être dans l'étendu des dex.min, dec.max, inc.min, inc.max
#'
#' @param radlab écrit les labels sous forme d'étoile
#' @param label.pos séquence de valeur à afficher en I et D, attention format particulier !!
#' @examples
#' label.pos = NULL
#' label.pos$I = seq(0, 90, by=20)
#' label.pos$D = seq(0, 90, by=10)
#' @export
lambert.ID.grid <- function (main = "", xlab = "", ylab = "", labels = NA, label.pos = NULL, radlab = FALSE,
start = 0, clockwise = FALSE, label.prop = 1.1,
grid.col = "gray", grid.bg = "transparent", show.radial.grid = TRUE, labels.precision = 0,
dec.min = -90, dec.max = 270, inc.min = 0, inc.max = 90, new = TRUE, ...)
{
# setting up coord. system
if (new == TRUE) {
par( pty = "s")
maxlength <- 100 # la valeur n'a pas d'influence, la fonction plot() calcul le reste
plot(c(-maxlength, maxlength), c(-maxlength, maxlength), type = "n", axes = FALSE, main = main, xlab = xlab, ylab = ylab, new = new)
}
labelsD <- NULL
maxlength <- 100
par(xpd = TRUE)
box.range <- find.extremum(inc.min, inc.max, dec.min, dec.max)
anglesD <- seq(dec.min, dec.max, by = 1) # angle de deviation en degrée
if (is.null(label.pos)) {
labelI.pos <- seq(inc.min, inc.max, by = 10)
labelD.pos <- seq(dec.min, dec.max, by = 10)
}
else {
labelI.pos <- label.pos$I
labelD.pos <- label.pos$D
}
# Supprime la superposition des labels pour D égale à -90 et 270
if ((labelD.pos[1] == -90) && (labelD.pos[length(labelD.pos)] == 270))
labelD.pos <- labelD.pos[-length(labelD.pos)]
if (show.radial.grid) {
# Trace un cercle autour
xpos <- X(inc.min, anglesD, maxlength, i.min = inc.min, box.range)
ypos <- Y(inc.min, anglesD, maxlength, i.min = inc.min, box.range)
lines(xpos, ypos, col = adjustcolor( grid.col, alpha.f = 0.5))
# Trace les cercles radiaux concentriques
if (length(labelI.pos)>0)
for (i in seq(length(labelI.pos), 1, by = -1)) {
xpos <- X(labelI.pos[i], anglesD, maxlength, i.min = inc.min, box.range)
ypos <- Y(labelI.pos[i], anglesD, maxlength, i.min = inc.min, box.range)
lines(xpos, ypos, col = adjustcolor( grid.col, alpha.f = 0.5)) #, border = grid.col)
}
if (!is.null(labels)) {
if (is.na(labels[1]))
labelsI <- as.character(round(labelI.pos, labels.precision))
labelsD <- as.character(round(labelD.pos, labels.precision))
}
if (clockwise == FALSE)
labelD.pos <- -labelD.pos
if (start)
labelD.pos <- labelD.pos + start
# Trace les rayons
#if (show.radial.grid) {
for (i in 1: length(labelD.pos)) {
xposA <- X(inc.min, labelD.pos[i], ray = maxlength, inc.min, box.range)
yposA <- Y(inc.min, labelD.pos[i], ray = maxlength, inc.min, box.range)
xposB <- X(inc.max, labelD.pos[i], ray = maxlength, inc.min, box.range)
yposB <- Y(inc.max, labelD.pos[i], ray = maxlength, inc.min, box.range)
segments( x0=xposA, y0=yposA, x1=xposB, y1=yposB, col = grid.col)
}
for (label in 2:length(labelI.pos)) {
xpos <- X(labelI.pos[label], dec.min, ray = maxlength, inc.min, box.range)
ypos <- Y(labelI.pos[label], dec.min, ray = maxlength, inc.min, box.range)
#labelsrt <- dec.min + 90 # labelI.pos[label] + 90 #* label.prop
corect<- 6
if (dec.min >= -90 && dec.min < 0) {
labelsrt <- ( 270 - dec.min)
xpos <- xpos + label.prop*cos(dec.min/180*pi) * corect
ypos <- ypos - label.prop*(2+sin(dec.min/180*pi)) * corect
}
else if (dec.min >= 0 && dec.min < 90) {
labelsrt <- (90 - dec.min)
xpos <- xpos - label.prop*cos(dec.min/180*pi) * corect
ypos <- ypos + label.prop*sin(dec.min/180*pi) * corect
}
else if (dec.min >= 90 && dec.min < 180) {
labelsrt <- (90 - dec.min)
xpos <- xpos + label.prop*cos(dec.min/180*pi) * corect
ypos <- ypos + label.prop*sin(dec.min/180*pi) * corect
}
else {
labelsrt <- (270 - dec.min)
xpos <- xpos - label.prop*cos(dec.min/180*pi) * corect
ypos <- ypos - label.prop*sin(dec.min/180*pi) * corect
}
# if (labelD.pos[label] > 0 && labelD.pos[label] < 180)
# labelsrt <- (90 - labelD.pos[label])
# else
# labelsrt <- (270 - labelD.pos[label]) labelsI[label],
text(xpos, ypos,labelsI[label] , srt = labelsrt, cex = par("cex.axis"))
# boxed.labels(xpos, ypos, labelsI[label], ypad = par("cex.axis"), border = FALSE, cex = par("cex.axis"))
}
# Ecrit les textes des angles
}
else {
# Trace un cercle autour
#for (i in seq(dec.min, dec.max, by = 1)) {
xpos <- X(inc.min, anglesD, maxlength, i.min = inc.min, box.range)
ypos <- Y(inc.min, anglesD, maxlength, i.min = inc.min, box.range)
lines(xpos, ypos, col = adjustcolor( grid.col, alpha.f = 0.5)) #, border = grid.col)
#}
}
if (!is.null(labelsD)) {
xpos <- X(inc.min, labelD.pos, ray = maxlength, inc.min, box.range) * label.prop
ypos <- Y(inc.min, labelD.pos, ray = maxlength, inc.min, box.range) * label.prop
if (radlab) { # radlab écrit les labels sous forme d'étoile
for (label in 1:length(labelD.pos)) {
if (labelD.pos[label] > 0 && labelD.pos[label] < 180)
labelsrt <- (90 - labelD.pos[label])
else
labelsrt <- (270 - labelD.pos[label])
text(xpos[label], ypos[label], labelsD[label], cex = par("cex.axis"), srt = labelsrt)
}
}
else { # boxed.labels(xpos, ypos, labelsD, ypad = 0.7, border = FALSE, cex = par("cex.axis"))
for (label in 1:length(labelD.pos)) {
text(xpos[label], ypos[label], labelsD[label], cex = par("cex.axis"), srt = 0)
}
}
}
par(xpd = FALSE)
}
#' lambert
#' Place des points I et D dans un repère Lambert avec un data.frame
#' @param data data.frame avec les variables $I d'inclinaison et $D de déclinaison
#' @param pt.names Correspond à la liste des noms des points. Laissée vide n'affiche rien. Si on met pt.names = "", cela affiche les noms
#' @param label.pos Séquence de valeur à afficher en I et D, voir fonction lambert.ID.grid
#' @param point.symbols défini la forme de points, correspond exactement au pch de la fonction points()
#' @param pch permet de changer la forme du symbole
#' @param show.grid permet d'afficher une grille en toile d'araigné sur le fond. Mettre à FALSE, si on superpose des diagrammes
#' @param show.grid.labels permet de changer échelle des graduations
#' @param inc.lim permet de restreindre l'affichage sur une étendue d'inclinaison. Ex: inc.lim = c(45, 90). Laissée à NULL, le diagramme s'addapte aux données
#' @param dec.min permet de restreindre l'étendue en déclinaison, borne minimale
#' @param dec.max permet de restreindre l'étendue en déclinaison, borne maximale
#' @param new permet d'initialiser la sortie graphique. Mettre à FALSE, si on superpose des diagrammes.
#' @export
lambert <- function (data , pt.names = NULL, labels = NA, label.pos = NULL,
radlab = FALSE, start = 0, clockwise = TRUE,
label.prop = 1.1, main = "", xlab = "", ylab = "", line.col = par("fg"),
lty = par("lty"), lwd = par("lwd"), mar = c(2, 2, 3, 2),
show.grid = TRUE, show.grid.labels = 10, show.radial.grid = TRUE,
grid.col = "gray", grid.bg = "transparent",
grid.left = FALSE, grid.unit = NULL, point.symbols = 1, pt.col = par("fg"), bg = pt.col,
inc.lim = NULL, radial.labels = NULL,
boxed.radial = TRUE, poly.col = NA,
dec.min = -90, dec.max = 270, new = TRUE, pch = 21, ...)
{
if (is.null(pt.names))
name <- NULL
else
name <- data$name
lambert.ID (data$I, data$D , pt.names = name, labels = labels, label.pos = label.pos,
radlab = radlab, start = start, clockwise = clockwise,
label.prop = label.prop, main = main, xlab = xlab, ylab = ylab, line.col = line.col,
lty = lty, lwd = lwd, mar = mar,
show.grid = show.grid, show.grid.labels = show.grid.labels, show.radial.grid = show.radial.grid,
grid.col = grid.col, grid.bg = grid.bg,
grid.left = grid.left, grid.unit = grid.unit, point.symbols = point.symbols, pt.col = pt.col, bg = pt.col,
inc.lim = inc.lim, radial.labels = radial.labels,
boxed.radial = boxed.radial, poly.col = poly.col,
dec.min = dec.min, dec.max = dec.max, new = new, pch = pch, ...)
}
#' Place des points I et D dans un repère Lambert
#' @export
lambert.ID <- function (inc, dec , pt.names = NA, labels = NA, label.pos = NULL,
radlab = FALSE, start = 0, clockwise = TRUE,
label.prop = 1.1, main = "", xlab = "", ylab = "", line.col = par("fg"),
lty = par("lty"), lwd = par("lwd"), mar = c(2, 2, 3, 2),
show.grid = TRUE, show.grid.labels = 10, show.radial.grid = TRUE,
grid.col = "gray", grid.bg = "transparent",
grid.left = FALSE, grid.unit = NULL, point.symbols = 1, pt.col = par("fg"), bg = pt.col,
inc.lim = NULL, radial.labels = NULL,
boxed.radial = TRUE, poly.col = NA,
dec.min = -90, dec.max = 270, new = TRUE, pch = 21, type = 'o')
{
if (is.null(inc.lim))
inc.lim <- range(abs(inc))
#lambert.ID(inclinaisons = inclinaisons, declinaisons = declinaisons, pt.names = pt.names, inc.lim = inc.lim,
# dec.min = dmin, dec.max = dmax, main = main, label.pos = label.pos, pt.col = pt.col, bg = bg, show.grid = show.grid, new = new)
if (show.grid == TRUE) {
if (is.null(label.pos)) {
label.pos$I = seq(inc.lim[1], inc.lim[2], by=10)
label.pos$D = seq(dec.min, dec.max, by=10)
}
lambert.ID.grid(main = main, label.pos = label.pos, labels = labels,
radlab = radlab, start = start,
clockwise = clockwise, show.radial.grid = show.radial.grid,
dec.min = dec.min, dec.max = dec.max, inc.min = inc.lim[1] , inc.max = inc.lim[2], new = new )
if (new == TRUE)
new <- FALSE
}
lambert.ID.point(inc, dec, dec.min = dec.min, dec.max = dec.max, inc.lim = inc.lim,
pt.names = pt.names, pt.col = pt.col, bg = bg, pch = pch, new = new, type = type)
}
#' Place des points I et D dans un repère Lambert et dessine le symbole
#' @export
lambert.ID.position <- function (data, declinaisons = NULL, position = "P", pt.names = NA, labels = NA, label.pos = NULL,
radlab = FALSE, start = 0, clockwise = TRUE,
label.prop = 1.1, main = "Position auto", xlab = "", ylab = "", line.col = par("fg"),
lty = par("lty"), lwd = par("lwd"), mar = c(2, 2, 3, 2),
show.grid = TRUE, show.grid.labels = 10, show.radial.grid = TRUE,
grid.col = "gray", grid.bg = "transparent",
grid.left = FALSE, grid.unit = NULL, point.symbols = 1, pt.col = par("fg"), bg = pt.col,
inc.lim = c(0, 90), radial.labels = NULL,
boxed.radial = TRUE, poly.col = NA, add = FALSE,
dec.min = -90, dec.max = 90, new = TRUE, ...)
{
if (is.null(declinaisons) ) {
inclinaisons <- data$I
declinaisons <- data$D
}
else {
inclinaisons <- data
declinaisons <- declinaisons
}
if (length(position) < length(inclinaisons))
position <- rep(position, length(inclinaisons))
if (is.null(inc.lim))
inc.lim <- range(abs(inclinaisons))
if (is.null(label.pos)) {
lab.pos <- NULL
lab.pos$I = seq(inc.lim[1], inc.lim[2], by = 20)
lab.pos$D = seq(dec.min, dec.max, by = 10)
} else {
lab.pos <- label.pos
}
ne <- new
if (length(which(position=="P")) > 0) {
lambert.ID(inclinaisons[which(position=="P")], declinaisons[which(position=="P")],
pt.names = pt.names[which(position=="P")], label.pos = lab.pos, main = main, show.grid = show.grid,
inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, pt.col = pt.col, pch = 23, new = ne)
ne <- FALSE
show.grid <- FALSE
main <- ""
}
if (length(which(position=="C")) > 0) {
lambert.ID(inclinaisons[which(position=="C")], declinaisons[which(position=="C")],
pt.names = pt.names[which(position=="C")], label.pos = lab.pos, main = main, show.grid = show.grid,
inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, pt.col = pt.col, pch = 22, new = ne)
ne <- FALSE
show.grid <- FALSE
main <- ""
}
if (length(which(position=="D")) > 0) {
lambert.ID(inclinaisons[which(position=="D")], declinaisons[which(position=="D")],
pt.names = pt.names[which(position=="D")], label.pos = lab.pos, main = main, show.grid = show.grid,
inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, pt.col = pt.col, pch = 24, new = ne)
}
}
#' Place des points I et D dans un repère Lambert
#' @export
lambert.ID.point <- function (inc, dec , pt.names = NA, labels = NA, label.pos = NULL,
start = 0, clockwise = TRUE,
lty = par("lty"), mar = c(2, 2, 3, 2),
pt.col = par("fg"), bg = pt.col, type = 'o',
inc.lim = NULL,
dec.min = -90, dec.max = 270, new = TRUE, pch = 21, ...)
{
maxlength <- 100 # la valeur n'a pas d'influence, la fonction plot() calcul le reste
# radlab écrit les labels sous forme d'étoile
if (is.null(inc.lim))
inc.lim <- range(abs(inc))
# Sélection des échantillons visibles dans le range
index.supprim <- NULL
for (i in 1:length(inc)) {
if (abs(inc[i])< inc.lim[1] || abs(inc[i])> inc.lim[2] || dec[i]<dec.min || dec[i]>dec.max )
index.supprim <- cbind(index.supprim, c(i))
}
if (!is.null(index.supprim)) {
inc <- inc[-index.supprim]
dec <- dec[-index.supprim]
if (!is.null(pt.names) ) {
pt.names <- pt.names[-index.supprim]
}
}
inc.min = inc.lim[1]
inc.max = inc.lim[2]
nbpoints <- length(inc)
if (clockwise == FALSE)
dec <- -dec
if (start)
dec <- dec + start
box.range <- find.extremum(inc.min, inc.max, dec.min, dec.max)
oldpar <- par("xpd", "mar", "pty")
# setting up coord. system
if (new == TRUE) {
par(mar = mar, pty = "s")
maxlength <- 100 # la valeur n'a pas d'influence, la fonction plot() calcul le reste
plot(c(-maxlength, maxlength), c(-maxlength, maxlength), type = "n", axes = FALSE, new = new)
}
# par(xpd = TRUE)
if (length(pch) < nbpoints)
pch <- rep(pch, length.out = nbpoints)
if (length(pt.col) < nbpoints)
pt.col <- rep(pt.col, length.out = nbpoints)
xpos <- X(inc, dec, ray = maxlength, i.min = inc.min, box.range)
ypos <- Y(inc, dec, ray = maxlength, i.min = inc.min, box.range)
# print points names
if (length(pt.names)>0 )
for (i in 1: nbpoints )
text(xpos[i], ypos[i], pt.names[i] , srt = 0, cex = par("cex"))
# pch = 0, cercle
# pch = 1, rond
# pch = 2, triangle
# pch = 3, plus
# pch = 4, croix
# pch = 5, losange
# pch = 6, triangle vers le bas
# pch = 7, carré avec croix
# pch = 8, étoile
# pch = 9, losange avec plus
# pch = 10, cercle avec plus
# pch = 11, triangles hauts et bas
# pch = 12, carré avec plus
# pch = 13, cercle avec croix
# pch = 14, carré et triangle vers le bas
# pch = 15, carré plein
# pch = 16, cercle plein
# pch = 17, triangle plein vers le haut
# pch = 18, losange plein
# pch = 19, cercle solide
# pch = 20, petit rond plein
# pch = 21, cercle plein bleu, accepte l'argument bg
# pch = 22, carré plein bleu
# pch = 23, losange plein bleu
# pch = 24, triangle plein, pointe vers le haut bleu
# pch = 25, triangle plein, pointe vers la bas bleu
if (!is.null(pt.col))
for (i in 1: nbpoints ) {
if(pt.col[i] != "transparent") {
if (inc[i]<0) {
bg.col <- gray(0.95)
points(xpos[i], ypos[i], pch = pch[i], col = pt.col[i], bg = bg.col, lty=lty, type = type)
}
else
points(xpos[i], ypos[i], pch = pch[i], col = pt.col[i], bg = pt.col[i], lty=lty, type = type)
}
}
invisible(oldpar)
}
## Plot lambert circle ----
## lambert.ID.circle.points
#' Calcul les points pour tracer un cercle
#' @param i.mean inclinaison du centre du cercle
#' @param d.mean déclinaiosn du centre du point
#' @param delta angle d'ouverture du cercle
#' @return une liste de I et D en degrés
#' @export
lambert.ID.circle.points <- function (i.mean, d.mean, delta)
{
Imoy <- i.mean*pi/180
Dmoy <- d.mean*pi/180
Delta <- delta*pi/180
pt <- NULL
pt$I <- NULL
pt$D <- NULL
for (k in seq(0, pi, length.out = 180)) {
I.tmp <- n_arcsin(sin(Imoy)*cos(Delta)+cos(k)*cos(Imoy)*sin(Delta))
if (abs(Imoy)==(pi/2)) {
D.tmp <- k
} else {
D.tmp <- Dmoy + n_arccos( (cos(Delta)-sin(Imoy)*sin(I.tmp))/(cos(Imoy)*cos(I.tmp)) )
}
pt$I<- c(pt$I , I.tmp*180/pi)
pt$D <- c(pt$D, D.AM(D.tmp*180/pi))
}
for (k in seq(pi, 2*pi, length.out = 180)) {
I.tmp <- n_arcsin(sin(Imoy)*cos(Delta)+cos(k)*cos(Imoy)*sin(Delta))
if (abs(Imoy)==(pi/2)) {
D.tmp <- k
} else {
D.tmp <- Dmoy - n_arccos( (cos(Delta)-sin(Imoy)*sin(I.tmp))/(cos(Imoy)*cos(I.tmp)) )
}
pt$I <- c(pt$I, I.tmp*180/pi)
pt$D <- c(pt$D, D.AM(D.tmp*180/pi))
}
return(pt)
}
#' Trace un cercle sur le diagramme lambert
#' @param col définie la couleur de la ligne
#' @param absolue permet de tracer la partie inclinaison négative des cercles
#' @export
lambert.ID.circle <- function (i.mean, d.mean, delta, inc.lim = NULL, dec.min = -90, dec.max = 270,
col = par("fg"), clockwise = TRUE, absolue = TRUE, lty = 1, ...)
{
pt <- lambert.ID.circle.points(i.mean, d.mean, delta)
maxlength <- 100 # la valeur n'a pas d'influence, la fonction plot() calcul le reste
# radlab écrit les labels sous forme d'étoile
if (is.null(inc.lim))
inc.lim <- range(abs(pt$I))
inc.min = inc.lim[1]
inc.max = inc.lim[2]
if (clockwise == FALSE)
pt$D <- -pt$D
box.range <- find.extremum(inc.min, inc.max, dec.min, dec.max)
xpos <- X(pt$I, pt$D, ray = maxlength, i.min = inc.min, box.range)
ypos <- Y(pt$I, pt$D, ray = maxlength, i.min = inc.min, box.range)
before.bad.condition <- FALSE
x0 <- xpos[1]
y0 <- ypos[1]
for (i in 1: length(pt$I) ) {
if (absolue)
bad.condition <- (abs(pt$I[i])< inc.lim[1] || abs(pt$I[i])> inc.lim[2] || pt$D[i]<dec.min || pt$D[i]>dec.max )
else
bad.condition <- (pt$I[i]< inc.lim[1] || pt$I[i]> inc.lim[2] || pt$D[i]<dec.min || pt$D[i]>dec.max )
if (before.bad.condition == TRUE && bad.condition == FALSE) {
x0 <- xpos[i]
y0 <- ypos[i]
}
if (before.bad.condition == FALSE && bad.condition == FALSE) {
x1 <- xpos[i]
y1 <- ypos[i]
if (pt$I[i]<0)
segments(x0, y0, x1, y1, lty = lty+2, col = col, ...)
else
segments(x0, y0, x1, y1, lty = lty, col = col, ...)
x0 <- xpos[i]
y0 <- ypos[i]
}
before.bad.condition <- bad.condition
}
}
#' Trace un cercle avec les champs de l'inclinaison possible
#' @param field définit la zone possible du champ
#' @export
lambert.ID.field <- function (data, dec = NULL , pt.names = NA, field = c(50, 75), inc.lim = c(0, 90), dec.min = -90, dec.max = 270, col = par("fg"),
main = "", pt.col = par("fg"), bg = pt.col, label.pos= NULL, show.grid = TRUE, new = TRUE)
{
#old.par <- par(no.readonly = TRUE) # all par settings which
if (is.null(label.pos)) {
label.pos$I = NA
label.pos$D = seq(-90, 180, by=90)
}
if (is.null(dec) ) {
inc <- data$I
dec <- data$D
if (is.null(pt.names))
pt.names <- data$name
}
else {
inc <- data
dec <- dec
}
if (is.null(inc.lim))
inc.lim <- range(abs(inc))
if (is.null(label.pos)) {
lab.pos$I = seq(inc.lim[1], inc.lim[2], by = 20)
lab.pos$D = seq(dec.min, dec.max, by = 10)
}
if (show.grid == TRUE)
lambert.ID.grid(main = main, label.pos = label.pos,
start = 0, dec.min = dec.min, dec.max = dec.max, inc.min = inc.lim[1], inc.max = inc.lim[2], new = new )
lambert.ID.point(inc, dec, inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, pt.names = pt.names, pt.col = pt.col, bg = bg, new = FALSE)
hinf <- 90 - field[1]
hsup <- 90 - field[2]
lambert.ID.circle(0, 180, hinf, col = adjustcolor( col, alpha.f = 0.5) , inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, absolue = FALSE)
lambert.ID.circle(0, 0, hinf, col = adjustcolor( col, alpha.f = 0.5) , inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, absolue = FALSE)
lambert.ID.circle(0, 90, hinf, col = adjustcolor( col, alpha.f = 0.5) , inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, absolue = FALSE)
lambert.ID.circle(0, -90, hinf, col = adjustcolor( col, alpha.f = 0.5) , inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, absolue = FALSE)
lambert.ID.circle(90, -90, hinf, col = adjustcolor( col, alpha.f = 0.5) , inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, absolue = FALSE)
lambert.ID.circle(0, 180, hsup, col = adjustcolor( col, alpha.f = 0.5) , inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, absolue = FALSE)
lambert.ID.circle(0, 0, hsup, col = adjustcolor( col, alpha.f = 0.5) , inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, absolue = FALSE)
lambert.ID.circle(0, 90, hsup, col = adjustcolor( col, alpha.f = 0.5) , inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, absolue = FALSE)
lambert.ID.circle(0, -90, hsup, col = adjustcolor( col, alpha.f = 0.5) , inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, absolue = FALSE)
lambert.ID.circle(90, -90, hsup, col = adjustcolor( col, alpha.f = 0.5) , inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, absolue = FALSE)
#on.exit(par(old.par))
}
#' Place des points X, Y et Z dans un repère Lambert
#' @export
lambert.XYZ <- function( X, Y , Z, pt.names = NA, labels = NA, label.pos = NULL,
radlab = FALSE, start = 0, clockwise = TRUE,
label.prop = 1.1, main = "", xlab = "", ylab = "", line.col = par("fg"),
lty = par("lty"), lwd = par("lwd"), mar = c(2, 2, 3, 2),
show.grid = TRUE, show.grid.labels = 10, show.radial.grid = TRUE,
grid.col = "gray", grid.bg = "transparent",
grid.left = FALSE, grid.unit = NULL, type = 'o', pt.col = "blue3", bg = pt.col,
inc.lim = NULL, radial.labels = NULL,
boxed.radial = TRUE, poly.col = NA, add = FALSE,
dec.min = -90, dec.max = 270, new = TRUE, pch = 21)
{
I <- to.polar.I(X, Y, Z)
D <- to.polar.D(X, Y, Z)
lambert.ID(I, D, pt.names = pt.names, label.pos = label.pos, main = main, show.grid = show.grid,
inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, pt.col = pt.col, pch = pch, new = new, lty = lty, type = type)
}
#' Place des points X, Y et Z dans un repère Lambert avec un data.frame
#' @export
lambert.XYZ.specimen <- function( Data, Y , Z, pt.names = "", labels = NA, label.pos = NULL,
radlab = FALSE, start = 0, clockwise = TRUE,
label.prop = 1.1, main = NULL, xlab = "", ylab = "", line.col = "blue3",
lty = par("lty"), lwd = par("lwd"), mar = c(2, 2, 3, 2),
show.grid = TRUE, show.grid.labels = 10, show.radial.grid = TRUE,
grid.col = "lightgray", grid.bg = "transparent",
grid.left = FALSE, grid.unit = NULL, type = 'o', pt.col = "blue", bg = pt.col,
inc.lim = c(0, 90), radial.labels = NULL,
boxed.radial = TRUE, poly.col = NA, add = FALSE,
dec.min = -90, dec.max = 270, new = TRUE, pch = 21, ...)
{
eta <- NULL
if(is.data.frame(Data)) {
X <- Data$X
Y <- Data$Y
Z <- Data$Z
if (is.null(pt.names))
eta <- Data$step
if (is.null(main))
main <- as.character(Data$name[1])
} else {
X <- Data
if (!is.null(pt.names))
eta <- pt.names
}
I <- to.polar.I(X, Y, Z)
D <- to.polar.D(X, Y, Z)
if (is.null(label.pos)) {
label.pos$I = c(90)
label.pos$D = seq(-90, 270, by=90)
}
lambert.ID(I, D, pt.names = pt.names, label.pos = label.pos, main = main, show.grid = show.grid, type = "l",
grid.col = grid.col,
inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, line.col = line.col, pt.col = pt.col, bg= par("fg"), new = new)
lambert.ID(I, D, pt.names = "", label.pos = label.pos, main = "", show.grid = FALSE,
inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, line.col = line.col, pt.col = pt.col, pch = pch, type=type, new = FALSE)
}
#' Place des points I et D dans un repère Lambert avec un data.frame
#' @export
lambert.ID.specimen <- function( Data, D , pt.names = "", labels = NA, label.pos = NULL,
radlab = FALSE, start = 0, clockwise = TRUE,
label.prop = 1.1, main = NULL, xlab = "", ylab = "", line.col = "blue3",
lty = par("lty"), lwd = par("lwd"), mar = c(2, 2, 3, 2),
show.grid = TRUE, show.grid.labels = 10, show.radial.grid = TRUE,
grid.col = "lightgray", grid.bg = "transparent",
grid.left = FALSE, grid.unit = NULL, type = 'o', pt.col = "blue3", bg = pt.col,
inc.lim = c(0, 90), radial.labels = NULL,
boxed.radial = TRUE, poly.col = NA, add = FALSE,
dec.min = -90, dec.max = 270, new = TRUE, pch = 21, ...)
{
eta <- NULL
if(is.data.frame(Data)) {
I <- Data$I
D <- Data$D
if (is.null(pt.names))
eta <- Data$step
if (is.null(main))
main <- as.character(Data$name[1])
} else {
I <- Data
if (!is.null(pt.names))
eta <- pt.names
}
if (is.null(label.pos)) {
label.pos$I = c(90)
label.pos$D = seq(-90, 270, by=90)
}
lambert.ID(I, D, pt.names = pt.names, label.pos = label.pos, main = main, show.grid = show.grid, type = "l",
grid.col = grid.col,
inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, line.col = line.col, pt.col = pt.col, bg= par("fg"), new = new)
lambert.ID(I, D, pt.names = "", label.pos = label.pos, main = "", show.grid = FALSE,
inc.lim = inc.lim, dec.min = dec.min, dec.max = dec.max, line.col = line.col, pt.col = pt.col, pch = pch, new = FALSE, type=type)
}
#' Trace un diagramme de Zijderveld type 1
#' @param Data soit une data.frame avec les mesures X, Y et Z, soit que les valeurs de X
#' @param Y les valeurs de Y, si Data n''est pas une data.frame
#' @param Z les valeurs de Z, si Data n''est pas une data.frame
#' @param panel.first = grid() : affiche une grille
#' @param pt.name = "": n'affiche rien. pt.name = NULL: affiche les étapes si Data est une data.frame
#' @param legend.pos = NULL : n'affiche pas la legende. legend.pos = "topleft" affiche en haut à gauche
#' @export
zijderveld1<- function(Data, Y = NULL, Z = NULL, pt.names = "", main = NULL, panel.first = NULL, pt.col = c("forestgreen", "blue3"),
isometric = TRUE, ylim = NULL, legend.pos = NULL, legend.txt = c("(Y, X)", "(Y, Z)"), new = TRUE, ...)
{
eta <- NULL
if(is.data.frame(Data)) {
X <- Data$X
Y <- Data$Y
Z <- Data$Z
if (is.null(pt.names))
eta <- Data$step
else
eta <- pt.names
if (is.null(main))
main <- as.character(Data$name[1])
} else {
X <- Data
if (!is.null(pt.names))
eta <- pt.names
}
if (isometric == TRUE) {
asp <- 1
} else {
asp <- NA
}
if (is.null(ylim)) {
Y.r <- range(X)
Z.r <- range(Z)
ylim <- c(min(Y.r[1], -Z.r[2]), max(Y.r[2], -Z.r[1]))
if (isometric == TRUE) {
if (ylim[1]>0)
ylim[1]<-0
if (ylim[2]<0)
ylim[2]<-0
}
}
if (new == TRUE) {
plot(Y, X, type = "o", pch = 21, main = main, col = pt.col[1], bg = adjustcolor( pt.col[1], alpha.f = 0.8), axes = FALSE,
panel.first = panel.first, xlab = "", ylab = "", ylim = ylim, asp = asp, xaxt="n", yaxt="n", new = new, ...)
if (!is.null(legend.pos))
legend(legend.pos, legend.txt, pch = c(19, 21), col = pt.col, bg = c(par("bg"), adjustcolor( pt.col[1], alpha.f = 0.8), adjustcolor( pt.col, alpha.f = 0.05)),
box.col = par("bg"), title = "")
ax1 <- axis(1, pos = 0, col = "darkgray")
ax2 <- axis(2, pos = 0, col = "darkgray") # Ordonnées
text(0, ax2[length(ax2)], "+X", col = "gray5", adj = c(-.5, 1), cex = par("cex.lab"))
text(0, ax2[1], "+Z", col = "gray5", adj = c(-.5, 0), cex = par("cex.lab"))
text( ax1[length(ax1)], 0, "+Y", col = "gray5", adj = c(1, -.5), cex = par("cex.lab"))
} else {
lines(Y, X, type = "o", pch = 21, col = pt.col[1], bg = adjustcolor( pt.col[1], alpha.f = 0.8), ...)
}
lines(Y, -Z, type = "o", pch = 21, col = pt.col[2], bg = adjustcolor( pt.col[2], alpha.f = 0.05), ...)
text(jitter(Y, 5, amount = 0), jitter(X, 5, amount = 0), eta, cex = par("cex.lab"))
}
#' Trace un diagramme de Zijderveld type 2
#' @export
zijderveld2<- function(Data, Y = NULL, Z = NULL, pt.names = "", main = NULL, panel.first = NULL, pt.col = c("forestgreen", "blue3"), isometric = TRUE,
ylim = NULL, legend.pos = NULL, new = TRUE, ...)
{
eta <- NULL
if(is.data.frame(Data)) {
X <- Data$X
Y <- Data$Y
Z <- Data$Z
if (is.null(main))
main <- as.character(Data$name[1])
if (is.null(pt.names))
eta <- Data$step
} else {
X <- Data
if (!is.null(pt.names))
eta <- pt.names
}
if (isometric == TRUE) {
asp <- 1
} else {
asp <- NA
}
if (is.null(ylim)) {
Y.r <- range(Y)
Z.r <- range(Z)
ylim <- c(min(Y.r[1], -Z.r[2]), max(Y.r[2], -Z.r[1]))
if (isometric == TRUE) {
if (ylim[1]>0)
ylim[1]<-0
if (ylim[2]<0)
ylim[2]<-0
}
}
if (new == TRUE) {
plot(-X, Y, main = main, type = "o", pch = 21, col = pt.col[1], bg = adjustcolor( pt.col[1], alpha.f = 0.8), axes = FALSE,
panel.first = panel.first, xlab = "", ylab = "", ylim = ylim, asp = asp, new = new)
text(jitter(-X, 5, amount = 0), jitter(Y, 5, amount = 0), eta, cex = par("cex.lab"))
if (!is.null(legend.pos))
legend(legend.pos, c("(-X, Y)", "(-X, Z)"), pch = c(19, 21), col = pt.col, bg = c(par("bg"), adjustcolor( pt.col[1], alpha.f = 0.8), adjustcolor( pt.col, alpha.f = 0.05)),
box.col = par("bg"), title = "")
ax1 <- axis(1, pos = 0, col = "darkgray")
ax2 <- axis(2, pos = 0, col = "darkgray") # Ordonnées
text(0, ax2[length(ax2)], "+Y", col = "gray5", adj = c(-.5, 1), cex = par("cex.lab"))
text(0, ax2[1], "+Z", col = "gray5", adj = c(-.5, 0), cex = par("cex.lab"))
text( ax1[length(ax1)] , 0, "-X", col = "gray5", adj = c(1, -.5), cex = par("cex.lab"))
} else {
lines(-X, Y, type = "o", pch = 21, col = pt.col[1], bg = adjustcolor( pt.col[1], alpha.f = 0.8), ...)
}
lines(-X, -Z, type = "o", pch = 21, col = pt.col[2], bg = adjustcolor( pt.col[2], alpha.f = 0.05))
text(jitter(-X, 5, amount = 0), jitter(Y, 5, amount = 0), eta, cex = par("cex.lab"))
}
# Repliement ----
#' repliement
#' Calcul le repliement pour les trois position à plat "P", de chant "C" et debout "D"
#' pour les matériaux déplacés, la référence est le nord donc -angD
#' @param data valeur de l'inclinaison, ou une data.frame en degrés
#' @param dec en degrés
#' @param position trois valeurs posible à plat "P", de chant "C" et debout "D"
#' @return en degrés
#' @export
repliement <- function (data, dec = NULL, aim = 1, name = NULL, number = NULL, position = "P")
{
if (is.null(dec) ) {
inc <- data$I
dec <- data$D
aim <- data$F
nom <- data$name
num <- data$number
}
else {
inc <- data
dec <- dec
if (is.null(name))
nom <- rep("", length(inc))
else
nom <- as.character(name)
if (is.null(number))
num <- c(1:length(inc))
else
num <- number
}
if (length(aim) < length(inc))
aim <- rep(aim, length(inc))
if (length(position) < length(inc))
position <- rep(position, length(inc))
X <- to.cartesian.X(inc, dec, aim)
Y <- to.cartesian.Y(inc, dec, aim)
Z <- to.cartesian.Z(inc, dec, aim)
res <- NULL
# Carottage à plat, repère conventionnel : Calcul des angles I-D pour les trois positions
for (i in 1: length(inc)) {
res$name <- c(res$name, as.character(nom[i]))
res$number <- c(res$number, num[i])
res$F <- c(res$F, aim[i])
if (position[i] == "O") { # origine
res$D <- c(res$D, angleD( X[i], Y[i] ) /pi * 180 )
res$I <- c(res$I, n_arcsin( Z[i]/aim[i] ) /pi * 180)
res$P <- c(res$P, "O")
}
if (position[i] == "P") { # à plat
t.d <- angleD(abs(X[i]), -Y[i]) /pi * 180
t.i <- n_arcsin(Z[i]/aim[i]) /pi * 180
if (X[i]>= 0 && Z[i]>=0 ) {
t.d <- -angleD(X[i], Y[i]) /pi * 180
}
if (X[i]> 0 && Z[i]<0 ) {
t.d <- -angleD(X[i], -Y[i]) /pi * 180
}
if (X[i]< 0 && Z[i]>0 ) {
t.d <- angleD(-X[i], Y[i]) /pi * 180
}
if (X[i]< 0 && Z[i]<0 ) {
t.d <- angleD(-X[i], -Y[i]) /pi * 180
}
res$I <- c(res$I, t.i)
res$D <- c(res$D, t.d )
res$P <- c(res$P, "P")
}
if (position[i] == "C") { # de chant -->> OK
t.i <- sign(Z[i]) *abs(n_arcsin( -Y[i]/aim[i])) /pi * 180
t.d <- angleD( X[i], Z[i]) /pi * 180
if (X[i]> 0 && Y[i]<0 ) {
t.d <- -t.d
}
if (X[i]< 0 && Y[i]>0 ) {
t.d <- t.d - 180
}
if (X[i]<= 0 && Y[i]<=0 ) {
t.d <- 180 - t.d
}
# normalisation de la déclinaison
if (t.d> 270)
t.d <- t.d - 360
if (t.d < -90)
t.d <- t.d + 360
res$I <- c(res$I, t.i )
res$D <- c(res$D, t.d )
res$P <- c(res$P, "C")
}
if (position[i] == "D") { # debout
t.i <- sign(Z[i]) * n_arcsin(abs(X[i])/aim[i]) /pi * 180
t.d <- angleD(Y[i], -Z[i]) /pi * 180
if (X[i]> 0 && Y[i]<=0 ) {
t.d <- t.d - 180
}
if (X[i]< 0 && Y[i]>0 ) {
t.d <- - t.d
}
if (X[i]< 0 && Y[i]<=0 ) {
t.d <- 180 - t.d
}
res$I <- c(res$I, t.i)
res$D <- c(res$D, t.d)
res$P <- c(res$P, "D")
}
tmp <- to.cartesian(t.i, t.d, aim = aim[i])
res$X <- c(res$X, tmp$X)
res$Y <- c(res$Y, tmp$Y)
res$Z <- c(res$Z, tmp$Z)
}
res.frame <- data.frame( number = as.numeric(res$number), name = as.character(res$name),
I = as.numeric(res$I), D = as.numeric(res$D), F = as.numeric(res$F),
X = as.numeric(res$X), Y =as.numeric(res$Y), Z =as.numeric(res$Z), position = res$P, stringsAsFactors = FALSE)
return(res.frame)
}
#' repliement automatique
#' Recherche la position qui permet d'avoir une position suivant les trois positions possible
#' donnant l'inclinaison la plus proche de la valeur inc.critique (en degrés)
#' @param data valeur de l'inclinaison, ou une data.frame en degrés
#' @param dec en degrés
#' @return I et D en degrés
#' @export
repliement.auto <- function (data, dec = NULL, aim = 1, name = NULL, number = NULL, inc.critique = 90)
{
if (is.null(dec) ) {
inc <- data$I
dec <- data$D
aim <- data$F
nom <- data$name
num <- data$number
}
else {
inc <- data
dec <- dec
if (is.null(name))
nom <- rep("", length(inc))
else
nom <- as.character(name)
if (is.null(number))
num <- c(1:length(inc))
else
num <- number
}
res <- NULL
res.P <- repliement(inc, dec, aim, name = nom, number = num, position = "P")
res.C <- repliement(inc, dec, aim, name = nom, number = num, position = "C")
res.D <- repliement(inc, dec, aim, name = nom, number = num, position = "D")
for (i in 1: length(inc)) {
# inc.sup <- 90
res.tmp <- NULL
# Initialisation avec la position à Plat
res.tmp$I <- res.P$I[i]
res.tmp$D <- res.P$D[i]
res.tmp$F <- res.P$F[i]
res.tmp$X <- res.P$X[i]
res.tmp$Y <- res.P$Y[i]
res.tmp$Z <- res.P$Z[i]
res.tmp$position <- res.P$position[i]
inc.sup <- abs(inc.critique - abs(res.P$I[i]))
# Comparaison avec la position de Chant
if (abs(inc.critique - abs(res.C$I[i])) <= inc.sup) {
res.tmp$I <- res.C$I[i]
res.tmp$D <- res.C$D[i]
res.tmp$F <- res.C$F[i]
res.tmp$position <- res.C$position[i]
res.tmp$X <- res.C$X[i]
res.tmp$Y <- res.C$Y[i]
res.tmp$Z <- res.C$Z[i]
inc.sup <- abs(inc.critique - abs(res.C$I[i]))
}
# Comparaison avec la position Debout
if (abs(inc.critique - abs(res.D$I[i])) <= inc.sup) {
res.tmp$I <- res.D$I[i]
res.tmp$D <- res.D$D[i]
res.tmp$F <- res.D$F[i]
res.tmp$position <- res.D$position[i]
res.tmp$X <- res.D$X[i]
res.tmp$Y <- res.D$Y[i]
res.tmp$Z <- res.D$Z[i]
#inc.sup <- abs(inc.critique-abs(res.D$I))
}
res$I <- c(res$I, res.tmp$I)
res$D <- c(res$D, res.tmp$D)
res$F <- c(res$F, res.tmp$F)
res$name <- c(res$name, nom[i])
res$number <- c(res$number, num[i])
res$X <- c(res$X, res.tmp$X)
res$Y <- c(res$Y, res.tmp$Y)
res$Z <- c(res$Z, res.tmp$Z)
res$position <- c(res$position, res.tmp$position)
}
res <- data.frame(number = res$number, name = res$name, I = as.numeric(res$I), D = as.numeric(res$D), F = as.numeric(res$F),
X = as.numeric(res$X), Y = as.numeric(res$Y), Z = as.numeric(res$Z), position = res$position, stringsAsFactors = FALSE)
return(res)
}
#' repliement.tranche
#' Recherche la position qui permet d'avoir une position suivant la position debout ou dechant
#' donnant l'inclinaison la plus proche de la valeur inc.critique (en degrés)
#' @param data valeur de l'inclinaison, ou une data.frame en degrés
#' @param dec en degrés
#' @return I et D en degrés
#' @export
repliement.tranche <- function (data, dec = NULL, aim = 1, name = NULL, number = NULL, inc.critique = 90)
{
if (is.null(dec) ) {
inc <- data$I
dec <- data$D
aim <- data$F
nom <- data$name
num <- data$number
}
else {
inc <- data
dec <- dec
if (is.null(name))
nom <- rep("", length(inc))
else
nom <- as.character(name)
if (is.null(number))
num <- c(1:length(inc))
else
num <- number
}
res <- NULL
res.C <- repliement(inc, dec, aim, name = nom, number = num, position = "C")
res.D <- repliement(inc, dec, aim, name = nom, number = num, position = "D")
for (i in 1: length(inc)) {
res.tmp <- NULL
# Initialisation avec la position de Chant
res.tmp$I <- res.C$I[i]
res.tmp$D <- res.C$D[i]
res.tmp$F <- res.C$F[i]
res.tmp$position <- res.C$position[i]
res.tmp$X <- res.D$X[i]
res.tmp$Y <- res.D$Y[i]
res.tmp$Z <- res.D$Z[i]
inc.sup <- abs(inc.critique - abs(res.C$I[i]))
# Comparaison avec la position Debout
if (abs(inc.critique - abs(res.D$I[i])) <= inc.sup) {
res.tmp$I <- res.D$I[i]
res.tmp$D <- res.D$D[i]
res.tmp$F <- res.D$F[i]
res.tmp$position <- res.D$position[i]
res.tmp$X <- res.D$X[i]
res.tmp$Y <- res.D$Y[i]
res.tmp$Z <- res.D$Z[i]
}
res$number <- c(res$number, num[i])
res$name <- c(res$name, nom[i])
res$I <- c(res$I, res.tmp$I)
res$D <- c(res$D, res.tmp$D)
res$F <- c(res$F, res.tmp$F)
res$X <- c(res$X, res.tmp$X)
res$Y <- c(res$Y, res.tmp$Y)
res$Z <- c(res$Z, res.tmp$Z)
res$position <- c(res$position, res.tmp$position)
}
res.Final <- data.frame( res , stringsAsFactors = FALSE)
return(res.Final)
}
# Fonction sur fichiers ----
#' read.AM.mesures
#' Lecture des mesures d'un fichier AM
#' @param encoding Pour les fichiers du magnétomètre, il faut "macroman" -> difficle à connaitre, peut être "latin1" ou "utf8".
#' @return une data.frame
#' @export
read.AM.mesures <- function(file.AM, encoding = "macroman")
{
# Lecture et Copy du fichier
lin<- NULL
fil <- file(file.AM, "r", encoding = encoding)
lin <- readLines(fil)
close(fil)
# Recherche position-ligne des noms
g <- NULL
for (i in 1:length(lin))
if (grepl("Id:", lin[i])==TRUE)
g<-c(g, i)
# Lecture mesure par nom
lname <- trimws(substr(lin[g],4, 15))
list.mesure <- NULL
lmes <- NULL
first.mesure <- NULL
last.mesure <- NULL
for (i in 1:length(g)) {
first.mesure <- g[i]+4
if (i<length(g))
last.mesure <- g[i+1]-2
else
last.mesure<- length(lin)
tEtap <- NULL
tEtap.val <- NULL
tX <- NULL
tY <- NULL
tZ <- NULL
tI <- NULL
tD <- NULL
tF <- NULL
tQual <- NULL
tApp <- NULL
tSuscep <- NULL
for (j in first.mesure:last.mesure) {
lEtap <- substr(lin[j], 3, 7)
lEtap.val <- substr(lin[j], 3, 5)
lX <- substr(lin[j], 9, 18)
lY <- substr(lin[j], 20, 29)
lZ <- substr(lin[j], 31, 40)
lQual <- substr(lin[j], 43, 44)
lApp <- substr(lin[j], 46, 46)
lSuscep <- substr(lin[j], 48, 52)
if ( is.na(as.numeric(lX)) || is.na(as.numeric(lY)) || is.na(as.numeric(lY)) ) {
lX <- 0
lY <- 0
lZ <- 0
lI <- 0
lD <- 0
lF <- 0
}
else {
lI <- to.polar.I(as.numeric(lX), as.numeric(lY), as.numeric(lZ))
lD <- to.polar.D(as.numeric(lX), as.numeric(lY), as.numeric(lZ))
lF <- to.polar.F(as.numeric(lX), as.numeric(lY), as.numeric(lZ))
}
tEtap <- c(tEtap, lEtap)
tEtap.val <- c(tEtap.val, lEtap.val)
tX <- c(tX, lX)
tY <- c(tY, lY)
tZ <- c(tZ, lZ)
tI <- c(tI, lI)
tD <- c(tD, lD)
tF <- c(tF, lF)
tQual <- c(tQual, lQual)
tApp <- c(tApp, lApp)
tSuscep <- c(tSuscep, lSuscep)
lmes <- data.frame(number = i, name = lname[i], step = tEtap, step.value = as.numeric(tEtap.val),
X = as.numeric(tX), Y = as.numeric(tY), Z = as.numeric(tZ),
I = as.numeric(tI), D = as.numeric(tD), F = as.numeric(tF),
Quality = as.numeric(tQual), App = tApp, Suscep = as.numeric(tSuscep), stringsAsFactors = FALSE)
}
list.mesure <- rbind(list.mesure, lmes)
}
return(list.mesure)
}
#' Lecture des infos sur mesures d'un fichier AM
#' @return une data.frame avec les infos sur les spécimens
#' @export
read.AM.info <- function (file.AM, encoding="macroman")
{
# Lecture et Copy du fichier
lin<- NULL
fil <- file(file.AM, "r", encoding=encoding)
lin <- readLines(fil)
close(fil)
# Recherche position-ligne des noms
g <- NULL
for (i in 1:length(lin))
if (grepl("Id:", lin[i])==TRUE)
g<-c(g,i )
# Lecture mesure par nom
lname <- trimws(substr(lin[g], 4, 15))
linc <- trimws(substr(lin[g], 20, 24))
laz <- trimws(substr(lin[g], 29, 33))
ltet <- trimws(substr(lin[g], 39, 43))
lpsy <- trimws(substr(lin[g], 49, 53))
lv <- trimws(substr(lin[g], 57, 61))
lTH <- trimws(substr(lin[g], 69, 72))
lshape <- trimws(substr(lin[g], 76, 78))
lT1 <- trimws(substr(lin[g+2], 14, 17))
lT2 <- trimws(substr(lin[g+2], 25, 28))
lT3 <- trimws(substr(lin[g+2], 36, 39))
lT4 <- trimws(substr(lin[g+2], 47, 50))
list.mesure <- NULL
list.mesure <- data.frame(number = c(1: length(g)), name = lname, inc = as.numeric(linc), az = as.numeric(laz), tet = as.numeric(ltet), psy = as.numeric(lpsy), TH =as.numeric(lTH),
shape = lshape, vol =as.numeric(lv), T1 = as.numeric(lT1), T2 = as.numeric(lT2), T3 = as.numeric(lT3), T4 = as.numeric(lT4), stringsAsFactors = FALSE)
return(list.mesure)
}
#' Lecture des infos d'orientation sur mesures d'un fichier AM
#' @return une data.frame avec les infos sur les spécimens
#' @export
read.AM.orient <- function (file.AM, encoding="macroman")
{
# Lecture et Copy du fichier
lin<- NULL
fil <- file(file.AM, "r", encoding=encoding)
lin <- readLines(fil)
close(fil)
# Recherche position-ligne des noms
g <- NULL
for (i in 1:length(lin))
if (grepl("Id:", lin[i])==TRUE)
g<-c(g,i+1 )
# Lecture mesure par nom
lname <- lname <- trimws(substr(lin[g-1], 4, 15))
lorient <- trimws(substr(lin[g], 8, 10))
lj <- trimws(substr(lin[g], 14, 16))
lm <- trimws(substr(lin[g], 20, 22))
la <- trimws(substr(lin[g], 26, 30))
lh <- trimws(substr(lin[g], 34, 37))
lmin <- trimws(substr(lin[g], 41, 43))
lsec <- trimws(substr(lin[g], 47, 49))
lSM <- trimws(substr(lin[g], 54, 59))
list.mesure <- NULL
list.mesure <- data.frame(number = c(1: length(g)), name = lname, orient = as.character(lorient), jour = as.numeric(lj), mois = as.numeric(lm), annee = as.numeric(la), h = as.numeric(lh), min =as.numeric(lmin),
sec = as.numeric(lsec), SM =as.numeric(lSM), stringsAsFactors = FALSE)
return(list.mesure)
}
#' Fonction de création de fichier pour les magnétomètres, pour des matériaux déplacés ----
#' @param encoding mettre "macroman" pour les mesures au molspin
#' @export
genere.AMD <- function(file.AMD = "fichier.AMD", list.ech, shape = "Cyl" , encoding = "macroman")
{
entete<- c( "Spinner_Molspin 2008" ,
"Commune : à définir",
"Site : à définir",
"Latitude : 0° 0' 0\" ",
"Longitude : 0° 0' 0\" IGRF:+00.0",
"Prélèvements sur matériaux déplacés",
"Type de carottage : à plat",
paste0("Date de création : " , format(Sys.time(), "%d/%m/%Y")),
"","")
txt.mesures <- entete
for (i in 1:length(list.ech)) {
txt.mesures <- c( txt.mesures,
paste("Id:", format(list.ech[i], width = 13), "in:000.0 az:000.0 Tet:000.0 Psy:000.0 v:01.00 com:TH 0.0µT ", shape, sep = ""),
"Repère:",
"CompDes: T1:0000T+ T2:0000T+ T3:0000T- T4:0000T-",
"")
}
# Ecriture du fichier
filCon <- file(file.AMD, encoding = encoding)
writeLines(txt.mesures, filCon)
close(filCon)
}
#' Fonction de création de fichier pour les magnétomètres, pour des structures en place ----
#' @param encoding mettre "macroman" pour les mesures au molspin
#' @export
genere.AMP <- function(file.AMP = "fichier.AMP", list.ech, shape = "Cyl" , encoding = "macroman")
{
entete<- c( "Spinner_Molspin 2008" ,
"Commune : à définir",
"Site : à Definir",
"Latitude : 0° 0' 0\" ",
"Longitude : 0° 0' 0\" IGRF:+00.0",
"Prélèvements sur structure en place",
"Type de carottage : à plat",
paste0("Date de création : " , format(Sys.time(), "%d/%m/%Y")),
"","")
txt.mesures <- entete
for (i in 1:length(list.ech)) {
txt.mesures <- c( txt.mesures,
paste("Id:", format(list.ech[i], width = 13), "in:000.0 az:000.0 Tet:000.0 Psy:000.0 v:01.00 com:TH 0.0µT ", shape, sep = ""),
"Orient:NM J: 1 M: 1 A:2000 H: 00 M: 0 S: 0 SM:000.0",
"CompDes: T1:0000T+ T2:0000T+ T3:0000T- T4:0000T-",
"")
}
# Ecriture du fichier
filCon <- file(file.AMP, encoding = encoding)
writeLines(txt.mesures, filCon)
close(filCon)
}
#' Lecture des mesures d'un fichier Pal (*.txt)
#' @param encoding Pour les fichiers du magnétomètre, il faut "macroman" -> difficle à connaitre, peut être "latin1" ou "utf8".
#' @return une data.frame
#' @export
read.Pal.mesures <- function(file.Pal, encoding = "macroman")
{
# Lecture et Copy du fichier
lin<- NULL
fil <- file(file.Pal, "r", encoding = encoding)
lin <- readLines(fil)
close(fil)
# Recherche position-ligne des noms
g <- NULL
for (i in 1:length(lin))
if (grepl("Id:", lin[i])==TRUE)
g<-c(g,i )
# Lecture mesure par nom
lname <- trimws(substr(lin[g],4, 15))
list.mesure <- NULL
lmes <- NULL
first.mesure <- NULL
last.mesure <- NULL
for (i in 1:length(g)) {
first.mesure <- g[i] + 2
if (i<length(g))
last.mesure <- g[i+1] - 1
else
last.mesure<- length(lin)
tEtap <- NULL
tEtap.val <- NULL
tX <- NULL
tY <- NULL
tZ <- NULL
tI <- NULL
tD <- NULL
tF <- NULL
tQual <- NULL
tApp <- NULL
tSuscep <- NULL
for (j in first.mesure:last.mesure) {
lEtap <- substr(lin[j], 3, 7)
lEtap.val <- substr(lin[j], 3, 5)
lX <- substr(lin[j], 9, 18)
lY <- substr(lin[j], 20, 29)
lZ <- substr(lin[j], 31, 40)
lQual <- substr(lin[j], 43, 44)
lApp <- substr(lin[j], 46, 46)
lSuscep <- substr(lin[j], 48, 52)
if ( is.na(as.numeric(lX)) || is.na(as.numeric(lY)) || is.na(as.numeric(lY)) ) {
lX <- 0
lY <- 0
lZ <- 0
lI <- 0
lD <- 0
lF <- 0
}
else {
lI <- to.polar.I(as.numeric(lX), as.numeric(lY), as.numeric(lZ))
lD <- to.polar.D(as.numeric(lX), as.numeric(lY), as.numeric(lZ))
lF <- to.polar.F(as.numeric(lX), as.numeric(lY), as.numeric(lZ))
}
tEtap <- c(tEtap, lEtap)
tEtap.val <- c(tEtap.val, lEtap.val)
tX <- c(tX, lX)
tY <- c(tY, lY)
tZ <- c(tZ, lZ)
tI <- c(tI, lI)
tD <- c(tD, lD)
tF <- c(tF, lF)
tQual <- c(tQual, lQual)
tApp <- c(tApp, lApp)
tSuscep <- c(tSuscep, lSuscep)
lmes <- data.frame(number = i, name = lname[i], step = tEtap, step.value = as.numeric(tEtap.val),
X = as.numeric(tX), Y = as.numeric(tY), Z = as.numeric(tZ),
I = as.numeric(tI), D = as.numeric(tD), F = as.numeric(tF),
Quality = as.numeric(tQual), App = tApp, Suscep = as.numeric(tSuscep), stringsAsFactors = FALSE)
}
list.mesure <- rbind(list.mesure, lmes)
}
return(list.mesure)
}
#' Lecture des infos sur mesures d'un fichier AM
#' @return une data.frame avec les infos sur les spécimens
#' @export
read.Pal.info <- function (file.Pal, encoding="macroman")
{
# Lecture et Copy du fichier
lin<- NULL
fil <- file(file.Pal, "r", encoding=encoding)
lin <- readLines(fil)
close(fil)
# Recherche position-ligne des noms
g <- NULL
for (i in 1:length(lin))
if (grepl("Id:", lin[i])==TRUE)
g<-c(g,i )
# Lecture mesure par nom
lname <- trimws(substr(lin[g], 4, 15))
linc <- trimws(substr(lin[g], 20, 24))
laz <- trimws(substr(lin[g], 29, 33))
ldip <- trimws(substr(lin[g], 39, 43))
lstr <- trimws(substr(lin[g], 49, 53))
lv <- trimws(substr(lin[g], 57, 61))
lcom <- trimws(substr(lin[g], 69, 100))
lL <- trimws(substr(lin[g+1], 3, 13))
lG <- trimws(substr(lin[g+1], 16, 26))
lH <- trimws(substr(lin[g+1], 33, 35))
lT <- trimws(substr(lin[g+1], 38, 56))
lazm <- trimws(substr(lin[g+1], 61, 66))
lazs <- trimws(substr(lin[g+1], 71, 77))
lOr <- trimws(substr(lin[g+1], 81, 92))
lFm <- trimws(substr(lin[g+1], 96, 106))
lLoc <- trimws(substr(lin[g+1], 110, 120))
list.mesure <- NULL
list.mesure <- data.frame(number = c(1: length(g)), name = lname, inc = as.numeric(linc), az = as.numeric(laz), dip = as.numeric(ldip), str = as.numeric(lstr), v = as.numeric(lv), com =as.character(lcom),
L = as.numeric(lL), G = as.numeric(lG), H = as.numeric(lH), T = as.character(lT),
azm = as.numeric(lazm), azs = as.numeric(lazs), Or = as.character(lOr), Fm = as.character(lFm), Loc = as.character(lLoc),
stringsAsFactors = FALSE)
return(list.mesure)
}
#' Lecture des mesures d'un fichier AM de l'ancien format
#' La valeur de la température d'anisotropie n'était pas informée, il est donc possible de le renseigner avec step.value
#' @param ani.step.value valeur de la température des manips d'anisotropie
#' @return une data.frame avec les infos sur les spécimens
#' @export
read.AM.oldType.mesures <- function(file.AM, encoding = "macroman", ani.step.value = 700)
{
# Lecture et Copy du fichier
lin<- NULL
fil <- file(file.AM, "r", encoding = encoding)
lin <- readLines(fil)
close(fil)
# Recherche position-ligne des noms
g <- NULL
# comptage et séparation des données, premier échantillon à ligne 12
current.name <- "" #trimws(substr(lin[12], 1, 8))
list.name <- NULL
for (i in 11:length(lin)) {
if ( trimws(substr(lin[i], 1, 8)) != current.name & trimws(substr(lin[i], 1, 8)) != "") {
current.name <- trimws(substr(lin[i], 1, 8))
list.name <- c(list.name, current.name)
g <- c(g, i)
}
}
# Lecture mesure par nom
lname <- trimws(substr(lin[g],1, 8))
list.mesure <- NULL
lmes <- NULL
first.mesure <- NULL
last.mesure <- NULL
for (i in 1:length(g)) {
first.mesure <- g[i]+1
if (i<length(g))
last.mesure <- g[i+1]-2
else
last.mesure<- length(lin)
tEtap <- NULL
tEtap.val <- NULL
tX <- NULL
tY <- NULL
tZ <- NULL
tI <- NULL
tD <- NULL
tF <- NULL
for (j in first.mesure:last.mesure) {
lMesure <- trimws(substr(lin[j], 12, 14) ) # correspond au champ Mesure
lEtap <- trimws(substr(lin[j], 19, 24) ) # correspond au champ Etape
lEtap.val <- trimws(substr(lin[j], 19, 21) )
lEtap.code <- trimws(substr(lin[j], 20, 23) )
ordre <- trimws(substr(lin[j], 26, 30) ) # correspond au champ Ordre
ordre.sens <- substr(ordre, 2, 2 )
# Interpretation des codes
if (lMesure == "ANI")
{
if (ordre.sens == "T")
{
lEtap.val <- ani.step.value
code <- substr(lEtap.code, nchar(lEtap.code)-1, nchar(lEtap.code))
lEtap.code <- code
}
else if (ordre.sens == "D" | ordre.sens == "I")
{
lEtap.val <- ani.step.value
code <- substr(lEtap.code, nchar(lEtap.code), nchar(lEtap.code))
if ( ordre.sens == "D") {
lEtap.code <- paste(code, "+", sep = "")
}
else {
lEtap.code <- paste(code, "-", sep = "")
}
}
lEtap <- paste(lEtap.val, lEtap.code, sep = "")
}
# lecture des mesures
lI <- trimws(substr(lin[j], 33, 43) )
lD <- trimws(substr(lin[j], 47, 57) )
lF <- trimws(substr(lin[j], 61, 71) )
if ( is.na(as.numeric(lI)) || is.na(as.numeric(lD)) || is.na(as.numeric(lF)) ) {
lX <- 0
lY <- 0
lZ <- 0
lI <- 0
lD <- 0
lF <- 0
}
else {
lX <- to.cartesian.X(as.numeric(lI), as.numeric(lD), as.numeric(lF))
lY <- to.cartesian.Y(as.numeric(lI), as.numeric(lD), as.numeric(lF))
lZ <- to.cartesian.Z(as.numeric(lI), as.numeric(lD), as.numeric(lF))
}
tEtap <- c(tEtap, lEtap)
tEtap.val <- c(tEtap.val, lEtap.val)
tX <- c(tX, lX)
tY <- c(tY, lY)
tZ <- c(tZ, lZ)
tI <- c(tI, lI)
tD <- c(tD, lD)
tF <- c(tF, lF)
lmes <- data.frame(number = i, name = lname[i], step = tEtap, step.value = as.numeric(tEtap.val),
X = as.numeric(tX), Y = as.numeric(tY), Z = as.numeric(tZ),
I = as.numeric(tI), D = as.numeric(tD), F = as.numeric(tF), stringsAsFactors = FALSE)
}
list.mesure <- rbind(list.mesure, lmes)
}
return(list.mesure)
}
#' Lecture des mesures d'un fichier AM de l'ancien format
#' @return une data.frame avec les infos sur les spécimens
#' @export
read.AM.oldType.info <- function (file.AM, encoding = "macroman")
{
# Lecture et Copy du fichier
lin<- NULL
fil <- file(file.AM, "r", encoding=encoding)
lin <- readLines(fil)
close(fil)
# Recherche position-ligne des noms
g <- NULL
# comptage et séparation des données, premier échantillon à ligne 12
current.name <- "" #trimws(substr(lin[12], 1, 8))
list.name <- NULL
for (i in 11:length(lin)) {
if ( trimws(substr(lin[i], 1, 8)) != current.name & trimws(substr(lin[i], 1, 8)) != "") {
current.name <- trimws(substr(lin[i], 1, 8))
list.name <- c(list.name, current.name)
g <- c(g, i)
}
}
# Lecture mesure par nom
lname <- trimws(substr(lin[g], 1, 8))
lop <- trimws(substr(lin[g], 10, 11))
lLongueur <- trimws(substr(lin[g], 12, 17))
lOrientation <- trimws(substr(lin[g], 22, 40))
lH <- trimws(substr(lin[g], 45, 48))
lT1 <- trimws(substr(lin[g], 53, 57))
lT2 <- trimws(substr(lin[g], 61, 65))
lT3 <- trimws(substr(lin[g], 69, 73))
lT4 <- trimws(substr(lin[g], 77, 81))
lPhi <- trimws(substr(lin[g], 86, 91))
lTet <- trimws(substr(lin[g], 95, 100))
list.mesure <- NULL
list.mesure <- data.frame( number = c(1: length(g)), name = lname, Opt = lop, Long = as.numeric(lLongueur), Orient = lOrientation ,TH =as.numeric(lH),
T1 = as.numeric(lT1), T2 = as.numeric(lT2), T3 = as.numeric(lT3), T4 = as.numeric(lT4),
Phi = as.numeric(lPhi), Tet = as.numeric(lTet), stringsAsFactors = FALSE)
return(list.mesure)
}
#' Extraction des mesures correspondant à un nom
#' @export
extract.mesures.specimen.name <- function( specimen.name, list.mesure)
{
selec <- which(list.mesure$name == trimws(specimen.name))
if (length(selec) == 0)
warning("Pas de mesure avec ce nom !")
res.list <- list.mesure[selec,]
return(res.list)
}
#' Extraction des mesures correspondant à un numéro
#' @export
extract.mesures.specimen.number <- function( specimen.number, list.mesure)
{
selec <- which(list.mesure$number == specimen.number)
if (length(selec) == 0)
warning("Pas de mesure avec ce numéro !")
res.list <- list.mesure[selec,]
return(res.list)
}
# Anisotropy Function ----
#' Calcul la matrice d'anisotropie symetrisée et normalisé pour un spécimen
#' qui sert à la correction
#' @param mesures data.frame contenant les mesures
#' @param step.value typiquement la température des mesures d'anisotropie
#' @param step.code code indiquant les étapes. les noms peuvent changer, mais pas l'ordre
#' @param volume la valeur du volume du spécimen
#' @param TH la valeur du champ appliqué
#' @return un data.frame avec les colonnes "L1", "L1.Inc", "L1.Dec", "L2", "L2.Inc", "L2.Dec", "L3", "L3.Inc", "L3.Dec", "F13", "F12", "F23"
#' @export
anisotropy.matrix.symetric <- function(mesures, step.value, step.code = c("Z+", "Z-", "X+", "X-", "Y+", "Y-", "ZB"), ...)
{
ani.step <- trimws(paste(as.character(step.value), step.code, sep = "") )
selec <- NULL
for (i in 1:length(ani.step)) {
selec <- c( selec, which(trimws(mesures$step) == trimws(ani.step[i])) )
}
res.list <- NULL
res.list <- mesures[selec,]
res.list <- res.list
mat.plus <- matrix( c( res.list$X[3], res.list$X[5], res.list$X[1],
res.list$Y[3], res.list$Y[5], res.list$Y[1],
res.list$Z[3], res.list$Z[5], res.list$Z[1]) , 3, 3)
mat.moins <- matrix( c( res.list$X[4], res.list$X[6], res.list$X[2],
res.list$Y[4], res.list$Y[6], res.list$Y[2],
res.list$Z[4], res.list$Z[6], res.list$Z[2]) , 3, 3)
mat.reel <- (mat.plus - mat.moins)/2 #/ (volume * 1E-6)# / coef.norm
# Symetrisation
coef.norm <- 1 #TH* 10/ (4*pi)
kxx <- mat.reel[1,1] / coef.norm
kyy <- mat.reel[2,2] / coef.norm
kzz <- mat.reel[3,3] / coef.norm
kxy <- (mat.reel[1,2] + mat.reel[2,1]) / 2 / coef.norm
kxz <- (mat.reel[1,3] + mat.reel[3,1]) / 2 / coef.norm
kyz <- (mat.reel[2,3] + mat.reel[3,2]) / 2 / coef.norm
# Normalisation
suscept <- (kxx + kyy + kzz)/3
mat.sym.norm <- matrix( c( kxx / suscept, kxy / suscept, kxz / suscept,
kxy / suscept, kyy / suscept, kyz / suscept,
kxz / suscept, kyz / suscept, kzz / suscept) , 3, 3)
return(mat.sym.norm)
}
#' Calcul du vecteur propre et de la matrice d'anisotropie pour un spécimen
#' @param mesures data.frame contenant les mesures
#' @param step.value typiquement la température des mesures d'anisotropie
#' @param step.code code indiquant les étapes. les noms peuvent changer, mais pas l'ordre
#' @param volume la valeur du volume du spécimen
#' @param TH la valeur du champ appliqué
#' @return un data.frame avec les colonnes "L1", "L1.Inc", "L1.Dec", "L2", "L2.Inc", "L2.Dec", "L3", "L3.Inc", "L3.Dec", "F13", "F12", "F23"
#' @export
anisotropy.eigen <- function(mesures, step.value, step.code = c("Z+", "Z-", "X+", "X-", "Y+", "Y-", "ZB"), volume = 1, TH = 1,...)
{
#step.code <- c("Z+", "Z-", "X+", "X-", "Y+", "Y-", "ZB")
ani.step <- trimws(paste(as.character(step.value), step.code, sep = "") )
selec <- NULL
for (i in 1:length(ani.step)) {
selec <- c( selec, which(trimws(mesures$step) == trimws(ani.step[i])) )
}
res.list <- NULL
res.list <- mesures[selec,]
res.list <- res.list
mat.plus <- matrix( c( res.list$X[3], res.list$X[5], res.list$X[1],
res.list$Y[3], res.list$Y[5], res.list$Y[1],
res.list$Z[3], res.list$Z[5], res.list$Z[1]) , 3, 3)
mat.moins <- matrix( c( res.list$X[4], res.list$X[6], res.list$X[2],
res.list$Y[4], res.list$Y[6], res.list$Y[2],
res.list$Z[4], res.list$Z[6], res.list$Z[2]) , 3, 3)
mat.reel <- (mat.plus - mat.moins)/2 / (volume * 1E-6)# / coef.norm
# Symetrisation
coef.norm <- TH* 10/ (4*pi)
kxx <- mat.reel[1,1] / coef.norm
kyy <- mat.reel[2,2] / coef.norm
kzz <- mat.reel[3,3] / coef.norm
kxy <- (mat.reel[1,2] + mat.reel[2,1]) / 2 / coef.norm
kxz <- (mat.reel[1,3] + mat.reel[3,1]) / 2 / coef.norm
kyz <- (mat.reel[2,3] + mat.reel[3,2]) / 2 / coef.norm
# normalisation
suscept <- (kxx + kyy + kzz)/3
mat.sym.norm <- matrix( c( kxx / suscept, kxy / suscept, kxz / suscept,
0, kyy / suscept, kyz / suscept,
0, 0, kzz / suscept) , 3, 3)
# vecteurs et valeurs propres
v <- eigen(mat.sym.norm, symmetric = TRUE)
# calcul des angles I,D des vecteurs propres}
v1 <- NULL
v1$I<-to.polar.I(v$vectors[1, 1], v$vectors[2, 1], v$vectors[3 ,1])
v1$D<-to.polar.D(v$vectors[1, 1], v$vectors[2, 1], v$vectors[3 ,1])
v2 <- NULL
v2$I<-to.polar.I(v$vectors[1, 2], v$vectors[2, 2], v$vectors[3 ,2])
v2$D<-to.polar.D(v$vectors[1, 2], v$vectors[2, 2], v$vectors[3 ,2])
v3 <- NULL
v3$I<-to.polar.I(v$vectors[1, 3], v$vectors[2, 3],v$vectors[3 ,3])
v3$D<-to.polar.D(v$vectors[1, 3], v$vectors[2, 3],v$vectors[3 ,3])
if (v3$I<0) {
v3$I <- -v3$I
v3$D <- D.AM(v3$D +180)
v2$I <- -v2$I
v2$D <- D.AM(v2$D +180)
}
F13 <- v$values[1]/v$values[3]
F12 <- v$values[1]/v$values[2]
F23 <- v$values[2]/v$values[3]
ani <- c(eigen = v, L1 = v1, L2 = v2, L3 = v3, F13 = F13, F12 = F12, F23 = F23)
return(ani)
}
#' Calcul les coordonnées des tenseurs propres matrice d'anisotropie
#' @param mesures data.frame contenant les mesures
#' @param step.value typiquement la température des mesures d'anisotropie
#' @param step.code code indiquant les étapes. les noms peuvent changer, mais pas l'ordre
#' @param volume la valeur du volume du spécimen
#' @param TH la valeur du champ appliqué
#' @return un data.frame avec les colonnes "L1", "L1.Inc", "L1.Dec", "L2", "L2.Inc", "L2.Dec", "L3", "L3.Inc", "L3.Dec", "F13", "F12", "F23"
#' @seealso \code{\link{anisotropy.eigen.tensor}}
#' @export
anisotropy.eigen.matrix <- function(mesures, step.value, step.code = c("Z+", "Z-", "X+", "X-", "Y+", "Y-", "ZB"), volume = 1, TH = 1,...)
{
ani.step <- trimws(paste(as.character(step.value), step.code, sep = "") )
selec <- NULL
for (i in 1:length(ani.step)) {
selec <- c( selec, which(trimws(mesures$step) == trimws(ani.step[i])) )
}
res.list <- NULL
res.list <- mesures[selec,]
res.list <- res.list
mat.plus <- matrix( c( res.list$X[3], res.list$X[5], res.list$X[1],
res.list$Y[3], res.list$Y[5], res.list$Y[1],
res.list$Z[3], res.list$Z[5], res.list$Z[1]) , 3, 3)
mat.moins <- matrix( c( res.list$X[4], res.list$X[6], res.list$X[2],
res.list$Y[4], res.list$Y[6], res.list$Y[2],
res.list$Z[4], res.list$Z[6], res.list$Z[2]) , 3, 3)
mat.reel <- (mat.plus - mat.moins)/2 / (volume * 1E-6)# / coef.norm
# Symetrisation
coef.norm <- TH* 10/ (4*pi)
kxx <- mat.reel[1,1] / coef.norm
kyy <- mat.reel[2,2] / coef.norm
kzz <- mat.reel[3,3] / coef.norm
kxy <- (mat.reel[1,2] + mat.reel[2,1]) / 2 / coef.norm
kxz <- (mat.reel[1,3] + mat.reel[3,1]) / 2 / coef.norm
kyz <- (mat.reel[2,3] + mat.reel[3,2]) / 2 / coef.norm
# normalisation
suscept <- (kxx + kyy + kzz)/3
mat.sym.norm <- matrix( c( kxx / suscept, kxy / suscept, kxz / suscept,
0, kyy / suscept, kyz / suscept,
0, 0, kzz / suscept) , 3, 3)
# vecteurs et valeurs propres
v <- eigen(mat.sym.norm, symmetric = TRUE)
return(as.matrix(v$vectors))
}
#' Calcul de la matrice moyenne symétrisée d'anisotropie moyen (anisotropie totale)
#' @param Data.mesures data.frame contenant les mesures
#' @param step.value typiquement la température des mesures d'anisotropie
#' @param Data.number numéro des échantillons
#' @seealso \code{\link{anisotropy.mean.eigen.tensor}}
#' @return une matrice carrée 3 x3
#' @export
anisotropy.mean.matrix.total <- function (Data.mesures, Data.number, step.value, step.code = c("ZZ",
"XX", "YY", "ZB"))
{
ani.moyen <- matrix(c(0, 0, 0, 0, 0, 0, 0, 0, 0), nrow = 3,
ncol = 3)
for (spe in 1:length(Data.number)) {
spe.mes <- extract.mesures.specimen.number(Data.number[spe],
Data.mesures)
ani.moyen <- ani.moyen + anisotropy.matrix.symetric.total(mesures = spe.mes,
step.value = step.value, step.code = step.code)
}
ani.moyen <- ani.moyen/length(Data.number)
kxx <- ani.moyen[1, 1]
kyy <- ani.moyen[2, 2]
kzz <- ani.moyen[3, 3]
kxy <- (ani.moyen[1, 2] + ani.moyen[2, 1])/2
kxz <- (ani.moyen[1, 3] + ani.moyen[3, 1])/2
kyz <- (ani.moyen[2, 3] + ani.moyen[3, 2])/2
suscept <- (kxx + kyy + kzz)/3
mat.sym <- matrix(c(kxx/suscept, kxy/suscept, kxz/suscept,
kxy/suscept, kyy/suscept, kyz/suscept, kxz/suscept, kyz/suscept,
kzz/suscept), 3, 3)
return(mat.sym)
}
#' Calcul de la direction et des valeurs du vecteur propre d'anisotropie moyen (anisotropie totale)
#' @param Data.mesures data.frame contenant les mesures
#' @param step.value typiquement la température des mesures d'anisotropie
#' @param Data.number numéro des échantillons
#' @seealso \code{\link{anisotropy.eigen.matrix}}, \code{\link{anisotropy.mean.matrix.total}}
#' @return un data.frame avec les colonnes "L1", "L2", "L3", "L1.Inc", "L1.Dec", "L2.Inc", "L2.Dec", "L3.Inc", "L3.Dec", "F13", "F12", "F23"
#' @export
anisotropy.mean.eigen.tensor.total <- function (Data.mesures, Data.number, step.value, step.code = c("ZZ",
"XX", "YY", "ZB"))
{
mat.sym <- anisotropy.mean.matrix.total(Data.mesures, Data.number,
step.value = step.value, step.code = step.code)
v <- eigen(mat.sym, symmetric = TRUE)
v1 <- to.polar(v$vectors[1, 1], v$vectors[2, 1], v$vectors[3,
1])
v2 <- to.polar(v$vectors[1, 2], v$vectors[2, 2], v$vectors[3,
2])
v3 <- to.polar(v$vectors[1, 3], v$vectors[2, 3], v$vectors[3,
3])
if (v3$I < 0) {
v3$I <- -v3$I
v3$D <- D.AM(v3$D + 180)
v2$I <- -v2$I
v2$D <- D.AM(v2$D + 180)
}
F13 <- v$values[1]/v$values[3]
F12 <- v$values[1]/v$values[2]
F23 <- v$values[2]/v$values[3]
Data <- c(L1 = v$values[1], L2 = v$values[2], L3 = v$values[3],
L1.Inc = v1$I, L1.Dec = v1$D, L2.Inc = v2$I, L2.Dec = v2$D,
L3.Inc = v3$I, L3.Dec = v3$D, F13 = F13, F12 = F12, F23 = F23)
col.names <- c("L1", "L2", "L3", "L1.Inc", "L1.Dec", "L2.Inc",
"L2.Dec", "L3.Inc", "L3.Dec", "F13", "F12", "F23")
return(as.data.frame(t(Data), col.names = col.names))
}
#' Calcul la matrice d'anisotropie symetrisée et normalisé pour un spécimen (anisotropie totale)
#' qui sert à la correction
#' @param mesures data.frame contenant les mesures
#' @param step.value typiquement la température des mesures d'anisotropie
#' @param step.code code indiquant les étapes. les noms peuvent changer, mais pas l'ordre
#' @param volume la valeur du volume du spécimen
#' @param TH la valeur du champ appliqué
#' @return un data.frame avec les colonnes "L1", "L1.Inc", "L1.Dec", "L2", "L2.Inc", "L2.Dec", "L3", "L3.Inc", "L3.Dec", "F13", "F12", "F23"
#' @export
anisotropy.matrix.symetric.total <- function (mesures, step.value, step.code = c("ZZ",
"XX", "YY", "ZB"), ...)
{
ani.step <- trimws(paste(as.character(step.value), step.code,
sep = ""))
selec <- NULL
for (i in 1:length(ani.step)) {
selec <- c(selec, which(trimws(mesures$step) == trimws(ani.step[i])))
}
res.list <- NULL
res.list <- mesures[selec, ]
res.list <- res.list
if (res.list$X[2] < 0){
res.list$X[1] <- -1*res.list$X[1]
res.list$X[2] <- -1*res.list$X[2]
res.list$X[3] <- -1*res.list$X[3]
}
if (res.list$Y[3] < 0){
res.list$Y[1] <- -1*res.list$Y[1]
res.list$Y[2] <- -1*res.list$Y[2]
res.list$Y[3] <- -1*res.list$Y[3]
}
if (res.list$Z[1] < 0){
res.list$Z[1] <- -1*res.list$Z[1]
res.list$Z[2] <- -1*res.list$Z[2]
res.list$Z[3] <- -1*res.list$Z[3]
}
mat.reel <- matrix(c(res.list$X[2], (res.list$X[3]), (res.list$X[1]),
(res.list$Y[2]), (res.list$Y[3]), (res.list$Y[1]),
(res.list$Z[2]), (res.list$Z[3]), (res.list$Z[1])), 3, 3)
coef.norm <- 1
kxx <- mat.reel[1, 1]/coef.norm
kyy <- mat.reel[2, 2]/coef.norm
kzz <- mat.reel[3, 3]/coef.norm
kxy <- (mat.reel[1, 2] + mat.reel[2, 1])/2/coef.norm
kxz <- (mat.reel[1, 3] + mat.reel[3, 1])/2/coef.norm
kyz <- (mat.reel[2, 3] + mat.reel[3, 2])/2/coef.norm
suscept <- (kxx + kyy + kzz)/3
mat.sym.norm <- matrix(c(kxx/suscept, kxy/suscept, kxz/suscept,
kxy/suscept, kyy/suscept, kyz/suscept, kxz/suscept, kyz/suscept,
kzz/suscept), 3, 3)
return(mat.sym.norm)
}
#' Calcul des tenseurs d'anisotropie pour tous les spécimens d'une liste de mesures (anisotropie totale)
#' @return un data.frame avec les colonnes "L1", "L2", "L3", "L1.Inc", "L1.Dec", "L2.Inc", "L2.Dec", "L3.Inc", "L3.Dec", "F13", "F12", "F23"
#' @export
anisotropy.eigen.tensors.total.all <- function (Data.mesures, Data.number, step.value, step.code = c("ZZ",
"XX", "YY", "ZB"))
{
numbers <- NULL
for (i in 1:length(Data.number)) {
if (length(which(numbers == Data.number[i])) == 0)
numbers <- c(numbers, Data.number[i])
}
Data <- NULL
for (i in 1:length(numbers)) {
mesures <- extract.mesures.specimen.number(numbers[i],
Data.mesures)
ani <- anisotropy.eigen.tensor.total(mesures, step.value = step.value,
step.code = step.code)
Data <- rbind(Data, ani)
}
col.names <- col.names <- c("L1", "L2", "L3", "L1.Inc", "L1.Dec",
"L2.Inc", "L2.Dec", "L3.Inc", "L3.Dec", "F13", "F12",
"F23")
return(as.data.frame(Data, col.names = col.names))
}
#' Calcul des directions et valeurs des vecteurs propres d'anisotropie totale pour un spécimen à une certaine température
#' @param mesures data.frame contenant les mesures
#' @param step.value typiquement la température des mesures d'anisotropie
#' @param step.code code indiquant les étapes. Les noms peuvent changer, mais pas l'ordre
#' @seealso \code{\link{anisotropy.eigen.matrix}}
#' @return un data.frame avec les colonnes "L1", "L1.Inc", "L1.Dec", "L2", "L2.Inc", "L2.Dec", "L3", "L3.Inc", "L3.Dec", "F13", "F12", "F23"
#' @export
anisotropy.eigen.tensor.total <- function (mesures, step.value, step.code = c("ZZ", "XX",
"YY", "ZB"))
{
ani.step <- trimws(paste(as.character(step.value), step.code,
sep = ""))
selec <- NULL
for (i in 1:length(ani.step)) {
selec <- c(selec, which(trimws(mesures$step) == trimws(ani.step[i])))
}
res.list <- NULL
res.list <- mesures[selec, ]
res.list <- res.list
col.names <- c("L1", "L1.Inc", "L1.Dec", "L2", "L2.Inc",
"L2.Dec", "L3", "L3.Inc", "L3.Dec", "F13", "F12", "F23")
verif <- 1
for (i in 1:3) {verif <- verif * res.list$X[i] * res.list$Y[i] *
res.list$Z[i]
}
if (is.null(verif) || is.na(verif)) {
Data <- c(L1 = 0, L2 = 0, L3 = 0, L1.Inc = 0, L1.Dec = 0,
L2.Inc = 0, L2.Dec = 0, L3.Inc = 0, L3.Dec = 0, F13 = 0,
F12 = 0, F23 = 0)
return(as.data.frame(t(Data), col.names = col.names))
}
if (res.list$X[2] < 0){
res.list$X[1] <- -1*res.list$X[1]
res.list$X[2] <- -1*res.list$X[2]
res.list$X[3] <- -1*res.list$X[3]
}
if (res.list$Y[3] < 0){
res.list$Y[1] <- -1*res.list$Y[1]
res.list$Y[2] <- -1*res.list$Y[2]
res.list$Y[3] <- -1*res.list$Y[3]
}
if (res.list$Z[1] < 0){
res.list$Z[1] <- -1*res.list$Z[1]
res.list$Z[2] <- -1*res.list$Z[2]
res.list$Z[3] <- -1*res.list$Z[3]
}
mat.reel <- matrix(c(res.list$X[2], (res.list$X[3]), (res.list$X[1]),
(res.list$Y[2]), (res.list$Y[3]), (res.list$Y[1]),
(res.list$Z[2]), (res.list$Z[3]), (res.list$Z[1])), 3, 3)
coef.norm <- 1
kxx <- mat.reel[1, 1]/coef.norm
kyy <- mat.reel[2, 2]/coef.norm
kzz <- mat.reel[3, 3]/coef.norm
kxy <- (mat.reel[1, 2] + mat.reel[2, 1])/2/coef.norm
kxz <- (mat.reel[1, 3] + mat.reel[3, 1])/2/coef.norm
kyz <- (mat.reel[2, 3] + mat.reel[3, 2])/2/coef.norm
suscept <- (kxx + kyy + kzz)/3
mat.sym.norm <- matrix(c(kxx/suscept, kxy/suscept, kxz/suscept,
0, kyy/suscept, kyz/suscept, 0, 0, kzz/suscept), 3, 3)
v <- eigen(mat.sym.norm, symmetric = TRUE)
v1 <- to.polar(v$vectors[1, 1], v$vectors[2, 1], v$vectors[3,
1])
v2 <- to.polar(v$vectors[1, 2], v$vectors[2, 2], v$vectors[3,
2])
v3 <- to.polar(v$vectors[1, 3], v$vectors[2, 3], v$vectors[3,
3])
if (v3$I < 0) {
v3$I <- -v3$I
v3$D <- D.AM(v3$D + 180)
v2$I <- -v2$I
v2$D <- D.AM(v2$D + 180)
print(v)}
if (is.null(v$values[3]) || is.null(v$values[2])) {
Data <- c(L1 = 0, L2 = 0, L3 = 0, L1.Inc = 0, L1.Dec = 0,
L2.Inc = 0, L2.Dec = 0, L3.Inc = 0, L3.Dec = 0, F13 = 0,
F12 = 0, F23 = 0)
}
else {
F13 <- v$values[1]/v$values[3]
F12 <- v$values[1]/v$values[2]
F23 <- v$values[2]/v$values[3]
Data <- c(L1 = v$values[1], L2 = v$values[2], L3 = v$values[3],
L1.Inc = v1$I, L1.Dec = v1$D, L2.Inc = v2$I, L2.Dec = v2$D,
L3.Inc = v3$I, L3.Dec = v3$D, F13 = F13, F12 = F12,
F23 = F23)
}
return(as.data.frame(t(Data), col.names = col.names))
}
#' Calcul des directions et valeurs des vecteurs propres d'anisotropie partielle pour un spécimen à une certaine température
#' @param mesures data.frame contenant les mesures
#' @param step.value typiquement la température des mesures d'anisotropie
#' @param step.code code indiquant les étapes. Les noms peuvent changer, mais pas l'ordre
#' @seealso \code{\link{anisotropy.eigen.matrix}}
#' @return un data.frame avec les colonnes "L1", "L1.Inc", "L1.Dec", "L2", "L2.Inc", "L2.Dec", "L3", "L3.Inc", "L3.Dec", "F13", "F12", "F23"
#' @export
anisotropy.eigen.tensor <- function (mesures, step.value, step.code = c("Z+", "Z-", "X+", "X-", "Y+", "Y-", "ZB") )
{
ani.step <- trimws(paste(as.character(step.value), step.code, sep = "") )
selec <- NULL
for (i in 1:length(ani.step)) {
selec <- c( selec, which(trimws(mesures$step) == trimws(ani.step[i])) )
}
res.list <- NULL
res.list <- mesures[selec,]
res.list <- res.list
col.names <- c("L1", "L1.Inc", "L1.Dec", "L2", "L2.Inc", "L2.Dec", "L3", "L3.Inc", "L3.Dec", "F13", "F12", "F23")
# vérification de l'existence de tous les termes
verif <- 1
for (i in 1 : 6)
verif <- verif * res.list$Z[i]* res.list$Z[i]* res.list$Z[i]
if ( is.null(verif) || is.na(verif) ) {
Data <- c( L1 = 0, L2 = 0, L3 = 0,
L1.Inc = 0, L1.Dec = 0,
L2.Inc = 0, L2.Dec = 0,
L3.Inc = 0, L3.Dec = 0,
F13 = 0, F12 = 0, F23 = 0)
return(as.data.frame(t(Data), col.names = col.names))
}
mat.plus <- matrix( c( res.list$X[3], res.list$X[5], res.list$X[1],
res.list$Y[3], res.list$Y[5], res.list$Y[1],
res.list$Z[3], res.list$Z[5], res.list$Z[1]) , 3, 3)
mat.moins <- matrix( c( res.list$X[4], res.list$X[6], res.list$X[2],
res.list$Y[4], res.list$Y[6], res.list$Y[2],
res.list$Z[4], res.list$Z[6], res.list$Z[2]) , 3, 3)
mat.reel <- (mat.plus - mat.moins)/2 #/ (volume * 1E-6)# / coef.norm
# Symetrisation
coef.norm <- 1 #TH* 10/ (4*pi)
kxx <- mat.reel[1,1] / coef.norm
kyy <- mat.reel[2,2] / coef.norm
kzz <- mat.reel[3,3] / coef.norm
kxy <- (mat.reel[1,2] + mat.reel[2,1]) / 2 / coef.norm
kxz <- (mat.reel[1,3] + mat.reel[3,1]) / 2 / coef.norm
kyz <- (mat.reel[2,3] + mat.reel[3,2]) / 2 / coef.norm
# normalisation
suscept <- (kxx + kyy + kzz)/3
mat.sym.norm <- matrix( c( kxx / suscept, kxy / suscept, kxz / suscept,
0, kyy / suscept, kyz / suscept,
0, 0, kzz / suscept) , 3, 3)
# vecteurs et valeurs propres
v <- eigen(mat.sym.norm, symmetric = TRUE)
# calcul des angles I,D des vecteurs propres}
v1 <- to.polar(v$vectors[1, 1], v$vectors[2, 1], v$vectors[3 ,1])
v2 <- to.polar(v$vectors[1, 2], v$vectors[2, 2], v$vectors[3 ,2])
v3 <- to.polar(v$vectors[1, 3], v$vectors[2, 3], v$vectors[3 ,3])
if (v3$I<0) {
v3$I <- -v3$I
v3$D <- D.AM(v3$D +180)
v2$I <- -v2$I
v2$D <- D.AM(v2$D +180)
}
if (is.null(v$values[3]) || is.null(v$values[2]) ) {
Data <- c( L1 = 0, L2 = 0, L3 = 0,
L1.Inc = 0, L1.Dec = 0,
L2.Inc = 0, L2.Dec = 0,
L3.Inc = 0, L3.Dec = 0,
F13 = 0, F12 = 0, F23 = 0)
}
else {
F13 <- v$values[1]/v$values[3]
F12 <- v$values[1]/v$values[2]
F23 <- v$values[2]/v$values[3]
Data <- c( L1 = v$values[1], L2 = v$values[2], L3 = v$values[3],
L1.Inc = v1$I, L1.Dec = v1$D,
L2.Inc = v2$I, L2.Dec = v2$D,
L3.Inc = v3$I, L3.Dec = v3$D,
F13 = F13, F12 = F12, F23 = F23)
}
return(as.data.frame(t(Data), col.names = col.names))
}
#' Calcul des tenseurs d'anisotropie pour une liste de numéro de spécimen
#' @param names liste de numéro de spécimen
#' @param Data.mesures data.frame contenant les mesures
#' @return un data.frame avec les colonnes "L1", "L2", "L3", "L1.Inc", "L1.Dec", "L2.Inc", "L2.Dec", "L3.Inc", "L3.Dec", "F13", "F12", "F23"
#' @export
anisotropy.eigen.tensors.numbers <- function(numbers, Data.mesures, step.value, step.code = c("Z+", "Z-", "X+", "X-", "Y+", "Y-", "ZB"))
{
Data <- NULL
for (i in 1:length(numbers) ) {
mesures <- extract.mesures.specimen.number(numbers[i], Data.mesures)
ani <- anisotropy.eigen.tensor(mesures, step.value = step.value, step.code = step.code)
Data <- rbind(Data, ani)
}
col.names <- c("L1", "L2", "L3", "L1.Inc", "L1.Dec", "L2.Inc", "L2.Dec", "L3.Inc", "L3.Dec", "F13", "F12", "F23")
return(as.data.frame(Data, col.names = col.names))
}
#' Calcul des tenseurs d'anisotropie pour une liste de nom de spécimen
#' @param names liste de noms de spécimens
#' @param Data.mesures data.frame contenant les mesures
#' @return un data.frame avec les variables "L1", "L2", "L3", "L1.Inc", "L1.Dec", "L2.Inc", "L2.Dec", "L3.Inc", "L3.Dec", "F13", "F12", "F23"
#' @export
anisotropy.eigen.tensors.names <- function(names, Data.mesures, step.value, step.code = c("Z+", "Z-", "X+", "X-", "Y+", "Y-", "ZB"))
{
Data <- NULL
for (i in 1:length(names) ) {
mesures <- extract.mesures.specimen.name(names[i], Data.mesures)
ani <- anisotropy.eigen.tensor(mesures, step.value = step.value, step.code = step.code)
Data <- rbind(Data, ani)
}
col.names <- c("L1", "L2", "L3", "L1.Inc", "L1.Dec", "L2.Inc", "L2.Dec", "L3.Inc", "L3.Dec", "F13", "F12", "F23")
return(as.data.frame(Data, col.names = col.names))
}
#' Calcul des tenseurs d'anisotropie pour tous les spécimens d'une liste de mesures
#' @return un data.frame avec les colonnes "L1", "L2", "L3", "L1.Inc", "L1.Dec", "L2.Inc", "L2.Dec", "L3.Inc", "L3.Dec", "F13", "F12", "F23"
#' @export
anisotropy.eigen.tensors.all <- function(Data.mesures, Data.number, step.value, step.code = c("Z+", "Z-", "X+", "X-", "Y+", "Y-", "ZB"))
{
numbers <- NULL
for (i in 1: length(Data.number) ) {
if ( length(which( numbers == Data.number[i] )) == 0 )
numbers <- c(numbers, Data.number[i])
}
Data <- NULL
for (i in 1:length(numbers) ) {
mesures <- extract.mesures.specimen.number(numbers[i], Data.mesures)
ani <- anisotropy.eigen.tensor(mesures, step.value = step.value, step.code = step.code )
Data <- rbind(Data, ani)
}
col.names <- col.names <- c("L1", "L2", "L3", "L1.Inc", "L1.Dec", "L2.Inc", "L2.Dec", "L3.Inc", "L3.Dec", "F13", "F12", "F23")
return(as.data.frame(Data, col.names = col.names))
}
#' Calcul de la matrice moyenne symétrisée d'anisotropie moyen
#' @param Data.mesures data.frame contenant les mesures
#' @param step.value typiquement la température des mesures d'anisotropie
#' @param Data.number numéro des échantillons
#' @seealso \code{\link{anisotropy.mean.eigen.tensor}}
#' @return une matrice carrée 3 x3
#' @export
anisotropy.mean.matrix <- function(Data.mesures, Data.number, step.value, step.code = c("Z+", "Z-", "X+", "X-", "Y+", "Y-", "ZB"))
{
ani.moyen <- matrix(c(0, 0, 0, 0, 0, 0, 0, 0, 0), nrow = 3, ncol = 3)
for (spe in 1: length(Data.number))
{
spe.mes <- extract.mesures.specimen.number(Data.number[spe], Data.mesures)
ani.moyen <- ani.moyen + anisotropy.matrix.symetric(mesures = spe.mes, step.value = step.value, step.code = step.code)
}
ani.moyen <- ani.moyen/ length(Data.number)
# Symetrisation
kxx <- ani.moyen[1,1]
kyy <- ani.moyen[2,2]
kzz <- ani.moyen[3,3]
kxy <- (ani.moyen[1,2] + ani.moyen[2,1]) / 2
kxz <- (ani.moyen[1,3] + ani.moyen[3,1]) / 2
kyz <- (ani.moyen[2,3] + ani.moyen[3,2]) / 2
suscept <- (kxx + kyy + kzz)/3
mat.sym <- matrix( c( kxx/suscept , kxy/suscept , kxz/suscept,
kxy/suscept , kyy/suscept , kyz/suscept,
kxz/suscept , kyz/suscept , kzz/suscept ) , 3, 3)
return(mat.sym)
}
#' Calcul de la direction et des valeurs du vecteur propre d'anisotropie moyen
#' @param Data.mesures data.frame contenant les mesures
#' @param step.value typiquement la température des mesures d'anisotropie
#' @param Data.number numéro des échantillons
#' @seealso \code{\link{anisotropy.eigen.matrix}}, \code{\link{anisotropy.mean.matrix}}
#' @return un data.frame avec les colonnes "L1", "L2", "L3", "L1.Inc", "L1.Dec", "L2.Inc", "L2.Dec", "L3.Inc", "L3.Dec", "F13", "F12", "F23"
#' @export
anisotropy.mean.eigen.tensor <- function(Data.mesures, Data.number, step.value, step.code = c("Z+", "Z-", "X+", "X-", "Y+", "Y-", "ZB"))
{
mat.sym <- anisotropy.mean.matrix(Data.mesures, Data.number, step.value = step.value, step.code = step.code)
v <- eigen(mat.sym, symmetric = TRUE)
# calcul des angles I,D des vecteurs propres}
v1 <- to.polar(v$vectors[1, 1], v$vectors[2, 1], v$vectors[3 ,1])
v2 <- to.polar(v$vectors[1, 2], v$vectors[2, 2], v$vectors[3 ,2])
v3 <- to.polar(v$vectors[1, 3], v$vectors[2, 3], v$vectors[3 ,3])
if (v3$I<0) {
v3$I <- -v3$I
v3$D <- D.AM(v3$D +180)
v2$I <- -v2$I
v2$D <- D.AM(v2$D +180)
}
F13 <- v$values[1]/v$values[3]
F12 <- v$values[1]/v$values[2]
F23 <- v$values[2]/v$values[3]
Data <- c( L1 = v$values[1], L2 = v$values[2], L3 = v$values[3],
L1.Inc = v1$I, L1.Dec = v1$D,
L2.Inc = v2$I, L2.Dec = v2$D,
L3.Inc = v3$I, L3.Dec = v3$D,
F13 = F13, F12 = F12, F23 = F23)
col.names <- c( "L1", "L2", "L3", "L1.Inc", "L1.Dec", "L2.Inc", "L2.Dec", "L3.Inc", "L3.Dec", "F13", "F12", "F23")
return(as.data.frame(t(Data), col.names = col.names))
}
#' Corrige les mesures avec la matrice d'anisotropie donnée
#' Il faut une matrice 3 x3
#' @param mesures.frame data.frame avec les mesures et variables X, Y, Z, i, D, F
#' @param ani.matric matrice 3 x 3 correspondant à la matrice (symétrique et normalisé) à utiliser pour la correction
#' @return un data.frame du même type que mesures.frame
#' @export
correction.anisotropy <- function(mesures.frame, ani.matrix)
{
if (!is.data.frame(mesures.frame))
warning("mesures must be a data.frame")
if (!is.matrix(ani.matrix))
warning("ani.matrix must be a matrix")
nbMesures <- length(mesures.frame[,1])
# inversion de la matrice
ani.inv <- solve(ani.matrix)
r_cal_echt <- NULL
# Calcul pour une mesure
correct <- function(mesure, aniso.inv) {
# Calcul de la correction
re.cal.ani <- aniso.inv %*% c( mesure$X, mesure$Y, mesure$Z)
# recopie des variables
re.cal <- mesure
re.cal$X <- re.cal.ani[1]
re.cal$Y <- re.cal.ani[2]
re.cal$Z <- re.cal.ani[3]
re.cal.ID <- to.polar(re.cal$X, re.cal$Y, re.cal$Z)
re.cal$I <- re.cal.ID$I
re.cal$D <- re.cal.ID$D
re.cal$F <- re.cal.ID$F
return(re.cal)
}
resT <- NULL
for (i in 1 : nbMesures)
resT <- rbind(resT, correct(mesures.frame[i,], ani.inv))
return(resT)
}
#' Tracer dans le diagramme Lambert/ Stéréo d'un tenseur
#' @param Data un data.frame avec les variables "L1.Inc", "L1.Dec", "L2.Inc", "L2.Dec", "L3.Inc", "L3.Dec"
#' @export
lambert.ID.tensors <- function(Data, pt.col = "blue3", new = TRUE, ...)
{
# Restructuration des données
L1.Inc <- as.numeric(Data$L1.Inc)
L2.Inc <- as.numeric(Data$L2.Inc)
L3.Inc <- as.numeric(Data$L3.Inc)
L1.Dec <- as.numeric(Data$L1.Dec)
L2.Dec <- as.numeric(Data$L2.Dec)
L3.Dec <- as.numeric(Data$L3.Dec)
if (length(L1.Inc) == 0)
return(print("no DATA"))
if (length(pt.col) < length(L1.Inc))
pt.col <- rep(pt.col, length.out = length(L1.Inc))
for (i in 1:length(L1.Inc) ) {
Da.I <- c(L1.Inc[i], L2.Inc[i], L3.Inc[i])
Da.D <- c(L1.Dec[i], L2.Dec[i], L3.Dec[i])
lambert.ID(Da.I, Da.D,
inc.lim = c(0, 90), pch = c(22, 24, 21), pt.col = pt.col[i], new = new )
new <- FALSE
}
}
#' Tracer d'un diagramme de Flinn
#' diagramme des paramètres d'anisotropie F12 en fonction de F23
#' @param Data soit correspond à un data.frame avec les variables $F23 et $F12, soit seulement des valeurs de F23 dans ce cas, renseignez Data.F12
#' @param Data.F12 des valeurs pour F12
#' @param absolue prend la valeur absolue des données
#' @export
flinn <- function( Data, Data.F12 = NULL, pt.names = NULL, pt.col = "blue3", pch = 21, type = "p",
xlab = "F23", ylab = "F12", main = "Flinn diagram", absolue = TRUE, new = TRUE)
{
par(pty="s", "xaxp")
if(is.data.frame(Data)) {
if (absolue == TRUE) {
X <- abs(Data$F23)
Y <- abs(Data$F12)
} else {
X <- Data$F23
Y <- Data$F12
}
} else {
if (absolue == TRUE) {
X <- abs(Data)
Y <- abs(Data.F12)
} else {
X <- Data
Y <- Data.F12
}
}
X.lim <- range(X)
if (X.lim[1]>1)
X.lim[1] <- 1
Y.lim <- range(Y)
if (Y.lim[1]>1)
Y.lim[1] <- 1
XY.max <- max(X.lim[2], Y.lim[2]) * 1.05
X.lim[2] <- XY.max
Y.lim[2] <- XY.max
if (new == TRUE) {
plot(x = X, y = Y, xlab = xlab, ylab = ylab, xlim = X.lim, ylim = Y.lim, type = type, col = "gray50", bg = pt.col, pch = pch,
xaxt = "n", yaxt = "n", asp = 1, bty ="n", main = main, new = TRUE )
ax1 <- axis(1, pos = X.lim[1], col = "gray10")
ax2 <- axis(2, pos = Y.lim[1], col = "gray10") # Ordonnées
cc<-array(c(0,1), c(1,2))
abline( coef = cc, col = "gray90")
main <- ""
} else {
points(x = X, y = Y, xlim = X.lim, ylim = Y.lim, type = type, col = "gray50", bg = pt.col, pch = pch,
xaxt = "n", yaxt = "n", asp = 1, bty ="n", new = FALSE)
}
text(jitter(X, 5, amount = 0), jitter(Y, 5, amount = 0), pt.names)
}
#' Tracer d'un diagramme de désaimantation
#' @param normalize permet de comparer l'évolution de l'aimanation quelque soit l'amplitude en visualisant le résultat comme un pourcentage du maximum
#' @export
demag <- function( Data, F = NULL, pt.col = "blue3", pch = 21, type = "b",
xlab = "°C", ylab = "", main = NULL,
names = NA, normalize = TRUE, step.J0 = NULL, new = TRUE, ...)
{
tmp.frame <- NULL
if (is.null(main))
main <- " F vs step.value"
if(is.data.frame(Data)) {
tmp.frame$name <- Data$name[!is.na(Data$step.value)]
tmp.frame$step.value <- Data$step.value[!is.na(Data$step.value)]
tmp.frame$F <- Data$F[!is.na(Data$step.value)]
} else {
# Création du frame interne
if (is.na(names))
tmp.frame$name <- as.character(c(1: length(Data)))
else
tmp.frame$name <- names
tmp.frame$step.value <- Data
tmp.frame$F <- F
}
if (length(pt.col) < length(tmp.frame$step.value) )
pt.col <- rep(pt.col, length(tmp.frame$step.value) )
# comptage et séparation des données
current <- tmp.frame$name[1]
list.name <- current
for (i in 1: length(tmp.frame$name)) {
if ( tmp.frame$name[i] != current) {
current <- tmp.frame$name[i]
list.name<- c(list.name, current)
}
}
if (is.null(step.J0) == FALSE) {
if (length(step.J0) < length(tmp.frame$step.value) )
step.J0 <- rep(step.J0, length(list.name) )
} else {
step.J0 <- rep(NA, length(list.name) )
}
xlim <- range(tmp.frame$step.value)
# recherche du Ymax pour définir la taille du graphique
Ymax <- 0
J0 <- 0
list.mesure.i <- NULL
if (normalize == TRUE) {
for (i in 1 : length(list.name)) {
list.mesure.i$F <- tmp.frame$F[tmp.frame$name == list.name[i]]
if (is.na(step.J0[i]) == TRUE) {
J0[i] <- list.mesure.i$F[1]
} else {
tmp.etp <- list.mesure.i$F[tmp.frame$step.value == step.J0[i]] # si il y a plusieurs valeurs pour la même étape, comme ani
J0[i] <- tmp.etp[1]
# J0[i] <- list.mesure.i$F[tmp.frame$step.value == step.J0[i]]
}
Ymax <- max(Ymax, tmp.frame$F[tmp.frame$name == list.name[i]]/J0[i] *100)
}
} else
Ymax <- max(tmp.frame$F)
list.mesure.i <- NULL
for (i in 1 : length(list.name)) {
list.mesure.i$step.value <- tmp.frame$step.value[which(tmp.frame$name == list.name[i])]
list.mesure.i$F <- tmp.frame$F[tmp.frame$name == list.name[i]]
if (normalize == TRUE) {
coefY <- 100 / J0[i]
} else
coefY <- 1
Xi <- list.mesure.i$step.value
Yi <- list.mesure.i$F * coefY
ylim <- c(0, Ymax)
if (i == 1)
plot(x = Xi, y = Yi, xlab = xlab, ylab = ylab, ylim = ylim, xlim = xlim, type = type,
col = adjustcolor( pt.col[i], alpha.f = 0.7), bg = pt.col[i], pch = pch,
yaxt = "n", bty = "n", main = main, new = new)
else
lines(x = Xi, y = Yi, type = type, col = adjustcolor( pt.col[i], alpha.f = 0.7), bg = pt.col[i], pch = pch, yaxt = "n", bty ="n")
}
axis(2, pos = 0, col = "darkgray") #cex.axis = 0.8) # Ordonnées
if (normalize == TRUE) {
mtext( paste(format(Ymax, digits = 3), "%"), side = 3, col = "gray5", adj = 0, cex = par("cex.lab"))
} else {
mtext( format(Ymax, digits = 3, scientific = TRUE), side = 3, col = "gray5", adj = 0, cex = par("cex.lab"))
}
}
# Orientation correction ----
#' Correction de carottage sur tranche
#' Tourne les mesures de manière à retrouver le résultat suivant la convention de carottage à plat
#' @export
correction.carottage.tranche <- function(mesures.brutes)
{
mesures.convent <- mesures.brutes
mesures.convent$X <- mesures.brutes$X
mesures.convent$Y <- - mesures.brutes$Z
mesures.convent$Z <- mesures.brutes$Y
for (i in 1 : length(mesures.convent$X)) {
mesures.convent$I[i] <- to.polar.I(mesures.convent$X[i], mesures.convent$Y[i], mesures.convent$Z[i])
mesures.convent$D[i] <- to.polar.D(mesures.convent$X[i], mesures.convent$Y[i], mesures.convent$Z[i])
}
return(mesures.convent)
}
#' Correction de carottage en bout
#' Tourne les mesures de manière à retrouver le résultat suivant la convention de carottage à plat
#' @export
correction.carottage.enbout <- function(mesures.brutes)
{
mesures.convent <- mesures.brutes
for (i in 1 : length(mesures.brutes$X)) {
mesures.convent$X[i] <- mesures.brutes$Z[i]
mesures.convent$Y[i] <- mesures.brutes$X[i]
mesures.convent$Z[i] <- mesures.brutes$Y[i]
mesures.convent$I[i] <- to.polar.I(mesures.convent$X[i], mesures.convent$Y[i], mesures.convent$Z[i])
mesures.convent$D[i] <- to.polar.D(mesures.convent$X[i], mesures.convent$Y[i], mesures.convent$Z[i])
}
return(mesures.convent)
}
#' Correction de repère d'orientement avec la norme archeomagnetique
#' Pour les Matériaux déplacés:
#' on utilise Inc et Az pour faire la correction de #, c'est à dire repère de carrotage perpendiculaire au bord long
#: Inc=0 Az =90°
#' cela revient à tourner dans le sens trigonométrique dans les stéréogrammes
#' @seealso \code{\link{correction.paleo}}, \code{\link{correction.bevel}}, \code{\link{correction.bending}}
#' @export
correction.archeo <-function(mes, inc=0, az=0) {
rad = pi /180
inc <- inc * rad
az <- az * rad
M_rot_In <- matrix(data = 0, 3,3)
M_rot_In[1,1] = cos(inc);
M_rot_In[1,2] = 0;
M_rot_In[1,3] = sin(inc);
M_rot_In[2,1] = 0;
M_rot_In[2,2] = 1;
M_rot_In[2,3] = 0;
M_rot_In[3,1] = -sin(inc);
M_rot_In[3,2] = 0;
M_rot_In[3,3] = cos(inc);
#M_rot_temp <- M_rot_In %*% M_rot_temp
M_rot_Az <- matrix(data = 0, 3,3)
M_rot_Az[1,1] = cos(az)
M_rot_Az[1,2] = sin(az)
M_rot_Az[1,3] = 0
M_rot_Az[2,1] = -sin(az)
M_rot_Az[2,2] = cos(az)
M_rot_Az[2,3] = 0
M_rot_Az[3,1] = 0
M_rot_Az[3,2] = 0
M_rot_Az[3,3] = 1
M_rot = M_rot_Az %*% M_rot_In
#système matriciel}
res<- mes # copy all variable
tmp <- NULL
for (i in 1:nrow(mes)) {
tmp <- matrix(c(mes$X[i], mes$Y[i],mes$Z[i]), 3, 1 )
tmp <- M_rot %*% tmp
tmp <- to.polar(tmp[1], tmp[2], tmp[3])
res$X[i] <- tmp$X
res$Y[i] <- tmp$Y
res$Z[i] <- tmp$Z
res$I[i] <- tmp$I
res$D[i] <- tmp$D
res$F[i] <- tmp$F
}
return(res)
}
#' C'est la correction de repère utilisée en paléomag
#' @param Inc =0 si carotte verticale et Inc=90° si carotte horizontale
#' @param Az est compté positif dans le sens des aiguilles d'une montre
#' @seealso \code{\link{correction.archeo}}, \code{\link{correction.bevel}} , \code{\link{correction.bending}}
#' @export
correction.paleo <-function(mes, inc=0, az=0) {
rad = pi /180
inc <- inc * rad
az <- az * rad
M_rot_In <- matrix(data = 0, 3,3)
M_rot_In[1,1] = cos(inc);
M_rot_In[1,2] = 0;
M_rot_In[1,3] = sin(inc);
M_rot_In[2,1] = 0;
M_rot_In[2,2] = 1;
M_rot_In[2,3] = 0;
M_rot_In[3,1] = -sin(inc);
M_rot_In[3,2] = 0;
M_rot_In[3,3] = cos(inc);
#M_rot_temp <- M_rot_In %*% M_rot_temp
M_rot_Az <- matrix(data = 0, 3,3)
M_rot_Az[1,1] = sin(az)
M_rot_Az[1,2] = cos(az)
M_rot_Az[1,3] = 0
M_rot_Az[2,1] = -cos(az)
M_rot_Az[2,2] = sin(az)
M_rot_Az[2,3] = 0
M_rot_Az[3,1] = 0
M_rot_Az[3,2] = 0
M_rot_Az[3,3] = 1
M_rot = M_rot_Az %*% M_rot_In
#système matriciel}
res<- mes # copy all variable
tmp <- NULL
for (i in 1:nrow(mes)) {
tmp <- matrix(c(mes$X[i], mes$Y[i],mes$Z[i]), 3, 1 )
tmp <- M_rot %*% tmp
tmp <- to.polar(tmp[1], tmp[2], tmp[3])
res$X[i] <- tmp$X
res$Y[i] <- tmp$Y
res$Z[i] <- tmp$Z
res$I[i] <- tmp$I
res$D[i] <- tmp$D
res$F[i] <- tmp$F
}
return(res)
}
#' Correction biseau - bevel
#' En archéomagnétisme correspond à une erreur de carottage par rapport à l'axe théorique de carottage,
#' à une mauvaise perpendicularité du carottage généralement
#' @param Theta est exprimé entre 0 et 90° (toujours positif)
#' @param psi est compté positif dans le sens des aiguilles d'une montre et donc négatif dans le sens inverse...
#' Note: la correction de biseau - bevel se fait avant la correction de repère
#' @seealso \code{\link{correction.paleo}}, \code{\link{correction.archeo}}, \code{\link{correction.bending}}
#' @export
correction.bevel <-function(mes, theta=0, psi=0) {
rad = pi /180
phi = 0 # initialisation
theta <- theta*rad
psi <- psi *rad
#rotation teta négatif pour amener le repère dans le plan du biseau
theta = - theta;
# détermination de Phi
if (abs(psy)==(pi/2)) {
phi <- -psi
} else {
phi <- -atan(tan(psi)*cos(theta)) #angle dans le plan de sciage}
if (psi>=+(pi/2)) phi = phi - pi;
if (psi<=-(pi/2)) phi = phi + pi;
}
M_rot_Phi <- matrix(data = 0, 3,3)
M_rot_Phi[1,1] = cos(phi);
M_rot_Phi[1,2] = sin(phi);
M_rot_Phi[1,3] = 0;
M_rot_Phi[2,1] = -sin(phi);
M_rot_Phi[2,2] = cos(phi);
M_rot_Phi[2,3] = 0;
M_rot_Phi[3,1] = 0;
M_rot_Phi[3,2] = 0;
M_rot_Phi[3,3] = 1;
M_rot_theta <- matrix(data = 0, 3,3)
M_rot_theta[1,1] = cos(theta);
M_rot_theta[1,2] = 0;
M_rot_theta[1,3] = -sin(theta);
M_rot_theta[2,1] = 0;
M_rot_theta[2,2] = 1;
M_rot_theta[2,3] = 0;
M_rot_theta[3,1] = sin(theta);
M_rot_theta[3,2] = 0;
M_rot_theta[3,3] = cos(theta);
M_rot_theta_phi <- M_rot_theta %*% M_rot_Phi
M_rot_psi <- matrix(data = 0, 3,3)
M_rot_psi[1,1] = cos(psi)
M_rot_psi[1,2] = sin(psi)
M_rot_psi[1,3] = 0
M_rot_psi[2,1] = -sin(psi)
M_rot_psi[2,2] = cos(psi)
M_rot_psi[2,3] = 0
M_rot_psi[3,1] = 0
M_rot_psi[3,2] = 0
M_rot_psi[3,3] = 1
M_rot <- M_rot_psy %*% M_rot_theta_phi
#système matriciel}
res<- mes # copy all variable
tmp <- NULL
for (i in 1:nrow(mes)) {
tmp <- matrix(c(mes$X[i], mes$Y[i],mes$Z[i]), 3, 1 )
tmp <- M_rot %*% tmp
tmp <- to.polar(tmp[1], tmp[2], tmp[3])
res$X[i] <- tmp$X
res$Y[i] <- tmp$Y
res$Z[i] <- tmp$Z
res$I[i] <- tmp$I
res$D[i] <- tmp$D
res$F[i] <- tmp$F
}
return(res)
}
#' Correction de pli = bending
#' Note: la correction de pli- bending se fait aprés la correction de repère
#' @seealso \code{\link{correction.paleo}}, \code{\link{correction.archeo}}, \code{\link{correction.bevel}}
correction.bending <- function(mes, dip, str) {
rad <- pi/180
dip <- dip *rad
str <- str *rad
M_rot_Pli <- matrix(data = 0, 3,3)
M_rot_Pli[1,1] = cos(str)* cos(str)+ sin(str)* sin(str)* cos(dip)
M_rot_Pli[1,2] = cos(str)* sin(str)*(1- cos(dip))
M_rot_Pli[1,3] = - sin(dip)* sin(str)
M_rot_Pli[2,1] = cos(str)* sin(str)*(1- cos(dip))
M_rot_Pli[2,2] = sin(str)* sin(str)+ cos(dip)* cos(str)* cos(str)
M_rot_Pli[2,3] = sin(dip)* cos(str)
M_rot_Pli[3,1] = sin(dip)* sin(str)
M_rot_Pli[3,2] =- sin(dip)* cos(str)
M_rot_Pli[3,3] = cos(dip);
#système matriciel}
res<- mes # copy all variable
tmp <- NULL
for (i in 1:nrow(mes)) {
tmp <- matrix(c(mes$X[i], mes$Y[i],mes$Z[i]), 3, 1 )
tmp <- M_rot %*% tmp
tmp <- to.polar(tmp[1], tmp[2], tmp[3])
res$X[i] <- tmp$X
res$Y[i] <- tmp$Y
res$Z[i] <- tmp$Z
res$I[i] <- tmp$I
res$D[i] <- tmp$D
res$F[i] <- tmp$F
}
return(res)
}
# Partial component ----
#' Calcul les directions du vecteur partiel pour une série d'étape
#' @param en0 permet de calculer la composante qui passe par l'origine (0, 0)
#' @return une data.frame "X", "Y", "Z", "I", "D", "F", "Sl", "MAD"
#' @export
partial.vector <- function(TabX, TabY, TabZ, en0 = TRUE)
{
col.names <- c("X", "Y", "Z", "I", "D", "F", "Sl", "MAD")
ntab <- length(TabX);
if ( (ntab<1) || (ntab!=length(TabY)) || (ntab!=length(TabZ))) {
warning("No mesure, to calculate the partial vector")
Data <- c( X = 0, Y = 0, Z = 0,
I = 0, D = 0, F = 0,
Sl = NA, MAD = NA )
return(as.data.frame(t(Data), col.names = col.names)) #il faut au moins 2 étapes
}
if ( ntab == 1) {
message("Only one mesure, to calculate the partial vector")
vp1 <- to.polar(TabX[1], TabY[1], TabZ[1])
Data <- c( X = TabX[1], Y = TabY[1], Z = TabZ[1],
I = vp1$I, D = vp1$D, F = vp1$F,
Sl = 1, MAD = 0 )
return(as.data.frame(t(Data), col.names = col.names)) #il faut au moins 2 étapes
}
# calcul du barycentre du nuage de points si 'en0' false
somx <- 0; somy <- 0; somz <- 0
if (en0 == FALSE) {
somx <- sum(TabX)
somy <- sum(TabY)
somz <- sum(TabZ)
}
xm <- somx/ ntab
ym <- somy/ ntab
zm <- somz/ ntab
Mom <- 0; # variable pour Kirschink
# calcul du moment suivant kischvink
# c.à.d. longueur du chemin total entre les points
for ( j in 2 : ntab) {
Mom <- Mom + sqrt( (TabX[j]-TabX[j-1])^2
+ (TabY[j]-TabY[j-1])^2
+ (TabZ[j]-TabZ[j-1])^2 )
}
# Longueur du plus court chemin
Sl <- sqrt( (TabX[ntab]-TabX[1])^2
+ (TabY[ntab]-TabY[1])^2
+ (TabZ[ntab]-TabZ[1])^2);
# Rapport des distances
Sl <- Sl/Mom;
sxx <- sum((TabX-xm)^2); sxy <- sum((TabX-xm)*(TabY-ym)); sxz <- sum((TabX-xm)*(TabZ-zm))
syy <- sum((TabY-ym)^2); syz <- sum((TabY-ym)*(TabZ-zm))
szz <- sum((TabZ-zm)^2);
# Matrice d inertie des points x, y, z pour le calcul de la droite
Ixx = syy+szz; Ixy = -sxy; Ixz = -sxz;
Iyy = sxx+szz; Iyz = -syz;
Izz = sxx+syy;
# MAD
mat.sym.norm <- matrix( c( sxx, sxy, sxz,
0, syy, syz,
0, 0, szz) , 3, 3)
# vecteurs et valeurs propres pour MAD
v.mad <- eigen(mat.sym.norm, symmetric = TRUE)
if (( v.mad$values[1] == 0) || ((v.mad$values[2] + v.mad$values[3])/ v.mad$values[1] < 0)) {
warning('MAD uncalculable')
MAD <- NA
} else {
MAD <- atan(sqrt( ((v.mad$values[2] + v.mad$values[3])/ v.mad$values[1]) ));
}
# Calcul composante partielle
# Matrice d'inertie des points x,y,z
# La direction correspond au vecteur propre minimum
mat.sym.norm <- matrix( c( Ixx , Ixy , Ixz ,
0, Iyy , Iyz ,
0, 0, Izz ) , 3, 3)
# vecteurs et valeurs propres pour MAD
v.cp <- eigen(mat.sym.norm, symmetric = TRUE)
v3 <- to.polar(v.cp$vectors[1, 3], v.cp$vectors[2, 3], v.cp$vectors[3 ,3])
vcorrect<- NULL
vcorrect$I <- sign(TabZ[1] - TabZ[ntab]) * abs(v3$I)
vcorrect$D <- v3$D
if (sign(vcorrect$I) != sign(v3$I)) {
vcorrect$D <- D.AM(v3$D +180)
}
# mise en forme du résultat
MAD <- MAD * 180 /pi
Data <- c( X = v.cp$vectors[1, 3], Y = v.cp$vectors[2, 3], Z = v.cp$vectors[3, 3],
I = vcorrect$I, D = vcorrect$D, F = v3$F,
Sl = Sl, MAD = MAD )
return(as.data.frame(t(Data), col.names = col.names))
}
#' Calcul le vecteur de la composante partielle
#' et retourne aussi le MAD
#' @param en0 permet de calculer la composante qui passe par l'origine (0, 0)
#' @return une data.frame "X", "Y", "Z", "I", "D", "F", "Sl", "MAD", "DANG"
#' @seealso \code{\link{partial.component.T1T2}}
#' @export
partial.component <- function(TabX, TabY, TabZ, en0 = FALSE)
{
vp <- partial.vector(TabX, TabY, TabZ, en0 = en0)
ntab <- length(TabX)
# Calcul de l'angle entre le vecteur passant par zéro et le vecteur ne passant pas par zéro
# d'aprés Lisa Tauxe
v.true <- partial.vector(TabX, TabY, TabZ, en0 = TRUE)
v.false <- partial.vector(TabX, TabY, TabZ, en0 = FALSE)
# produit scalaire x*xp+y*yp+z*zp=cos(teta)*(x2+y2+z2)*(xp2+yp2+zp2);
DANG <- v.true$X * v.false$X + v.true$Y * v.false$Y + v.true$Z * v.false$Z
DANG <- DANG / (sqrt( v.true$X^2 + v.true$Y^2 + v.true$Z^2)* sqrt( v.false$X^2+ v.false$Y^2+ v.false$Z^2) )
DANG <- n_arccos(DANG) *180/pi
return( cbind.data.frame(vp, DANG))
}
#' Calcul le vecteur de la composante partielle en calculant la composante entre les étapes T1 et T2
#' la fonction ne tient pas compte des étapes d'anisotropie, si step.code est bien rensiegné
#' @param en0 permet de calculer la composante qui passe par l'origine (0, 0)
#' @param corr.ani corrige de l'anisotropie
#' @return une data.frame "X", "Y", "Z", "I", "D", "F", "Sl", "MAD", "DANG"
#' @seealso \code{\link{partial.component, zijderveld1.T1T2}}
#' @export
partial.component.T1T2 <- function(Data, T1 = NULL, T2 = NULL, corr.ani = FALSE, ani.step.value = NULL,
step.code = c("Z+", "Z-", "X+", "X-", "Y+", "Y-", "ZB"),
en0 = FALSE )
{
if (!is.data.frame(Data))
warning("Data n'est pas une data.frame")
res.list <- Data
if (corr.ani == TRUE) {
if (is.null(ani.step.value)) { # recherche des étapes d'anisotropie
for (i in 1:length(Data$step)) {
if (substring(Data$step[i], 4) == step.code[3])
ani.step.value <- Data$step.value[i]
}
}
ani <- anisotropy.matrix.symetric(Data, step.value = ani.step.value, step.code = step.code)
}
if (!is.null(ani.step.value))
Data <- remove.step(Data, step.value = ani.step.value, step.code = step.code)
# recherche étape en dessous de T1
if (is.null(T1) | T1 == 0 | is.na(T1))
T1 <- Data$step.value[1]
if (is.null(T2) | is.na(T2))
T2 <- Data$step.value[length(Data$step.value)]
if (T2 < T1) {
warning(" T2 < T1 ")
}
iT1 <- 1
while(iT1 <= length(Data$step.value) & Data$step.value[iT1] < T1 ) {
iT1 <- iT1 + 1
}
# recherche étape au dessus de T2
iT2 <- length(Data$step.value)
while(iT2 > 0 & Data$step.value[iT2] > T2) {
iT2 <- iT2 -1
}
# Selection de la composante partielle
TabX <- Data$X[iT1:iT2]
TabY <- Data$Y[iT1:iT2]
TabZ <- Data$Z[iT1:iT2]
# Correction des directions par l'anisotropie
if (corr.ani == TRUE) {
# inversion de la matrice
aniso.inv <- solve(ani)
for(i in 1: length(TabX)) {
vp.cor <- aniso.inv %*% c( TabX[i], TabY[i], TabZ[i])
TabX[i] <- vp.cor[1]
TabY[i] <- vp.cor[2]
TabZ[i] <- vp.cor[3]
}
}
ntab <- length(TabX)
# Calcul de l'angle entre le vecteur passant par zéro et le vecteur ne passant pas par zéro
# aprés correction d'anisotropie
# d'aprés Lisa Tauxe
v.true <- partial.vector(TabX, TabY, TabZ, en0 = TRUE)
v.false <- partial.vector(TabX, TabY, TabZ, en0 = FALSE)
# produit scalaire x*xp+y*yp+z*zp=cos(teta)*(x2+y2+z2)*(xp2+yp2+zp2);
DANG <- (v.true$X * v.false$X) + (v.true$Y * v.false$Y) + (v.true$Z * v.false$Z)
DANG <- DANG / (sqrt( v.true$X^2 + v.true$Y^2 + v.true$Z^2)* sqrt( v.false$X^2+ v.false$Y^2+ v.false$Z^2) )
DANG <- n_arccos(DANG) *180/pi
vp <- NULL
if (en0 == TRUE) {
vp <- v.true
} else {
vp <- v.false
}
return( cbind.data.frame(vp, DANG))
}
#' Trace un diagramme de zijderveld1 en calculant la composante entre les étapes T1 et T2
#' par défaut la fonction n'affiche pas les étapes d'anisotropie et ne corrige pas les directions de l'anisotropie
#' @param T1 correspond à step.value ou température la plus basse
#' @param T2 correspond à step.value ou température la plus haute
#' @param en0 booléen permettant de forcer la composante partielle à passer par l'origine
#' @param show.step booléen permettant l'affichage des étapes
#' @param withAni permet de voir les étapes d'anisotropie
#' @param ani.step.value correspond à l'step.value ou la température de la détermination de l'anisotropie
#' @param main titre de la figure
#' @param step.code chaîne de caractère représentant les étapes de l'anisotropie "Z+", "Z-", "X+", "X-", "Y+", "Y-", "ZB". LEs mesures doivent suivre cette ordre est obligatoire
#' @seealso \code{\link{partial.component.T1T2, zijderveld2.T1T2}}
#' @export
zijderveld1.T1T2 <- function(Data, T1 = NULL, T2 = NULL, show.step = FALSE, ignore.ani = TRUE, ani.step.value = NULL, main = "",
step.code = c("Z+", "Z-", "X+", "X-", "Y+", "Y-", "ZB"),
legend.pos = NULL, legend.txt = c("(Y, X)", "(Y, Z)"),
en0 = FALSE )
{
if (is.null(T1))
T1 <- Data$step.value[1]
if (is.null(T2))
T2 <- Data$step.value[length(Data$step.value)]
res.list <- Data
if (ignore.ani == TRUE) { # suppression des étape d anisotropie
Data <- remove.step(Data, step.value = ani.step.value, step.code = step.code)
}
# recherche étape en dessous de T1
iT1 <- 1
while(Data$step.value[iT1] < T1) {
iT1 <- iT1 + 1
}
# recherche étape au dessus de T2
iT2 <- length(Data$step.value)
while(Data$step.value[iT2] > T2) {
iT2 <- iT2 -1
}
# Calcul de la composante partielle
TabX <- Data$X[iT1:iT2]
TabY <- Data$Y[iT1:iT2]
TabZ <- Data$Z[iT1:iT2]
vp <- partial.component(TabX, TabY, TabZ, en0 = en0)
ntab <- length(TabX)
somx <- 0; somy <- 0; somz <- 0
if (en0 == FALSE) {
somx <- sum(TabX)
somy <- sum(TabY)
somz <- sum(TabZ)
}
xm <- somx/ ntab
ym <- somy/ ntab
zm <- somz/ ntab
# a, b : Valeurs indiquant le point d’interception sur l’axe des y et la pente de la droite -> y = a + bx
# droite sur les déviations axe (Y, X)
bd <- vp$X/vp$Y
ad <- xm - bd*ym
# droite sur les inclinaisons axe (Y, Z), +Z est négatif
bi <- -vp$Z/vp$Y
ai <- -zm - bi*ym
Y.r <- range(Data$X)
Z.r <- range(Data$Z)
ylim <- c(min(Y.r[1], -Z.r[2]), max(Y.r[2], -Z.r[1]))
if (ylim[1]>0)
ylim[1]<-0
if (ylim[2]<0)
ylim[2]<-0
if (show.step == TRUE) {
pt.names <- Data$step
} else {
pt.names <- rep("", length(Data$X) )
}
zijderveld1(Data$X[1:iT1], Data$Y[1:iT1], Data$Z[1:iT1], ylim = ylim, pt.names = pt.names[1:iT1], legend.pos = legend.pos, legend.txt = legend.txt, main = main )
if (iT2 != length(Data$X))
zijderveld1(Data$X[iT2:length(Data$X)], Data$Y[iT2:length(Data$X)], Data$Z[iT2:length(Data$X)], pt.names = pt.names[iT2:length(Data$X)], new = FALSE)
zijderveld1(Data$X[iT1:iT2], Data$Y[iT1:iT2], Data$Z[iT1:iT2], pt.col = c("red", "red") , pt.names = pt.names[iT1:iT2], new = FALSE)
abline(ad, bd)
abline(ai, bi)
}
#' Trace un diagramme de zijderveld en calculant la composante entre les step.value T1 et T2
#' @param T1 correspond à step.value ou température la plus basse
#' @param T2 correspond à step.value ou température la plus haute
#' @param en0 booléen permettant de forcer la composante partielle de passer par l'origine
#' @param show.step booléen permettant l'affichage des étapes
#' @param TRUE permet de voir les étapes d'anisotropie
#' @param ani.step.value correspond à l'step.value ou la température de la détermination de l'anisotropie
#' @param step.code chaîne de caractère représentant les étapes de l'anisotropie "Z+", "Z-", "X+", "X-", "Y+", "Y-", "ZB". Cette ordre est obligatoire
#' @seealso \code{\link{partial.component.T1T2, zijderveld2.T1T2}}
#' @export
zijderveld2.T1T2 <- function(Data, T1 = NULL, T2 = NULL, show.step = FALSE, ignore.ani = TRUE, ani.step.value = NULL, main = "",
step.code = c("Z+", "Z-", "X+", "X-", "Y+", "Y-", "ZB"),
legend.pos = NULL, legend.txt = c("(Y, X)", "(Y, Z)"),
en0 = FALSE )
{
if (is.null(T1))
T1 <- Data$step.value[1]
if (is.null(T2))
T2 <- Data$step.value[length(Data$step.value)]
res.list <- Data
if (ignore.ani == TRUE) { # suppression des étape d anisotropie
Data <- remove.step(Data, step.value = ani.step.value, step.code = step.code)
}
# recherche étape en dessous de T1
iT1 <- 1
while(Data$step.value[iT1] < T1) {
iT1 <- iT1 + 1
}
# recherche étape au dessus de T2
iT2 <- length(Data$step.value)
while(Data$step.value[iT2] > T2) {
iT2 <- iT2 -1
}
# Calcul de la composante partielle
TabX <- Data$X[iT1:iT2]
TabY <- Data$Y[iT1:iT2]
TabZ <- Data$Z[iT1:iT2]
vp <- partial.component(TabX, TabY, TabZ, en0 = en0)
ntab <- length(TabX)
somx <- 0; somy <- 0; somz <- 0
if (en0 == FALSE) {
somx <- sum(TabX)
somy <- sum(TabY)
somz <- sum(TabZ)
}
xm <- somx/ ntab
ym <- somy/ ntab
zm <- somz/ ntab
# a, b : Valeurs indiquant le point d’interception sur l’axe des y et la pente de la droite -> y = a + bx
# droite sur les déviations axe (Y, X)
bd <- vp$Y/(-vp$X)
ad <- ym + bd*xm
# droite sur les inclinaisons axe (Y, Z), +Z est négatif
bi <- -vp$Z/(-vp$X)
ai <- -zm + bi*xm
if (show.step == TRUE) {
pt.names <- Data$step
} else {
pt.names <- rep("", length(Data$X) )
}
Y.r <- range(Data$Y)
Z.r <- range(Data$Z)
ylim <- c(min(Y.r[1], -Z.r[2]), max(Y.r[2], -Z.r[1]))
# if (isometric == TRUE) {
# if (ylim[1]>0)
# ylim[1]<-0
# if (ylim[2]<0)
# ylim[2]<-0
# }
zijderveld2(Data$X[1:iT1], Data$Y[1:iT1], Data$Z[1:iT1], ylim =ylim, pt.names = pt.names[1:iT1], legend.pos = legend.pos, legend.txt = legend.txt, main = main )
if (iT2 != length(Data$X))
zijderveld2(Data$X[iT2:length(Data$X)], Data$Y[iT2:length(Data$X)], Data$Z[iT2:length(Data$X)], pt.names = pt.names[iT2:length(Data$X)], new = FALSE)
zijderveld2(Data$X[iT1:iT2], Data$Y[iT1:iT2], Data$Z[iT1:iT2], pt.col = c("red", "red") , pt.names = pt.names[iT1:iT2], new = FALSE)
abline(ad, bd)
abline(ai, bi)
}
#' Supprime les étapes à la valeur step.value et avec les codes step.code
#' Utiliser par défaut pour enlever les étapes d'anisotropie
#' @param Data un data.frame possédant la variable $step de type chr
#' @param step.value valeur de la température . Par defaut NUll, alors la tempértature est retrouvée automatiquement avec les step.code définis. Si step.value = '', alors suppression de toutes les étapes avec le step.code
#' @param step.code chaîne de caractère représentant par exemple les étapes de l'anisotropie "Z+", "Z-", "X+", "X-", "Y+", "Y-", "ZB", ou des erreurs "??"
#' @param verbose affiche des commentaires et avertissements
#' @export
remove.step <- function(Data, step.value = NULL, step.code = c("Z+", "Z-", "X+", "X-", "Y+", "Y-", "ZB"), verbose = TRUE )
{
selec <- NULL
if (is.null(step.value)) {
for (i in 1:length(Data$step)) {
if (substring(Data$step[i], 4) == step.code[3])
step.value <- Data$step.value[i]
}
} else if (step.value == "") {
for (i in 1:length(Data$step))
{
for (j in 1: length(step.code)) {
selec <- c( selec, which(substring(Data$step, 4) == step.code[j]) )
}
}
}
remove.step <- trimws(paste(step.value, step.code, sep = ""))
for (i in 1:length(remove.step)) {
selec <- c( selec, which(trimws(Data$step) == trimws(remove.step[i])) )
}
if (verbose == TRUE) {
if (length(selec)== 0) {
warning("No step to remove")
return(Data)
} else {
print(paste(Data[selec,]$step))
}
}
if (length(selec) > 0) {
res.list <- Data[-selec,]
}
else {
res.list <- Data
}
return(res.list)
}
# Calcul rotation ----
#' Fait tourner les mesures selon deviation
#' @param Data un data.frame possédant la variable $step de type chr
#' @param deviation valeur de l'angle de rotation (en degrés).
#' @export
rotation.mesure <- function(Data, deviation)
{
res <- Data
for (i in 1 : length(res$D)) {
res$D[i] <- as.numeric(res$D[i] + deviation)
res$X[i] <- as.numeric(to.cartesian.X(res$I[i], res$D[i], res$F[i]) )
res$Y[i] <- as.numeric(to.cartesian.Y(res$I[i], res$D[i], res$F[i]) )
res$Z[i] <- as.numeric(to.cartesian.Z(res$I[i], res$D[i], res$F[i]) )
}
return(res)
}
# Calcul astronomique ----
# Le jour julien 0 commence le 24 novembre -4713 (4712 BC) à 12h
#' The number of Julian days for astronomical calculations
#' Julian Day 0 starts November 24th -4713 (4712 BC) at 12:00 pm
#' @seealso \code{\link{https://codes-sources.commentcamarche.net/source/31774-calcul-de-la-position-du-soleil-declinaison-angle-horaire-altitude-et-azimut-altaz-solaire}}
#' @export
julian.day <- function( day, month, year, hour, minute, seconde)
{
day.hour <- day + hour/24.0 + minute/1440.0 + seconde/86400.0
if (month == 1 || month == 2) {
year <- year-1.0
month <- month+12.0
}
a <- trunc(year/100.0)
b <- 2 - a + trunc(a/4.0)
julian <- trunc(365.25*(year+4716.0)) + trunc(30.6001*(month+1.0)) + day.hour + b - 1524.5
return (as.numeric(julian))
}
#' Calculate the azimuth of the sun in a place at a given date at a given time "UTC".
#' @seealso \code{\link{https://codes-sources.commentcamarche.net/source/31774-calcul-de-la-position-du-soleil-declinaison-angle-horaire-altitude-et-azimut-altaz-solaire}}
#' @seealso \code{\link{https://fr.planetcalc.com/320/}}
#' @export
sun.azimuth <- function(day, month, year, hour, minute, seconde=0, longdeg, longmin=0, longsec=0, latdeg, latmin=0, latsec=0)
{
longitude <- DMS.to.DD(longdeg, longmin, longsec)
latitude <- DMS.to.DD(latdeg, latmin, latsec)
# Heure d'hiver ou d'été
correction_heure <- 0
jj <- julian.day(day, month, year, hour, minute, seconde) - correction_heure/24.0 - 2451545.0
# Calculs ascension droite et déclinaison
g <- 357.529 + 0.98560028*jj
q <- 280.459 + 0.98564736*jj
l <- q + 1.915 * sin(g*pi/180.0) + 0.020*sin(2*g*pi/180.0) # Ellipticité
e <- 23.439 - 0.00000036*jj
ascension_droite <- atan(cos(e*pi/180.0)*sin(l*pi/180.0)/cos(l*pi/180.0))*(180.0/pi)/15.0
if (cos(l*pi/180.0) < 0) {
ascension_droite <- 12.0 + ascension_droite
}
if (cos(l*pi/180.0)>0 && sin(l*pi/180.0) < 0) {
ascension_droite <- ascension_droite + 24.0
}
declinaison <- asin(sin(e*pi/180.0)*sin(l*pi/180.0))*180.0/pi
nb_siecle <- jj/36525.0
heure_siderale1 <- (24110.54841 + (8640184.812866*nb_siecle) + (0.093104*(nb_siecle*nb_siecle)) - (0.0000062*(nb_siecle*nb_siecle*nb_siecle)))/3600.0
heure_siderale2 <- ((heure_siderale1/24.0) - trunc(heure_siderale1/24.0)) * 24.0
angleH <- 360.0*heure_siderale2/23.9344
angleT <- (hour - correction_heure - 12.0 + minute/60.0 + seconde/3600.0)*360.0/23.9344 # jour sidéraux = 23h56min 4,0989s -> 23,93447h -> 0,9972696 jour solaire
angle <- angleT + angleH
angle_horaire <- angle - ascension_droite*15.0 + longitude
# calculs altitude et azimut
altitude <- asin( sin(declinaison*pi/180.0)*sin(latitude*pi/180.0) - cos(declinaison*pi/180.0)*cos(latitude*pi/180.0)*cos(angle_horaire*pi/180.0) )*180.0/pi
azimut <- acos( (sin(declinaison*pi/180.0) - sin(latitude*pi/180.0)*sin(altitude*pi/180.0)) / (cos(latitude*pi/180.0)*cos(altitude*pi/180.0)) )*180.0/pi
sinazimut <- (cos(declinaison*pi/180.0)*sin(angle_horaire*pi/180.0)) / cos(altitude*pi/180.0)
if (sinazimut < 0) {
azimut <- 360 - azimut;
}
return(as.numeric(azimut))
}
# Reduction ----
#' Geocentric Axial Dipole
#' Reduction suivant le Dipôle Axiale Centré
#' @param lat.reloc Latitude de réduction. On peut aussi utiliser "Paris" pour 48.85
#' "Madrid" pour 40.4; "Meriden" pour 52.43; "Athenes" pour 37.96
#' @return I.reloc en degré
#' @examples
#' relocate.GAD(65, 47.12)
#' @seealso \code{\link{relocate.VADM}}, \code{\link{relocate.VDM}}, \code{\link{relocate.VGP} }
#' @export
relocate.GAD <- function( I.site, lat.site, lat.reloc = "Paris")
{
if (lat.reloc == "Paris") {
lat.reloc <- 48.85
}
if (lat.reloc == "Madrid") {
lat.reloc <- 40.4
}
if (lat.reloc == "Meriden") {
lat.reloc <- 52.43
}
if (lat.reloc == "Athenes") {
lat.reloc <- 37.96
}
I.reloc <- I.site + 0.5 * (3 * cos(I.site * pi /180)^2 + 1) * (lat.reloc - lat.site)
return(data.frame(I.reloc = I.reloc) )
}
#' Virtual Axial Dipole Moment VADM
#' @examples
#' Reduction par defaut à Paris
#' relocate.VADM(55, 47.12)
#' relocate.VADM(55, 47.12, "Paris")
#' relocate.VADM(55, 47.12, lat.reloc = "48.85")
#' @seealso \code{\link{relocate.GAD}}, \code{\link{relocate.VDM}}, \code{\link{relocate.VGP} }
#' @export
relocate.VADM <- function( F.site, lat.site, lat.reloc = "Paris")
{
if (lat.reloc == "Paris") {
lat.reloc <- 48.85
}
if (lat.reloc == "Madrid") {
lat.reloc <- 40.4
}
if (lat.reloc == "Meriden") {
lat.reloc <- 52.43
}
if (lat.reloc == "Athenes") {
lat.reloc <- 37.96
}
F.reloc <- as.numeric(F.site * sqrt((3 * sin(lat.reloc * pi /180)^2 + 1) / (3 * sin(lat.site * pi /180)^2 + 1)) )
return(data.frame(F.reloc = F.reloc))
}
#' Virtual Dipôle Moment
#' @examples
#' relocate.VDM(55, 65,5, 47.12, 2.175,"Paris")
#' @seealso \code{\link{relocate.GAD}}, \code{\link{relocate.VADM}}, \code{\link{relocate.VGP} }
#' @export
relocate.VDM <- function( F.site, I.site, D.site, lat.site, lon.site, lat.reloc = "Paris", lon.reloc = 0)
{
if (lat.reloc == "Paris") {
lon.reloc <- 2.3
lat.reloc <- 48.85
}
if (lat.reloc == "Madrid") {
lon.reloc <- -3.68
lat.reloc <- 40.4
}
if (lat.reloc == "Meriden") {
lon.reloc <- -1.62
lat.reloc <- 52.43
}
if (lat.reloc == "Athenes") {
lon.reloc <- 23.72
lat.reloc <- 37.96
}
rad <- pi /180
LAR <- lat.reloc * rad
LGR <- lon.reloc * rad
LA <- lat.site * rad
LG <- lon.site * rad
# Calcul de la distance p du pôle
pol <- (pi / 2) - atan(tan(I.site * rad) / 2)
lap <- asin(sin(LA) * cos(pol) + cos(LA) * sin(pol) * cos(D.site * rad))
beta <- asin(sin(pol) * sin(D.site * rad) / cos(lap))
if (cos(pol) >= (sin(LA) * sin(lap)))
{
lgp <- LG + beta
}
else
{
lgp <- LG + pi - beta
}
# Calcul de Iij et Dij corrigés
pol <- acos(sin(LAR) * sin(lap) + cos(LAR) * cos(lap) * cos(lgp - LGR))
I.reloc <- as.numeric(atan(2 * tan((pi / 2) - pol)) )
F.reloc <- as.numeric( F.site * sqrt((3 * cos(I.site * rad)^2 + 1) / (3 * cos(I.reloc)^2 + 1)) )
return(data.frame(I.reloc = I.reloc /rad , F.reloc = F.reloc, lat.pole = lap / rad , lon.pole = lgp / rad))
}
#' Correction Virtual Geomagnetic Pole
#' Paris lat:48.85 lon:2.3
#' Madrid lat:40.4 lon:-3.68
#' Meriden lat:52.43 lon:-1.62
#' Athenes lat:37.96 lon:23.72
#' @examples
#' relocate.VGP(65,5,DMS.to.DD(47,7,15),DMS.to.DD(2,10,12),"Paris")
#' @seealso \code{\link{relocate.GAD, relocate.VADM, relocate.VDM }}
#' @references Westphal, p.117 et Merill McElhinny, p.80
#' @export
relocate.VGP <- function(I.site, D.site, lat.site, lon.site, lat.reloc = "Paris", lon.reloc = 0)
{
rad <- as.numeric(pi /180)
degre <- as.numeric(180 /pi)
if (lat.reloc == "Paris") {
lon.reloc <- 2.3
lat.reloc <- 48.85
}
if (lat.reloc == "Madrid") {
lon.reloc <- -3.68
lat.reloc <- 40.4
}
if (lat.reloc == "Meriden") {
lon.reloc <- -1.62
lat.reloc <- 52.43
}
if (lat.reloc == "Athenes") {
lon.reloc <- 23.72
lat.reloc <- 37.96
}
LAR <- lat.reloc * rad
LGR <- lon.reloc * rad
LA <- lat.site * rad
LG <- lon.site * rad
# Calcul de la distance p du pôle
pol <- (pi / 2) - atan(tan(I.site * rad) / 2)
lap <- asin(sin(LA) * cos(pol) + cos(LA) * sin(pol) * cos(D.site * rad))
beta <- asin(sin(pol) * sin(D.site * rad) / cos(lap))
if (cos(pol) >= (sin(LA) * sin(lap)))
{
lgp <- LG + beta
}
else
{
lgp <- LG + pi - beta
}
# Calcul de Iij et Dij corrigés
pol <- acos(sin(LAR) * sin(lap) + cos(LAR) * cos(lap) * cos(lgp - LGR))
I.reloc <- atan(2 * tan((pi / 2) - pol)) * degre
D.reloc <- asin(sin(lgp - LGR) * cos(lap) / sin(pol)) * degre
return(data.frame(I.reloc = as.numeric(I.reloc), D.reloc = as.numeric(D.reloc), lat.pole = as.numeric(lap*degre) , lon.pole = as.numeric(lgp*degre) ) )
}
# igrf13syn
# les coefs
g0 <- c(-31543,-2298, 5922, -677, 2905,-1061, 924, 1121,1022,-1469, -330, 1256, 3, 572, 523, 876, 628, 195, 660, -69, -361, -210, 134, -75, -184, 328, -210, 264, 53, 5, -33, -86, -124, -16, 3, 63, 61, -9, -11, 83, -217, 2, -58, -35, 59, 36, -90, -69, 70, -55, -45, 0, -13, 34, -10, -41, -1, -21, 28, 18, -12, 6, -22, 11, 8, 8, -4, -14, -9, 7, 1, -13, 2, 5, -9, 16, 5, -5, 8, -18, 8, 10, -20, 1, 14, -11, 5, 12, -3, 1, -2, -2, 8, 2, 10, -1, -2, -1, 2, -3, -4, 2, 2, 1, -5, 2, -2, 6, 6, -4, 4, 0, 0, -2, 2, 4, 2, 0, 0, -6.)
g1 <- c(-31464,-2298, 5909, -728, 2928,-1086, 1041, 1065, 1037,-1494, -357, 1239, 34, 635, 480, 880, 643, 203, 653, -77, -380, -201, 146, -65, -192, 328, -193, 259, 56, -1, -32, -93, -125, -26, 11, 62, 60, -7, -11, 86, -221, 4, -57, -32, 57, 32, -92, -67, 70, -54, -46, 0, -14, 33, -11, -41, 0, -20, 28, 18, -12, 6, -22, 11, 8, 8, -4, -15, -9, 7, 1, -13, 2, 5, -8, 16, 5, -5, 8, -18, 8, 10, -20, 1, 14, -11, 5, 12, -3, 1, -2, -2, 8, 2, 10, 0, -2, -1, 2, -3, -4, 2, 2, 1, -5, 2, -2, 6, 6, -4, 4, 0, 0, -2, 2, 4, 2, 0, 0, -6.)
g2 <- c(-31354,-2297, 5898, -769, 2948,-1128, 1176, 1000, 1058,-1524, -389, 1223, 62, 705, 425, 884, 660, 211, 644, -90, -400, -189, 160, -55, -201, 327, -172, 253, 57, -9, -33, -102, -126, -38, 21, 62, 58, -5, -11, 89, -224, 5, -54, -29, 54, 28, -95, -65, 71, -54, -47, 1, -14, 32, -12, -40, 1, -19, 28, 18, -13, 6, -22, 11, 8, 8, -4, -15, -9, 6, 1, -13, 2, 5, -8, 16, 5, -5, 8, -18, 8, 10, -20, 1, 14, -11, 5, 12, -3, 1, -2, -2, 8, 2, 10, 0, -2, -1, 2, -3, -4, 2, 2, 1, -5, 2, -2, 6, 6, -4, 4, 0, 0, -2, 2, 4, 2, 0, 0, -6.)
g3 <- c(-31212,-2306, 5875, -802, 2956,-1191, 1309, 917, 1084,-1559, -421, 1212, 84, 778, 360, 887, 678, 218, 631, -109, -416, -173, 178, -51, -211, 327, -148, 245, 58, -16, -34, -111, -126, -51, 32, 61, 57, -2, -10, 93, -228, 8, -51, -26, 49, 23, -98, -62, 72, -54, -48, 2, -14, 31, -12, -38, 2, -18, 28, 19, -15, 6, -22, 11, 8, 8, -4, -15, -9, 6, 2, -13, 3, 5, -8, 16, 6, -5, 8, -18, 8, 10, -20, 1, 14, -11, 5, 12, -3, 1, -2, -2, 8, 2, 10, 0, -2, -1, 2, -3, -4, 2, 2, 1, -5, 2, -2, 6, 6, -4, 4, 0, 0, -2, 1, 4, 2, 0, 0, -6.)
g4 <- c(-31060,-2317, 5845, -839, 2959,-1259, 1407, 823, 1111,-1600, -445, 1205, 103, 839, 293, 889, 695, 220, 616, -134, -424, -153, 199, -57, -221, 326, -122, 236, 58, -23, -38, -119, -125, -62, 43, 61, 55, 0, -10, 96, -233, 11, -46, -22, 44, 18, -101, -57, 73, -54, -49, 2, -14, 29, -13, -37, 4, -16, 28, 19, -16, 6, -22, 11, 7, 8, -3, -15, -9, 6, 2, -14, 4, 5, -7, 17, 6, -5, 8, -19, 8, 10, -20, 1, 14, -11, 5, 12, -3, 1, -2, -2, 9, 2, 10, 0, -2, -1, 2, -3, -4, 2, 2, 1, -5, 2, -2, 6, 6, -4, 4, 0, 0, -2, 1, 4, 3, 0, 0, -6.)
g5 <- c(-30926,-2318, 5817, -893, 2969,-1334, 1471, 728, 1140,-1645, -462, 1202, 119, 881, 229, 891, 711, 216, 601, -163, -426, -130, 217, -70, -230, 326, -96, 226, 58, -28, -44, -125, -122, -69, 51, 61, 54, 3, -9, 99, -238, 14, -40, -18, 39, 13, -103, -52, 73, -54, -50, 3, -14, 27, -14, -35, 5, -14, 29, 19, -17, 6, -21, 11, 7, 8, -3, -15, -9, 6, 2, -14, 4, 5, -7, 17, 7, -5, 8, -19, 8, 10, -20, 1, 14, -11, 5, 12, -3, 1, -2, -2, 9, 2, 10, 0, -2, -1, 2, -3, -4, 2, 2, 1, -5, 2, -2, 6, 6, -4, 4, 0, 0, -2, 1, 4, 3, 0, 0, -6.)
g6 <- c(-30805,-2316, 5808, -951, 2980,-1424, 1517, 644, 1172,-1692, -480, 1205, 133, 907, 166, 896, 727, 205, 584, -195, -422, -109, 234, -90, -237, 327, -72, 218, 60, -32, -53, -131, -118, -74, 58, 60, 53, 4, -9, 102, -242, 19, -32, -16, 32, 8, -104, -46, 74, -54, -51, 4, -15, 25, -14, -34, 6, -12, 29, 18, -18, 6, -20, 11, 7, 8, -3, -15, -9, 5, 2, -14, 5, 5, -6, 18, 8, -5, 8, -19, 8, 10, -20, 1, 14, -12, 5, 12, -3, 1, -2, -2, 9, 3, 10, 0, -2, -2, 2, -3, -4, 2, 2, 1, -5, 2, -2, 6, 6, -4, 4, 0, 0, -2, 1, 4, 3, 0, 0, -6.)
g7 <- c(-30715,-2306, 5812,-1018, 2984,-1520, 1550, 586, 1206,-1740, -494, 1215, 146, 918, 101, 903, 744, 188, 565, -226, -415, -90, 249, -114, -241, 329, -51, 211, 64, -33, -64, -136, -115, -76, 64, 59, 53, 4, -8, 104, -246, 25, -25, -15, 25, 4, -106, -40, 74, -53, -52, 4, -17, 23, -14, -33, 7, -11, 29, 18, -19, 6, -19, 11, 7, 8, -3, -15, -9, 5, 1, -15, 6, 5, -6, 18, 8, -5, 7, -19, 8, 10, -20, 1, 15, -12, 5, 11, -3, 1, -3, -2, 9, 3, 11, 0, -2, -2, 2, -3, -4, 2, 2, 1, -5, 2, -2, 6, 6, -4, 4, 0, 0, -1, 2, 4, 3, 0, 0, -6.)
g8 <- c(-30654,-2292, 5821,-1106, 2981,-1614, 1566, 528, 1240,-1790, -499, 1232, 163, 916, 43, 914, 762, 169, 550, -252, -405, -72, 265, -141, -241, 334, -33, 208, 71, -33, -75, -141, -113, -76, 69, 57, 54, 4, -7, 105, -249, 33, -18, -15, 18, 0, -107, -33, 74, -53, -52, 4, -18, 20, -14, -31, 7, -9, 29, 17, -20, 5, -19, 11, 7, 8, -3, -14, -10, 5, 1, -15, 6, 5, -5, 19, 9, -5, 7, -19, 8, 10, -21, 1, 15, -12, 5, 11, -3, 1, -3, -2, 9, 3, 11, 1, -2, -2, 2, -3, -4, 2, 2, 1, -5, 2, -2, 6, 6, -4, 4, 0, 0, -1, 2, 4, 3, 0, 0, -6.)
g9 <- c(-30594,-2285, 5810,-1244, 2990,-1702, 1578, 477, 1282,-1834, -499, 1255, 186, 913, -11, 944, 776, 144, 544, -276, -421, -55, 304, -178, -253, 346, -12, 194, 95, -20, -67, -142, -119, -82, 82, 59, 57, 6, 6, 100, -246, 16, -25, -9, 21, -16, -104, -39, 70, -40, -45, 0, -18, 0, 2, -29, 6, -10, 28, 15, -17, 29, -22, 13, 7, 12, -8, -21, -5, -12, 9, -7, 7, 2, -10, 18, 7, 3, 2, -11, 5, -21, -27, 1, 17, -11, 29, 3, -9, 16, 4, -3, 9, -4, 6, -3, 1, -4, 8, -3, 11, 5, 1, 1, 2, -20, -5, -1, -1, -6, 8, 6, -1, -4, -3, -2, 5, 0, -2, -2.)
ga <- c(-30554,-2250, 5815,-1341, 2998,-1810, 1576, 381, 1297,-1889, -476, 1274, 206, 896, -46, 954, 792, 136, 528, -278, -408, -37, 303, -210, -240, 349, 3, 211, 103, -20, -87, -147, -122, -76, 80, 54, 57, -1, 4, 99, -247, 33, -16, -12, 12, -12, -105, -30, 65, -55, -35, 2, -17, 1, 0, -40, 10, -7, 36, 5, -18, 19, -16, 22, 15, 5, -4, -22, -1, 0, 11, -21, 15, -8, -13, 17, 5, -4, -1, -17, 3, -7, -24, -1, 19, -25, 12, 10, 2, 5, 2, -5, 8, -2, 8, 3, -11, 8, -7, -8, 4, 13, -1, -2, 13, -10, -4, 2, 4, -3, 12, 6, 3, -3, 2, 6, 10, 11, 3, 8)
gb <- c(-30500,-2215, 5820,-1440, 3003,-1898, 1581, 291, 1302,-1944, -462, 1288, 216, 882, -83, 958, 796, 133, 510, -274, -397, -23, 290, -230, -229, 360, 15, 230, 110, -23, -98, -152, -121, -69, 78, 47, 57, -9, 3, 96, -247, 48, -8, -16, 7, -12, -107, -24, 65, -56, -50, 2, -24, 10, -4, -32, 8, -11, 28, 9, -20, 18, -18, 11, 9, 10, -6, -15, -14, 5, 6, -23, 10, 3, -7, 23, 6, -4, 9, -13, 4, 9, -11, -4, 12, -5, 7, 2, 6, 4, -2, 1, 10, 2, 7, 2, -6, 5, 5, -3, -5, -4, -1, 0, 2, -8, -3, -2, 7, -4, 4, 1, -2, -3, 6, 7, -2, -1, 0, -3.)
gc <- c(-30421,-2169, 5791,-1555, 3002,-1967, 1590, 206, 1302,-1992, -414, 1289, 224, 878, -130, 957, 800, 135, 504, -278, -394, 3, 269, -255, -222, 362, 16, 242, 125, -26, -117, -156, -114, -63, 81, 46, 58, -10, 1, 99, -237, 60, -1, -20, -2, -11, -113, -17, 67, -56, -55, 5, -28, 15, -6, -32, 7, -7, 23, 17, -18, 8, -17, 15, 6, 11, -4, -14, -11, 7, 2, -18, 10, 4, -5, 23, 10, 1, 8, -20, 4, 6, -18, 0, 12, -9, 2, 1, 0, 4, -3, -1, 9, -2, 8, 3, 0, -1, 5, 1, -3, 4, 4, 1, 0, 0, -1, 2, 4, -5, 6, 1, 1, -1, -1, 6, 2, 0, 0, -7.)
gd <- c(-30334,-2119, 5776,-1662, 2997,-2016, 1594, 114, 1297,-2038, -404, 1292, 240, 856, -165, 957, 804, 148, 479, -269, -390, 13, 252, -269, -219, 358, 19, 254, 128, -31, -126, -157, -97, -62, 81, 45, 61, -11, 8, 100, -228, 68, 4, -32, 1, -8, -111, -7, 75, -57, -61, 4, -27, 13, -2, -26, 6, -6, 26, 13, -23, 1, -12, 13, 5, 7, -4, -12, -14, 9, 0, -16, 8, 4, -1, 24, 11, -3, 4, -17, 8, 10, -22, 2, 15, -13, 7, 10, -4, -1, -5, -1, 10, 5, 10, 1, -4, -2, 1, -2, -3, 2, 2, 1, -5, 2, -2, 6, 4, -4, 4, 0, 0, -2, 2, 3, 2, 0, 0, -6.)
ge <- c(-30220,-2068, 5737,-1781, 3000,-2047, 1611, 25, 1287,-2091, -366, 1278, 251, 838, -196, 952, 800, 167, 461, -266, -395, 26, 234, -279, -216, 359, 26, 262, 139, -42, -139, -160, -91, -56, 83, 43, 64, -12, 15, 100, -212, 72, 2, -37, 3, -6, -112, 1, 72, -57, -70, 1, -27, 14, -4, -22, 8, -2, 23, 13, -23, -2, -11, 14, 6, 7, -2, -15, -13, 6, -3, -17, 5, 6, 0, 21, 11, -6, 3, -16, 8, 10, -21, 2, 16, -12, 6, 10, -4, -1, -5, 0, 10, 3, 11, 1, -2, -1, 1, -3, -3, 1, 2, 1, -5, 3, -1, 4, 6, -4, 4, 0, 1, -1, 0, 3, 3, 1, -1, -4.)
gf<- c(-30100,-2013, 5675,-1902, 3010,-2067, 1632, -68, 1276,-2144, -333, 1260, 262, 830, -223, 946, 791, 191, 438, -265, -405, 39, 216, -288, -218, 356, 31, 264, 148, -59, -152, -159, -83, -49, 88, 45, 66, -13, 28, 99, -198, 75, 1, -41, 6, -4, -111, 11, 71, -56, -77, 1, -26, 16, -5, -14, 10, 0, 22, 12, -23, -5, -12, 14, 6, 6, -1, -16, -12, 4, -8, -19, 4, 6, 0, 18, 10, -10, 1, -17, 7, 10, -21, 2, 16, -12, 7, 10, -4, -1, -5, -1, 10, 4, 11, 1, -3, -2, 1, -3, -3, 1, 2, 1, -5, 3, -2, 4, 5, -4, 4, -1, 1, -1, 0, 3, 3, 1, -1, -5.)
gg <- c(-29992,-1956, 5604,-1997, 3027,-2129, 1663, -200, 1281, -2180, -336, 1251, 271, 833, -252, 938, 782, 212, 398, -257, -419, 53, 199, -297, -218, 357, 46, 261, 150, -74, -151, -162, -78, -48, 92, 48, 66, -15, 42, 93, -192, 71, 4, -43, 14, -2, -108, 17, 72, -59, -82, 2, -27, 21, -5, -12, 16, 1, 18, 11, -23, -2, -10, 18, 6, 7, 0, -18, -11, 4, -7, -22, 4, 9, 3, 16, 6, -13, -1, -15, 5, 10, -21, 1, 16, -12, 9, 9, -5, -3, -6, -1, 9, 7, 10, 2, -6, -5, 2, -4, -4, 1, 2, 0, -5, 3, -2, 6, 5, -4, 3, 0, 1, -1, 2, 4, 3, 0, 0, -6.)
gi <- c(-29873,-1905, 5500,-2072, 3044,-2197, 1687, -306, 1296,-2208, -310, 1247, 284, 829, -297, 936, 780, 232, 361, -249, -424, 69, 170, -297, -214, 355, 47, 253, 150, -93, -154, -164, -75, -46, 95, 53, 65, -16, 51, 88, -185, 69, 4, -48, 16, -1, -102, 21, 74, -62, -83, 3, -27, 24, -2, -6, 20, 4, 17, 10, -23, 0, -7, 21, 6, 8, 0, -19, -11, 5, -9, -23, 4, 11, 4, 14, 4, -15, -4, -11, 5, 10, -21, 1, 15, -12, 9, 9, -6, -3, -6, -1, 9, 7, 9, 1, -7, -5, 2, -4, -4, 1, 3, 0, -5, 3, -2, 6, 5, -4, 3, 0, 1, -1, 2, 4, 3, 0, 0, -6.)
gj <- c(-29775,-1848, 5406,-2131, 3059,-2279, 1686, -373, 1314,-2239, -284, 1248, 293, 802, -352, 939, 780, 247, 325, -240, -423, 84, 141, -299, -214, 353, 46, 245, 154, -109, -153, -165, -69, -36, 97, 61, 65, -16, 59, 82, -178, 69, 3, -52, 18, 1, -96, 24, 77, -64, -80, 2, -26, 26, 0, -1, 21, 5, 17, 9, -23, 0, -4, 23, 5, 10, -1, -19, -10, 6, -12, -22, 3, 12, 4, 12, 2, -16, -6, -10, 4, 9, -20, 1, 15, -12, 11, 9, -7, -4, -7, -2, 9, 7, 8, 1, -7, -6, 2, -3, -4, 2, 2, 1, -5, 3, -2, 6, 4, -4, 3, 0, 1, -2, 3, 3, 3, -1, 0, -6.)
gk <- c(-29692,-1784, 5306,-2200, 3070,-2366, 1681, -413, 1335,-2267, -262, 1249, 302, 759, -427, 940, 780, 262, 290, -236, -418, 97, 122, -306, -214, 352, 46, 235, 165, -118, -143, -166, -55, -17, 107, 68, 67, -17, 68, 72, -170, 67, -1, -58, 19, 1, -93, 36, 77, -72, -69, 1, -25, 28, 4, 5, 24, 4, 17, 8, -24, -2, -6, 25, 6, 11, -6, -21, -9, 8, -14, -23, 9, 15, 6, 11, -5, -16, -7, -4, 4, 9, -20, 3, 15, -10, 12, 8, -6, -8, -8, -1, 8, 10, 5, -2, -8, -8, 3, -3, -6, 1, 2, 0, -4, 4, -1, 5, 4, -5, 2, -1, 2, -2, 5, 1, 1, -2, 0, -7.)
gk <- c(gk, rep(0, 75))
gl <- c(-29619.4,-1728.2, 5186.1,-2267.7, 3068.4,-2481.6, 1670.9, -458.0, 1339.6,-2288.0, -227.6, 1252.1, 293.4, 714.5, -491.1, 932.3, 786.8, 272.6, 250.0, -231.9, -403.0, 119.8, 111.3, -303.8, -218.8, 351.4, 43.8, 222.3, 171.9, -130.4, -133.1, -168.6, -39.3, -12.9, 106.3, 72.3, 68.2, -17.4, 74.2, 63.7, -160.9, 65.1, -5.9, -61.2, 16.9, 0.7, -90.4, 43.8, 79.0, -74.0, -64.6, 0.0, -24.2, 33.3, 6.2, 9.1, 24.0, 6.9, 14.8, 7.3, -25.4, -1.2, -5.8, 24.4, 6.6, 11.9, -9.2, -21.5, -7.9, 8.5, -16.6, -21.5, 9.1, 15.5, 7.0, 8.9, -7.9, -14.9, -7.0, -2.1, 5.0, 9.4, -19.7, 3.0, 13.4, -8.4, 12.5, 6.3, -6.2, -8.9, -8.4, -1.5, 8.4, 9.3, 3.8, -4.3, -8.2, -8.2, 4.8, -2.6, -6.0, 1.7, 1.7, 0.0, -3.1, 4.0, -0.5, 4.9, 3.7, -5.9, 1.0, -1.2, 2.0, -2.9, 4.2, 0.2, 0.3, -2.2, -1.1, -7.4, 2.7, -1.7, 0.1, -1.9, 1.3, 1.5, -0.9, -0.1, -2.6, 0.1, 0.9, -0.7, -0.7, 0.7, -2.8, 1.7, -0.9, 0.1, -1.2, 1.2, -1.9, 4.0, -0.9, -2.2, -0.3, -0.4, 0.2, 0.3, 0.9, 2.5, -0.2, -2.6, 0.9, 0.7, -0.5, 0.3, 0.3, 0.0, -0.3, 0.0, -0.4, 0.3, -0.1, -0.9, -0.2, -0.4, -0.4, 0.8, -0.2, -0.9, -0.9, 0.3, 0.2, 0.1, 1.8, -0.4, -0.4, 1.3, -1.0, -0.4, -0.1, 0.7, 0.7, -0.4, 0.3, 0.3, 0.6, -0.1, 0.3, 0.4, -0.2, 0.0, -0.5, 0.1, -0.9)
gm <- c(-29554.63,-1669.05, 5077.99,-2337.24, 3047.69,-2594.50, 1657.76, -515.43, 1336.30,-2305.83, -198.86, 1246.39, 269.72, 672.51, -524.72, 920.55, 797.96, 282.07, 210.65, -225.23, -379.86, 145.15, 100.00, -305.36, -227.00, 354.41, 42.72, 208.95, 180.25, -136.54, -123.45, -168.05, -19.57, -13.55, 103.85, 73.60, 69.56, -20.33, 76.74, 54.75, -151.34, 63.63, -14.58, -63.53, 14.58, 0.24, -86.36, 50.94, 79.88, -74.46, -61.14, -1.65, -22.57, 38.73, 6.82, 12.30, 25.35, 9.37, 10.93, 5.42, -26.32, 1.94, -4.64, 24.80, 7.62, 11.20, -11.73, -20.88, -6.88, 9.83, -18.11, -19.71, 10.17, 16.22, 9.36, 7.61, -11.25, -12.76, -4.87, -0.06, 5.58, 9.76, -20.11, 3.58, 12.69, -6.94, 12.67, 5.01, -6.72, -10.76, -8.16, -1.25, 8.10, 8.76, 2.92, -6.66, -7.73, -9.22, 6.01, -2.17, -6.12, 2.19, 1.42, 0.10, -2.35, 4.46, -0.15, 4.76, 3.06, -6.58, 0.29, -1.01, 2.06, -3.47, 3.77, -0.86, -0.21, -2.31, -2.09, -7.93, 2.95, -1.60, 0.26, -1.88, 1.44, 1.44, -0.77, -0.31, -2.27, 0.29, 0.90, -0.79, -0.58, 0.53, -2.69, 1.80, -1.08, 0.16, -1.58, 0.96, -1.90, 3.99, -1.39, -2.15, -0.29, -0.55, 0.21, 0.23, 0.89, 2.38, -0.38, -2.63, 0.96, 0.61, -0.30, 0.40, 0.46, 0.01, -0.35, 0.02, -0.36, 0.28, 0.08, -0.87, -0.49, -0.34, -0.08, 0.88, -0.16, -0.88, -0.76, 0.30, 0.33, 0.28, 1.72, -0.43, -0.54, 1.18, -1.07, -0.37, -0.04, 0.75, 0.63, -0.26, 0.21, 0.35, 0.53, -0.05, 0.38, 0.41, -0.22, -0.10, -0.57, -0.18, -0.82)
gp <- c(-29496.57,-1586.42, 4944.26,-2396.06, 3026.34,-2708.54, 1668.17, -575.73, 1339.85,-2326.54, -160.40, 1232.10, 251.75, 633.73, -537.03, 912.66, 808.97, 286.48, 166.58, -211.03, -356.83, 164.46, 89.40, -309.72, -230.87, 357.29, 44.58, 200.26, 189.01, -141.05, -118.06, -163.17, -0.01, -8.03, 101.04, 72.78, 68.69, -20.90, 75.92, 44.18, -141.40, 61.54, -22.83, -66.26, 13.10, 3.02, -78.09, 55.40, 80.44, -75.00, -57.80, -4.55, -21.20, 45.24, 6.54, 14.00, 24.96, 10.46, 7.03, 1.64, -27.61, 4.92, -3.28, 24.41, 8.21, 10.84, -14.50, -20.03, -5.59, 11.83, -19.34, -17.41, 11.61, 16.71, 10.85, 6.96, -14.05, -10.74, -3.54, 1.64, 5.50, 9.45, -20.54, 3.45, 11.51, -5.27, 12.75, 3.13, -7.14, -12.38, -7.42, -0.76, 7.97, 8.43, 2.14, -8.42, -6.08, -10.08, 7.01, -1.94, -6.24, 2.73, 0.89, -0.10, -1.07, 4.71, -0.16, 4.44, 2.45, -7.22, -0.33, -0.96, 2.13, -3.95, 3.09, -1.99, -1.03, -1.97, -2.80, -8.31, 3.05, -1.48, 0.13, -2.03, 1.67, 1.65, -0.66, -0.51, -1.76, 0.54, 0.85, -0.79, -0.39, 0.37, -2.51, 1.79, -1.27, 0.12, -2.11, 0.75, -1.94, 3.75, -1.86, -2.12, -0.21, -0.87, 0.30, 0.27, 1.04, 2.13, -0.63, -2.49, 0.95, 0.49, -0.11, 0.59, 0.52, 0.00, -0.39, 0.13, -0.37, 0.27, 0.21, -0.86, -0.77, -0.23, 0.04, 0.87, -0.09, -0.89, -0.87, 0.31, 0.30, 0.42, 1.66, -0.45, -0.59, 1.08, -1.14, -0.31, -0.07, 0.78, 0.54, -0.18, 0.10, 0.38, 0.49, 0.02, 0.44, 0.42, -0.25, -0.26, -0.53, -0.26, -0.79)
gq <- c(-29441.46,-1501.77, 4795.99,-2445.88, 3012.20,-2845.41, 1676.35, -642.17, 1350.33,-2352.26, -115.29, 1225.85, 245.04, 581.69, -538.70, 907.42, 813.68, 283.54, 120.49, -188.43, -334.85, 180.95, 70.38, -329.23, -232.91, 360.14, 46.98, 192.35, 196.98, -140.94, -119.14, -157.40, 15.98, 4.30, 100.12, 69.55, 67.57, -20.61, 72.79, 33.30, -129.85, 58.74, -28.93, -66.64, 13.14, 7.35, -70.85, 62.41, 81.29, -75.99, -54.27, -6.79, -19.53, 51.82, 5.59, 15.07, 24.45, 9.32, 3.27, -2.88, -27.50, 6.61, -2.32, 23.98, 8.89, 10.04, -16.78, -18.26, -3.16, 13.18, -20.56, -14.60, 13.33, 16.16, 11.76, 5.69, -15.98, -9.10, -2.02, 2.26, 5.33, 8.83, -21.77, 3.02, 10.76, -3.22, 11.74, 0.67, -6.74, -13.20, -6.88, -0.10, 7.79, 8.68, 1.04, -9.06, -3.89, -10.54, 8.44, -2.01, -6.26, 3.28, 0.17, -0.40, 0.55, 4.55, -0.55, 4.40, 1.70, -7.92, -0.67, -0.61, 2.13, -4.16, 2.33, -2.85, -1.80, -1.12, -3.59, -8.72, 3.00, -1.40, 0.00, -2.30, 2.11, 2.08, -0.60, -0.79, -1.05, 0.58, 0.76, -0.70, -0.20, 0.14, -2.12, 1.70, -1.44, -0.22, -2.57, 0.44, -2.01, 3.49, -2.34, -2.09, -0.16, -1.08, 0.46, 0.37, 1.23, 1.75, -0.89, -2.19, 0.85, 0.27, 0.10, 0.72, 0.54, -0.09, -0.37, 0.29, -0.43, 0.23, 0.22, -0.89, -0.94, -0.16, -0.03, 0.72, -0.02, -0.92, -0.88, 0.42, 0.49, 0.63, 1.56, -0.42, -0.50, 0.96, -1.24, -0.19, -0.10, 0.81, 0.42, -0.13, -0.04, 0.38, 0.48, 0.08, 0.48, 0.46, -0.30, -0.35, -0.43, -0.36, -0.71)
gr <- c(-29404.8, -1450.9, 4652.5, -2499.6, 2982.0, -2991.6, 1677.0, -734.6, 1363.2, -2381.2, -82.1, 1236.2, 241.9, 525.7, -543.4, 903.0, 809.5, 281.9, 86.3, -158.4, -309.4, 199.7, 48.0, -349.7, -234.3, 363.2, 47.7, 187.8, 208.3, -140.7, -121.2, -151.2, 32.3, 13.5, 98.9, 66.0, 65.5, -19.1, 72.9, 25.1, -121.5, 52.8, -36.2, -64.5, 13.5, 8.9, -64.7, 68.1, 80.6, -76.7, -51.5, -8.2, -16.9, 56.5, 2.2, 15.8, 23.5, 6.4, -2.2, -7.2, -27.2, 9.8, -1.8, 23.7, 9.7, 8.4, -17.6, -15.3, -0.5, 12.8, -21.1, -11.7, 15.3, 14.9, 13.7, 3.6, -16.5, -6.9, -0.3, 2.8, 5.0, 8.4, -23.4, 2.9, 11.0, -1.5, 9.8, -1.1, -5.1, -13.2, -6.3, 1.1, 7.8, 8.8, 0.4, -9.3, -1.4, -11.9, 9.6, -1.9, -6.2, 3.4, -0.1, -0.2, 1.7, 3.6, -0.9, 4.8, 0.7, -8.6, -0.9, -0.1, 1.9, -4.3, 1.4, -3.4, -2.4, -0.1, -3.8, -8.8, 3.0, -1.4, 0.0, -2.5, 2.5, 2.3, -0.6, -0.9, -0.4, 0.3, 0.6, -0.7, -0.2, -0.1, -1.7, 1.4, -1.6, -0.6, -3.0, 0.2, -2.0, 3.1, -2.6, -2.0, -0.1, -1.2, 0.5, 0.5, 1.3, 1.4, -1.2, -1.8, 0.7, 0.1, 0.3, 0.8, 0.5, -0.2, -0.3, 0.6, -0.5, 0.2, 0.1, -0.9, -1.1, 0.0, -0.3, 0.5, 0.1, -0.9, -0.9, 0.5, 0.6, 0.7, 1.4, -0.3, -0.4, 0.8, -1.3, 0.0, -0.1, 0.8, 0.3, 0.0, -0.1, 0.4, 0.5, 0.1, 0.5, 0.5, -0.4, -0.5, -0.4, -0.4, -0.6)
gs <- c( 5.7, 7.4, -25.9, -11.0, -7.0, -30.2, -2.1, -22.4, 2.2, -5.9, 6.0, 3.1, -1.1, -12.0, 0.5, -1.2, -1.6, -0.1, -5.9, 6.5, 5.2, 3.6, -5.1, -5.0, -0.3, 0.5, 0.0, -0.6, 2.5, 0.2, -0.6, 1.3, 3.0, 0.9, 0.3, -0.5, -0.3, 0.0, 0.4, -1.6, 1.3, -1.3, -1.4, 0.8, 0.0, 0.0, 0.9, 1.0, -0.1, -0.2, 0.6, 0.0, 0.6, 0.7, -0.8, 0.1, -0.2, -0.5, -1.1, -0.8, 0.1, 0.8, 0.3, 0.0, 0.1, -0.2, -0.1, 0.6, 0.4, -0.2, -0.1, 0.5, 0.4, -0.3, 0.3, -0.4, -0.1, 0.5, 0.4, 0.0)
gs <- c(gs, rep(0, 115))
gh <- c( g0, g1, g2, g3, g4, g5, g6, g7, g8, g9, ga, gb, gc, gd, ge, gf, gg, gi, gj, gk, gl, gm, gp, gq, gr, gs)
p <- rep(0, 105)
q <- rep(0, 105)
cl <- rep(0, 13)
sl <- rep(0, 13)
#' This is a synthesis routine for the 13th generation IGRF as agreed
#' in December 2019 by IAGA Working Group V-MOD. It is valid 1900.0 to
#' 2025.0 inclusive. Values for dates from 1945.0 to 2015.0 inclusive are
#' definitive, otherwise they are non-definitive.
#' INPUT
#'@param isv = 0 if main-field values are required, = 1 if secular variation values are required
#'@param date = year A.D. Must be greater than or equal to 1900.0 and less than or equal to 2030.0. Warning message is given
#' for dates greater than 2025.0. Must be double precision.
#'@param itype = 1 if geodetic (spheroid); = 2 if geocentric (sphere)
#'@param alt = height in km above sea level if itype = 1; = distance from centre of Earth in km if itype = 2 (>3485 km)
#'@param colat = colatitude (0-180)
#'@param elong = east-longitude (0-360)
#'
#'@return x,y,z
#' x = north component (nT) if isv = 0, nT/year if isv = 1
#' y = east component (nT) if isv = 0, nT/year if isv = 1
#' z = vertical component (nT) if isv = 0, nT/year if isv = 1
#' f = total intensity (nT) if isv = 0, rubbish if isv = 1
#' if isv=0 I, D and f are returned else I=NA, D=NA and f=NA
#' To get the other geomagnetic elements (D, I, H and secular
#' variations dD, dH, dI and dF) use routines ptoc and ptocsv.
#'
#' Adapted from 8th generation version to include new maximum degree for
#' main-field models for 2000.0 and onwards and use WGS84 spheroid instead
#' of International Astronomical Union 1966 spheroid as recommended by IAGA
#' in July 2003. Reference radius remains as 6371.2 km - it is NOT the mean
#' radius (= 6371.0 km) but 6371.2 km is what is used in determining the
#' coefficients. Adaptation by Susan Macmillan, August 2003 (for
#' 9th generation), December 2004, December 2009 & December 2014;
#' by William Brown, December 2019, February 2020.
#'
#' Coefficients at 1995.0 incorrectly rounded (rounded up instead of
#' to even) included as these are the coefficients published in Excel
#' spreadsheet July 2005.
#' igrf13syn(isv=isv, date=date, itype=itype , alt=alt, colat= colat, elong=elong)
#' @seealso \code{\link{https://www.ngdc.noaa.gov/IAGA/vmod/igrf.html}}
#' @references Thébault, E., Finlay, C.C., Beggan, C.D. et al. International Geomagnetic Reference Field: the 12th generation. Earth Planet Sp 67, 79 (2015).
#' https://doi.org/10.1186/s40623-015-0228-9 (\link{https://earth-planets-space.springeropen.com/articles/10.1186/s40623-015-0228-9}): the 12th generation, Erwan Thébault, Christopher C Finlay, Ciarán D Beggan, Patrick Alken, Julien Aubert, Olivier Barrois, Francois Bertrand, Tatiana Bondar, Axel Boness, Laura Brocco, Elisabeth Canet, Aude Chambodut, Arnaud Chulliat, Pierdavide Coïsson, Francois Civet, Aimin Du, Alexandre Fournier, Isabelle Fratter, Nicolas Gillet, Brian Hamilton, Mohamed Hamoudi, Gauthier Hulot, Thomas Jager, Monika Korte, Weijia Kuang, Xavier Lalanne, Benoit Langlais, Jean-Michel Léger, Vincent Lesur, Frank J Lowes et al. Earth, Planets and Space 2015, 67:79 (27 May 2015)
#'
#' @examples
#' isv <- 1
#' date <- 2000
#' itype <- 1 # geodetic (spheroid) alt from the sea
#' alt <- 50 # in km
#' lat <- 45 # Nord positive
#' colat <- 90 - lat
#' elong <- 10
#'
#' @export
igrf13syn <- function(isv, date, itype, alt, colat, elong) {
# set initial values
x = 0.0
y = 0.0
z = 0.0
if (date < 1900.0 || date > 2025.0) {
message(' Date must be in the range [1900.0..2030.0]')
break;
}
if (date > 2020.0) {
t = date - 2020.0
tc = 1.0
if (isv == 1) {
t = 1.0
tc = 0.0
}
# pointer for last coefficient in pen-ultimate set of MF coefficients...
ll = 3255
nmx = 13
nc = nmx*(nmx+2)
kmx = (nmx+1)*(nmx+2)/2
} else {
t = 0.2*(date - 1900.0)
ll = t
one = ll
t = t - one
#
#SH models before 1995.0 are only to degree 10
#
if (date < 1995.0) {
nmx = 10
nc = nmx*(nmx+2)
ll = nc*ll
kmx = (nmx+1)*(nmx+2)/2
}
else {
nmx = 13
nc = nmx*(nmx+2)
ll = 0.2*(date - 1995.0)
#
# 19 is the number of SH models that extend to degree 10
#
ll = 120*19 + nc*ll
kmx = (nmx+1)*(nmx+2)/2
}
tc = 1.0 - t
if (isv== 1) {
tc = -0.2
t = 0.2
}
}
r = alt
one = as.numeric(colat*0.017453292) # con version deg to rad
ct = as.numeric( cos(one) )
st = as.numeric( sin(one) )
one = elong*0.017453292
cl[1] = as.numeric(cos(one) )
sl[1] = as.numeric(sin(one) )
cd = 1.0
sd = 0.0
l = 1
m = 1
n = 0
if (itype != 2) {
# conversion from geodetic to geocentric coordinates
# (using the WGS84 spheroid)
a2 = 40680631.6
b2 = 40408296.0
one = a2*st*st
two = b2*ct*ct
three = one + two
rho = as.numeric( sqrt(three))
r = as.numeric( sqrt(alt*(alt + 2.0*rho) + (a2*one + b2*two)/three) )
cd = (alt + rho)/r
sd = (a2 - b2)/rho*ct*st/r
one = ct
ct = ct*cd - st*sd
st = st*cd + one*sd
}
ratio = 6371.2/r
rr = ratio*ratio
# computation of Schmidt quasi-normal coefficients p and x(=q)
p[1] = 1.0
p[3] = st
q[1] = 0.0
q[3] = ct
for (k in seq(2, kmx) ) {
if (n < m) {
m = 0
n = n + 1
rr = rr*ratio
fn = n
gn = n - 1
}
fm = m
if (m != n) {
gmm = m*m
one = as.numeric( sqrt(fn*fn - gmm))
two = as.numeric( sqrt(gn*gn - gmm)/one )
three = (fn + gn)/one
i = k - n
j = i - n + 1
p[k] = three*ct*p[i] - two*p[j]
q[k] = three*(ct*q[i] - st*p[i]) - two*q[j]
} else if (k != 3) {
one = as.numeric(sqrt(1.0 - 0.5/fm) )
j = k - n - 1
p[k] = one*st*p[j]
q[k] = one*(st*q[j] + ct*p[j])
cl[m] = cl[m-1]*cl[1] - sl[m-1]*sl[1]
sl[m] = sl[m-1]*cl[1] + cl[m-1]*sl[1]
}
# synthesis of x, y and z in geocentric coordinates
lm = ll + l
one = (tc*gh[lm] + t*gh[lm+nc])*rr
if (m == 0) {
x = x + one*q[k]
z = z - (fn + 1.0)*one*p[k]
l = l + 1
} else {
two = (tc*gh[lm+1] + t*gh[lm+nc+1])*rr
three = one*cl[m] + two*sl[m]
x = x + three*q[k]
z = z - (fn + 1.0)*three*p[k]
if (st == 0.0) {
y = y + (one*sl[m] - two*cl[m])*q[k]*ct
} else {
y = y + (one*sl[m] - two*cl[m])*fm*p[k]/st
}
l = l + 2
}
m = m + 1
}
# conversion to coordinate system specified by itype
one = x
x = x*cd + z*sd
z = z*cd - one*sd
f = sqrt(x*x + y*y + z*z)
ret<-NULL
ret$x <- x
ret$y <- y
ret$z <- z
if (isv == 0) {
ret$type <- 'Main-Field'
ret$f <- f
hsq = x*x + y*y
hoz = sqrt(hsq)
dec = atan2(y,x)
inc = atan2(z,hoz)
ret$dec <- dec/pi*180
ret$inc <- inc/pi*180
ret$hoz <- hoz
} else {
ret$type <- 'Secular Variation'
ret$f <- NA
ret$dec <- NA
ret$inc <- NA
ret$hoz <- NA
}
return(ret)
}
#' Standart calcul and plot to study paleo and archeo magnetic magnétisation
#' by convention we use the two last character of the variable step to indicate the type of manip
#' example 100RA , 100 is the temperature (step.value) , R is the sens of the magnetisation and A is the name of the step (step.name)
#' @references Coe 1978 : DOI: 10.1029/JB083iB04p01740
#' Prévost et Al. 1985 DOI: 10.1029/JB090iB12p10417
#'
#' @param mesures data.frame with the package convention format
#' @param relative plot with a relative value in percent
#' @param verbose show comment
#' @param show.plot display the plot
#' @param TH lab field
#' @param aim.coef used to correct the measurement often 1E-10x1E6 x volume
#' @param show.step.value display on the plot the value of each step
#' @param R.mark = 'R', V.mark = 'V' conventional notation to mark the sens of the magnetisation with the step name
#' @param P.mark = 'P' mark the pTRM check loop
#' @param L.mark = "L", Q.mark = "Q" mark to indiquate the slow cooling step and the quick (fast-normal) cooling step
#' @param step.J0 is the step of the natural magnetisation eg "0N0", default 20N0
#' @param begin.step.value the first step.value (temperature) used to determinate the magnetic field
#' @param end.step.value the last step.value (temperature) used to determinate the magnetic field
#' @param loop.col the color of the line showing the the check loop process
#' @param pt.col the color of the line and the plot
#' @export
arai <- function(mesures, relative = TRUE, verbose = TRUE, show.plot = TRUE, TH = 60, aim.coef = 1E-10*1E6, step.J0 = "20N0", show.step.value = FALSE, R.mark = 'R', V.mark = 'V', P.mark = 'P', L.mark = "L", Q.mark = "Q", pt.col = "blue", loop.col = "forestgreen", begin.step.value = 0, end.step.value = 1000) {
# __________________
if (is.null(step.J0)) {
step.J0 <- mes.sel$step[1]
}
ATRR <- mesures[which(substr(mesures$step, nchar(mesures$step)-1, nchar(mesures$step)-1 ) == R.mark),]
ATRV <- mesures[which(substr(mesures$step, nchar(mesures$step)-1, nchar(mesures$step)-1 ) == V.mark),]
J0 <- mesures [which(trimws(mesures$step) ==trimws(step.J0) ), ]
if (J0$F < 0 ) {
warning("error on step.J0, F must be positive")
} else {
ATRR <- rbind.data.frame(J0, ATRR)
ATRV <- rbind.data.frame(J0, ATRV)
}
for (i in 1:length(ATRR$step) ) {
ATRR$step.name[i] <- substr(ATRR$step[i], nchar(ATRR$step[i]), nchar(ATRR$step[i]) )
}
for (i in 1:length(ATRV$step) ) {
ATRV$step.name[i] <- substr(ATRV$step[i], nchar(ATRV$step[i]), nchar(ATRV$step[i]) )
}
ARN <- NULL
ATR <- NULL
RN <- NULL
TR <- NULL
pt.col.res <- NULL
# tableau ATR vs ARN
for (i in ATRR$step.name) {
iATRR <- which(ATRR$step.name == i)
iATRV <- which(ATRV$step.name == i)
atrXR <- ATRR[iATRR, ]$X *aim.coef
atrXV <- ATRV[iATRV, ]$X *aim.coef
atrYR <- ATRR[iATRR, ]$Y *aim.coef
atrYV <- ATRV[iATRV, ]$Y *aim.coef
atrZR <- ATRR[iATRR, ]$Z *aim.coef
atrZV <- ATRV[iATRV, ]$Z *aim.coef
if (ATRR[iATRR, ]$step.value != ATRV[iATRV, ]$step.value) {
warning(paste0("Error in step.name within step.value = ", ATRR[iATRR, ]$step, ATRV[iATRV, ]$step) )
next
}
RN$X <- (atrXR + atrXV)/2
RN$Y <- (atrYR + atrYV)/2
RN$Z <- (atrZR + atrZV)/2
RN <- to.polar(RN$X, RN$Y, RN$Z)
RN$step.value <- ATRR[iATRR, ]$step.value
RN$step.name <- i
ARN <-rbind.data.frame(ARN, RN, stringsAsFactors = FALSE)
TR$X <- (atrXR - atrXV)/2
TR$Y <- (atrYR - atrYV)/2
TR$Z <- (atrZR - atrZV)/2
TR <- to.polar(TR$X, TR$Y, TR$Z)
TR$step.value <- ATRR[iATRR, ]$step.value
TR$step.name <- i
ATR <-rbind.data.frame(ATR, TR, stringsAsFactors = FALSE)
if ((RN$step.value >= begin.step.value) && (RN$step.value <= end.step.value)) {
pt.col.res <- c(pt.col.res, "red")
} else {
pt.col.res <- c(pt.col.res, pt.col)
}
}
xlim <- range(ATR$F)
ylim <- range(ARN$F)
if (relative == TRUE) {
ATRmax <- max(ATR$F) / 100
ARNmax <- max(ARN$F) / 100
} else {
ATRmax <- 1
ARNmax <- 1
}
# Plot Arai
if (show.plot == TRUE) {
xlim <- range(ATR$F/ATRmax)
ylim <- range(ARN$F/ARNmax)
if (relative == TRUE) {
xlab <- "% ATR"
ylab <- "% ARN"
} else {
xlab <- "ATR"
ylab <- "ARN"
}
plot(y = ARN$F/ARNmax, x = ATR$F/ATRmax, type='o', col = pt.col.res, pch = 20, xlim = xlim, ylim = ylim, xlab = xlab, ylab = ylab)
if (show.step.value == TRUE) {
text(y= ARN$F, x=ATR$F, ARN$step.value, adj = 0)
}
}
# stat with all points
Xmoy <- mean(ATR$F)
Ymoy <- mean(ARN$F)
n <- length(ATR$F)
# calcul with a population, not with a sample
covYX <- cov(ATR$F, ARN$F) * (n-1)/n
S2x <- var(ATR$F) * (n-1)/n
S2y <- var(ARN$F) * (n-1)/n
a_tot <- -sqrt(S2y/S2x)
b_tot <- Ymoy - a_tot*Xmoy
JTRM <- (-b_tot/a_tot)
# loop pTRM check
ATRP <- mesures[which(substr(mesures$step, nchar(mesures$step)-1, nchar(mesures$step)-1 ) == P.mark),]
for (i in 1:length(ATRP$step) ) {
ATRP$step.name[i] <- substr(ATRP$step[i], nchar(ATRP$step[i]), nchar(ATRP$step[i]) )
}
# Plot loop
TP <- NULL
ATP <- NULL
for (i in ATRP$step.name) {
iATRV <- which(ATRV$step.name == i)
iATRP <- which(ATRP$step.name == i)
atrXV <- ATRV[iATRV, ]$X *aim.coef
atrXP <- ATRP[iATRP, ]$X *aim.coef
atrYV <- ATRV[iATRV, ]$Y *aim.coef
atrYP <- ATRP[iATRP, ]$Y *aim.coef
atrZV <- ATRV[iATRV, ]$Z *aim.coef
atrZP <- ATRP[iATRP, ]$Z *aim.coef
TP$X <-(atrXP - atrXV)/2
TP$Y <- (atrYP - atrYV)/2
TP$Z <- (atrZP - atrZV)/2
TP <- to.polar(TP$X, TP$Y, TP$Z)
TP$step.value <- ATRP[iATRP, ]$step.value
TP$step.name <- i
ATP <-rbind.data.frame(ATP, TP, stringsAsFactors = FALSE)
arnLoop.name <- ARN[which(ARN$step.name == i), ]
arnLoop.value <- ARN[which(ARN$step.value == TP$step.value), ]
atrLoop <- ATR[which(ATR$step.name == i), ]
if (show.plot == TRUE) {
points( x= TP$F/ATRmax, y= arnLoop.value$F/ARNmax, col = loop.col, pch = 4)
lines( x= c(atrLoop$F/ATRmax, TP$F/ATRmax, TP$F/ATRmax), y = c(arnLoop.name$F/ARNmax, arnLoop.name$F/ARNmax, arnLoop.value$F/ARNmax), col = loop.col)
}
}
res<- NULL
res$ARN <- ARN
res$ATR <- ATR
res$ATP <- ATP
# Statistic
n <- 0
Crm <- CrmMax <- 0
tabX <- NULL
tabY <- NULL
for (i in 1:length(ARN$step.name)) {
if ((ARN$step.value[i] >= begin.step.value) && (ARN$step.value[i] <= end.step.value)) {
tabX <- c( tabX, ATR[which(ATR$step.value == ARN$step.value[i]),]$F /ATRmax)
tabY <- c( tabY, ARN$F[i] /ARNmax)
n <- n+1
if (n==1) {
incl_ET1.rad <- ARN$I[i]/180*pi
} else {
Crm <- ( sin( incl_ET1.rad -ARN$I[i]/180*pi) /sin(incl_ET1.rad -pi/2))*ARN$F[i]
if (abs(Crm)>CrmMax) {
CrmMax <- abs(Crm)
}
}
}
}
CrmMax <- CrmMax/ ( tabX[length(tabX)] - tabX[1])*100
if (n >= 2) {
Xmoy <- mean(tabX)
Ymoy <- mean(tabY)
# calcul sur une population, pas sur un echantillon
covYX <- cov(tabY, tabX) * (n-1)/n
S2x <- var(tabX) * (n-1)/n
S2y <- var(tabY) * (n-1)/n
a_aff <- -sqrt(S2y/S2x)
b_aff <- Ymoy - a_aff*Xmoy
abline(b_aff, a_aff, col= "red")
# Calcul du coef. de corrélation linéaire de la droite entre les 2 étapes
R <- cor(tabY, tabX)
# calcul de la variance eq n°3 : Prévost et Al. 1985 DOI: 10.1029/JB090iB12p10417
s <- covYX/sqrt(S2x*S2y)
if (s < -1) {
warning('Error on sigma Prévost =', s);
s<- abs(s);
} else {
s <- sqrt( 2+(2*s));
sigmaPrevost85 <- s/sqrt(n-2);
# Calcul de sigma pour Coe 1978 : DOI: 10.1029/JB083iB04p01740
sigmaCoe <- ((2*S2y)-2*a_aff*covYX) /((n-2)*S2x)
sigmaCoe <- sqrt(sigmaCoe)
}
# fraction of pTRM used
fs1s2 <- function(tx,ty, i1, i2) {
(a_aff*tabX[i1] + b_aff + tabY[i1] )/2 - (a_aff*tabX[i2] + b_aff + tabY[i2])/2
}
nStep <- length(tabX)
# Coe et Al. 1978)
fCoe78 <- fs1s2(tabX*ATRmax, tabY*ATRmax, 1, nStep) /b_aff
g<-0
for (i in 2:length(tabX)) {
g <- g + fs1s2(tabX*ATRmax, tabY*ATRmax, i-1, i)^2
}
g <- 1 - g/(fCoe78*b_aff)^2
qCoe78 <- abs(a_aff)*fCoe78*g/sigmaCoe;
qPrevost85 <- fCoe78*g/sigmaCoe
SigFe <- sigmaCoe*TH
Fe <- -a_aff*TH
if (verbose == TRUE) {
Commentaire <- paste0('Coef. Corr. lin. R= ', format(R, digits = 3), ' pour ', n,' points')
Commentaire <- c(Commentaire, paste0(' Sigmab ( Coe 1978) = ',format(sigmaCoe, digits = 3)) )
Commentaire <- c(Commentaire, paste0('with lab field : ', TH, ' µT => Fe= ', format(Fe, digits = 3), ' ± ', format(SigFe, digits = 3), ' µT (Coe et Al. 1978)') )
Commentaire <- c(Commentaire, paste0('f = ', format(fCoe78*100, digits = 4), '% (Coe et Al. 1978)') )
Commentaire <- c(Commentaire, paste0('q = ', format(qCoe78, digits = 3)) )
Commentaire <- c(Commentaire, paste0('g = ', format(g, digits = 3)) )
Commentaire <- c(Commentaire, paste0('Crm = ', format(CrmMax, digits = 4), ' (Coe 1984)') )
Commentaire <- c(Commentaire, paste0('q (Prévost 85) = ', format(qPrevost85, digits = 3)) )
Commentaire <- c(Commentaire, paste0('sigma (Prévost 85) = ', format(sigmaPrevost85, digits = 3)) )
print(Commentaire)
}
# Cooling rate
# slow step
ATRL <- mes.sel[which(substr(mes.sel$step, nchar(mes.sel$step)-1, nchar(mes.sel$step)-1 ) == L.mark),]
for (i in 1:length(ATRL$step) ) {
ATRL$step.name[i] <- substr(ATRL$step[i], nchar(ATRL$step[i]), nchar(ATRL$step[i]) )
}
ATRQ <- mes.sel[which(substr(mes.sel$step, nchar(mes.sel$step)-1, nchar(mes.sel$step)-1 ) == Q.mark),]
for (i in 1:length(ATRQ$step) ) {
ATRQ$step.name[i] <- substr(ATRQ$step[i], nchar(ATRQ$step[i]), nchar(ATRQ$step[i]) )
}
# quick step
for (i in ATRL$step.name) {
iARN <- which(ARN$step.name == i)
iATR <- which(ATR$step.name == i)
iATRL <- which(ATRL$step.name == i)
atrXL <- ATRL[iATRL, ]$X*aim.coef - ARN[iARN, ]$X
atrYL <- ATRL[iATRL, ]$Y *aim.coef - ARN[iARN, ]$Y
atrZL <- ATRL[iATRL, ]$Z*aim.coef - ARN[iARN, ]$Z
trL <- to.polar(atrXL, atrYL, atrZL)
rateL <- (trL$F - ATR[iATR, ]$F) / (ATR[iATR, ]$F)
FeL <- Fe*(1-rateL)
SigFeL <- SigFe * (1-rateL)
iATRQ <- which(ATRQ$step.name == i)
atrXQ <- ATRQ[iATRQ, ]$X *aim.coef - ARN[iARN, ]$X
atrYQ <- ATRQ[iATRQ, ]$Y *aim.coef - ARN[iARN, ]$Y
atrZQ <- ATRQ[iATRQ, ]$Z *aim.coef - ARN[iARN, ]$Z
trQ <- to.polar(atrXQ, atrYQ, atrZQ)
rateQ <- (trQ$F - ATR[iATR, ]$F) / (ATR[iATR, ]$F)
if (verbose == TRUE) {
Commentaire <- paste0('Speed Rate with slow step: ', format(rateL*100, digits = 4), ' %')
Commentaire <- c( Commentaire, paste0('Derive speed Rate with quick step: ', format(rateQ*100, digits = 4), ' %') )
Commentaire <- c( Commentaire, paste0('Fe Lent= ', format(FeL, digits = 3), ' ± ', format(SigFeL, digits = 3), ' µT') )
print(Commentaire)
}
}
res$stat <- data.frame(Fe, SigFe, FeL, SigFeL, rateL, rateQ, sigmaCoe, JTRM, fCoe78, qCoe78, g, CrmMax, qPrevost85, sigmaPrevost85)
}
return(res)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.