def calculateUncertaintyH(self): #propagate variance to spectrum fvars = np.sum(self.var_s) fvarr = np.sum(self.var_r) ufdsam_r = unumpy.uarray(self.fdsam.real, fvars**0.5) ufdsam_i = unumpy.uarray(self.fdsam.imag, fvars**0.5) ufdref_r = unumpy.uarray(self.fdref.real, fvarr**0.5) ufdref_i = unumpy.uarray(self.fdref.imag, fvarr**0.5) #calculate angle and phase uncertainty uphase_ref = unumpy.arctan2(ufdref_i, ufdref_r) uphase_sam = unumpy.arctan2(ufdsam_i, ufdsam_r) uphase_sam_stddevs = unumpy.std_devs(uphase_sam) uphase_ref_stddevs = unumpy.std_devs(uphase_ref) # do the phase interpolation only considering the nominal values phasesamC, b = phaseOffsetRemoval( self.freqs, np.unwrap(unumpy.nominal_values(uphase_sam)), self.fminPhase, self.fmaxPhase) phaserefC, a = phaseOffsetRemoval( self.freqs, np.unwrap(unumpy.nominal_values(uphase_ref)), self.fminPhase, self.fmaxPhase) uphase_ref = unumpy.uarray(phaserefC, uphase_ref_stddevs) uphase_sam = unumpy.uarray(phasesamC, uphase_sam_stddevs) ufabss = (ufdsam_r**2 + ufdsam_i**2)**0.5 ufabsr = (ufdref_r**2 + ufdref_i**2)**0.5 uHabs = ufabss / ufabsr uHphase = uphase_sam - uphase_ref #calculate real and imaginary uncertainty ufdsam_r = unumpy.uarray(self.fdsam.real, fvars**0.5) ufdsam_i = unumpy.uarray(self.fdsam.imag, fvars**0.5) ufdref_r = unumpy.uarray(self.fdref.real, fvarr**0.5) ufdref_i = unumpy.uarray(self.fdref.imag, fvarr**0.5) Hr = (ufdsam_r * ufdref_r + ufdsam_i * ufdref_i) / \ (ufdref_r**2 + ufdref_i**2) Hi = (ufdsam_i * ufdref_r - ufdsam_r * ufdref_i) / \ (ufdref_r**2 + ufdref_i**2) self.uHabs = uHabs self.uHphase = uHphase self.uHreal = Hr self.uHimag = Hi return uHabs, uHphase, Hr, Hi
def stress_from_strain_inplane(ex,ey,exy=0,ec=None,dex=None): if dex is None: if ec is None: raise else: E,v = ec else: E,v = __Ev_from_DEX(*dex) f = E/(1-v**2) stress_x=f*(ex+v*ey) stress_y=f*(ey+v*ex) stress_xy=f*(1-v)*exy smean = (stress_x+stress_y)/2. sdiff = unumpy.sqrt(((stress_x-stress_y)/2)**2.+stress_xy**2) stress_1 = smean+sdiff stress_2 = smean-sdiff rotation = unumpy.arctan2(stress_xy,sdiff)/2 #s1,s2,srot = __principal_inplane(nominal_value(stress_x),nominal_value(stress_y),nominal_value(stress_xy)) return dict(stress_x=stress_x, stress_y=stress_y, stress_xy=stress_xy, stress_1=stress_1, stress_2=stress_2, stress_rotation=rotation)
def GcGs_to_azi(self): self.psi2[:] = np.arctan2(self.Gs, self.Gc)/2./np.pi*180. self.psi2[self.psi2<0.] += 180. self.amp[:] = np.sqrt(self.Gs**2 + self.Gc**2)/2.*100. Gc_with_un = unumpy.uarray(self.Gc, self.unGc) Gs_with_un = unumpy.uarray(self.Gs, self.unGs) self.unpsi2[:] = unumpy.std_devs( unumpy.arctan2(Gs_with_un, Gc_with_un)/2./np.pi*180.) self.unpsi2[self.unpsi2>90.] = 90. self.unamp[:] = unumpy.std_devs( unumpy.sqrt(Gs_with_un**2 + Gc_with_un**2)/2.*100.) self.unamp[self.unamp>self.amp] = self.amp[self.unamp>self.amp]
def tan2visibilities(coeffs): """ Long Summary ------------ Technically the fit measures phase AND amplitude, so to retrieve the phase we need to consider both sin and cos terms. Consider one fringe: A { cos(kx)cos(dphi) + sin(kx)sin(dphi) } = A(a cos(kx) + b sin(kx)), where a = cos(dphi) and b = sin(dphi) and A is the fringe amplitude, therefore coupling a and b. In practice we measure A*a and A*b from the coefficients, so: Ab/Aa = b/a = tan(dphi) call a' = A*a and b' = A*b (we actually measure a', b') (A*sin(dphi))^2 + (A*cos(dphi)^2) = A^2 = a'^2 + b'^2 Short Summary ------------- From the solution to the fit, calculate the fringe amplitude and phase. Parameters ---------- coeffs: 1D float array Returns ------- amp, delta: 1D float array, 1D float array fringe amplitude & phase """ if type(coeffs[0]).__module__ != 'uncertainties.core': # if uncertainties not present, proceed as usual # coefficients of sine terms mulitiplied by 2*pi delta = np.zeros(int((len(coeffs) - 1) / 2)) amp = np.zeros(int((len(coeffs) - 1) / 2)) for q in range(int((len(coeffs) - 1) / 2)): delta[q] = (np.arctan2(coeffs[2 * q + 2], coeffs[2 * q + 1])) amp[q] = np.sqrt(coeffs[2 * q + 2]**2 + coeffs[2 * q + 1]**2) log.debug('tan2visibilities: shape coeffs:%s shape delta:%s ', np.shape(coeffs), np.shape(delta)) # returns fringe amplitude & phase return amp, delta else: # propagate uncertainties qrange = np.arange(int((len(coeffs) - 1) / 2)) fringephase = unumpy.arctan2(coeffs[2 * qrange + 2], coeffs[2 * qrange + 1]) fringeamp = unumpy.sqrt(coeffs[2 * qrange + 2]**2 + coeffs[2 * qrange + 1]**2) return fringeamp, fringephase
def tan2visibilities(coeffs, verbose=False): """ Technically the fit measures phase AND amplitude, so to retrieve the phase we need to consider both sin and cos terms. Consider one fringe: A { cos(kx)cos(dphi) + sin(kx)sin(dphi) } = A(a cos(kx) + b sin(kx)), where a = cos(dphi) and b = sin(dphi) and A is the fringe amplitude, therefore coupling a and b In practice we measure A*a and A*b from the coefficients, so: Ab/Aa = b/a = tan(dphi) call a' = A*a and b' = A*b (we actually measure a', b') (A*sin(dphi))^2 + (A*cos(dphi)^2) = A^2 = a'^2 + b'^2 Edit 10/2014: pistons now returned in units of radians!! Edit 05/2017: J. Sahlmann added support of uncertainty propagation """ if type(coeffs[0]).__module__ != 'uncertainties.core': # if uncertainties not present, proceed as usual # coefficients of sine terms mulitiplied by 2*pi delta = np.zeros(int((len(coeffs) - 1) / 2)) # py3 amp = np.zeros(int((len(coeffs) - 1) / 2)) # py3 for q in range(int((len(coeffs) - 1) / 2)): # py3 delta[q] = (np.arctan2(coeffs[2 * q + 2], coeffs[2 * q + 1])) amp[q] = np.sqrt(coeffs[2 * q + 2]**2 + coeffs[2 * q + 1]**2) if verbose: print("shape coeffs", np.shape(coeffs)) print("shape delta", np.shape(delta)) # returns fringe amplitude & phase return amp, delta else: # propagate uncertainties qrange = np.arange(int((len(coeffs) - 1) / 2)) # py3 fringephase = unumpy.arctan2(coeffs[2 * qrange + 2], coeffs[2 * qrange + 1]) fringeamp = unumpy.sqrt(coeffs[2 * qrange + 2]**2 + coeffs[2 * qrange + 1]**2) return fringeamp, fringephase
theta1 = misura(value=_theta1, name="$\\theta '$") x = misura(value=_x, name="$x$") #---------------------------------------------------------------------------------------# #-/////////////////////// CALCULATIONS ////////////////////////////////////////////////-# #---------------------------------------------------------------------------------------# # Legge di riflessione _thetaI = [] _Theta = [] _index = [] _ThetaTh = [] for i in range(10): _thetaI.append(_theta1[i]) _Theta.append(unp.arctan2(_y[i], _x[i]) * 180 / np.pi) _index.append((_thetaI[i] * 2) - _Theta[i]) _ThetaTh.append((_theta1[i] * 2)) thetaI = misura(value=_thetaI, name="$\\theta_i$") Theta = misura(value=_Theta, name="$\\Theta$") index = misura(value=_index, name="$2\\theta_i - \\Theta$") ThetaTh = misura(value=_ThetaTh, name="$2 \\theta_i$") ### Correlazione lineare tra due valori (x,y) fitLine = poly_fit(thetaI, Theta) #---------------------------------------------------------------------------------------# #-/////////////////////// RESULTS /////////////////////////////////////////////////////-# #---------------------------------------------------------------------------------------#
_l_h2o = ne([13.4, 12.0, 10.3, 9.2, 7.9, 7.0, 6.2, 5.5, 4.5, 3.6], 0.5) d = misura(value=_d, name="$d$") thetaI = misura(value=_thetaI, name="$\\theta_i$") l_h2o = misura(value=_l_h2o, name="$l$") #---------------------------------------------------------------------------------------# #-/////////////////////// CALCULATIONS ////////////////////////////////////////////////-# #---------------------------------------------------------------------------------------# _thetaT_h2o = [] _nT_h2o = [] _index = [] _thetaT_Th = [] for i in range(len(_l_h2o)): _thetaT_h2o.append(unp.arctan2(_l_h2o[i], _h1_h2o[i]) * 180 / np.pi) _nT_h2o.append( unp.sin(_thetaI[i] / 180 * np.pi) / unp.sin(_thetaT_h2o[i] / 180 * np.pi)) _index.append((1.334 - _nT_h2o[i]) / 1.334) _thetaT_Th.append( asin(0.749625 * unp.sin(_thetaI[i] / 180 * np.pi)) / np.pi * 180) thetaT_h2o = misura(value=_thetaT_h2o, name="$\\theta_t$") nT_h2o = misura(value=_nT_h2o, name="$n_{exp}$") index = misura(value=_index, name="$(n - n_{exp}) / n$") thetaT_Th = misura(value=_thetaT_Th, name="$\\theta_t$") ### Correlazione lineare tra due valori (x,y) fitLine = poly_fit(thetaI, thetaT_h2o)
def geometric_elements_with_uncertainties(thiele_innes_parameters, thiele_innes_parameters_errors=None, correlation_matrix=None, post_process=False, return_angles_in_deg=True): """ Return geometrical orbit elements a, omega, OMEGA, i. If errors are not given they are assumed to be 0 and correlation matrix is set to identity. Complement to the pystrometry.geometric_elements function that allows to compute parameter uncertainties as well. Parameters ---------- thiele_innes_parameters : array Array of Thiele Innes parameters [A,B,F,G] in milli-arcsecond thiele_innes_parameters_errors : array, optional Array of the errors of the Thiele Innes parameters [A,B,F,G] in milli-arcsecond correlation_matrix : (4, 4) array, optional Correlation matrix for the Thiele Innes parameters [A,B,F,G] Returns ------- geometric_parameters : array Orbital elements [a_mas, omega_deg, OMEGA_deg, i_deg] geometric_parameters_errors : array Errors of the orbital elements [a_mas, omega_deg, OMEGA_deg, i_deg] """ # Checks on the errors and correlation matrix if (thiele_innes_parameters_errors is None) and (correlation_matrix is None): # Define errors to 0 and correlation matrix to identity thiele_innes_parameters_errors = [0, 0, 0, 0] correlation_matrix = np.identity(4) elif (thiele_innes_parameters_errors is not None) and (correlation_matrix is not None): # If both are given continue to the calculation pass else: # If either one of them is provided but not the other raise an error raise ValueError("thieles_innes_parameters_erros and correlation_matrix must be" \ "specified together.") # Define uncorrelated (value, uncertainty) pairs A_u = (thiele_innes_parameters[0], thiele_innes_parameters_errors[0]) B_u = (thiele_innes_parameters[1], thiele_innes_parameters_errors[1]) F_u = (thiele_innes_parameters[2], thiele_innes_parameters_errors[2]) G_u = (thiele_innes_parameters[3], thiele_innes_parameters_errors[3]) # Create correlated quantities A, B, F, G = correlated_values_norm([A_u, B_u, F_u, G_u], correlation_matrix) p = (A**2 + B**2 + G**2 + F**2) / 2. q = A * G - B * F a_mas = unp.sqrt(p + unp.sqrt(p**2 - q**2)) i_rad = unp.arccos(q / (a_mas**2.)) omega_rad = (unp.arctan2(B - F, A + G) + unp.arctan2(-B - F, A - G)) / 2. OMEGA_rad = (unp.arctan2(B - F, A + G) - unp.arctan2(-B - F, A - G)) / 2. if post_process: # convert angles to nominal ranges omega_rad, OMEGA_rad = pystrometry.adjust_omega_OMEGA( omega_rad, OMEGA_rad) if return_angles_in_deg: # Convert radians to degrees i_deg = i_rad * 180 / np.pi omega_deg = omega_rad * 180 / np.pi OMEGA_deg = OMEGA_rad * 180 / np.pi else: i_deg = i_rad omega_deg = omega_rad OMEGA_deg = OMEGA_rad # Extract nominal values and standard deviations geometric_parameters = np.array([ unp.nominal_values(a_mas), unp.nominal_values(omega_deg), unp.nominal_values(OMEGA_deg), unp.nominal_values(i_deg) ]) geometric_parameters_errors = np.array([ unp.std_devs(a_mas), unp.std_devs(omega_deg), unp.std_devs(OMEGA_deg), unp.std_devs(i_deg) ]) return geometric_parameters, geometric_parameters_errors