def corr(a, b, axis=None): u""" 相関係数を計算する。 :Arguments: **a, b** : array_like 入力 **axis** : int, optional a, b の一方が1次元で、もう一方が多次元の場合に相関を計算する軸。 :Returns: **r** : array_like """ a = np.asarray(a) b = np.asarray(b) if axis == None: if not a.shape == b.shape: raise ValueError, "input array must have shame shape" else: if a.ndim == 1 and b.ndim>1: a = tools.expand(a, b.ndim, axis=axis) elif b.ndim == 1 and a.ndim>1: b = tools.expand(b, a.ndim, axis=axis) a_anom = a - a.mean(axis=axis) b_anom = b - b.mean(axis=axis) xy = (a_anom*b_anom).sum(axis=axis) xx = np.sqrt((a_anom**2).sum(axis=axis)) yy = np.sqrt((b_anom**2).sum(axis=axis)) r = xy/xx/yy return r
def corr(a, b, axis=None): u""" 相関係数を計算する。 :Arguments: **a, b** : array_like 入力 **axis** : int, optional a, b の一方が1次元で、もう一方が多次元の場合に相関を計算する軸。 :Returns: **r** : array_like """ a = np.asarray(a) b = np.asarray(b) if axis == None: if not a.shape == b.shape: raise ValueError, "input array must have shame shape" else: if a.ndim == 1 and b.ndim > 1: a = tools.expand(a, b.ndim, axis=axis) elif b.ndim == 1 and a.ndim > 1: b = tools.expand(b, a.ndim, axis=axis) a_anom = a - a.mean(axis=axis) b_anom = b - b.mean(axis=axis) xy = (a_anom * b_anom).sum(axis=axis) xx = np.sqrt((a_anom**2).sum(axis=axis)) yy = np.sqrt((b_anom**2).sum(axis=axis)) r = xy / xx / yy return r
def __init__(self, db, path, remote_root, redirect_stdout=False, redirect_stderr=False, finish_up_after=None, save_interval=None): self.db = db self.dbstate = sql.book_dct_postgres_serial(self.db) if self.dbstate is None: raise JobError(JobError.NOJOB, 'No job was found to run.') print "Selected job id=%d in table=%s in db=%s" % ( self.dbstate.id, self.db.tablename, self.db.dbname) try: state = expand(self.dbstate) # The id isn't set by the line above state["jobman.id"] = self.dbstate.id if "dbdict" in state: state.jobman = state.dbdict experiment = resolve(state.jobman.experiment) remote_path = os.path.join(remote_root, self.db.dbname, self.db.tablename, str(self.dbstate.id)) super(DBRSyncChannel, self).__init__(path, remote_path, experiment, state, redirect_stdout, redirect_stderr, finish_up_after, save_interval) except: self.dbstate['jobman.status'] = self.ERR_START raise
def runner_cmdline(options, experiment, *strings): """ Start an experiment with parameters given on the command line. Usage: cmdline [options] <experiment> <parameters> Run an experiment with parameters provided on the command line. See the help topics for experiment and parameters for syntax information. Example use: jobman cmdline mymodule.my_experiment \\ stopper::pylearn.stopper.nsteps \\ # use pylearn.stopper.nsteps stopper.n=10000 \\ # the argument "n" of nsteps is 10000 lr=0.03 you can use the jobman.experiments.example1 as a working mymodule.my_experiment """ parser = getattr(parse, options.parser, None) or resolve(options.parser) _state = parser(*strings) state = expand(_state) state.setdefault('jobman', DD()).experiment = experiment state.jobman.time = time.ctime() experiment = resolve(experiment) if options.workdir and options.dry_run: raise UsageError('Please use only one of: --workdir, --dry-run.') if options.workdir and options.workdir_dir: raise UsageError('Please use only one of: --workdir, --workdir_dir.') if options.workdir: workdir = options.workdir elif options.dry_run or options.workdir_dir: if options.workdir_dir and not os.path.exists(options.workdir_dir): os.mkdir(options.workdir_dir) workdir = tempfile.mkdtemp(dir=options.workdir_dir) else: workdir_gen = getattr(workdirgen, options.workdir_gen, None) or resolve(options.workdir_gen) workdir = workdir_gen(state) print "The working directory is:", os.path.join(os.getcwd(), workdir) channel = StandardChannel(workdir, experiment, state, redirect_stdout=options.redirect or options.redirect_stdout, redirect_stderr=options.redirect or options.redirect_stderr, finish_up_after=options.finish_up_after or None, save_interval=options.save_every or None) channel.catch_sigint = not options.allow_sigint channel.run(force=options.force) if options.dry_run: shutil.rmtree(workdir, ignore_errors=True)
def div(u, v, lon, lat, xdim, ydim, cyclic=True, sphere=True): ur""" 水平発散を計算する。 :Arguments: **u, v** : ndarray ベクトルの東西、南北成分。 **lon, lat** : array_like 緯度と経度 **xdim, ydim** : int 緯度、経度の軸 **cyclic** : bool, optional 経度微分の際に周境界とするかどうか。デフォルトはTrue **sphere** : bool, optional 球面緯度経度座標かどうか。デフォルトはTrue。Falseにすると直交座標として扱う。 :Returns: **div** : ndarray u, v と同じ形状のndarray .. note:: 球面緯度経度座標系における水平発散は次のように定義される。 .. math:: \mbox{\boldmath $\nabla$}\cdot\mbox{\boldmath $v$} = \frac{1}{a\cos\phi} \left[ \frac{\partial u}{\partial \lambda} +\frac{\partial (v\cos\phi)}{\partial \phi} \right] = \frac{1}{a\cos\phi}\frac{\partial u}{\partial \lambda} + \frac{1}{a}\frac{\partial v}{\partial \phi} - \frac{v\tan\phi}{a} ここで、aは地球半径。これを中央差分で次のように計算する。 .. math:: (\mbox{\boldmath $\nabla$}\cdot\mbox{\boldmath $v$})_{i,j} = \left(\frac{1}{a\cos\phi}\frac{\partial u}{\partial \lambda}\right)_{i,j} + \left(\frac{1}{a}\frac{\partial v}{\partial \phi}\right)_{i,j} - \frac{v_{i,j}\tan\phi_{j}}{a} 緯度、経度微分の項は、:py:func:`dvardx`、 :py:func:`dvardy` を内部で呼ぶ。境界の扱いもこれらに準ずる。 **Examples** >>> from pymet.grid import div >>> """ u, v = np.array(u), np.array(v) ndim = u.ndim out = dvardx(u, lon, lat, xdim, ydim, cyclic=cyclic, sphere=sphere) + dvardy(v, lat, ydim, sphere=sphere) if sphere: out = out - v * tools.expand(np.tan(lat * d2r), ndim, ydim) / a0 out = np.rollaxis(out, ydim, 0) out[0, ...] = 0. out[-1, ...] = 0. out = np.rollaxis(out, 0, ydim + 1) return out
def runner_cmdline(options, experiment, *strings): """ Start an experiment with parameters given on the command line. Usage: cmdline [options] <experiment> <parameters> Run an experiment with parameters provided on the command line. See the help topics for experiment and parameters for syntax information. Example use: jobman cmdline mymodule.my_experiment \\ stopper::pylearn.stopper.nsteps \\ # use pylearn.stopper.nsteps stopper.n=10000 \\ # the argument "n" of nsteps is 10000 lr=0.03 you can use the jobman.experiments.example1 as a working mymodule.my_experiment """ parser = getattr(parse, options.parser, None) or resolve(options.parser) _state = parser(*strings) state = expand(_state) state.setdefault('jobman', DD()).experiment = experiment state.jobman.time = time.ctime() experiment = resolve(experiment) if options.workdir and options.dry_run: raise UsageError('Please use only one of: --workdir, --dry-run.') if options.workdir and options.workdir_dir: raise UsageError('Please use only one of: --workdir, --workdir_dir.') if options.workdir: workdir = options.workdir elif options.dry_run or options.workdir_dir: if options.workdir_dir and not os.path.exists(options.workdir_dir): os.mkdir(options.workdir_dir) workdir = tempfile.mkdtemp(dir=options.workdir_dir) else: workdir_gen = getattr(workdirgen, options.workdir_gen, None) or resolve(options.workdir_gen) workdir = workdir_gen(state) print "The working directory is:", os.path.join(os.getcwd(), workdir) channel = StandardChannel(workdir, experiment, state, redirect_stdout=options.redirect or options.redirect_stdout, redirect_stderr=options.redirect or options.redirect_stderr, finish_up_after=options.finish_up_after or None, save_interval=options.save_every or None ) channel.catch_sigint = not options.allow_sigint channel.run(force=options.force) if options.dry_run: shutil.rmtree(workdir, ignore_errors=True)
def laplacian(var, lon, lat, xdim, ydim, cyclic=True, sphere=True): ur""" 球面上での2次元ラプラシアンを計算する。 :Arguments: **var** : ndarray スカラー場 **lon, lat** : array_like 緯度と経度 **xdim, ydim** : int 緯度、経度の軸 **cyclic** : bool, optional 経度微分の際に周境界とするかどうか。デフォルトはTrue **sphere** : bool, optional 球面緯度経度座標かどうか。デフォルトはTrue。Falseにすると直交座標として扱う。 :Returns: **out** : ndarray varと同じ形状のndarray .. note:: 球面緯度経度座標系における2次元ラプラシアンは次のように定義される。 .. math:: \nabla_{h}^2\Phi &= \frac{1}{a^2\cos^2\phi} \left[ \frac{\partial^2 \Phi}{\partial \lambda^2} + \cos\phi\frac{\partial}{\partial \phi} \left( \cos\phi \frac{\partial \Phi}{\partial \phi} \right) \right] \\ &= \frac{1}{a^2\cos^2\phi}\frac{\partial \Phi}{\partial \lambda} + \frac{1}{a^2}\frac{\partial^2 \Phi}{\partial \phi^2} - \frac{\tan\phi}{a^2}\frac{\partial \Phi}{\partial \phi} ここで、aは地球半径。これを中央差分で次のように計算する。 .. math:: (\nabla_{h}^2\Phi)_{i,j} = \left(\frac{1}{a^2\cos^2\phi}\frac{\partial^2 \Phi}{\partial \lambda^2}\right)_{i,j} - \left(\frac{1}{a^2}\frac{\partial^2 \Phi}{\partial \phi^2}\right)_{i,j} - \frac{\tan\phi_{j}}{a} \left( \frac{1}{a}\frac{\partial \Phi}{\partial \phi}\right)_{i,j} 緯度、経度微分の項は、:py:func:`d2vardx2`、 :py:func:`d2vardy2` を内部で呼ぶ。境界の扱いもこれらに準ずる。 """ var = np.asarray(var) ndim = var.ndim if sphere: out = d2vardx2( var, lon, lat, xdim, ydim, cyclic=cyclic, sphere=sphere ) + d2vardy2(var, lat, ydim, sphere=sphere) - tools.expand( np.tan(lat * d2r), ndim, ydim) * dvardy(var, lat, ydim) / a0 else: out = d2vardx2(var, lon, lat, xdim, ydim, cyclic=cyclic, sphere=sphere) + d2vardy2(var, lat, ydim, sphere=sphere) return out
def rot(u, v, lon, lat, xdim, ydim, cyclic=True, sphere=True): ur""" 回転の鉛直成分を計算する。 :Arguments: **u, v** : ndarray ベクトルの東西、南北成分。 **lon, lat** : array_like 緯度と経度 **xdim, ydim** : int 緯度、経度の軸 **cyclic** : bool, optional 経度微分の際に周境界とするかどうか。デフォルトはTrue **sphere** : bool, optional 球面緯度経度座標かどうか。デフォルトはTrue。Falseにすると直交座標として扱う。 :Returns: **div** : ndarray u, v と同じ形状のndarray .. note:: 球面緯度経度座標系における回転の鉛直成分は次のように定義される。 .. math:: \mbox{\boldmath $k$}\cdot(\mbox{\boldmath $\nabla$}\times\boldmath{v}) &= \frac{1}{a\cos\phi} \left[ \frac{\partial v}{\partial \lambda} - \frac{\partial (u\cos\phi)}{\partial \phi} \right] \\ &= \frac{1}{a\cos\phi}\frac{\partial v}{\partial \lambda} - \frac{1}{a}\frac{\partial u}{\partial \phi} + \frac{u\tan\phi}{a} ここで、aは地球半径。これを中央差分で次のように計算する。 .. math:: [\mbox{\boldmath $k$}\cdot(\mbox{\boldmath $\nabla$}\times\boldmath{v})]_{i,j} = \left(\frac{1}{a\cos\phi}\frac{\partial v}{\partial \lambda}\right)_{i,j} - \left(\frac{1}{a}\frac{\partial u}{\partial \phi}\right)_{i,j} + \frac{u_{i,j}\tan\phi_{j}}{a} 緯度、経度微分の項は、:py:func:`dvardx`、 :py:func:`dvardy` を内部で呼ぶ。境界の扱いもこれらに準ずる。 """ u, v = np.array(u), np.array(v) ndim = u.ndim out = dvardx(v, lon, lat, xdim, ydim, cyclic=cyclic, sphere=sphere) - dvardy(u, lat, ydim, sphere=sphere) if sphere: out = out + u * tools.expand(np.tan(lat * d2r), ndim, ydim) / a0 out = np.rollaxis(out, ydim, 0) out[0, ...] = 0. out[-1, ...] = 0. out = np.rollaxis(out, 0, ydim + 1) return out
def rhmd(temp, qval, lev, zdim, punit=100., qtyp='q'): u""" """ eps = constants.air_eps t, q = np.ma.getdata(temp), np.ma.getdata(qval) mask = np.ma.getmask(temp) | np.ma.getmask(qval) ndim = t.ndim if qtyp == 'q': es = np.exp(19.482 - 4303.4/(t-29.65))*100. # JMA/WMO (Pa) lev = tools.expand(lev, ndim, axis=zdim)*punit e = q*lev/(eps+(1-eps)*q) rh = e/es * 100 else: raise TypeError, "qtyp '{0}' is incorrect".format(qtyp) return rh
def absvrt(uwnd, vwnd, lon, lat, xdim, ydim, cyclic=True, sphere=True): u""" """ u, v = np.ma.getdata(uwnd), np.ma.getdata(vwnd) mask = np.ma.getmask(uwnd) | np.ma.getmask(vwnd) ndim = u.ndim vor = rot(u, v, lon, lat, xdim, ydim, cyclic=cyclic, sphere=sphere) f = tools.expand(constants.earth_f(lat), ndim, axis=ydim) out = f + vor out = np.ma.array(out, mask=mask) out = tools.mrollaxis(out, ydim, 0) out[0,...] = np.ma.masked out[-1,...] = np.ma.masked out = tools.mrollaxis(out, 0, ydim+1) return out
def pottemp(temp, lev, zdim, punit=100., p0=100000.): ur""" 温位を計算する。 :Arguments: **temp** : array_like 気温 [K] **lev** : array_like 気圧 [punit*Pa] **zdim** : int 鉛直次元の軸 **punit** : float, optional **p0** : float, optional 基準気圧。デフォルトは1000hPa。 :Returns: **out** : ndarray .. note:: 温位は次のように定義される。 .. math:: \theta = T\left( \frac{p_{0}}{p} \right)^{\frac{R_d}{C_p}} **Referrences** **Examples** >>> """ temp = np.asarray(temp) ndim = temp.ndim p = tools.expand(lev, ndim, axis=zdim) out = temp * ((p0/p/punit)**kappa) return out
def stability(temp, lev, zdim, punit=100.): ur""" p座標系での静的安定度(Brunt-Vaisala振動数)を計算する。 :Arguments: **temp** : array_like 気温 [K] **lev** : array_like 等圧面の気圧 **zdim** : int 鉛直次元の位置 **punit** : float, optional Paに変換するためのファクター。デフォルトは100.。 :Returns: **N** : ndarray 静的安定度 .. note:: p面上の静的安定度は次式で定義される。 .. math:: N^2 = g\frac{\partial (\ln\theta)}{\partial z} = -\alpha\frac{\partial(\ln\theta)}{\partial p} **References** **Examples** >>> """ temp = np.asarray(temp) ndim = temp.ndim p = tools.expand(lev, ndim, axis=zdim)*punit theta = pottemp(temp, lev, zdim, punit=punit) alpha = rd*temp/p N = -alpha * dvardp(np.log(theta), lev, zdim, punit=punit) return N
def ertelpv(uwnd, vwnd, temp, lon, lat, lev, xdim, ydim, zdim, cyclic=True, punit=100., sphere=True): ur""" エルテルのポテンシャル渦度を計算する。 :Arguments: **uwnd, vwnd** : ndarray 東西風、南北風 [m/s] **temp** : ndarray 気温 [K] **lon, lat** : array_like 経度、緯度 [degrees] **lev** : array_like 気圧 [punit*Pa] **xdim, ydim, zdim** : int 東西、南北、鉛直次元の軸 **cyclic** : bool, optional 東西境界を周期境界で扱うか。デフォルトはTrue。 **punit** : float, optional Paに換算するための定数。デフォルトは100、すなわちlevはhPaで与えられると解釈する。 :Returns: **out** : ndarray .. note:: p座標系のポテンシャル渦度は次のように定義される。 .. math:: P = -g (f\mathbf{k}+\nabla_{p}\times\mathbf{v})\cdot\nabla_{p}\theta 鉛直風を含む項は他の項に比べ小さいから、次の近似的値を計算している。 .. math:: P \simeq -g\left\{ (f + \zeta)\frac{\partial\theta}{\partial p} - \frac{\partial v}{\partial p} \frac{\partial\theta}{\partial x} + \frac{\partial u}{\partial p}\frac{\partial\theta}{\partial y}\right\} **Referrences** Hoskins, B.J., M.E. McIntyre and A.E. Robertson, 1985: On the use and significance of isentropic potential vorticity maps, `QJRMS`, 111, 877-946, <http://onlinelibrary.wiley.com/doi/10.1002/qj.49711147002/abstract> **Examples** >>> """ u, v, t = np.ma.getdata(uwnd), np.ma.getdata(vwnd), np.ma.getdata(temp) mask = np.ma.getmask(uwnd) | np.ma.getmask(vwnd) | np.ma.getmask(temp) ndim = u.ndim # potential temperature theta = pottemp(t, lev, zdim, punit=punit) # dthdp = dvardp(theta, lev, zdim, punit=punit) dudp = dvardp(u, lev, zdim, punit=punit) dvdp = dvardp(v, lev, zdim, punit=punit) dthdx = dvardx(theta, lon, lat, xdim, ydim, cyclic=cyclic, sphere=sphere) dthdy = dvardy(theta, lat, ydim, sphere=sphere) # absolute vorticity vor = rot(u, v, lon, lat, xdim, ydim, cyclic=cyclic, sphere=sphere) f = tools.expand(constants.earth_f(lat), ndim, axis=ydim) avor = f + vor out = -g * (avor*dthdp - (dthdx*dvdp-dthdy*dudp)) out = np.ma.array(out, mask=mask) out = tools.mrollaxis(out, ydim, 0) out[0,...] = np.ma.masked out[-1,...] = np.ma.masked out = tools.mrollaxis(out, 0, ydim+1) return out
def tnflux3d(U, V, T, strm, lon, lat, lev, xdim, ydim, zdim, cyclic=True, limit=100, punit=100.): ur""" Takaya & Nakamura (2001) の波活動度フラックスをp面上で計算する。 :Arguments: **U, V** : ndarray 気候値東西風、南北風 [m/s] **T** : ndarray 気候値気温 [K] **strm** : ndarray 流線関数偏差 [m^2/s] **lon, lat** : array_like 経度、緯度 [degrees] **lev** : array_like 等圧面の気圧 **xdim, ydim, zdim** : int 東西、南北、鉛直次元の軸 **cyclic** : bool, optional 東西境界を周期境界で扱うか。デフォルトはTrue。 **limit** : float, optional デフォルトは100. **punit** : float, optional 等圧面の気圧levをPaに変換するファクター。デフォルトは100.、すなわちhPaからPaへ変換。 :Returns: **tnx, tny, tnz** : MaskedArray フラックスの東西、南北、鉛直成分 .. note:: p座標系のwave-activityフラックスは次で定義される。 .. math:: \mathbf{W}=\frac{1}{2|\mathbf{U}|} \left( \begin{array}{c} U({\Psi'}_{x}^{2}-\Psi'{\Psi'}_{xx}) + V({\Psi'}_{x}{\Psi'}_{y}-\Psi'{\Psi'}_{xy})\\ U({\Psi'}_{x}{\Psi'}_{y}-\Psi'{\Psi'}_{xy}) + V({\Psi'}_{x}^{2}-\Psi'{\Psi'}_{xx}) \\ \frac{f^2}{S^2}[U({\Psi'}_{x}{\Psi'}_{p}-\Psi'{\Psi'}_{xp}) + V({\Psi'}_{y}{\Psi'}_{p}-\Psi'{\Psi'}_{yp})] \end{array} \right) ここでSは静的安定度。 **References** Takaya, K and H. Nakamura, 2001: A formulation of a phase-independent wave-activity flux for stationary and migratory quasigeostrophic eddies on a zonally varying basic flow, `JAS`, 58, 608-627. <http://journals.ametsoc.org/doi/abs/10.1175/1520-0469%282001%29058%3C0608%3AAFOAPI%3E2.0.CO%3B2> **Examples** >>> """ U, V, T = np.asarray(U), np.asarray(V), np.asarray(T) ndim=U.ndim S = stability(T, lev, zdim, punit=punit) f = tools.expand(constants.const_f(lat), ndim, axis=ydim) dstrmdx = dvardx(strm, lon, lat, xdim, ydim, cyclic=cyclic) dstrmdy = dvardy(strm, lat, ydim) dstrmdp = dvardp(strm, lev, zdim, punit=punit) d2strmdx2 = d2vardx2(strm, lon, lat, xdim, ydim, cyclic=cyclic) d2strmdy2 = d2vardy2(strm, lat, ydim) d2strmdxdy = dvardy(dstrmdx, lat, ydim) d2strmdxdp = dvardx(dstrmdp, lon, lat, xdim, ydim, cyclic=True) d2strmdydp = dvardy(dstrmdp, lat, ydim) tnx = U * (dstrmdx**2 - strm*d2strmdx2) + V * (dstrmdx*dstrmdy - strm*d2strmdxdy) tny = U * (dstrmdx*dstrmdy - strm*d2strmdxdy) + V * (dstrmdy**2 - strm*d2strmdy2) tnz = f**2/S**2 * ( U*(dstrmdx*dstrmdp - strm*d2strmdxdp) - V*(dstrmdy*dstrmdp - strm*d2strmdydp) ) tnx = 0.5*tnx/np.abs(U + 1j*V) tny = 0.5*tny/np.abs(U + 1j*V) # 水平成分の大きさがlimit以上のグリッドと東風領域をマスクする。 tnxy = np.sqrt(tnx**2 + tny**2) tnx = np.ma.asarray(tnx) tny = np.ma.asarray(tny) tnz = np.ma.asarray(tnz) tnx[(U<0) | (tnxy>limit)] = np.ma.masked tny[(U<0) | (tnxy>limit)] = np.ma.masked tnz[(U<0) | (tnxy>limit)] = np.ma.masked return tnx, tny, tnz
def eof(data, tdim=0, lat=None, ydim=None): """ EOF解析。 :Arguments: **data** : ndarray 入力する2次元以上のデータ配列。 **tdim** : int, optional 入力データの時間次元の軸。デフォルトは0、すなわち先頭。 **lat** : array_like, optional 指定すると緯度に応じた面積重みをつける。 **ydim** : int, optional latを指定した場合の緯度次元の軸 :Returns: **EOFs** : ndarray m番目のEOFモードの空間構造。形状(M,Xn),Xnは空間方向のデータ数、M=min(Xn,Tn) **PCs** : ndarray m番目のEOFモードの時系列。形状(M,Tn),Tnは時間方向のデータ数。M=min(Xn,Tn) **lambdas** : 1darray m番目のEOFモードの寄与率[%]。長さM。 .. note:: 計算の際にはSVD解析を用いる。 **Referrences** **Examples** >>> """ data = np.asarray(data) ndim = data.ndim dtype = data.dtype if ndim<2: raise ValueError, "input data must have more than two dimendin." #緯度重みを考慮 if lat!=None and ydim!=None: factor = tools.expand(np.sqrt(np.cos(PI/180.*lat)), ndim, axis=ydim) data = data * factor #時間軸を先頭に data = np.rollaxis(data, tdim, 0) data, oldshape = tools.unshape(data) tn, xn = data.shape #SVD A, Lh, E = linalg.svd(data, full_matrices=False) lambdas = Lh*Lh/tn EOFs = E PCs = np.transpose(A*Lh) #規格化 EOFs = EOFs * np.sqrt(lambdas)[:,NA] PCs = PCs / np.sqrt(lambdas)[:,NA] #寄与率 lambdas = lambdas / lambdas.sum() * 100. # 形状を戻す eofshape = list(oldshape) eofshape.pop(tdim) eofshape.insert(0, len(lambdas)) EOFs = EOFs.reshape(eofshape) #(M,Tn,...) print eofshape #緯度重みを考慮 if lat!=None and ydim!=None: factor = tools.expand(np.sqrt(np.cos(PI/180.*lat)), ndim, axis=ydim) EOFs = EOFs / factor return EOFs, PCs, lambdas
def eof(data, tdim=0, lat=None, ydim=None): """ EOF解析。 :Arguments: **data** : ndarray 入力する2次元以上のデータ配列。 **tdim** : int, optional 入力データの時間次元の軸。デフォルトは0、すなわち先頭。 **lat** : array_like, optional 指定すると緯度に応じた面積重みをつける。 **ydim** : int, optional latを指定した場合の緯度次元の軸 :Returns: **EOFs** : ndarray m番目のEOFモードの空間構造。形状(M,Xn),Xnは空間方向のデータ数、M=min(Xn,Tn) **PCs** : ndarray m番目のEOFモードの時系列。形状(M,Tn),Tnは時間方向のデータ数。M=min(Xn,Tn) **lambdas** : 1darray m番目のEOFモードの寄与率[%]。長さM。 .. note:: 計算の際にはSVD解析を用いる。 **Referrences** **Examples** >>> """ data = np.asarray(data) ndim = data.ndim dtype = data.dtype if ndim < 2: raise ValueError, "input data must have more than two dimendin." #緯度重みを考慮 if lat != None and ydim != None: factor = tools.expand(np.sqrt(np.cos(PI / 180. * lat)), ndim, axis=ydim) data = data * factor #時間軸を先頭に data = np.rollaxis(data, tdim, 0) data, oldshape = tools.unshape(data) tn, xn = data.shape #SVD A, Lh, E = linalg.svd(data, full_matrices=False) lambdas = Lh * Lh / tn EOFs = E PCs = np.transpose(A * Lh) #規格化 EOFs = EOFs * np.sqrt(lambdas)[:, NA] PCs = PCs / np.sqrt(lambdas)[:, NA] #寄与率 lambdas = lambdas / lambdas.sum() * 100. # 形状を戻す eofshape = list(oldshape) eofshape.pop(tdim) eofshape.insert(0, len(lambdas)) EOFs = EOFs.reshape(eofshape) #(M,Tn,...) print eofshape #緯度重みを考慮 if lat != None and ydim != None: factor = tools.expand(np.sqrt(np.cos(PI / 180. * lat)), ndim, axis=ydim) EOFs = EOFs / factor return EOFs, PCs, lambdas
def dvardx(var, lon, lat, xdim, ydim, cyclic=True, sphere=True): ur""" 経度方向のx微分を中央差分で計算。 :Arguments: **var** : ndarray 微分を計算する領域の格子点の値 **lon** : array_like 経度, もしくはx座標 **lat** : array_like 緯度, もしくはy座標 **xdim, ydim**: int 入力配列の経度、緯度次元のインデックス **cyclic** : bool, optional 東西の境界を周期境界として扱うかどうか。False の場合は周期境界を用いずに前方、後方差分 で計算する。デフォルトは True。 **sphere** : bool, optional 球面緯度経度座標かどうか。デフォルトはTrue。Falseにすると直交座標として扱う。 :Returns: **result** : ndarray varと同じ形状。 .. note:: 球面緯度経度座標系におけるx微分は、次のように定義される。 .. math:: \frac{\partial \Phi}{\partial x} = \frac{1}{a\cos\phi}\frac{\partial \Phi}{\partial \lambda} ここで、aは地球半径。これを中央差分で次のように計算する。 .. math:: \left( \frac{\partial \Phi}{\partial x} \right)_{i,j} = \frac{1}{a\cos\phi_{j}}\frac{\Phi_{i+1,j} - \Phi_{i-1,j}}{\lambda_{i+1} - \lambda_{i-1}} cyclic=Falseの場合は、両端は前方、後方差分を用いて、 .. math:: \left( \frac{\partial \Phi}{\partial x} \right)_{0,j} = \frac{1}{a\cos\phi_{j}}\frac{\Phi_{1,j} - \Phi_{0,j}}{\lambda_{1} - \lambda_{0}} \hspace{3em} \left( \frac{\partial \Phi}{\partial x} \right)_{N-1,j} = \frac{1}{a\cos\phi_{j}}\frac{\Phi_{N-1,j} - \Phi_{N-2,j}}{\lambda_{N-1} - \lambda_{N-2}} で計算する。sphere=Falseの場合は、 .. math:: \left( \frac{\partial \Phi}{\partial x} \right)_{i,j} = \frac{\Phi_{i+1,j} - \Phi_{i-1,j}}{x_{i+1} - x_{i-1}} **Examples** >>> var.shape (24, 73, 144) >>> lon = np.arange(0, 360, 2.5) >>> lat = np.arange(-90, 90.1, 2.5) >>> result = dvardx(var, lon, lat, 2, 1, cyclic=True) >>> result.shape (24, 73, 144) 領域が全球でない場合。 >>> var.shape (24, 73, 72) >>> lon = np.arange(0, 180, 2.5) >>> lat = np.arange(-90, 90.1, 2.5) >>> result = dvardx(var, lon, lat, 2, 1, cyclic=False) >>> result.shape (24, 73, 72) """ var = np.array(var) ndim = var.ndim var = np.rollaxis(var, xdim, ndim) if cyclic and sphere: dvar = np.concatenate(\ ((var[...,1]-var[...,-1])[...,NA],\ (var[...,2:]-var[...,:-2]),\ (var[...,0]-var[...,-2])[...,NA]), axis=-1) dx = np.r_[(lon[1]+360-lon[-1]),\ (lon[2:]-lon[:-2] ),\ (lon[0]+360-lon[-2] )] else: dvar = np.concatenate(\ ((var[...,1]-var[...,0])[...,NA],\ (var[...,2:]-var[...,:-2]),\ (var[...,-1]-var[...,-2])[...,NA]), axis=-1) dx = np.r_[(lon[1]-lon[0] ),\ (lon[2:]-lon[:-2] ),\ (lon[-1]-lon[-2])] dvar = np.rollaxis(dvar, ndim - 1, xdim) if sphere: dx = a0 * PI / 180. * tools.expand(dx, ndim, xdim) * tools.expand( np.cos(lat * d2r), ndim, ydim) else: dx = tools.expand(dx, ndim, xdim) out = dvar / dx return out
def setup(self): # Extract a single experiment from the table that is not # already running. set self.experiment and self.state super(DBRSyncChannel, self).setup() self.state.jobman.sql.host_name = socket.gethostname() def state_del(state, keys): # Delete from the state the following key if present for key in keys: if hasattr(state, key): del state[key] # put jobs scheduler info into the state condor_slot = os.getenv("_CONDOR_SLOT") sge_task_id = os.getenv('SGE_TASK_ID') pbs_task_id = os.getenv('PBS_JOBID') if condor_slot: self.state.jobman.sql.condor_slot = condor_slot job_ad_file = os.getenv("_CONDOR_JOB_AD", None) if job_ad_file: f = open(job_ad_file) try: for line in f.readlines(): if line.startswith('GlobalJobId = '): self.state.jobman.sql.condor_global_job_id = line.split( '=')[1].strip()[1:-1] elif line.startswith('Out = '): self.state.jobman.sql.condor_stdout = line.split( '=')[1].strip()[1:-1] elif line.startswith('Err = '): self.state.jobman.sql.condor_stderr = line.split( '=')[1].strip()[1:-1] elif line.startswith('OrigIwd = '): self.state.jobman.sql.condor_origiwd = line.split( '=')[1].strip()[1:-1] finally: f.close() elif sge_task_id: self.state.jobman.sql.sge_task_id = sge_task_id self.state.jobman.sql.job_id = os.getenv('JOB_ID') self.state.jobman.sql.sge_stdout = os.getenv('SGE_STDOUT_PATH') self.state.jobman.sql.sge_stderr = os.getenv('SGE_STDERR_PATH') elif pbs_task_id: self.state.jobman.sql.pbs_task_id = pbs_task_id self.state.jobman.sql.pbs_queue = os.getenv('PBS_QUEUE') self.state.jobman.sql.pbs_arrayid = os.getenv('PBS_ARRAYID') self.state.jobman.sql.pbs_num_ppn = os.getenv('PBS_NUM_PPN') # delete old jobs scheduler info into the state # this is needed in case we move a job to a different system. # to know where it is running now. key_to_del = [] if not condor_slot: key_to_del.extend(['jobman.sql.condor_global_job_id', 'jobman.sql.condor_stdout', 'jobman.sql.condor_stderr', 'jobman.sql.condor_origiwd', 'jobman.sql.condor_slot']) if not sge_task_id: key_to_del.extend(['jobman.sql.sge_task_id', 'jobman.sql.job_id', 'jobman.sql.sge_stdout', 'self.state.jobman.sql.sge_stderr']) if not pbs_task_id: key_to_del.extend(['jobman.sql.pbs_task_id', 'jobman.sql.pbs_queue', 'jobman.sql.pbs_arrayid', 'jobman.sql.pbs_num_ppn']) flattened_state = flatten(self.state) deleted = False for k in key_to_del: if k in flattened_state: del flattened_state[k] deleted = True if deleted: self.state = expand(flattened_state) self.state.jobman.sql.start_time = time.time() self.state.jobman.sql.host_workdir = self.path self.dbstate.update(flatten(self.state))
def setup(self): # Extract a single experiment from the table that is not # already running. set self.experiment and self.state super(DBRSyncChannel, self).setup() self.state.jobman.sql.host_name = socket.gethostname() def state_del(state, keys): # Delete from the state the following key if present for key in keys: if hasattr(state, key): del state[key] #put jobs scheduler info into the state condor_slot = os.getenv("_CONDOR_SLOT") sge_task_id = os.getenv('SGE_TASK_ID') pbs_task_id = os.getenv('PBS_JOBID') if condor_slot: self.state.jobman.sql.condor_slot = condor_slot job_ad_file = os.getenv("_CONDOR_JOB_AD", None) if job_ad_file: f = open(job_ad_file) try: for line in f.readlines(): if line.startswith('GlobalJobId = '): self.state.jobman.sql.condor_global_job_id = line.split( '=')[1].strip()[1:-1] elif line.startswith('Out = '): self.state.jobman.sql.condor_stdout = line.split( '=')[1].strip()[1:-1] elif line.startswith('Err = '): self.state.jobman.sql.condor_stderr = line.split( '=')[1].strip()[1:-1] elif line.startswith('OrigIwd = '): self.state.jobman.sql.condor_origiwd = line.split( '=')[1].strip()[1:-1] finally: f.close() elif sge_task_id: self.state.jobman.sql.sge_task_id = sge_task_id self.state.jobman.sql.job_id = os.getenv('JOB_ID') self.state.jobman.sql.sge_stdout = os.getenv('SGE_STDOUT_PATH') self.state.jobman.sql.sge_stderr = os.getenv('SGE_STDERR_PATH') elif pbs_task_id: self.state.jobman.sql.pbs_task_id = pbs_task_id self.state.jobman.sql.pbs_queue = os.getenv('PBS_QUEUE') self.state.jobman.sql.pbs_arrayid = os.getenv('PBS_ARRAYID') self.state.jobman.sql.pbs_num_ppn = os.getenv('PBS_NUM_PPN') #delete old jobs scheduler info into the state #this is needed in case we move a job to a different system. #to know where it is running now. key_to_del = [] if not condor_slot: key_to_del.extend([ 'jobman.sql.condor_global_job_id', 'jobman.sql.condor_stdout', 'jobman.sql.condor_stderr', 'jobman.sql.condor_origiwd', 'jobman.sql.condor_slot' ]) if not sge_task_id: key_to_del.extend([ 'jobman.sql.sge_task_id', 'jobman.sql.job_id', 'jobman.sql.sge_stdout', 'self.state.jobman.sql.sge_stderr' ]) if not pbs_task_id: key_to_del.extend([ 'jobman.sql.pbs_task_id', 'jobman.sql.pbs_queue', 'jobman.sql.pbs_arrayid', 'jobman.sql.pbs_num_ppn' ]) flattened_state = flatten(self.state) deleted = False for k in key_to_del: if k in flattened_state: del flattened_state[k] deleted = True if deleted: self.state = expand(flattened_state) self.state.jobman.sql.start_time = time.time() self.state.jobman.sql.host_workdir = self.path self.dbstate.update(flatten(self.state))
def d2vardx2(var, lon, lat, xdim, ydim, cyclic=True, sphere=True): ur""" 経度方向の2階x微分を中央差分で計算。 :Arguments: **var** : ndarray 微分を計算する領域の格子点の値 **lon** : array_like 経度、もしくはx座標 **lat** : array_like 緯度、もしくはy座標 **xdim, ydim** : int 経度、緯度次元のインデックス。 **cyclic** : bool, optional 経度方向にはサイクリックとするかどうか。デフォルトではTrue。Falseの場合は東西端はゼロとする。 **sphere** : bool, optional 球面緯度経度座標かどうか。デフォルトはTrue。Falseにすると直交座標として扱う。 :Returns: **result** : ndarray varと同じ形状をもつ。 .. note:: 球面緯度経度座標系におけるx2回微分は、次のように定義される。 .. math:: \frac{\partial^2 \Phi}{\partial x^2} = \frac{1}{a^2\cos^2\phi}\frac{\partial^2 \Phi}{\partial \lambda^2} ここで、aは地球半径。これを中央差分で次のように計算する。 .. math:: \left( \frac{\partial^2 \Phi}{\partial x^2} \right)_{i,j} = \frac{4}{a^2\cos^2\phi_{j}}\frac{\Phi_{i+1,j} - 2\Phi_{i,j} + \Phi_{i-1,j}}{\lambda_{i+1} - \lambda_{i-1}} cyclic=Falseの場合は、両端はゼロとする。 **Examples** >>> >>> """ var = np.array(var) ndim = var.ndim #roll lon dim axis to last var = np.rollaxis(var, xdim, ndim) if cyclic and sphere: dvar = np.concatenate(\ ((var[...,1]-2*var[...,0]+var[...,-1])[...,NA],\ (var[...,2:]-2*var[...,1:-1]+var[...,:-2]),\ (var[...,0]-2*var[...,-1]+var[...,-2])[...,NA]),\ axis=-1) dx = np.r_[(lon[1]+360-lon[-1]),\ (lon[2:]-lon[:-2] ),\ (lon[0]+360-lon[-2] )] else: #edge is zero dvar = np.concatenate(\ ((var[...,0]-var[...,0])[...,NA],\ (var[...,2:]-2*var[...,1:-1]+var[...,:-2]),\ (var[...,0]-var[...,0])[...,NA]),\ axis=-1) dx = np.r_[(lon[1]-lon[0] ),\ (lon[2:]-lon[:-2] ),\ (lon[-1]-lon[-2])] dvar = np.rollaxis(dvar, ndim - 1, xdim) if sphere: dx2 = a0**2 * (PI / 180.)**2 * tools.expand( dx**2, ndim, xdim) * tools.expand( np.cos(lat * d2r)**2, ndim, ydim) else: dx2 = tools.expand(dx**2, ndim, xdim) out = 4. * dvar / dx2 #reroll lon dim axis to original dim out = np.rollaxis(out, ndim - 1, xdim) return out