def zoomToAll(self): if self.m_nImgs < 1: return posA=N.array(self.m_imgPosArr) sizA=N.array(self.m_imgSizeArr) a=N.array([N.minimum.reduce(posA), N.maximum.reduce(posA+sizA), ]) from .all import U MC = N.array([0.5, 0.5]) # mosaic viewer's center (0.5, 0.5) a -= MC hypot = N.array((N.hypot(a[0][0], a[0][1]), N.hypot(a[1][0], a[1][1]))) theta = N.array((N.arctan2(a[0][1], a[0][0]), N.arctan2(a[1][1], a[1][0]))) # radians phi = theta + U.deg2rad(self.m_rot) mimXY = N.array((hypot[0]*N.cos(phi[0]), hypot[0]*N.sin(phi[0]))) maxXY = N.array((hypot[1]*N.cos(phi[1]), hypot[1]*N.sin(phi[1]))) a = N.array((mimXY, maxXY)) a.sort(0) if self.m_aspectRatio == -1: a = N.array(([a[0][0],-a[1][1]],[a[1][0],-a[0][1]])) self.zoomToRect(x0=a[0][0], y0=a[0][1], x1=a[-1][0],y1=a[-1][1])
def hgs_to_hcc(heliogcoord, heliocframe): """ Convert from Heliographic Stonyhurst to Heliograpic Carrington. """ hglon = heliogcoord.lon hglat = heliogcoord.lat r = heliogcoord.radius.to(u.m) l0b0_pair = [heliocframe.L0, heliocframe.B0] l0_rad = l0b0_pair[0].to(u.rad) b0_deg = l0b0_pair[1] lon = np.deg2rad(hglon) lat = np.deg2rad(hglat) cosb = np.cos(b0_deg.to(u.rad)) sinb = np.sin(b0_deg.to(u.rad)) lon = lon - l0_rad cosx = np.cos(lon) sinx = np.sin(lon) cosy = np.cos(lat) siny = np.sin(lat) x = r * cosy * sinx y = r * (siny * cosb - cosy * cosx * sinb) zz = r * (siny * sinb + cosy * cosx * cosb) representation = CartesianRepresentation(x.to(u.km), y.to(u.km), zz.to(u.km)) return heliocframe.realize_frame(representation)
def EclipticToEquatorial(input): """ Convert the SkyPosition object input from the inherited 'eliptic' system to to 'equatorial'. """ # intermediates sinB = np.sin(input.latitude) cosB = np.cos(input.latitude) sinL = np.sin(input.longitude) cosL = np.cos(input.longitude) # components sinD = cosB*sinL*np.sin(lal.IEARTH)\ + sinB*np.cos(lal.IEARTH) sinA = cosB*sinL*np.cos(lal.IEARTH)\ - sinB*np.sin(lal.IEARTH) cosA = cosB*cosL # output output.system = 'equatorial' output.latitude = np.arcsin(sinD) output.longitude = np.arctan2(sinA, cosA) output.normalize() return output
def compute_shear(e1, e2, distx, disty): """Compute the shear.""" phi = numpy.arctan2(disty, distx) gamt = - (e1 * numpy.cos(2.0 * phi) + e2 * numpy.cos(2.0 * phi)) gamc = - e1 * numpy.sin(2.0 * phi) + e2 * numpy.cos(2.0 * phi) dist = numpy.sqrt(distx**2 + disty**2) return gamt, gamc, dist
def ellipticalGaussian2D(x0=0.,y0=0.,sigmax=1.,sigmay=1.,phi=0.,amp=1.,offset=0.): """A generalized 2D ellipitical Gaussian function with centre (x0,y0), width (sigmax,sigmay), amplitude amp, offset, and rotation angle phi (radians) """ aa=((np.cos(phi))**2.)/(2.*(sigmax**2.)) + ((np.sin(phi))**2.)/(2.*(sigmay**2.)) bb=(-1.*np.sin(2.*phi))/(4.*(sigmax**2.)) + (np.sin(2.*phi))/(4.*(sigmay**2.)) cc=((np.sin(phi))**2.)/(2.*(sigmax**2.)) + ((np.cos(phi))**2.)/(2.*(sigmay**2.)) return lambda x,y: amp * np.exp( -1.*( aa*((x-x0)**2.) - 2.*bb*(x-x0)*(y-y0) + cc*((y-y0)**2.) ) ) + offset
def reconstruct(self, t, x, y, z, core_x, core_y): """Reconstruct angles for many detections :param t: arrival times in the detectors in ns. :param x,y,z: positions of the detectors in m. :param core_x,core_y: core position at z = 0 in m. :return: theta as derived by Montanus2014, phi as derived by Montanus2014. """ if not logic_checks(t, x, y, z): return nan, nan regress2d = RegressionAlgorithm() theta, phi = regress2d.reconstruct_common(t, x, y) dtheta = 1. iteration = 0 while dtheta > 0.001: iteration += 1 if iteration > self.MAX_ITERATIONS: return nan, nan nxnz = tan(theta) * cos(phi) nynz = tan(theta) * sin(phi) nz = cos(theta) x_proj = [xi - zi * nxnz for xi, zi in zip(x, z)] y_proj = [yi - zi * nynz for yi, zi in zip(y, z)] t_proj = [ti + zi / (c * nz) - self.time_delay(xpi, ypi, core_x, core_y, theta, phi) for ti, xpi, ypi, zi in zip(t, x_proj, y_proj, z)] theta_prev = theta theta, phi = regress2d.reconstruct_common(t_proj, x_proj, y_proj) dtheta = abs(theta - theta_prev) return theta, phi
def to_SQL(self, RAname, DECname): if self.DECdeg != 90.0 and self.DECdeg != -90.0: RAmax = self.RAdeg + \ 360.0 * np.arcsin(np.sin(0.5*self.radius) / np.cos(self.DEC))/np.pi RAmin = self.RAdeg - \ 360.0 * np.arcsin(np.sin(0.5*self.radius) / np.cos(self.DEC))/np.pi else: #just in case, for some reason, we are looking at the poles RAmax = 360.0 RAmin = 0.0 DECmax = self.DECdeg + self.radiusdeg DECmin = self.DECdeg - self.radiusdeg #initially demand that all objects are within a box containing the circle #set from the DEC1=DEC2 and RA1=RA2 limits of the haversine function bound = ("%s between %f and %f and %s between %f and %f " % (RAname, RAmin, RAmax, DECname, DECmin, DECmax)) #then use the Haversine function to constrain the angular distance form boresite to be within #the desired radius. See http://en.wikipedia.org/wiki/Haversine_formula bound = bound + ("and 2 * ASIN(SQRT( POWER(SIN(0.5*(%s - %s) * PI() / 180.0),2)" % (DECname,self.DECdeg)) bound = bound + ("+ COS(%s * PI() / 180.0) * COS(%s * PI() / 180.0) " % (DECname, self.DECdeg)) bound = bound + ("* POWER(SIN(0.5 * (%s - %s) * PI() / 180.0),2)))" % (RAname, self.RAdeg)) bound = bound + (" < %s " % self.radius) return bound
def test_arclength_half_circle(): """ Here we define the tests for the lenght computer of our ArcLengthParametrizer, we try it with a half a circle and a fan. We test it both in 2d and 3d.""" # Number of interpolation points minus one n = 5 toll = 1.e-6 points = np.linspace(0, 1, (n+1) ) R = 1 P = 1 control_points_2d = np.asmatrix(np.zeros([n+1,2]))#[np.array([R*np.cos(5*i * np.pi / (n + 1)), R*np.sin(5*i * np.pi / (n + 1)), P * i]) for i in range(0, n+1)] control_points_2d[:,0] = np.transpose(np.matrix([R*np.cos(1 * i * np.pi / (n + 1))for i in range(n+1)])) control_points_2d[:,1] = np.transpose(np.matrix([R*np.sin(1 * i * np.pi / (n + 1))for i in range(n+1)])) control_points_3d = np.asmatrix(np.zeros([n+1,3]))#[np.array([R*np.cos(5*i * np.pi / (n + 1)), R*np.sin(5*i * np.pi / (n + 1)), P * i]) for i in range(0, n+1)] control_points_3d[:,0] = np.transpose(np.matrix([R*np.cos(1 * i * np.pi / (n + 1))for i in range(n+1)])) control_points_3d[:,1] = np.transpose(np.matrix([R*np.sin(1 * i * np.pi / (n + 1))for i in range(n+1)])) control_points_3d[:,2] = np.transpose(np.matrix([P*i for i in range(n+1)])) vsl = AffineVectorSpace(UniformLagrangeVectorSpace(n+1),0,1) dummy_arky_2d = ArcLengthParametrizer(vsl, control_points_2d) dummy_arky_3d = ArcLengthParametrizer(vsl, control_points_3d) length2d = dummy_arky_2d.compute_arclength()[-1,1] length3d = dummy_arky_3d.compute_arclength()[-1,1] # print (length2d) # print (n * np.sqrt(2)) l2 = np.pi * R l3 = 2 * np.pi * np.sqrt(R * R + (P / (2 * np.pi)) * (P / (2 * np.pi))) print (length2d, l2) print (length3d, l3) assert (length2d - l2) < toll assert (length3d - l3) < toll
def get_gabors(self, rf): lams = float(rf[0])/self.sfs # lambda = 1./sf #1./np.array([.1,.25,.4]) sigma = rf[0]/2./np.pi # rf = [100,100] gabors = np.zeros(( len(oris),len(phases),len(lams), rf[0], rf[1] )) i = np.arange(-rf[0]/2+1,rf[0]/2+1) #print i j = np.arange(-rf[1]/2+1,rf[1]/2+1) ii,jj = np.meshgrid(i,j) for o, theta in enumerate(self.oris): x = ii*np.cos(theta) + jj*np.sin(theta) y = -ii*np.sin(theta) + jj*np.cos(theta) for p, phase in enumerate(self.phases): for s, lam in enumerate(lams): fxx = np.cos(2*np.pi*x/lam + phase) * np.exp(-(x**2+y**2)/(2*sigma**2)) fxx -= np.mean(fxx) fxx /= np.linalg.norm(fxx) #if p==0: #plt.subplot(len(oris),len(lams),count+1) #plt.imshow(fxx,cmap=mpl.cm.gray,interpolation='bicubic') #count+=1 gabors[o,p,s,:,:] = fxx plt.show() return gabors
def rotate(data, interpArray, rotation_angle): for i in range(interpArray.shape[0]): for j in range(interpArray.shape[1]): i1 = i - (interpArray.shape[0] / 2. - 0.5) j1 = j - (interpArray.shape[1] / 2. - 0.5) x = i1 * numpy.cos(rotation_angle) - j1 * numpy.sin(rotation_angle) y = i1 * numpy.sin(rotation_angle) + j1 * numpy.cos(rotation_angle) x += data.shape[0] / 2. - 0.5 y += data.shape[1] / 2. - 0.5 if x >= data.shape[0] - 1: x = data.shape[0] - 1.1 x1 = numpy.int32(x) if y >= data.shape[1] - 1: y = data.shape[1] - 1.1 y1 = numpy.int32(y) xGrad1 = data[x1 + 1, y1] - data[x1, y1] a1 = data[x1, y1] + xGrad1 * (x - x1) xGrad2 = data[x1 + 1, y1 + 1] - data[x1, y1 + 1] a2 = data[x1, y1 + 1] + xGrad2 * (x - x1) yGrad = a2 - a1 interpArray[i, j] = a1 + yGrad * (y - y1) return interpArray
def delta(phase,inc, ecc = 0, omega=0): """ Compute the distance center-to-center between planet and host star. ___ INPUT: phase: orbital phase in radian inc: inclination of the system in radian OPTIONAL INPUT: ecc: omega: // OUTPUT: distance center-to-center, double-float number. ___ """ phase = 2*np.pi*phase if ecc == 0 and omega == 0: delta = np.sqrt(1-(np.cos(phase)**2)*(np.sin(inc)**2)) else: delta = (1.-ecc**2.)/(1.-ecc*np.sin(phase-omega))* np.sqrt((1.-(np.cos(phase))**2.*(np.sin(inc))**2)) return delta
def compute_slat_lift(slat_angle,sweep_angle): """ SUAVE.Methods.Aerodynamics.compute_slat_lift(vehicle): Computes the increase of lift due to slat deployment Inputs: slat_angle - Slat deflection angle - [rad] sweep_angle - Wing sweep angle - [rad] Outputs: dcl_slat - Lift coefficient increase due to slat Assumptions: if needed """ #unpack sa = slat_angle / Units.deg sw = sweep_angle #---AA241 Method dcl_slat = (sa/23.)*(np.cos(sw))**1.4 * np.cos(sa * Units.deg)**2 #returning dcl_slat return dcl_slat
def rv_pqw(k, p, ecc, nu): """Returns r and v vectors in perifocal frame. """ r_pqw = (np.array([cos(nu), sin(nu), 0 * nu]) * p / (1 + ecc * cos(nu))).T v_pqw = (np.array([-sin(nu), (ecc + cos(nu)), 0]) * sqrt(k / p)).T return r_pqw, v_pqw
def rotateAboutXaxis (x, y, z, alpha, verbose = 0) : if verbose : print "\t x axis rotation of ", alpha, "given ", x[0], y[0], z[0] alpha = alpha*2*np.pi/360. xp = x yp = y*np.cos(alpha) - z*np.sin(alpha) zp = y*np.sin(alpha) + z*np.cos(alpha) return xp,yp,zp
def lomb(t, y, freq): r"""Calculates Lomb periodogram.""" # Sets constants. nfreq = len(freq) fmax, fmin = freq[-1], freq[0] power = np.zeros(nfreq) f4pi = freq * 4 * np.pi pi2 = np.pi * 2. n = len(y) cosarg = np.zeros(n) sinarg = np.zeros(n) argu = np.zeros(n) var = np.cov(y) # Variance. yn = y - y.mean() # Do one Lomb loop. for fi in range(nfreq): sinsum = np.sum(np.sin(f4pi[fi]) * t) cossum = np.sum(np.cos(f4pi[fi]) * t) tau = np.arctan2(sinsum, cossum) argu = pi2 * freq[fi] * (t - tau) cosarg = np.cos(argu) cfi = np.sum(yn * cosarg) cosnorm = np.sum(cosarg ** 2) sinarg = np.sin(argu) sfi = np.sum(yn * sinarg) sinnorm = np.sum(sinarg ** 2) power[fi] = (cfi ** 2 / cosnorm + sfi ** 2 / sinnorm) / 2 * var return power
def sphToCartesian(ra0, ra, dec, r=1) : ra = (ra-(ra0-90))*2*np.pi/360. dec = dec*2*np.pi/360. x = r * np.cos(ra)*np.cos(dec) y = r * np.sin(ra)*np.cos(dec) z = r * np.sin(dec) return x,y,z
def sph2cart(*args): """Convert from spherical coordinates (elevation, azimuth, radius) to cartesian (x,y,z) usage: array3xN[x,y,z] = sph2cart(array3xN[el,az,rad]) OR x,y,z = sph2cart(elev, azim, radius) """ if len(args)==1: #received an Nx3 array elev = args[0][0,:] azim = args[0][1,:] radius = args[0][2,:] returnAsArray = True elif len(args)==3: elev = args[0] azim = args[1] radius = args[2] returnAsArray = False z = radius * numpy.sin(radians(elev)) x = radius * numpy.cos(radians(elev))*numpy.cos(radians(azim)) y = radius * numpy.cos(radians(elev))*numpy.sin(radians(azim)) if returnAsArray: return numpy.asarray([x, y, z]) else: return x, y, z
def rotate (x, y, angle) : angle = angle*2*np.pi/360. rotMatrix = np.array([[np.cos(angle), -np.sin(angle)], [np.sin(angle), np.cos(angle)]], dtype=np.float64) newx = x*rotMatrix[0,0] + y*rotMatrix[0,1] newy = x*rotMatrix[1,0] + y*rotMatrix[1,1] return newx,newy
def __find_index(self, lat, lon, latvar, lonvar, n=1): if self._kdt.get(latvar.name) is None: latvals = latvar[:] * RAD_FACTOR lonvals = lonvar[:] * RAD_FACTOR clat, clon = np.cos(latvals), np.cos(lonvals) slat, slon = np.sin(latvals), np.sin(lonvals) triples = np.array(list(zip(np.ravel(clat * clon), np.ravel(clat * slon), np.ravel(slat)))) self._kdt[latvar.name] = KDTree(triples) del clat, clon del slat, slon del triples if not hasattr(lat, "__len__"): lat = [lat] lon = [lon] lat = np.array(lat) lon = np.array(lon) lat_rad = lat * RAD_FACTOR lon_rad = lon * RAD_FACTOR clat, clon = np.cos(lat_rad), np.cos(lon_rad) slat, slon = np.sin(lat_rad), np.sin(lon_rad) q = np.array([clat * clon, clat * slon, slat]).transpose() dist_sq_min, minindex_1d = self._kdt[latvar.name].query( np.float32(q), k=n ) iy_min, ix_min = np.unravel_index(minindex_1d, latvar.shape) return iy_min, ix_min, dist_sq_min * EARTH_RADIUS
def dist(lon1, lat1, lon2, lat2): R = 6371.004 lon1, lat1 = angle_conversion(lon1), angle_conversion(lat1) lon2, lat2 = angle_conversion(lon2), angle_conversion(lat2) l = R*np.arccos(np.cos(lat1)*np.cos(lat2)*np.cos(lon1-lon2)+\ np.sin(lat1)*np.sin(lat2)) return l
def phase_fit(deg, phase, order, efunc=None): """Fit Legendre polynomials to DISR phase function. phase - scattering phase amplitude deg - scattering angle (degrees) order - maximum order of Legendre polynomial efunc - phase functin error estimate """ from scipy.optimize import leastsq from scipy.interpolate import interp1d residuals = lambda p, y, x, err: (y - legendre_eval(x,p))/err dom = np.cos(deg*pi/180) phase_interp = interp1d(deg, phase, bounds_error=False) degint = np.linspace(0,180,100) xint = np.cos(degint*pi/180.) yint = phase_interp(degint) if not efunc: efunc = lambda x: 0.10 error = efunc(degint)*yint fit_coeffs = leastsq(residuals, np.ones(order+1), args=(yint, xint, error)) return fit_coeffs[0]
def signaltest_xyt1(coastlines=False): """ Generate """ nt = 100 nx = 128 ny = 128 t1d = np.linspace(0, 20 * np.pi, nt) x1d = np.linspace(0, 2 * np.pi, nx) y1d = np.linspace(0, 2 * np.pi, ny) t, y, x = np.meshgrid(t1d, y1d, x1d, indexing='ij') # Create four times modulation with m1 = np.cos(1.5 * t) m2 = np.cos(2 * t) m3 = np.cos(0.5 * t) m4 = np.cos(t) # Create a spatio-temporal gaussian noise noise = 0.8 * np.random.normal(0, 0.2, (nt, ny, nx)) # Create four spatial patterns z1 = np.sin(x) * np.sin(y) * m1 z2 = np.sin(2.5 * x) * np.sin(y) * m2 z3 = np.sin(x) * np.sin(2.5 * y) * m3 z4 = np.sin(2.5 * x) * np.sin(2.5 * y) * m4 z = z1 + z2 + z3 + z4 + noise if coastlines: z[:, 0:ny/4, 0:nx/4] = np.nan return xr.DataArray(z, coords=[t1d, y1d, x1d], dims=['time', 'y', 'x'], name='signal')
def array2raster(newRasterfn,rasterOrigin,pixelWidth,pixelHeight, data, variables, rotate=0): """Convert data dictionary (of arrays) into a multiband GeoTiff :param newRasterfn: filename to save to :param rasterOrigin: location of top left corner :param pixelWidth: e-w pixel size :param pixelHeight: n-s pixel size :param data: dictionary containing the data arrays :param variables: list of which keys from the dictionary to output :param rotate: Optional rotation angle (in radians) """ cols = len(data['longitude']) rows = len(data['latitude']) originX = rasterOrigin[0] originY = rasterOrigin[1] we_res = np.cos(rotate) * pixelWidth rotX = np.sin(rotate) * pixelWidth rotY = -np.sin(rotate) * pixelHeight ns_res = np.cos(rotate) * pixelHeight driver = gdal.GetDriverByName('GTiff') nbands = len(variables) outRaster = driver.Create(newRasterfn, cols, rows, nbands, gdal.GDT_Float32) outRaster.SetGeoTransform((originX, we_res, rotX, originY, rotY, ns_res)) for band,key in enumerate(variables, 1): outband = outRaster.GetRasterBand(band) outband.SetNoDataValue(0) outband.WriteArray(data[key]) outband.FlushCache() outRasterSRS = osr.SpatialReference() outRasterSRS.ImportFromEPSG(4326) outRaster.SetProjection(outRasterSRS.ExportToWkt())
def kdtree_fast(latvar,lonvar,lat0,lon0): ''' :param latvar: :param lonvar: :param lat0: :param lon0: :return: ''' rad_factor = pi/180.0 # for trignometry, need angles in radians # Read latitude and longitude from file into numpy arrays latvals = latvar[:] * rad_factor lonvals = lonvar[:] * rad_factor ny,nx = latvals.shape clat,clon = cos(latvals),cos(lonvals) slat,slon = sin(latvals),sin(lonvals) # Build kd-tree from big arrays of 3D coordinates triples = list(zip(ravel(clat*clon), ravel(clat*slon), ravel(slat))) kdt = cKDTree(triples) lat0_rad = lat0 * rad_factor lon0_rad = lon0 * rad_factor clat0,clon0 = cos(lat0_rad),cos(lon0_rad) slat0,slon0 = sin(lat0_rad),sin(lon0_rad) dist_sq_min, minindex_1d = kdt.query([clat0*clon0, clat0*slon0, slat0]) iy_min, ix_min = unravel_index(minindex_1d, latvals.shape) return iy_min,ix_min
def spherical_to_cartesian(lons, lats, depths): """ Return the position vectors (in Cartesian coordinates) of list of spherical coordinates. For equations see: http://mathworld.wolfram.com/SphericalCoordinates.html. Parameters are components of spherical coordinates in a form of scalars, lists or numpy arrays. ``depths`` can be ``None`` in which case it's considered zero for all points. :returns: ``numpy.array`` of 3d vectors representing points' coordinates in Cartesian space. The array has the same shape as parameter arrays. In particular it means that if ``lons`` and ``lats`` are scalars, the result is a single 3d vector. Vector of length ``1`` represents distance of 1 km. See also :func:`cartesian_to_spherical`. """ phi = numpy.radians(lons) theta = numpy.radians(lats) if depths is None: rr = EARTH_RADIUS else: rr = EARTH_RADIUS - numpy.array(depths) cos_theta_r = rr * numpy.cos(theta) xx = cos_theta_r * numpy.cos(phi) yy = cos_theta_r * numpy.sin(phi) zz = rr * numpy.sin(theta) vectors = numpy.array([xx.transpose(), yy.transpose(), zz.transpose()]) \ .transpose() return vectors
def random_rotation(x, rg, row_axis=1, col_axis=2, channel_axis=0, fill_mode='nearest', cval=0.): """Performs a random rotation of a Numpy image tensor. # Arguments x: Input tensor. Must be 3D. rg: Rotation range, in degrees. row_axis: Index of axis for rows in the input tensor. col_axis: Index of axis for columns in the input tensor. channel_axis: Index of axis for channels in the input tensor. fill_mode: Points outside the boundaries of the input are filled according to the given mode (one of `{'constant', 'nearest', 'reflect', 'wrap'}`). cval: Value used for points outside the boundaries of the input if `mode='constant'`. # Returns Rotated Numpy image tensor. """ theta = np.pi / 180 * np.random.uniform(-rg, rg) rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1]]) h, w = x.shape[row_axis], x.shape[col_axis] transform_matrix = transform_matrix_offset_center(rotation_matrix, h, w) x = apply_transform(x, transform_matrix, channel_axis, fill_mode, cval) return x
def tunnel_fast(latvar,lonvar,lat0,lon0): ''' Find closest point in a set of (lat,lon) points to specified point latvar - 2D latitude variable from an open netCDF dataset lonvar - 2D longitude variable from an open netCDF dataset lat0, lon0 - query point Returns iy,ix such that the square of the tunnel distance between (latval[iy,ix], lonval[iy,ix]) and (lat0, lon0) is minimum. :param latvar: :param lonvar: :param lat0: :param lon0: :return: ''' rad_factor = pi/180.0 # for trignometry, need angles in radians # Read latitude and longitude from file into numpy arrays latvals = latvar[:] * rad_factor lonvals = lonvar[:] * rad_factor ny,nx = latvals.shape lat0_rad = lat0 * rad_factor lon0_rad = lon0 * rad_factor # Compute numpy arrays for all values, no loops clat,clon = cos(latvals),cos(lonvals) slat,slon = sin(latvals),sin(lonvals) delX = cos(lat0_rad)*cos(lon0_rad) - clat*clon delY = cos(lat0_rad)*sin(lon0_rad) - clat*slon delZ = sin(lat0_rad) - slat; dist_sq = delX**2 + delY**2 + delZ**2 minindex_1d = dist_sq.argmin() # 1D index of minimum element iy_min,ix_min = unravel_index(minindex_1d, latvals.shape) return iy_min,ix_min
def calc_Tb(thetak=np.pi/3., phik=np.pi/8., thetan=np.pi/3., phin=np.pi/4., delta=0., Ts=11.1, Tg=57.23508, z=20, verbose=False, xalpha=34.247221, xc=0.004176, xB=0.365092, x1s=1.): """ Calculates brightness-temperature fluctuation T[K] from eq 1 of Paper II. NOTE: Magnetic-field direction is along the z-axis! It takes x's (all unitless), temperatures in [K], and angles in [rad].""" k_dot_n = np.cos(thetan)*np.cos(thetak) + np.sin(thetan)*np.sin(thetak)*np.cos(phin)*np.cos(phik) + np.sin(thetan)*np.sin(thetak)*np.sin(phin)*np.sin(phik) summ = 0. for i,m in enumerate( np.array([-2,-1,0,1,2]) ): summand = Y2( m,thetak,phik ) * np.conjugate( Y2( m,thetan,phin ) ) / (1. + xalpha + xc - 1j*m*xB) summ += summand.real first_term = 1 + delta + delta*k_dot_n**2 second_term = 1 + 2.*delta + 2.*delta*k_dot_n**2 - delta*4.*np.pi/75.*summ res = x1s * ( 1 - Tg/Ts ) * np.sqrt( (1 + z)/10. ) * ( 26.4 * first_term - 0.128 * x1s * ( Tg/Ts ) * np.sqrt( (1 + z)/10. ) * second_term) if verbose: print '\n' print 'xalpha = %f' % xalpha print 'xc = %f' % xc print 'xB = %f' % xB print 'k_dot_n=%f' % k_dot_n print 'summ=%f' % summ print 'first=%f' % 26.4*first_term print 'second=%f' % second_term return res/1000. #this is to make it to K from mK.
def get_new_cell(self): """Returns new basis vectors""" a = np.sqrt(self.a) b = np.sqrt(self.b) c = np.sqrt(self.c) ad = self.atoms.cell[0] / np.linalg.norm(self.atoms.cell[0]) Z = np.cross(self.atoms.cell[0], self.atoms.cell[1]) Z /= np.linalg.norm(Z) X = ad - np.dot(ad, Z) * Z X /= np.linalg.norm(X) Y = np.cross(Z, X) alpha = np.arccos(self.x / (2 * b * c)) beta = np.arccos(self.y / (2 * a * c)) gamma = np.arccos(self.z / (2 * a * b)) va = a * np.array([1, 0, 0]) vb = b * np.array([np.cos(gamma), np.sin(gamma), 0]) cx = np.cos(beta) cy = (np.cos(alpha) - np.cos(beta) * np.cos(gamma)) \ / np.sin(gamma) cz = np.sqrt(1. - cx * cx - cy * cy) vc = c * np.array([cx, cy, cz]) abc = np.vstack((va, vb, vc)) T = np.vstack((X, Y, Z)) return np.dot(abc, T)
def rotateAboutZaxis (x, y, z, alpha, verbose = 0) : if verbose : print "\t z axis rotation of ", alpha, "given ", x[0], y[0], z[0] alpha = alpha*2*np.pi/360. xp = x*np.cos(alpha) - y*np.sin(alpha) yp = x*np.sin(alpha) + y*np.cos(alpha) zp = z return xp,yp,zp
def igrf_geo(r, theta, phi): """ Calculates components of the main (internal) geomagnetic field in the spherical geographic (geocentric) coordinate system, using IAGA international geomagnetic reference model coefficients (e.g., http://www.ngdc.noaa.gov/iaga/vmod/igrf.html, revised: 22 march, 2005) Before the first call of this subroutine, or if the time was changed, the model coefficients should be updated by calling the subroutine recalc Python version by Sheng Tian :param r: spherical geographic (geocentric) coordinates: radial distance r in units Re=6371.2 km :param theta: colatitude theta in radians :param phi: longitude phi in radians :return: br, btheta, bphi. Spherical components of the main geomagnetic field in nanotesla (positive br outward, btheta southward, bphi eastward) """ # common /geopack2/ g(105),h(105),rec(105) global g, h, rec ct = np.cos(theta) st = np.sin(theta) minst = 1e-5 if np.abs(st) < minst: smlst = True else: smlst = False # In this new version, the optimal value of the parameter nm (maximal order of the spherical # harmonic expansion) is not user-prescribed, but calculated inside the subroutine, based # on the value of the radial distance r: irp3 = np.int64(r + 2) nm = np.int64(3 + 30 / irp3) if nm > 13: nm = 13 k = nm + 1 # r dependence is encapsulated here. a = np.empty(k) b = np.empty(k) ar = 1 / r # a/r a[0] = ar * ar # a[n] = (a/r)^(n+2). b[0] = a[0] # b[n] = (n+1)(a/r)^(n+2) for n in range(1, k): a[n] = a[n - 1] * ar b[n] = a[n] * (n + 1) # t - short for theta, f - short for phi. br, bt, bf = [0.] * 3 d, p = [0., 1] # m = 0. P^n,0 m = 0 smf, cmf = [0., 1] p1, d1, p2, d2 = [p, d, 0., 0] l0 = 0 mn = l0 for n in range(m, k): w = g[mn] * cmf + h[mn] * smf br += b[n] * w * p1 # p1 is P^n,m. bt -= a[n] * w * d1 # d1 is dP^n,m/dt. xk = rec[mn] # Eq 16c and its derivative on theta. d0 = ct * d1 - st * p1 - xk * d2 # dP^n,m/dt = ct*dP^n-1,m/dt - st*P_n-1,m - K^n,m*dP^n-2,m/dt p0 = ct * p1 - xk * p2 # P^n,m = ct*P^n-1,m - K^n,m*P^n-2,m d2, p2, d1 = [d1, p1, d0] p1 = p0 mn += n + 1 # Eq 16b and its derivative on theta. d = st * d + ct * p # dP^m,m/dt = st*dP^m-1,m-1/dt + ct*P^m-1,m-1 p = st * p # P^m,m = st*P^m-1,m-1 # Similarly for P^n,m l0 = 0 for m in range(1, k): # sum over m smf = np.sin(m * phi) # sin(m*phi) cmf = np.cos(m * phi) # cos(m*phi) p1, d1, p2, d2 = [p, d, 0., 0] tbf = 0. l0 += m + 1 mn = l0 for n in range(m, k): # sum over n w = g[mn] * cmf + h[mn] * smf # [g^n,m*cos(m*phi)+h^n,m*sin(m*phi)] br += b[n] * w * p1 bt -= a[n] * w * d1 tp = p1 if smlst: tp = d1 tbf += a[n] * (g[mn] * smf - h[mn] * cmf) * tp xk = rec[mn] d0 = ct * d1 - st * p1 - xk * d2 # dP^n,m/dt = ct*dP^n-1,m/dt - st*P_n-1,m - K^n,m*dP^n-2,m/dt p0 = ct * p1 - xk * p2 # P^n,m = ct*P^n-1,m - K^n,m*P^n-2,m d2, p2, d1 = [d1, p1, d0] p1 = p0 mn += n + 1 d = st * d + ct * p p = st * p # update B_phi. tbf *= m bf += tbf if smlst: if ct < 0.: bf = -bf else: bf /= st return br, bt, bf
def get_full_state(self): qpos = np.copy(self.sim.qpos()) qvel = np.copy(self.sim.qvel()) # ref_pos, ref_vel = self.get_ref_state(self.phase + self.phase_add) ref_pos, ref_vel = self.get_ref_state(0) # TODO: maybe convert to set subtraction for clarity # {i for i in range(35)} - # {0, 10, 11, 12, 13, 17, 18, 19, 24, 25, 26, 27, 31, 32, 33} # this is everything except pelvis x and qw, achilles rod quaternions, # and heel spring/foot crank/plantar rod angles # note: x is forward dist, y is lateral dist, z is height # makes sense to always exclude x because it is in global coordinates and # irrelevant to phase-based control. Z is inherently invariant to # trajectory despite being global coord. Y is only invariant to straight # line trajectories. # CLOCK BASED (NO TRAJECTORY) if self.clock_based: clock = [np.sin(2 * np.pi * self.phase / (self.phaselen+1)), np.cos(2 * np.pi * self.phase / (self.phaselen+1))] ext_state = np.concatenate((clock, [self.speed])) # ASLIP TRAJECTORY elif self.aslip_traj and not self.clock_based: if(self.phase == 0): ext_state = np.concatenate(get_ref_aslip_ext_state(self, self.phaselen - 1)) else: ext_state = np.concatenate(get_ref_aslip_ext_state(self, self.phase)) # OTHER TRAJECTORY else: ext_state = np.concatenate([ref_pos[self.pos_index], ref_vel[self.vel_index]]) # Update orientation new_orient = self.cassie_state.pelvis.orientation[:] new_translationalVelocity = self.cassie_state.pelvis.translationalVelocity[:] # new_translationalVelocity[0:2] += self.com_vel_offset quaternion = euler2quat(z=self.orient_add, y=0, x=0) iquaternion = inverse_quaternion(quaternion) new_orient = quaternion_product(iquaternion, self.cassie_state.pelvis.orientation[:]) if new_orient[0] < 0: new_orient = -new_orient new_translationalVelocity = rotate_by_quaternion(self.cassie_state.pelvis.translationalVelocity[:], iquaternion) motor_pos = self.cassie_state.motor.position[:] joint_pos = np.concatenate([self.cassie_state.joint.position[0:2], self.cassie_state.joint.position[3:5]]) joint_vel = np.concatenate([self.cassie_state.joint.velocity[0:2], self.cassie_state.joint.velocity[0:2]]) if self.joint_rand: motor_pos += self.joint_offsets[0:10] joint_pos += self.joint_offsets[10:14] # Use state estimator robot_state = np.concatenate([ self.cassie_state.leftFoot.position[:], # left foot position self.cassie_state.rightFoot.position[:], # right foot position new_orient, # pelvis orientation motor_pos, # actuated joint positions self.cassie_state.pelvis.rotationalVelocity[:], # pelvis rotational velocity self.cassie_state.motor.velocity[:], # actuated joint velocities joint_pos, # unactuated joint positions joint_vel # unactuated joint velocities ]) #TODO: Set up foot position for non state est if self.state_est: state = np.concatenate([robot_state, ext_state]) else: state = np.concatenate([qpos[self.pos_index], qvel[self.vel_index], ext_state]) self.state_history.insert(0, state) self.state_history = self.state_history[:self.history+1] return np.concatenate(self.state_history)
def A(q): return np.array([[np.sin(q[0]), 0], [np.cos(q[1]), q[0] + q[1]]])
def f(u, t): x, dxdt = u return [dxdt, cos(t)**3 - sin(t) - x - dxdt - x**3]
def u_exact(t): return cos(t)
def test_motion(tb, handles, env, apron, ppe_loc, ppe_trans, apron_robot): shoulder_z_idx = 1 elbow_z_idx = 3 wrist_x_idx = 4 right_angles = [0, np.pi * 0.4, 0, np.pi * 0.6, np.pi * 0.3, 0, 0] left_angles = [0, np.pi * 0.4, 0, np.pi * 0.6, np.pi * 0.3, 0, 0] torso_angles = [0, 0, 0, 0, 0, 0, np.pi, 0, 0] #pull forward traj_len = 4 # traj_len = 3 shoulder_angle_inc = 0 elbow_angle_inc = -np.pi * 0.01 rhand = tb.human.GetLink('rHand') lhand = tb.human.GetLink('lHand') prev_rtt = rhand.GetTransform() prev_rt1 = np.dot(prev_rtt, rhand.GetGeometries()[0].GetTransform())[0:3, 3] prev_ltt = lhand.GetTransform() prev_lt1 = np.dot(prev_ltt, lhand.GetGeometries()[0].GetTransform())[0:3, 3] prev_ppet = (prev_rt1 + prev_lt1) * 0.5 prev_apron_trans = apron.GetTransform() prev_apron_loc = prev_ppet prev_apron_trans[0:3, 3] = prev_apron_loc # apron.SetTransform(prev_apron_trans) apron_robot.RayCollisionCheckWithMove(prev_apron_trans) prev_state = apron_robot.out_of_collision index = 0 for i in range(0, traj_len): index += 1 right_angles[shoulder_z_idx] += shoulder_angle_inc right_angles[elbow_z_idx] += elbow_angle_inc left_angles[shoulder_z_idx] += shoulder_angle_inc left_angles[elbow_z_idx] += elbow_angle_inc tb.MoveHumanUpperSingle(right_angles, left_angles) rt = rhand.GetTransform()[0:3, 3] rtt = rhand.GetTransform() rt1 = np.dot(rtt, rhand.GetGeometries()[0].GetTransform())[0:3, 3] lt = lhand.GetTransform()[0:3, 3] ltt = lhand.GetTransform() lt1 = np.dot(ltt, lhand.GetGeometries()[0].GetTransform())[0:3, 3] ppet = (rt1 + lt1) * 0.5 d_ppet = ppet - prev_ppet prev_ppet = ppet apron_trans = apron.GetTransform() #apron_loc = apron_trans[0:3,3] + d_ppet apron_loc = ppet apron_trans[0:3, 3] = apron_loc # apron.SetTransform(apron_trans) apron_robot.RayCollisionCheckWithMove(apron_trans) if (apron_robot.out_of_collision != prev_state): tb.state_change_index = index prev_state = apron_robot.out_of_collision ppe_loc.append(ppet) apron_trans = apron.GetTransform() rot_mat = np.array([[np.cos(np.pi), -np.sin(np.pi), 0], [np.sin(np.pi), np.cos(np.pi), 0], [0, 0, 1]]) apron_trans[0:3, 0:3] = np.dot(apron_trans[0:3, 0:3], rot_mat) ppe_trans.append(apron_trans) #ppet = apron.GetTransform()[0:3,3] if (i == 0): handles.append( env.plot3(points=array(((ppet[0], ppet[1], ppet[2]))), pointsize=5.0, colors=array(((1, 0.5, 0))))) else: handles.append( env.plot3(points=array(((ppet[0], ppet[1], ppet[2]))), pointsize=5.0, colors=array(((1, 0, 0))))) #pull up traj_len = 10 shoulder_angle_inc = np.pi * 0.03 elbow_angle_inc = -np.pi * 0.035 rhand = tb.human.GetLink('rHand') lhand = tb.human.GetLink('lHand') prev_rtt = rhand.GetTransform() prev_rt1 = np.dot(prev_rtt, rhand.GetGeometries()[0].GetTransform())[0:3, 3] prev_ltt = lhand.GetTransform() prev_lt1 = np.dot(prev_ltt, lhand.GetGeometries()[0].GetTransform())[0:3, 3] prev_ppet = (prev_rt1 + prev_lt1) * 0.5 prev_apron_trans = apron.GetTransform() prev_apron_loc = prev_ppet prev_apron_trans[0:3, 3] = prev_apron_loc apron.SetTransform(prev_apron_trans) if (apron_robot.out_of_collision != prev_state): tb.state_change_index = i prev_state = apron_robot.out_of_collision for i in range(0, traj_len): index += 1 right_angles[shoulder_z_idx] += shoulder_angle_inc right_angles[elbow_z_idx] += elbow_angle_inc left_angles[shoulder_z_idx] += shoulder_angle_inc left_angles[elbow_z_idx] += elbow_angle_inc tb.MoveHumanUpperSingle(right_angles, left_angles) rt = rhand.GetTransform()[0:3, 3] rtt = rhand.GetTransform() rt1 = np.dot(rtt, rhand.GetGeometries()[0].GetTransform())[0:3, 3] lt = lhand.GetTransform()[0:3, 3] ltt = lhand.GetTransform() lt1 = np.dot(ltt, lhand.GetGeometries()[0].GetTransform())[0:3, 3] ppet = (rt1 + lt1) * 0.5 d_ppet = ppet - prev_ppet prev_ppet = ppet apron_trans = apron.GetTransform() #apron_loc = apron_trans[0:3,3] + d_ppet apron_loc = ppet apron_trans[0:3, 3] = apron_loc # apron.SetTransform(apron_trans) apron_robot.RayCollisionCheckWithMove(apron_trans) if (apron_robot.out_of_collision != prev_state): tb.state_change_index = index prev_state = apron_robot.out_of_collision ppe_loc.append(ppet) apron_trans = apron.GetTransform() rot_mat = np.array([[np.cos(np.pi), -np.sin(np.pi), 0], [np.sin(np.pi), np.cos(np.pi), 0], [0, 0, 1]]) apron_trans[0:3, 0:3] = np.dot(apron_trans[0:3, 0:3], rot_mat) ppe_trans.append(apron_trans) #ppet = apron.GetTransform()[0:3,3] handles.append( env.plot3(points=array(((ppet[0], ppet[1], ppet[2]))), pointsize=5.0, colors=array(((1, 0, 0))))) #pull down traj_len = 8 shoulder_angle_inc = 0 elbow_angle_inc = -np.pi * 0.02 prev_rtt = rhand.GetTransform() prev_rt1 = np.dot(prev_rtt, rhand.GetGeometries()[0].GetTransform())[0:3, 3] prev_ltt = lhand.GetTransform() prev_lt1 = np.dot(prev_ltt, lhand.GetGeometries()[0].GetTransform())[0:3, 3] prev_ppet = (prev_rt1 + prev_lt1) * 0.5 prev_apron_trans = apron.GetTransform() prev_apron_loc = prev_ppet prev_apron_trans[0:3, 3] = prev_apron_loc # apron.SetTransform(prev_apron_trans) apron_robot.RayCollisionCheckWithMove(prev_apron_trans) for i in range(0, traj_len): index += i right_angles[shoulder_z_idx] += shoulder_angle_inc right_angles[elbow_z_idx] += elbow_angle_inc left_angles[shoulder_z_idx] += shoulder_angle_inc left_angles[elbow_z_idx] += elbow_angle_inc tb.MoveHumanUpperSingle(right_angles, left_angles) rt = rhand.GetTransform()[0:3, 3] rtt = rhand.GetTransform() rt1 = np.dot(rtt, rhand.GetGeometries()[0].GetTransform())[0:3, 3] lt = lhand.GetTransform()[0:3, 3] ltt = lhand.GetTransform() lt1 = np.dot(ltt, lhand.GetGeometries()[0].GetTransform())[0:3, 3] ppet = (rt1 + lt1) * 0.5 d_ppet = ppet - prev_ppet prev_ppet = ppet apron_trans = apron.GetTransform() #apron_loc = apron_trans[0:3,3] + d_ppet apron_loc = ppet apron_trans[0:3, 3] = apron_loc # apron.SetTransform(apron_trans) apron_robot.RayCollisionCheckWithMove(apron_trans) if (apron_robot.out_of_collision != prev_state): tb.state_change_index = index prev_state = apron_robot.out_of_collision ppe_loc.append(ppet) apron_trans = apron.GetTransform() rot_mat = np.array([[np.cos(np.pi), -np.sin(np.pi), 0], [np.sin(np.pi), np.cos(np.pi), 0], [0, 0, 1]]) apron_trans[0:3, 0:3] = np.dot(apron_trans[0:3, 0:3], rot_mat) ppe_trans.append(apron_trans) #ppet = apron.GetTransform()[0:3,3] handles.append( env.plot3(points=array(((ppet[0], ppet[1], ppet[2]))), pointsize=5.0, colors=array(((1, 0, 0))))) if (i > 3): elbow_angle_inc = np.pi * 0.03 shoulder_angle_inc = -np.pi * 0.04 direction = [0, 1, 0] angle = np.pi * 0.5 rot_mat = transformations.rotation_matrix(angle, direction) idx = 0 for ppe_trans_point in ppe_trans: ppe_trans_point[0:3, 0:3] = np.dot(rot_mat[0:3, 0:3], ppe_trans_point[0:3, 0:3]) ppe_trans[idx] = ppe_trans_point from_vec = ppe_trans_point[0:3, 3] to_vec_1 = from_vec + 0.05 * (ppe_trans_point[0:3, 0]) to_vec_2 = from_vec + 0.05 * (ppe_trans_point[0:3, 1]) to_vec_3 = from_vec + 0.05 * (ppe_trans_point[0:3, 2]) idx += 1 handles.append( env.plot3(points=ppe_trans[tb.state_change_index][0:3, 3], pointsize=5.0, colors=array(((0, 1, 0)))))
def __clockwise_rotation__(self, coordinate, theta): a = np.cos(theta) b = np.sin(theta) rotation = np.array([[a, -1 * b], [b, a]]) coordinate = coordinate.T return np.dot(rotation, coordinate).T
element_list = [] count = 0 for k,z in enumerate(z_list): number_in_layer = 1 for seg in range(segment+1): for i,r in enumerate(r_interpolated_list[seg]): node_list.append({}) node_list[count]['node_layer'] = k node_list[count]['node_row'] = seg node_list[count]['r'] = r theta = theta_list[i] + 2*np.pi/n*k if theta >= 2*np.pi: theta -= 2*np.pi node_list[count]['theta'] = theta node_list[count]['x'] = r*np.cos(theta) node_list[count]['y'] = r*np.sin(theta) node_list[count]['z'] = z number_in_layer = int(seg*m*4 + round(theta/(np.pi/m/2)) + 1) if number_in_layer > (segment+1)*m*4: number_in_layer -= (segment+1)*m*4 node_list[count]['node_number_in_layer'] = number_in_layer node_list[count]['node_column'] = (number_in_layer-1) % (m*4) node_list[count]['node_number'] = k*(segment+1)*m*4 + number_in_layer count += 1 count = 0 for k,z in enumerate(z_list[:-1]): element_in_layer = 1 for seg in range(segment): for i,theta in enumerate(theta_list):
def X(t, p=365.25, n=10): x = 2 * np.pi * (np.arange(n) + 1) * t[:, None] / p return np.concatenate((np.cos(x), np.sin(x)), axis=1)
def step(self, action, return_omniscient_state=False, f_term=0): self.l_foot_orient = 0 self.r_foot_orient = 0 self.l_foot_cost = 0 self.r_foot_cost = 0 self.l_foot_cost_even = 0 self.r_foot_cost_even = 0 self.l_foot_cost_smooth = 0 self.r_foot_cost_smooth = 0 self.l_foot_cost_var = 0 self.r_foot_cost_var = 0 self.l_foot_cost_clock = 0 self.r_foot_cost_clock = 0 self.torque_cost = 0 self.hiproll_cost = 0 self.hiproll_act = 0 self.hipyaw_vel = 0 self.hipyaw_act = 0 foot_pos = np.zeros(6) self.smooth_cost = 0 self.pel_stable = 0 self.left_rollyaw_torque_cost = 0 self.right_rollyaw_torque_cost = 0 # Reward clocks one2one_clock = 0.5*(np.cos(2*np.pi/(self.phaselen+1)*self.phase) + 1) zero2zero_clock = 0.5*(np.cos(2*np.pi/(self.phaselen+1)*(self.phase-(self.phaselen+1)/2)) + 1) one2one_var, zero2zero_var = 1, 0#self.clock_fn(self.swing_ratio, self.phase, self.phaselen+1) for _ in range(self.simrate): self.step_simulation(action) qvel = self.sim.qvel() # Foot Orientation Cost self.l_foot_orient += 20*(1 - np.inner(self.neutral_foot_orient, self.sim.xquat("left-foot")) ** 2) self.r_foot_orient += 20*(1 - np.inner(self.neutral_foot_orient, self.sim.xquat("right-foot")) ** 2) # Hip Yaw velocity cost self.hiproll_cost += (np.abs(qvel[6]) + np.abs(qvel[19])) / 3 self.hipyaw_vel += (np.abs(qvel[7]) + np.abs(qvel[20])) if self.prev_action is not None: self.hiproll_act += 2*np.linalg.norm(self.prev_action[[0, 5]] - action[[0, 5]]) self.hipyaw_act += 2*np.linalg.norm(self.prev_action[[1, 6]] - action[[1, 6]]) else: self.hiproll_act += 0 self.hipyaw_act += 0 # Stable Pelvis cost self.pel_stable += 0.05*(np.abs(self.cassie_state.pelvis.rotationalVelocity[:]).sum() + np.abs(self.cassie_state.pelvis.translationalAcceleration[:]).sum()) # Foot height cost des_height = 0.15 self.sim.foot_pos(foot_pos) foot_forces = self.sim.get_foot_forces() r_ground_cost = foot_pos[5]**2 + np.linalg.norm(self.rfoot_vel) r_height_cost = 40*(des_height - foot_pos[5])**2 r_td_cost = 40*(foot_pos[5])**2 * self.rfoot_vel[2]**2 l_ground_cost = foot_pos[2]**2 + np.linalg.norm(self.lfoot_vel) l_height_cost = 40*(des_height - foot_pos[2])**2 l_td_cost = 40*(foot_pos[2])**2 * self.lfoot_vel[2]**2 # Right foot cost # if foot_forces[0] == 0: # # If left foot in air, then keep right foot in place and on ground # self.r_foot_cost += r_ground_cost # else: # # Otherwise, left foot is on ground and can lift right foot up. # if not self.r_high: # # If right foot not reach desired height yet, then use distance cost # self.r_foot_cost += r_height_cost # else: # # Otherwise right foot reached height, bring back down slowly. Weight distance by z vel # self.r_foot_cost += r_td_cost # # Left foot cost # if foot_forces[1] == 0: # # If right foot in air, then keep left foot in place and on ground # self.l_foot_cost += l_ground_cost # else: # # Otherwise, right foot is on ground and can lift left foot up. # if not self.r_high: # # If left foot not reach desired height yet, then use distance cost # self.l_foot_cost += l_height_cost # else: # # Otherwise left foot reached height, bring back down slowly. Weight distance by z vel # self.l_foot_cost += l_td_cost # # Foot height cost even # # For first half of cycle, lift up left foot and keep right foot on ground. # if self.phase < self.phaselen / 2.0: # self.r_foot_cost_even += r_ground_cost # if not self.l_high: # # If left foot not reach desired height yet, then use distance cost # self.l_foot_cost_even += l_height_cost # else: # # Otherwise left foot reached height, bring back down slowly. Weight distance by z vel # self.l_foot_cost_even += l_td_cost # # For second half of cycle, lift up right foot and keep left foot on ground # else: # self.l_foot_cost_even += l_ground_cost # if not self.r_high: # # If right foot not reach desired height yet, then use distance cost # self.r_foot_cost_even += r_height_cost # else: # # Otherwise right foot reached height, bring back down slowly. Weight distance by z vel # self.r_foot_cost_even += r_td_cost # Foot height cost smooth # Left foot starts on ground and then lift up and then back on ground. # Right foot starts in air and then put on ground and then lift back up. self.l_foot_cost_smooth += zero2zero_clock*l_height_cost + one2one_clock*l_ground_cost self.r_foot_cost_smooth += one2one_clock*r_height_cost + zero2zero_clock*r_ground_cost self.l_foot_cost_var += zero2zero_var*l_height_cost + one2one_var*l_ground_cost self.r_foot_cost_var += one2one_var*r_height_cost + zero2zero_var*r_ground_cost if self.load_clock: l_clock = self.left_clock(self.phase) r_clock = self.right_clock(self.phase) self.l_foot_cost_clock += l_clock*l_height_cost + (1-l_clock)*l_ground_cost self.r_foot_cost_clock += r_clock*r_height_cost + (1-r_clock)*r_ground_cost # Torque costs curr_torques = np.array(self.cassie_state.motor.torque[:]) if self.prev_torque is not None: self.smooth_cost += 0.0001*np.linalg.norm(np.square(curr_torques - self.prev_torque)) else: self.smooth_cost += 0 self.prev_torque = curr_torques self.torque_cost += 0.00006*np.linalg.norm(np.square(curr_torques)) self.left_rollyaw_torque_cost += zero2zero_clock*0.006*np.linalg.norm(np.square(curr_torques[[0, 1]])) self.right_rollyaw_torque_cost += one2one_clock*0.006*np.linalg.norm(np.square(curr_torques[[5, 6]])) self.l_foot_orient /= self.simrate self.r_foot_orient /= self.simrate self.l_foot_cost /= self.simrate self.r_foot_cost /= self.simrate self.l_foot_cost_even /= self.simrate self.r_foot_cost_even /= self.simrate self.l_foot_cost_smooth /= self.simrate self.r_foot_cost_smooth /= self.simrate self.l_foot_cost_var /= self.simrate self.r_foot_cost_var /= self.simrate self.l_foot_cost_clock /= self.simrate self.r_foot_cost_clock /= self.simrate self.smooth_cost /= self.simrate self.torque_cost /= self.simrate self.hiproll_cost /= self.simrate self.hiproll_act /= self.simrate self.hipyaw_vel /= self.simrate self.hipyaw_act /= self.simrate self.pel_stable /= self.simrate self.left_rollyaw_torque_cost /= self.simrate self.right_rollyaw_torque_cost /= self.simrate # print("hipyaw cost: ", self.hipyaw_cost) # print("torquecost: ", self.torque_cost) # print("hiproll act cost: ", self.hiproll_act) height = self.sim.qpos()[2] self.curr_action = action self.time += 1 self.phase += self.phase_add if (self.aslip_traj and self.phase >= self.phaselen) or self.phase > self.phaselen: # self.phase = 0 self.phase -= self.phaselen self.counter += 1 # Early termination done = not(height > 0.4 and height < 3.0) reward = self.compute_reward(action) # reset avg foot quaternion self.avg_lfoot_quat = np.zeros(4) self.avg_rfoot_quat = np.zeros(4) # update previous action self.prev_action = action # self.update_speed(self.speed_schedule[min(int(np.floor(self.time/self.speed_time)), 2)]) # if self.time > self.orient_time: # self.orient_add = self.orient_command # TODO: make 0.3 a variable/more transparent if reward < 0.4:# or np.exp(-self.l_foot_cost_smooth) < f_term or np.exp(-self.r_foot_cost_smooth) < f_term: done = True if return_omniscient_state: return self.get_full_state(), self.get_omniscient_state(), reward, done, {} else: return self.get_full_state(), reward, done, {}
def sun(ut): """ Calculates four quantities necessary for coordinate transformations which depend on sun position (and, hence, on universal time and season) Based on http://aa.usno.navy.mil/faq/docs/SunApprox.php and http://aa.usno.navy.mil/faq/docs/GAST.php :param ut: ut sec, can be array. :return: gst,slong,srasn,sdec. gst - greenwich mean sidereal time, slong - longitude along ecliptic srasn - right ascension, sdec - declination of the sun (radians) obliq - mean oblique of the ecliptic (radian) Python version by Sheng Tian """ twopi = 2 * np.pi jd2000 = 2451545.0 # convert to Julian date. t0_jd = 2440587.5 # in day, 0 of Julian day. secofdaygsw_x = 1. / 86400 # 1/sec of day. t_jd = ut * secofdaygsw_x + t0_jd # d = mjd - mj2000. d = t_jd - jd2000 d = np.squeeze(d) # mean obliquity of the ecliptic, e. # e = 23.439 - 0.00000036*d ; in degree. e = 0.4090877233749509 - 6.2831853e-9 * d # mean anomaly of the Sun, g. # g = 357.529 + 0.98560028*d ; in degree. g = 6.2400582213628066 + 0.0172019699945780 * d g = np.mod(g, twopi) # mean longitude of the Sun, q. # q = 280.459 + 0.98564736*d ; in degree. q = 4.8949329668507771 + 0.0172027916955899 * d q = np.mod(q, twopi) # geocentric apparent ecliptic longitude, l. # l = q + 1.915 sin g + 0.020 sin 2g ; in degree. l = q + 0.0334230551756914 * np.sin(g) + 0.0003490658503989 * np.sin(2 * g) # vl - q, mean longitude of the sun. # vl = np.mod(279.696678+0.9856473354*dj,360.)/rad # q = np.mod(4.881627937990388+0.01720279126623886*dj, twopi) # g, mean anomaly of the sun. # g = np.mod(358.475845+0.985600267*dj,360.)/rad # g = np.mod(6.256583784118852+0.017201969767685215*dj, twopi) # slong - l, geocentric apparent ecliptic longitude. # slong = (vl + (1.91946-0.004789*t)*sin(g) + 0.020094*sin(2*g))/rad # l = q+(0.03350089686033036-2.2884002156881157e-09*dj)*np.sin(g)+0.0003507064598957406*np.sin(2*g) # l = np.mod(l, twopi) # obliq - e, mean obliquity of the ecliptic. # obliq = (23.45229-0.0130125*t)/rad # e = 0.40931967763254096-6.217959450123535e-09*dj # sin(d) = sin(e) * sin(L) sind = np.sin(e) * np.sin(l) sdec = np.arcsin(sind) # tan(RA) = cos(e)*sin(L)/cos(L) srasn = np.arctan2(np.cos(e) * np.sin(l), np.cos(l)) srasn = np.mod(srasn, twopi) # http://aa.usno.navy.mil/faq/docs/GAST.php # gst - gmst, greenwich mean sidereal time. # gst = np.mod(279.690983+.9856473354*dj+360.*fday+180.,360.)/rad # gst = np.mod(4.881528541489487+0.01720279126623886*dj+twopi*fday+np.pi, twopi) # gmst = 18.697374558 + 24.06570982441908*d # in hour gmst = 4.894961212735792 + 6.30038809898489 * d # in rad gmst = np.mod(gmst, twopi) return gmst, l, srasn, sdec, e
def geodgeo(p1, p2, j): """ This subroutine (1) converts vertical local height (altitude) h and geodetic latitude xmu into geocentric coordinates r and theta (geocentric radial distance and colatitude, respectively; also known as ecef coordinates), as well as (2) performs the inverse transformation from {r,theta} to {h,xmu}. The subroutine uses world geodetic system wgs84 parameters for the earth's ellipsoid. the angular quantities (geo colatitude theta and geodetic latitude xmu) are in radians, and the distances (geocentric radius r and altitude h above the earth's ellipsoid) are in kilometers. if j>0, the transformation is made from geodetic to geocentric coordinates using simple direct equations. if j<0, the inverse transformation from geocentric to geodetic coordinates is made by means of a fast iterative algorithm. j>0 j<0 input: j, h,xmu j, r,theta output: j, r,theta j, h,xmu Author: N.A. Tsyganenko Date: Dec 5, 2007 :param h: Altitude in km. :param xmu: Geodetic latitude in radian. :param r: Geocentric distance in km. :param theta: Spherical co-latitude in radian. """ # r_eq is the semi-major axis of the earth's ellipsoid, # and beta is its second eccentricity squared r_eq, beta = 6378.137, 6.73949674228e-3 if j > 0: # Direct transformation(GEOD->GEO): h, xmu = [p1, p2] cosxmu = np.cos(xmu) sinxmu = np.sin(xmu) den = np.sqrt(cosxmu**2 + (sinxmu / (1 + beta))**2) coslam = cosxmu / den sinlam = sinxmu / (den * (1 + beta)) rs = r_eq / np.sqrt(1 + beta * sinlam**2) x = rs * coslam + h * cosxmu z = rs * sinlam + h * sinxmu r = np.sqrt(x**2 + z**2) theta = np.arccos(z / r) return r, theta else: # Inverse transformation(GEO->GEOD): r, theta = [p1, p2] phi = np.pi * 0.5 - theta phi1, dphi, h, xmu, tol = phi, 0, 0, 0, 1e-6 for n in range(100): if np.abs(dphi) > tol: break sp = np.sin(phi1) arg = sp * (1 + beta) / np.sqrt(1 + beta * (2 + beta) * sp**2) xmu = np.arcsin(arg) rs = r_eq / np.sqrt(1 + beta * np.sin(phi1)**2) cosfims = np.cos(phi1 - xmu) h = np.sqrt((rs * cosfims)**2 + r**2 - rs**2) - rs * cosfims z = rs * np.sin(phi1) + h * np.sin(xmu) x = rs * np.cos(phi1) + h * np.cos(xmu) rr = np.sqrt(x**2 + z**2) dphi = np.arcsin(z / rr) - phi phi1 -= dphi return h, xmu
if __name__ == '__main__': parser = argparse.ArgumentParser(description='experiment setting') parser.add_argument('--path', type=str) parser.add_argument('--midclass', type=str) parser.add_argument('--subclass', type=str) parser.add_argument('--description', type=str) parser.add_argument('--total_timesteps', type=int, default=1000000) parser.add_argument('--pomdp', dest='pomdp', action='store_true') parser.add_argument('--mdp', dest='pomdp', action='store_false') parser.set_defaults(pomdp=False) args = parser.parse_args() manager = ExperimentManager(args.path, args.midclass, args.subclass) manager.make_description(args.description) np.random.seed() goal = np.random.random() * 2 * np.pi goal = np.array([np.cos(goal), np.sin(goal)]) * 256 if args.pomdp: env = PartialTwoDimNavEnv(goal) else: env = TwoDimNavEnv(goal) model = PPO2(MlpPolicy, env, tensorboard_log=manager.sub_path, full_tensorboard_log=True, n_steps=1024) model.learn(total_timesteps=args.total_timesteps) model.save(os.path.join(manager.sub_path, 'model'))
def recalc(ut, vxgse=-400, vygse=0, vzgse=0): """ 1. Prepares elements of rotation matrices for transformations of vectors between several coordinate systems, most frequently used in space physics. 2. Prepares coefficients used in the calculation of the main geomagnetic field (igrf model) This subroutine should be invoked before using the following subroutines: igrf_geo, igrf_gsm, dip, geomag, geogsm, magsm, smgsm, gsmgse, geigeo. There is no need to repeatedly invoke recalc, if multiple calculations are made for the same date and time. :param ut: Universal time in second. :param v[xyz]gse: The solar wind velocity expressed in GSE. :return: psi. Dipole tilt angle in radian. Python version by Sheng Tian """ # The common block /geopack1/ contains elements of the rotation matrices and other # parameters related to the coordinate transformations performed by this package # common /geopack1/ st0,ct0,sl0,cl0,ctcl,stcl,ctsl,stsl,sfi,cfi,sps, # cps,shi,chi,hi,psi,xmut,a11,a21,a31,a12,a22,a32,a13,a23,a33,ds3, # cgst,sgst,ba(6) # st0/ct0 - sin/cos of teta0 (colat in geo?). sl0/cl0 - sin/cos of lambda0 (longitude in geo?). # ctcl/stcl - . ctsl/stsl - . geo x and z? # sfi/cfi/xmut - rotate angle between mag and sm and its sin/cos. # sps/cps/psi - tilt angle and its sin/cos. # shi/chi/hi - rotate angle between gse to gsm and its sin/cos. # a[11,...,33] - matrix converts geo to gsm. # cgst/sgst - cos/sin of gst. # ds3. # ba(6). global st0,ct0,sl0,cl0,ctcl,stcl,ctsl,stsl,sfi,cfi,sps,cps, \ shi,chi,hi,psi,xmut,ds3,cgst,sgst,ba, \ a11,a21,a31,a12,a22,a32,a13,a23,a33, \ e11,e21,e31,e12,e22,e32,e13,e23,e33 # The common block /geopack2/ contains coefficients of the IGRF field model, calculated # for a given year and day from their standard epoch values. the array rec contains # coefficients used in the recursion relations for legendre associate polynomials. # common /geopack2/ g(105),h(105),rec(105) global g, h, rec # Compute the m,n related coefficients (following the notation in Davis 2004): # 1. The Schmidt quasi-normalization: S_n,m, which normalizes the associated Legendre polynomials P_n^m # to the Guassian normalized associated Legendre polynomials P^n,m. # # Since g_n^m * P_n^m should be constant, mutiplying S_n,m to g_n^m is equivalently converting P_n^m to P^n,m. # The benefit of doing so is that P^n,m follows simple recursive form, c.f. Eq (16 a-c) and Eq(17 a-b). # 2. rec[mn], which used in the recursion relation. k = 14 nmn = np.int32((k + 1) * k / 2) # rec[mn]. rec = np.empty(nmn, dtype=float) mn = 0 for n in range(k): # K^1,m = 0, Eq (17a), automatically done. n2 = 2 * n + 1 n2 = n2 * (n2 - 2) for m in range(n + 1): rec[mn] = (n - m) * ( n + m) / n2 # K^n,m = (n-m)(n+m)/(2n+1)(2n-1), Eq (17b) mn += 1 # coefficients for a given time, g_n^m(t), h_n^m(t) g, h = load_igrf(ut) # now multiply them by schmidt normalization factors: s = 1. # S_0,0 = 1, Eq (18a) mn = 0 for n in range(1, k): mn += 1 # skip m=0. s *= (2 * n - 1) / n g[mn] *= s # S_n,0 = S_n-1,0 * (2n-1)/n, Eq (18b) h[mn] *= s p = s for m in range(1, n + 1): if m == 1: aa = 2 # aa = delta_m,1 else: aa = 1 p *= np.sqrt(aa * (n - m + 1) / (n + m)) mn += 1 g[mn] *= p # S_n,m = S_n,m-1 * sqrt(aa(n-m+1)/(n+m)), Eq (18c) h[mn] *= p # now g/h are actually g^n,m, Eq (14 a-b) g10 = -g[1] g11 = -g[2] h11 = -h[2] # Now calculate the components of the unit vector ezmag in geo coord.system: # sin(teta0)*cos(lambda0), sin(teta0)*sin(lambda0), and cos(teta0) # st0 * cl0 st0 * sl0 ct0 sq = g11**2 + h11**2 sqq = np.sqrt(sq) sqr = np.sqrt(g10**2 + sq) sl0 = h11 / sqq cl0 = g11 / sqq st0 = sqq / sqr ct0 = g10 / sqr stcl = st0 * cl0 stsl = st0 * sl0 ctsl = ct0 * sl0 ctcl = ct0 * cl0 gst, slong, srasn, sdec, obliq = sun(ut) # All vectors are expressed in GEI. # xgse_[xyz] (s[123]) are the components of the unit vector exgsm=exgse in GEI, # pointing from the earth's center to the sun: xgse_x = np.cos(srasn) * np.cos(sdec) xgse_y = np.sin(srasn) * np.cos(sdec) xgse_z = np.sin(sdec) # zgse_[xyz] (dz[123]) in GEI has the components (0,-sin(delta),cos(delta)) = (0.,-0.397823,0.917462); # Here delta = 23.44214 deg for the epoch 1978 (see the book by gurevich or other astronomical handbooks). # Here the most accurate time-dependent formula is used: zgse_x = 0. zgse_y = -np.sin(obliq) zgse_z = np.cos(obliq) # ygse_[xyz] (dy[123]) = zgse_[xyz] x xgsm_[xyz] in GEI: ygse_x = zgse_y * xgse_z - zgse_z * xgse_y ygse_y = zgse_z * xgse_x - zgse_x * xgse_z ygse_z = zgse_x * xgse_y - zgse_y * xgse_x # zsm_[xyz] (dip[123]) are the components of the unit vector zsm=zmag in GEI: cgst = np.cos(gst) sgst = np.sin(gst) zsm_x = stcl * cgst - stsl * sgst zsm_y = stcl * sgst + stsl * cgst zsm_z = ct0 # xgsw_[xyz] (x[123]) in GEI. v1 = -1 / np.sqrt(vxgse * vxgse + vygse * vygse + vzgse * vzgse) xgsw_x = (vxgse * xgse_x + vygse * ygse_x + vzgse * zgse_x) * v1 xgsw_y = (vxgse * xgse_y + vygse * ygse_y + vzgse * zgse_y) * v1 xgsw_z = (vxgse * xgse_z + vygse * ygse_z + vzgse * zgse_z) * v1 # ygsw (y[123]) = zsm x xgsw in GEI. ygsw_x = zsm_y * xgsw_z - zsm_z * xgsw_y ygsw_y = zsm_z * xgsw_x - zsm_x * xgsw_z ygsw_z = zsm_x * xgsw_y - zsm_y * xgsw_x y = np.sqrt(ygsw_x * ygsw_x + ygsw_y * ygsw_y + ygsw_z * ygsw_z) ygsw_x = ygsw_x / y ygsw_y = ygsw_y / y ygsw_z = ygsw_z / y # zgsw (z[123]) = xgsw x ygsw in GEI. zgsw_x = xgsw_y * ygsw_z - xgsw_z * ygsw_y zgsw_y = xgsw_z * ygsw_x - xgsw_x * ygsw_z zgsw_z = xgsw_x * ygsw_y - xgsw_y * ygsw_x # xgsm = xgse in GEI. xgsm_x, xgsm_y, xgsm_z = xgse_x, xgse_y, xgse_z # ygsm = zsm x xgsm in GEI. ygsm_x = zsm_y * xgsm_z - zsm_z * xgsm_y ygsm_y = zsm_z * xgsm_x - zsm_x * xgsm_z ygsm_z = zsm_x * xgsm_y - zsm_y * xgsm_x y = np.sqrt(ygsm_x * ygsm_x + ygsm_y * ygsm_y + ygsm_z * ygsm_z) ygsm_x = ygsm_x / y ygsm_y = ygsm_y / y ygsm_z = ygsm_z / y # ezgsm = exgsm x eygsm in GEI. zgsm_x = xgse_y * ygsm_z - xgse_z * ygsm_y zgsm_y = xgse_z * ygsm_x - xgse_x * ygsm_z zgsm_z = xgse_x * ygsm_y - xgse_y * ygsm_x # The elements of the matrix gse to gsm are the scalar products: # chi=em22=(eygsm,eygse), shi=em23=(eygsm,ezgse), em32=(ezgsm,eygse)=-em23, and em33=(ezgsm,ezgse)=em22 chi = ygsm_x * ygse_x + ygsm_y * ygse_y + ygsm_z * ygse_z shi = ygsm_x * zgse_x + ygsm_y * zgse_y + ygsm_z * zgse_z hi = np.arcsin(shi) # elements of the matrix gsm to gsw are the scalar products: # e11 = (exgsm, exgsw) e12 = (exgsm, eygsw) e13 = (exgsm, ezgsw) # e21 = (eygsm, exgsw) e22 = (eygsm, eygsw) e23 = (eygsm, ezgsw) # e31 = (ezgsm, exgsw) e32 = (ezgsm, eygsw) e33 = (ezgsm, ezgsw) e11 = xgsm_x * xgsw_x + xgsm_y * xgsw_y + xgsm_z * xgsw_z e12 = xgsm_x * ygsw_x + xgsm_y * ygsw_y + xgsm_z * ygsw_z e13 = xgsm_x * zgsw_x + xgsm_y * zgsw_y + xgsm_z * zgsw_z e21 = ygsm_x * xgsw_x + ygsm_y * xgsw_y + ygsm_z * xgsw_z e22 = ygsm_x * ygsw_x + ygsm_y * ygsw_y + ygsm_z * ygsw_z e23 = ygsm_x * zgsw_x + ygsm_y * zgsw_y + ygsm_z * zgsw_z e31 = zgsm_x * xgsw_x + zgsm_y * xgsw_y + zgsm_z * xgsw_z e32 = zgsm_x * ygsw_x + zgsm_y * ygsw_y + zgsm_z * ygsw_z e33 = zgsm_x * zgsw_x + zgsm_y * zgsw_y + zgsm_z * zgsw_z # Tilt angle: psi=arcsin(ezsm dot exgsm) sps = zsm_x * xgse_x + zsm_y * xgse_y + zsm_z * xgse_z cps = np.sqrt(1. - sps**2) psi = np.arcsin(sps) # The elements of the matrix mag to sm are the scalar products: # cfi=gm22=(eysm,eymag), sfi=gm23=(eysm,exmag); They can be derived as follows: # In geo the vectors exmag and eymag have the components (ct0*cl0,ct0*sl0,-st0) and (-sl0,cl0,0), respectively. # Hence, in gei the components are: # exmag: ct0*cl0*cos(gst)-ct0*sl0*sin(gst) # ct0*cl0*sin(gst)+ct0*sl0*cos(gst) # -st0 # eymag: -sl0*cos(gst)-cl0*sin(gst) # -sl0*sin(gst)+cl0*cos(gst) # 0 # The components of eysm in gei were found above as ysm_in_geix, ysm_in_geiy, and ysm_in_geiz; # Now we only have to combine the quantities into scalar products: xmag_x = ct0 * (cl0 * cgst - sl0 * sgst) xmag_y = ct0 * (cl0 * sgst + sl0 * cgst) xmag_z = -st0 ymag_x = -(sl0 * cgst + cl0 * sgst) ymag_y = -(sl0 * sgst - cl0 * cgst) cfi = ygsm_x * ymag_x + ygsm_y * ymag_y sfi = ygsm_x * xmag_x + ygsm_y * xmag_y + ygsm_z * xmag_z xmut = (np.arctan2(sfi, cfi) + 3.1415926536) * 3.8197186342 # The elements of the matrix geo to gsm are the scalar products: # a11=(exgeo,exgsm), a12=(eygeo,exgsm), a13=(ezgeo,exgsm), # a21=(exgeo,eygsm), a22=(eygeo,eygsm), a23=(ezgeo,eygsm), # a31=(exgeo,ezgsm), a32=(eygeo,ezgsm), a33=(ezgeo,ezgsm), # All the unit vectors in brackets are already defined in gei: # xgeo=(cgst,sgst,0), ygeo=(-sgst,cgst,0), zgeo=(0,0,1) # and therefore: a11 = xgsm_x * cgst + xgse_y * sgst a12 = -xgsm_x * sgst + xgse_y * cgst a13 = xgsm_z a21 = ygsm_x * cgst + ygsm_y * sgst a22 = -ygsm_x * sgst + ygsm_y * cgst a23 = ygsm_z a31 = zgsm_x * cgst + zgsm_y * sgst a32 = -zgsm_x * sgst + zgsm_y * cgst a33 = zgsm_z return psi
def AnalyticalT(x, Izero): """ The analytic solution. """ coef = np.sqrt(alpha * rhozero / kappa) * (Izero / Azero) return (np.cos((coef / 2) * x) / np.cos(coef * 0.12) - 1) / alpha
def shuetal_mgnp(xn_pd, vel, bzimf, xgsm, ygsm, zgsm): """ For any point of space with coordinates (xgsm,ygsm,zgsm) and specified conditions in the incoming solar wind, this subroutine: (1) determines if the point (xgsm,ygsm,zgsm) lies inside or outside the model magnetopause of Shue et al. (jgr-a, v.103, p. 17691, 1998). (2) calculates the gsm position of a point {xmgnp,ymgnp,zmgnp}, lying at the model magnetopause and asymptotically tending to the nearest boundary point with respect to the observation point {xgsm,ygsm,zgsm}, as it approaches the magnetopause. :param xn_pd: either solar wind proton number density (per c.c.) (if vel>0) or the solar wind ram pressure in nanopascals (if vel<0) :param vel: either solar wind velocity (km/sec) or any negative number, which indicates that xn_pd stands for the solar wind pressure, rather than for the density :param bzimf: imf bz in nanoteslas :param xgsm,ygsm,zgsm: gsm position of the observation point in earth radii :return: xmgnp,ymgnp,zmgnp. GSM position of the boundary point. dist. Distance (in re) between the observation point (xgsm,ygsm,zgsm) and the model magnetopause id. position flag: id=+1 (-1) means that the observation point lies inside (outside) of the model magnetopause, respectively. Last mofification: April 4, 2003 Author: N.A. Tsyganenko """ # pd is the solar wind dynamic pressure (in npa) if vel < 0: pd = xn_pd else: pd = 1.94e-6 * xn_pd * vel**2 # Define the angle phi, measured duskward from the noon-midnight meridian plane; # if the observation point lies on the x axis, the angle phi cannot be uniquely # defined, and we set it at zero: if (ygsm != 0) | (zgsm != 0): phi = np.arctan2(ygsm, zgsm) else: phi = 0 # First, find out if the observation point lies inside the Shue et al bdry # and set the value of the id flag: id = -1 r0 = (10.22 + 1.29 * np.tanh(0.184 * (bzimf + 8.14))) * pd**(-0.15151515) alpha = (0.58 - 0.007 * bzimf) * (1. + 0.024 * np.log(pd)) r = np.sqrt(xgsm**2 + ygsm**2 + zgsm**2) rm = r0 * (2. / (1. + xgsm / r))**alpha if r < rm: id = 1 # Now, find the corresponding t96 magnetopause position, to be used as # a starting approximation in the search of a corresponding Shue et al. # boundary point: xmt96, ymt96, zmt96, dist, id96 = t96_mgnp(pd, -1., xgsm, ygsm, zgsm) rho2 = ymt96**2 + zmt96**2 r = np.sqrt(rho2 + xmt96**2) st = np.sqrt(rho2) / r ct = xmt96 / r # Now, use newton's iterative method to find the nearest point at the Shue et al.'s boundary: nit = 0 while nit < 1000: nit += 1 t = np.arctan2(st, ct) rm = r0 * (2. / (1. + ct))**alpha f = r - rm gradf_r = 1. gradf_t = -alpha / r * rm * st / (1. + ct) gradf = np.sqrt(gradf_r**2 + gradf_t**2) dr = -f / gradf**2 dt = dr / r * gradf_t r = r + dr t = t + dt st = np.sin(t) ct = np.cos(t) ds = np.sqrt(dr**2 + (r * dt)**2) if ds <= 1.e-4: break else: print(' boundary point could not be found; iterations do not converge') xmgnp = r * np.cos(t) rho = r * np.sin(t) ymgnp = rho * np.sin(phi) zmgnp = rho * np.cos(phi) dist = np.sqrt((xgsm - xmgnp)**2 + (ygsm - ymgnp)**2 + (zgsm - zmgnp)**2) return xmgnp, ymgnp, zmgnp, dist, id
def create_window(N, window_type='uniform'): """A method to create window functions commonly used in signal processing. Windows supported are: Hamming, Hanning, uniform (rectangular window), triangular window, blackmann window among others. Parameters ---------- N : int Total number of data points in window. If negative, abs is taken. window_type : {``uniform``, ``parzen``, ``hamming``, ``hanning``, ``triangular``,\ ``welch``, ``blackmann``, ``flat-top``}, optional, default ``uniform`` Type of window to create. Returns ------- window: numpy.ndarray Window function of length ``N``. """ if not isinstance(N, int): raise TypeError('N (window length) must be an integer') windows = ['uniform', 'parzen', 'hamming', 'hanning', 'triangular', 'welch', 'blackmann', 'flat-top'] if not isinstance(window_type, string_types): raise TypeError('type of window must be specified as string!') window_type = window_type.lower() if window_type not in windows: raise ValueError( "Wrong window type specified or window function is not available") # Return empty array as window if N = 0 if N == 0: return np.array([]) window = None N = abs(N) # Window samples index n = np.arange(N) # Constants N_minus_1 = N - 1 N_by_2 = np.int((np.floor((N_minus_1) / 2))) # Create Windows if window_type == 'uniform': window = np.ones(N) if window_type == 'parzen': N_parzen = np.int(np.ceil((N + 1) / 2)) N2_plus_1 = np.int(np.floor((N_parzen / 2))) + 1 window = np.zeros(N_parzen) windlag0 = np.arange(0, N2_plus_1) / (N_parzen - 1) windlag1 = 1 - np.arange(N2_plus_1, N_parzen) / (N_parzen - 1) window[:N2_plus_1] = 1 - (1 - windlag0) * windlag0 * windlag0 * 6 window[N2_plus_1:] = windlag1 * windlag1 * windlag1 * 2 lagindex = np.arange(N_parzen - 1, 0, -1) window = np.concatenate((window[lagindex], window)) window = window[:N] if window_type == 'hamming': window = 0.54 - 0.46 * np.cos((2 * np.pi * n) / N_minus_1) if window_type == 'hanning': window = 0.5 * (1 - np.cos(2 * np.pi * n / N_minus_1)) if window_type == 'triangular': window = 1 - np.abs((n - (N_by_2)) / N) if window_type == 'welch': N_minus_1_by_2 = N_minus_1 / 2 window = 1 - np.square((n - N_minus_1_by_2) / N_minus_1_by_2) if window_type == 'blackmann': a0 = 0.42659 a1 = 0.49656 a2 = 0.076849 window = a0 - a1 * np.cos((2 * np.pi * n) / N_minus_1) + a2 * np.cos( (4 * np.pi * n) / N_minus_1) if window_type == 'flat-top': a0 = 1 a1 = 1.93 a2 = 1.29 a3 = 0.388 a4 = 0.028 window = a0 - a1 * np.cos((2 * np.pi * n) / N_minus_1) + \ a2 * np.cos((4 * np.pi * n) / N_minus_1) - \ a3 * np.cos((6 * np.pi * n) / N_minus_1) + \ a4 * np.cos((8 * np.pi * n) / N_minus_1) return window
def t96_mgnp(xn_pd, vel, xgsm, ygsm, zgsm): """ For any point of space with given coordinates (xgsm,ygsm,zgsm), this subroutine defines the position of a point (xmgnp,ymgnp,zmgnp) at the T96 model magnetopause, having the same value of the ellipsoidal tau-coordinate, and the distance between them. This is not the shortest distance d_min to the boundary, but dist asymptotically tends to d_min, as the observation point gets closer to the magnetopause. The pressure-dependent magnetopause is that used in the t96_01 model (Tsyganenko, jgr, v.100, p.5599, 1995; esa sp-389, p.181, oct. 1996) :param xn_pd: either solar wind proton number density (per c.c.) (if vel>0) or the solar wind ram pressure in nanopascals (if vel<0) :param vel: either solar wind velocity (km/sec) or any negative number, which indicates that xn_pd stands for the solar wind pressure, rather than for the density :param xgsm,ygsm,zgsm: gsm position of the observation point in earth radii :return: xmgnp,ymgnp,zmgnp. GSM position of the boundary point. dist. Distance (in re) between the observation point (xgsm,ygsm,zgsm) and the model magnetopause id. position flag: id=+1 (-1) means that the observation point lies inside (outside) of the model magnetopause, respectively. Last mofification: April 3, 2003 Author: N.A. Tsyganenko """ # Define solar wind dynamic pressure (nanopascals, assuming 4% of alpha-particles), # if not explicitly specified in the input: if vel < 0: pd = xn_pd else: pd = 1.94e-6 * xn_pd * vel**2 # ratio of pd to the average pressure, assumed equal to 2 npa: # The power index 0.14 in the scaling factor is the best-fit value # obtained from data and used in the t96_01 version # Values of the magnetopause parameters for pd = 2 npa: rat = pd / 2.0 rat16 = rat**0.14 a0, s00, x00 = [70., 1.08, 5.48] # Values of the magnetopause parameters, scaled by the actual pressure: # xm is the x-coordinate of the "seam" between the ellipsoid and the cylinder # For details on the ellipsoidal coordinates, see the paper: # N.A. Tsyganenko, Solution of chapman-ferraro problem for an ellipsoidal magnetopause, planet.space sci., v.37, p.1037, 1989). a = a0 / rat16 s0 = s00 x0 = x00 / rat16 xm = x0 - a if (ygsm != 0) | (zgsm != 0): phi = np.arctan2(ygsm, zgsm) else: phi = 0 rho = np.sqrt(ygsm**2 + zgsm**2) if xgsm < xm: xmgnp = xgsm rhomgnp = a * np.sqrt(s0**2 - 1) ymgnp = rhomgnp * np.sin(phi) zmgnp = rhomgnp * np.cos(phi) dist = np.sqrt((xgsm - xmgnp)**2 + (ygsm - ymgnp)**2 + (zgsm - zmgnp)**2) if rhomgnp > rho: id = 1 else: id = -1 return xmgnp, ymgnp, zmgnp, dist, id xksi = (xgsm - x0) / a + 1. xdzt = rho / a sq1 = np.sqrt((1. + xksi)**2 + xdzt**2) sq2 = np.sqrt((1. - xksi)**2 + xdzt**2) sigma = 0.5 * (sq1 + sq2) tau = 0.5 * (sq1 - sq2) # Now calculate (x,y,z) for the closest point at the magnetopause xmgnp = x0 - a * (1. - s0 * tau) arg = (s0**2 - 1.) * (1. - tau**2) if arg < 0: arg = 0 rhomgnp = a * np.sqrt(arg) ymgnp = rhomgnp * np.sin(phi) zmgnp = rhomgnp * np.cos(phi) # Now calculate the distance between the points {xgsm,ygsm,zgsm} and {xmgnp,ymgnp,zmgnp}: # (in general, this is not the shortest distance d_min, but dist asymptotically tends # to d_min, as we are getting closer to the magnetopause): dist = np.sqrt((xgsm - xmgnp)**2 + (ygsm - ymgnp)**2 + (zgsm - zmgnp)**2) if sigma > s0: id = -1 # id = -1 means that the point lies outside else: id = 1 # id = 1 means that the point lies inside return xmgnp, ymgnp, zmgnp, dist, id
from moviepy.editor import * from moviepy.video.tools.segmenting import findObjects # WE CREATE THE TEXT THAT IS GOING TO MOVE, WE CENTER IT. screensize = (720,460) txtClip = TextClip('Cool effect',color='white', font="Amiri-Bold", kerning = 5, fontsize=100) cvc = CompositeVideoClip( [txtClip.set_pos('center')], size=screensize) # THE NEXT FOUR FUNCTIONS DEFINE FOUR WAYS OF MOVING THE LETTERS # helper function rotMatrix = lambda a: np.array( [[np.cos(a),np.sin(a)], [-np.sin(a),np.cos(a)]] ) def vortex(screenpos,i,nletters): d = lambda t : 1.0/(0.3+t**8) #damping a = i*np.pi/ nletters # angle of the movement v = rotMatrix(a).dot([-1,0]) if i%2 : v[1] = -v[1] return lambda t: screenpos+400*d(t)*rotMatrix(0.5*d(t)*a).dot(v) def cascade(screenpos,i,nletters): v = np.array([0,-1]) d = lambda t : 1 if t<0 else abs(np.sinc(t)/(1+t**4)) return lambda t: screenpos+v*400*d(t-0.15*i) def arrive(screenpos,i,nletters):
def calc_eck(param): twotheta = param["twotheta"] * param["sample_sense"] thetam = param["thetam"] * param["mono_sense"] thetaa = param["thetaa"] * param["ana_sense"] ki_Q = param["angle_ki_Q"] * param["sample_sense"] kf_Q = param["angle_kf_Q"] * param["sample_sense"] ki = param["ki"] kf = param["kf"] E = param["E"] Q = param["Q"] # -------------------------------------------------------------------- # mono/ana focus mono_curvh = param["mono_curvh"] mono_curvv = param["mono_curvv"] ana_curvh = param["ana_curvh"] ana_curvv = param["ana_curvv"] if param["mono_is_optimally_curved_h"]: mono_curvh = foc_curv(param["dist_src_mono"], param["dist_mono_sample"], np.abs(2.*thetam), False) if param["mono_is_optimally_curved_v"]: mono_curvv = foc_curv(param["dist_src_mono"], param["dist_mono_sample"], np.abs(2.*thetam), True) if param["ana_is_optimally_curved_h"]: ana_curvh = foc_curv(param["dist_sample_ana"], param["dist_ana_det"], np.abs(2.*thetaa), False) if param["ana_is_optimally_curved_v"]: ana_curvv = foc_curv(param["dist_sample_ana"], param["dist_ana_det"], np.abs(2.*thetaa), True) inv_mono_curvh = 0. inv_mono_curvv = 0. inv_ana_curvh = 0. inv_ana_curvv = 0. if param["mono_is_curved_h"]: inv_mono_curvh = 1./mono_curvh if param["mono_is_curved_v"]: inv_mono_curvv = 1./mono_curvv if param["ana_is_curved_h"]: inv_ana_curvh = 1./ana_curvh if param["ana_is_curved_v"]: inv_ana_curvv = 1./ana_curvv # -------------------------------------------------------------------- lam = k2lam(ki) coll_h_pre_mono = param["coll_h_pre_mono"] coll_v_pre_mono = param["coll_v_pre_mono"] if param["use_guide"]: coll_h_pre_mono = lam*param["guide_div_h"] coll_v_pre_mono = lam*param["guide_div_v"] # dict with results res = {} res["Q_avg"] = np.array([ Q, 0., 0., E ]) # ------------------------------------------------------------------------- # - if the instruments works in kf=const mode and the scans are counted for # or normalised to monitor counts no ki^3 or kf^3 factor is needed. # - if the instrument works in ki=const mode the kf^3 factor is needed. # TODO #tupScFact = get_scatter_factors(param.flags, param.thetam, param.ki, param.thetaa, param.kf); tupScFact = [1., 1., 1.] dmono_refl = param["dmono_refl"] * tupScFact[0] dana_effic = param["dana_effic"] * tupScFact[1] dxsec = tupScFact[2] #if param.mono_refl_curve: # dmono_refl *= (*param.mono_refl_curve)(param.ki) #if param.ana_effic_curve: # dana_effic *= (*param.ana_effic_curve)(param.kf) #-------------------------------------------------------------------------- # mono part [A, B, C, D, dReflM] = get_mono_vals( param["src_w"], param["src_h"], param["mono_w"], param["mono_h"], param["dist_src_mono"], param["dist_mono_sample"], ki, thetam, coll_h_pre_mono, param["coll_h_pre_sample"], coll_v_pre_mono, param["coll_v_pre_sample"], param["mono_mosaic"], param["mono_mosaic_v"], inv_mono_curvh, inv_mono_curvv, param["pos_x"] , param["pos_y"], param["pos_z"], dmono_refl) #-------------------------------------------------------------------------- #-------------------------------------------------------------------------- # ana part # equ 43 in [eck14] pos_y2 = - param["pos_x"]*np.sin(twotheta) + param["pos_y"]*np.cos(twotheta) pos_z2 = param["pos_z"] # vertical scattering in kf axis, formula from [eck20] if param["kf_vert"]: pos_z2 = -pos_y2 pos_y2 = param["pos_z"] [E, F, G, H, dReflA] = get_mono_vals( param["det_w"], param["det_h"], param["ana_w"], param["ana_h"], param["dist_ana_det"], param["dist_sample_ana"], kf, -thetaa, param["coll_h_post_ana"], param["coll_h_post_sample"], param["coll_v_post_ana"], param["coll_v_post_sample"], param["ana_mosaic"], param["ana_mosaic_v"], inv_ana_curvh, inv_ana_curvv, param["pos_x"], pos_y2, pos_z2, dana_effic) # vertical scattering in kf axis, formula from [eck20] if param["kf_vert"]: T_vert = np.array( [[ 1., 0., 0. ], [ 0., 0., 1. ], [ 0., -1., 0. ]]) E = np.dot(np.dot(np.transpose(T_vert), E), T_vert) F = np.dot(T_vert, F) #-------------------------------------------------------------------------- # equ 4 & equ 53 in [eck14] dE = (ki**2. - kf**2.) / (2.*Q**2.) kipara = Q*(0.5+dE) kfpara = Q-kipara kperp = np.sqrt(np.abs(kipara**2. - ki**2.)) kperp *= param["sample_sense"] # trafo, equ 52 in [eck14] T = np.identity(6) T[0,3] = T[1,4] = T[2,5] = -1. T[3,0] = 2.*ksq2E * kipara T[3,3] = 2.*ksq2E * kfpara T[3,1] = 2.*ksq2E * kperp T[3,4] = -2.*ksq2E * kperp T[4,1] = T[5,2] = (0.5 - dE) T[4,4] = T[5,5] = (0.5 + dE) Tinv = la.inv(T) # equ 54 in [eck14] Dalph_i = rotation_matrix_3d_z(-ki_Q) Dalph_f = rotation_matrix_3d_z(-kf_Q) Arot = np.dot(np.dot(np.transpose(Dalph_i), A), Dalph_i) Erot = np.dot(np.dot(np.transpose(Dalph_f), E), Dalph_f) matAE = np.zeros((6,6)) matAE[0:3, 0:3] = Arot matAE[3:6, 3:6] = Erot # U1 matrix # typo in paper in quadric trafo in equ 54 (top)? U1 = np.dot(np.dot(np.transpose(Tinv), matAE), Tinv) # V1 vector vecBF = np.zeros(6) vecBrot = np.dot(np.transpose(Dalph_i), B) vecFrot = np.dot(np.transpose(Dalph_f), F) vecBF[0:3] = vecBrot vecBF[3:6] = vecFrot V1 = np.dot(vecBF, Tinv) # -------------------------------------------------------------------------- # integrate last 2 vars -> equs 57 & 58 in [eck14] U2 = reso.quadric_proj(U1, 5); U = reso.quadric_proj(U2, 4); V2 = reso.quadric_proj_vec(V1, U1, 5); V = reso.quadric_proj_vec(V2, U2, 4); W = (C + D + G + H) - 0.25*V1[5]/U1[5,5] - 0.25*V2[4]/U2[4,4] Z = dReflM*dReflA * np.sqrt(np.pi/np.abs(U1[5,5])) * np.sqrt(np.pi/np.abs(U2[4,4])) # -------------------------------------------------------------------------- # quadratic part of quadric (matrix U) # careful: factor -0.5*... missing in U matrix compared to normal gaussian! res["reso"] = 2. * U; # linear (vector V) and constant (scalar W) part of quadric res["reso_v"] = V; res["reso_s"] = W; if param["sample_sense"] < 0.: # mirror Q_perp matMirror = mirror_matrix(len(res["reso"]), 1) res["reso"] = np.dot(np.dot(np.transpose(matMirror), res["reso"]), matMirror) res["reso_v"][1] = -res["reso_v"][1] # prefactor and volume res["res_vol"] = reso.ellipsoid_volume(res["reso"]) res["r0"] = Z # missing volume prefactor to normalise gaussian, # cf. equ. 56 in [eck14] to equ. 1 in [pop75] and equ. A.57 in [mit84] res["r0"] *= res["res_vol"] * np.pi * 3. res["r0"] *= np.exp(-W) res["r0"] *= dxsec # Bragg widths res["coherent_fwhms"] = reso.calc_coh_fwhms(res["reso"]) res["ok"] = True if np.isnan(res["r0"]) or np.isinf(res["r0"]) or np.isnan(res["reso"].any()) or np.isinf(res["reso"].any()): res["ok"] = False return res
pcolormesh uses a QuadMesh, a faster generalization of pcolor, but with some restrictions. This demo illustrates a bug in quadmesh with masked data. """ import numpy as np from matplotlib.pyplot import figure, show, savefig from matplotlib import cm, colors from numpy import ma n = 12 x = np.linspace(-1.5, 1.5, n) y = np.linspace(-1.5, 1.5, n*2) X, Y = np.meshgrid(x, y) Qx = np.cos(Y) - np.cos(X) Qz = np.sin(Y) + np.sin(X) Qx = (Qx + 1.1) Z = np.sqrt(X**2 + Y**2)/5 Z = (Z - Z.min()) / (Z.max() - Z.min()) # The color array can include masked values: Zm = ma.masked_where(np.fabs(Qz) < 0.5*np.amax(Qz), Z) fig = figure() ax = fig.add_subplot(121) ax.pcolormesh(Qx, Qz, Z, shading='gouraud') ax.set_title('Without masked values') ax = fig.add_subplot(122)
def __dfmoll(x,args): return 2.*(1.+np.cos(2.*x))
def lr_fun_cos(cur_epoch): """Cosine schedule (cfg.OPTIM.LR_POLICY = 'cos').""" lr = 0.5 * (1.0 + np.cos(np.pi * cur_epoch / cfg.OPTIM.MAX_EPOCH)) return (1.0 - cfg.OPTIM.MIN_LR) * lr + cfg.OPTIM.MIN_LR
def func_yt(t, y0, zeta, beta, gamma, delta): return y0*(1-(1/np.sqrt(1-zeta**2))*np.exp(-beta*t)*np.cos(gamma*t - delta))
def uniform_boundary_points(self, n): theta = np.linspace(0, 2 * np.pi, num=n, endpoint=False) X = np.vstack((np.cos(theta), np.sin(theta))).T return self.radius * X + self.center
def iq_mixer(signal, lo, time_array, fs, lpf_cutoff): inphase = lpf(signal * np.cos(2 * np.pi * lo * time_array), lpf_cutoff, fs) quadrature = lpf(-1 * signal * np.sin(2 * np.pi * lo * time_array), lpf_cutoff, fs) return inphase, quadrature
def f(t): x=np.sin(t) y=np.cos(t) z=np.linspace(-1,1,len(x)) return x,y,z
def damped_vibrations(t, A, b, w): return A*exp(-b*t)*cos(w*t)
f = 2.*omega*np.sin(lats) # coriolis outputMinMaxSum(f, "f") # zonal jet. vg = np.zeros((nlats,nlons),np.float) u1 = (umax/en)*np.exp(1./((x.lats-phi0)*(x.lats-phi1))) outputMinMaxSum(u1, "u1") ug = np.zeros((nlats),np.float) ug = np.where(np.logical_and(x.lats < phi1, x.lats > phi0), u1, ug) ug.shape = (nlats,1) ug = ug*np.ones((nlats,nlons),dtype=np.float) # broadcast to shape (nlats,nlonss) outputMinMaxSum(ug, "ug") # height perturbation. hbump = hamp*np.cos(lats)*np.exp(-(lons/alpha)**2)*np.exp(-(phi2-lats)**2/beta) outputMinMaxSum(hbump, "hbump") # initial vorticity, divergence in spectral space vrtspec, divspec = x.getvrtdivspec(ug,vg) outputSpecMinMaxSum(vrtspec, "vrtspec") outputSpecMinMaxSum(divspec, "divspec") # create hyperdiffusion factor # hyperdiff_fact = np.exp((-dt/efold)*(x.lap/x.lap[-1])**(ndiss/2)) # solve nonlinear balance eqn to get initial zonal geopotential, # add localized bump (not balanced). vrtg = x.spectogrd(vrtspec)
import matplotlib.pyplot as plt from lineticks import LineTicks # Acceleration due to gravity, m.s-2 g = 9.81 # Initial speed (m.s-1) and launch angle (deg) v0, alpha_deg = 40, 45 alpha = np.radians(alpha_deg) # Time of flight tmax = 2 * v0 * np.sin(alpha) / g # Grid of time points, and (x,y) coordinates of trajectory n = 100 t = np.linspace(0, tmax, n) x = v0 * t * np.cos(alpha) y = -g * t**2 / 2 + v0 * t * np.sin(alpha) fig, ax = plt.subplots(facecolor='w') fig.suptitle('Trajectory of a projectile launched at {} m/s at an angle' ' of {}°'.format(v0, alpha_deg)) traj, = ax.plot(x, y, c='purple', lw=4) ax.set_xlabel('Range /m') ax.set_ylabel('Height /m') ax.set_xlim(-20, x[-1] + 10) # Add major ticks every 10th time point and minor ticks every 4th; # label the major ticks with the corresponding time in secs. major_ticks = LineTicks(traj, range(0, n, 10), 10,