def NRM_dir_stat(sc): """ Function to calculate the NRM direction statistics, DANG, free floating direction and NRMdev. input: Mdec_free,Minc_free, x, y, z, Yint output: DANG, NRMdev, dir_vec_free """ # input: directional_statistics/ mean_dir_stat[Mdec_free,Minc_free, x, y, z] # arai_statistics/ intercept_stats[Yint] # output: directional_statistics/ NRM_dir_stat[DANG, NRMdev, dir_vec_free] x = sc["directional_statistics"]["mean_dir_stat"]["x"] y = sc["directional_statistics"]["mean_dir_stat"]["y"] z = sc["directional_statistics"]["mean_dir_stat"]["z"] Mdec_free = sc["directional_statistics"]["mean_dir_stat"]["Mdec_free"] Minc_free = sc["directional_statistics"]["mean_dir_stat"]["Minc_free"] Yint = sc["arai_statistics"]["intercept_stats"]["Yint"] mean_x = sum(x) / len(x) mean_y = sum(y) / len(y) mean_z = sum(z) / len(z) center_of_mass = [mean_x, mean_y, mean_z] # calculate DANG & NRMdev dir_vec_free = helpers.dir2cart(Mdec_free, Minc_free, 1) DANG = helpers.get_angle_diff(dir_vec_free, center_of_mass) NRMdev = ((math.sin(math.radians(DANG)) * helpers.norm(center_of_mass)) / abs(Yint)) * 100 sc["directional_statistics"]["NRM_dir_stat"]["dir_vec_free"] = dir_vec_free sc["directional_statistics"]["NRM_dir_stat"]["DANG"] = DANG sc["directional_statistics"]["NRM_dir_stat"]["NRMdev"] = NRMdev return sc
def best_fit_lines_Zijderveld(sc): """ Function to calculate the direction of the Best - Fit lines for the Zijderveld, use the Free floating direction input: Free-floating direction (Mdec_free, Minc_free) and the center-of-mass vector (CMvec) to calculate the size of the plot output: The (x,y) coordinates for the horizontal (line_H_) and vertical (line_V_) lines for the Zijderveld diagram, for the two options, Up-North (UpN) or Up-West (UpW) """ # input: directional_statistics/ mean_dir_stat[CMvec, Mdec_free, Minc_free ] # output: best_fit_lines/ best_fit_lines_Zijderveld[line_H_UpN, line_V_UpN, line_H_UpW, line_V_UpW] CMvec = sc["directional_statistics"]["mean_dir_stat"]["CMvec"] Mdec_free = sc["directional_statistics"]["mean_dir_stat"]["Mdec_free"] Minc_free = sc["directional_statistics"]["mean_dir_stat"]["Minc_free"] # first find in which order of magnitude the point for the lines should be, they should be outside the area of the zijderveld plot # find the maximum absolute value for the center of mass and take an order of magnitude bigger to be sure to outside of the plot Abs_CMvec = [] for i in range(len(CMvec)): Abs_CMvec.append(abs(CMvec[i])) M = max(Abs_CMvec) * 10 # get the direction vector with the correct magnitude M Dvec = helpers.dir2cart(Mdec_free, Minc_free, M) # Center of mass - Direction vector is the first point P1 = helpers.list_min_list(CMvec, Dvec) # Center of mass + Direction vector is the second point P2 = helpers.list_plus_list(CMvec, Dvec) # North Up line_H_UpN = [[P1[1], P1[0]], [P2[1], P2[0]]] line_V_UpN = [[P1[1], -1 * P1[2]], [P2[1], -1 * P2[2]]] # West Up line_H_UpW = [[P1[0], -1 * P1[1]], [P2[0], -1 * P2[1]]] line_V_UpW = [[P1[0], -1 * P1[2]], [P2[0], -1 * P2[2]]] sc["best_fit_lines"]["best_fit_lines_Zijderveld"][ "line_H_UpN"] = line_H_UpN sc["best_fit_lines"]["best_fit_lines_Zijderveld"][ "line_V_UpN"] = line_V_UpN sc["best_fit_lines"]["best_fit_lines_Zijderveld"][ "line_H_UpW"] = line_H_UpW sc["best_fit_lines"]["best_fit_lines_Zijderveld"][ "line_V_UpW"] = line_V_UpW return sc
def alpha_stat(sc): """ Function to calculate the alpha statistic, the angular difference between the anchored and free-floating best-fit directions input: free floating direction vector (dir_vec_free), and the anchored direction (Mdec_anc, Minc_anc) output: alpha """ # input: directional_statistics/ mean_dir_stat[Mdec_anc, Minc_anc] # NRM_dir_stat[dir_vec_free] # output: directional_statistics/ alpha_stat[alpha] Mdec_anc = sc["directional_statistics"]["mean_dir_stat"]["Mdec_anc"] Minc_anc = sc["directional_statistics"]["mean_dir_stat"]["Minc_anc"] dir_vec_free = sc["directional_statistics"]["NRM_dir_stat"]["dir_vec_free"] dir_vec_anc = [] dir_vec_anc = helpers.dir2cart(Mdec_anc, Minc_anc, 1) alpha = helpers.get_angle_diff(dir_vec_free, dir_vec_anc) sc["directional_statistics"]["alpha_stat"]["alpha"] = alpha return sc
def field_basics_pTh(sc): """ Function to write the field basics to the suitcase for pseudo-Thellier. Only difference here w.r.t. the field_basics function above is that the "infield_steps" are now the ARM_aqc_steps for the NAA format, for pTh-GF (generic format) this is still the infieldstep. The lab field strength (Blab), and the direction of the labfield as provided by the user in the input (field_dir_vec_initial). The labfield direction is chcked with the direction of the last ptrm_step to check if the field_dir_vec_initial is correct or if it should be anti-parallel to that. input: the ptrm_gained_vec from the basisc, the infield_steps and the ARM_acq_steps from the measurements output: the field basics: Blab, field_dir_vec_initial, field_dir_vec """ # input: preprocessed/ msrmnts [infield_steps, ARM_acq_steps] # basics [ptrm_gained_vec] # output: preprocessed/ field_basics [Blab, field_dir_vec_initial, field_dir_vec] infield_steps = sc["preprocessed"]["msrmnts"]["infield_steps"] ARM_acq_steps = sc["preprocessed"]["msrmnts"]["ARM_acq_steps"] ptrm_gained_vec = sc["preprocessed"]["basics"]["ptrm_gained_vec"] # make extra if statement if len(infield_steps) == 0: infield_steps = ARM_acq_steps # get lab field strength and direction of applied labfield Blab = infield_steps[0]["lab_field"] field_dir_vec_initial = helpers.dir2cart(infield_steps[0]["lab_field_dec"], infield_steps[0]["lab_field_inc"], 1) # check the field_dir_vec_initial, in an experiment the specimen could have been rotated so that field dir vec should be negative # check this by comparing the direction of the ptrm with field_dir_vec_initial vecl = ptrm_gained_vec[len(ptrm_gained_vec) - 1] # last ptrm gained step vecl_abs = [] # make this vector absolute for i in range(len(vecl)): vecl_abs.append(abs(vecl[i])) # check field direction, and make it positive or negative is necessary, only works for fields applied along principal axis if field_dir_vec_initial[2] == 1 or field_dir_vec_initial[2] == -1: if field_dir_vec_initial[0] == 0 and field_dir_vec_initial[1] == 0: # then you have [0,0,1] or [0,0,-1] if (max(vecl) - max(vecl_abs)) < 0: field_dir_vec = [0, 0, -1] else: field_dir_vec = [0, 0, 1] else: # [x,x,1] en x != 0 field_dir_vec = field_dir_vec_initial elif field_dir_vec_initial[1] == 1 or field_dir_vec_initial[1] == -1: if field_dir_vec_initial[0] == 0 and field_dir_vec_initial[2] == 0: # then you have [0,1,0] or [0,-1,0] if (max(vecl) - max(vecl_abs)) < 0: field_dir_vec = [0, -1, 0] else: field_dir_vec = [0, 1, 0] else: # [x,1,x] en x != 0 field_dir_vec = field_dir_vec_initial elif field_dir_vec_initial[0] == 1 or field_dir_vec_initial[0] == -1: if field_dir_vec_initial[1] == 0 and field_dir_vec_initial[2] == 0: # then you have [1,0,0] or [-1,0,0] if (max(vecl) - max(vecl_abs)) < 0: field_dir_vec = [-1, 0, 0] else: field_dir_vec = [1, 0, 0] else: # [1,x,x] with x != 0 field_dir_vec = field_dir_vec_initial else: # All other field directions that are not principal axis field_dir_vec = field_dir_vec_initial sc["preprocessed"]["field_basics"]["Blab"] = Blab sc["preprocessed"]["field_basics"][ "field_dir_vec_initial"] = field_dir_vec_initial sc["preprocessed"]["field_basics"]["field_dir_vec"] = field_dir_vec return sc
def anisotropy_calc(sc): """ Function that calculates the paleointensity correction factor when anisotropy data is available. It uses the previously calculated s-tensor. First the direction of the NRM for the selected part of the Arai plot is determined to give Mhat_ChRM. Which is used to get the anisotropy correction c. The anisotropy correction in multiplied with Banc to get Banc_aniso_corr. input: s-tensor, the direction of the applied labfield, direction of the data selection, the original Banc output: the anisotropy correction anis_c, the anisotropy corrected paleointensity estimate Banc_aniso_corr """ # input: preprocessed/ field_basics [field_dir_vec] # s_tensor [s1_list, s2_list, s3_list, s4_list, s5_list, s6_list, scheck_list] # arai_statistics/ PI_Banc_est [B_anc] # directional_statistics/ mean_dir_stat [Mdec_free, Minc_free] # output: anisotropy_statistics/ Anisotropy_Correction [anis_c, Banc_aniso_corr] Mdec_free = sc["directional_statistics"]["mean_dir_stat"]["Mdec_free"] Minc_free = sc["directional_statistics"]["mean_dir_stat"]["Minc_free"] field_dir_vec = sc["preprocessed"]["field_basics"]["field_dir_vec"] B_anc = sc["arai_statistics"]["PI_Banc_est"]["B_anc"] Xp_list = sc["preprocessed"]["aniso_trm"]["x+"] s_tensor = sc["anisotropy_statistics"]["Aniso_tensor"]["s_tensor"] if Xp_list != None: # then there is anisotropy data, do calculations, if no anisotropy data present do nothing anis_c = [] # the direction of the NRM, should be determined from the selected Arai plot # this is the Mdec_free & Minc_free, the unit vecotr of this gives -> Mhat_ChRM # get mean unit vector Mhat_ChRM = helpers.dir2cart(Mdec_free, Minc_free, 1) Blab_orient = field_dir_vec # it was: helpers.dir2cart(Mdec_free, Minc_free, 1), that is wrong!! (13 feb 2020) s1 = s_tensor[0] s2 = s_tensor[1] s3 = s_tensor[2] s4 = s_tensor[3] s5 = s_tensor[4] s6 = s_tensor[5] A1 = [s1, s4, s6] A2 = [s4, s2, s5] A3 = [s6, s5, s3] A = [A1, A2, A3] # make A and Mhat_ChRM into a numpy arrays (1) A = numpy.array(A) Mhat_ChRM = numpy.array(Mhat_ChRM) # do numpy calculation (2) Hanc = numpy.linalg.solve(A, Mhat_ChRM) # back to python lists (3) A = A.tolist() Mhat_ChRM = Mhat_ChRM.tolist() Hanc = Hanc.tolist() # unit vector in the direction of the ancient field Hanc_hat = helpers.list_div_num(Hanc, helpers.norm(Hanc)) Manc = [] Mlab = [] for i in range(len(A)): Manc.append(helpers.dot_product(A[i], Hanc_hat)) Mlab.append(helpers.dot_product(A[i], field_dir_vec)) aniso_c = helpers.norm(Mlab) / helpers.norm(Manc) Banc_aniso_corr = aniso_c * B_anc sc["anisotropy_statistics"]["Anisotropy_Correction"][ "aniso_c"] = aniso_c sc["anisotropy_statistics"]["Anisotropy_Correction"][ "Banc_aniso_corr"] = Banc_aniso_corr return (sc)