Reorganiced pywafo

master
Per.Andreas.Brodtkorb 15 years ago
parent 6f5bcd9eed
commit d7a654d89b

@ -1,4 +0,0 @@
import os
os.system('epydoc --html -o html --name wafo --graph all src/wafo')

@ -1,22 +0,0 @@
setup.py
src\wafo\__init__.py
src\wafo\dctpack.py
src\wafo\definitions.py
src\wafo\demo_sg.py
src\wafo\info.py
src\wafo\interpolate.py
src\wafo\kdetools.py
src\wafo\misc.py
src\wafo\namedtuple.py
src\wafo\objects.py
src\wafo\plotbackend.py
src\wafo\polynomial.py
src\wafo\polynomial_old.py
src\wafo\sg_filter.py
src\wafo\data\__init__.py
src\wafo\data\info.py
src\wafo\spectrum\__init__.py
src\wafo\spectrum\dispersion_relation.py
src\wafo\spectrum\models.py
src\wafo\transform\__init__.py
src\wafo\transform\models.py

@ -1,56 +0,0 @@
"""
Install wafo
Usage:
python setup.py install [, --prefix=$PREFIX]
python setup.py develop
python setup.py bdist_wininst
"""
#!/usr/bin/env python
import os, sys
# make sure we import from WAFO in this package, not an installed one:
sys.path.insert(0, os.path.join('src'))
import wafo
if __file__ == 'setupegg.py':
# http://peak.telecommunity.com/DevCenter/setuptools
from setuptools import setup, Extension
else:
from distutils.core import setup
package_name = "wafo"
subpackages = ('spectrum','data','transform','covariance')
subpackagesfull = [os.path.join(package_name,f) for f in subpackages]
subtests = [os.path.join(subpkg,'test') for subpkg in subpackages]
testscripts = [os.path.join(subtst, f) for subtst in subtests
for f in os.listdir(os.path.join('src',package_name,subtst))
if not (f.startswith('.') or f.endswith('~') or
f.endswith('.old') or f.endswith('.bak'))]
datadir = 'data'
datafiles = [os.path.join(datadir, f) for f in os.listdir(os.path.join('src',package_name,datadir))
if not (f.endswith('.py') or f.endswith('test') )]
#docs = [os.path.join('doc', f) for f in os.listdir('doc')]
packagedata = testscripts + datafiles + ['c_library.pyd'] #,'disufq1.c','diffsumfunq.pyd','diffsumfunq.pyf','findrfc.c','rfc.pyd','rfc.pyf']
setup(
version = '0.11',
author='WAFO-group',
author_email='wafo@maths.lth.se',
description = wafo.__doc__,
license = "GPL",
url='http://www.maths.lth.se/matstat/wafo/',
name = package_name.upper(),
package_dir = {'': 'src'},
packages = [package_name,] + list(subpackagesfull),
package_data = {package_name: packagedata},
#package_data = {'': ['wafo.cfg']},
#scripts = [os.path.join('bin', f)
# for f in os.listdir('bin')
# if not (f.startswith('.') or f.endswith('~') or
# f.endswith('.old') or f.endswith('.bak'))],
)

@ -0,0 +1,92 @@
Metadata-Version: 1.0
Name: WAFO
Version: 0.11
Summary:
WAFO
=====
WAFO is a toolbox Python routines for statistical analysis and simulation of random waves and random loads.
WAFO is freely redistributable software, see WAFO licence, cf. the GNU General Public License (GPL) and
contain tools for:
Fatigue Analysis
----------------
-Fatigue life prediction for random loads
-Theoretical density of rainflow cycles
Sea modelling
-------------
-Simulation of linear and non-linear Gaussian waves
-Estimation of seamodels (spectrums)
-Joint wave height, wave steepness, wave period distributions
Statistics
------------
-Extreme value analysis
-Kernel density estimation
-Hidden markov models
WAFO consists of several modules with short descriptions below.
The modules SPECTRUM, COVARIANCE, TRANSFORM, WAVEMODELS, and MULTIDIM are
mainly for oceanographic applications.
The modules CYCLES, MARKOV, and DAMAGE are mainly for fatigue problems.
The contents file for each module is shown by typing 'help module-name'
Type 'help fatigue' for a presentation of all routines related to fatigue.
The paths to the modules are initiated by the function 'initwafo'.
ONEDIM - Data analysis of time series. Example: extraction of
turning points, estimation of spectrum and covariance function.
Estimation transformation used in transformed Gaussian model.
COVARIANCE - Computation of spectral functions, linear
and non-linear time series simulation.
SPECTRUM - Computation of spectral moments and covariance functions, linear
and non-linear time series simulation.
Ex: common spectra implemented, directional spectra,
bandwidth measures, exact distributions for wave characteristics.
TRANSFORM - Modelling with linear or transformed Gaussian waves. Ex:
WAVEMODELS - Models for distributions of wave characteristics found in
the literature. Ex: parametric models for breaking
limited wave heights.
MULTIDIM - Multi-dimensional time series analysis. (Under construction)
CYCLES - Cycle counting, discretization, and crossings, calculation of
damage. Simulation of discrete Markov chains, switching Markov
chains, harmonic oscillator. Ex: Rainflow cycles and matrix,
discretization of loads. Damage of a rainflow count or
matrix, damage matrix, S-N plot.
MARKOV - Routines for Markov loads, switching Markov loads, and
their connection to rainflow cycles.
DAMAGE - Calculation of damage. Ex: Damage of a rainflow count or
matrix, damage matrix, S-N plot.
SIMTOOLS - Simulation of random processes. Ex: spectral simulation,
simulation of discrete Markov chains, switching Markov
chains, harmonic oscillator
STATISTICS - Statistical tools and extreme-value distributions.
Ex: generation of random numbers, estimation of parameters,
evaluation of pdf and cdf
KDETOOLS - Kernel-density estimation.
MISC - Miscellaneous routines. Ex: numerical integration, smoothing
spline, binomial coefficient, water density.
WDEMOS - WAFO demos.
DOCS - Documentation of toolbox, definitions. An overview is given
in the routine wafomenu.
DATA - Measurements from marine applications.
PAPERS - Commands that generate figures in selected scientific
publications.
SOURCE - Fortran and C files. Information on compilation.
EXEC - Executable files (cf. SOURCE), pre-compiled for Solaris,
Alpha-Dec or Windows.
WAFO homepage: <http://www.maths.lth.se/matstat/wafo/>
On the WAFO home page you will find:
- The WAFO Tutorial
- New versions of WAFO to download.
- Reported bugs.
- List of publications related to WAFO.
Home-page: http://www.maths.lth.se/matstat/wafo/
Author: WAFO-group
Author-email: wafo@maths.lth.se
License: GPL
Description: UNKNOWN
Platform: UNKNOWN

@ -0,0 +1,39 @@
setup.py
setup_old.py
src/WAFO.egg-info/SOURCES.txt
src/Wafo.egg-info/PKG-INFO
src/Wafo.egg-info/SOURCES.txt
src/Wafo.egg-info/dependency_links.txt
src/Wafo.egg-info/top_level.txt
src/wafo/__init__.py
src/wafo/data_structures.py
src/wafo/dctpack.py
src/wafo/definitions.py
src/wafo/demo_sg.py
src/wafo/gaussian.py
src/wafo/info.py
src/wafo/integrate.py
src/wafo/interpolate.py
src/wafo/kdetools.py
src/wafo/meshgrid.py
src/wafo/misc.py
src/wafo/namedtuple.py
src/wafo/objects.py
src/wafo/plotbackend.py
src/wafo/polynomial.py
src/wafo/polynomial_old.py
src/wafo/sg_filter.py
src/wafo/wafodata.py
src/wafo.egg-info/SOURCES.txt
src/wafo/covariance/__init__.py
src/wafo/covariance/core.py
src/wafo/data/__init__.py
src/wafo/data/info.py
src/wafo/spectrum/__init__.py
src/wafo/spectrum/core.py
src/wafo/spectrum/dispersion_relation.py
src/wafo/spectrum/models.py
src/wafo/test/__init__.py
src/wafo/transform/__init__.py
src/wafo/transform/core.py
src/wafo/transform/models.py

@ -0,0 +1,5 @@
wafo\spectrum
wafo\covariance
wafo
wafo\data
wafo\transform

@ -0,0 +1,64 @@
(dp0
S'show_imports'
p1
I0
sS'private_css'
p2
S'default'
p3
sS'prj_name'
p4
S'WAFO'
p5
sS'docformat'
p6
S'restructuredtext'
p7
sS'inheritance'
p8
S'grouped'
p9
sS'help'
p10
NsS'modules'
p11
(S'C:/pab/workspace/PYWAFO/src/wafo/objects.py'
p12
S'C:/pab/workspace/PYWAFO/src/wafo/__init__.py'
p13
S'C:/pab/workspace/PYWAFO/src/wafo/info.py'
p14
S'C:/pab/workspace/PYWAFO/src/wafo/plotbackend.py'
p15
S'C:/pab/workspace/PYWAFO/src/wafo/spectrum/__init__.py'
p16
S'C:/pab/workspace/PYWAFO/src/wafo/spectrum/dispersion_relation.py'
p17
S'C:/pab/workspace/PYWAFO/src/wafo/spectrum/models.py'
p18
S'C:/pab/workspace/PYWAFO/src/wafo/data/info.py'
p19
S'C:/pab/workspace/PYWAFO/src/wafo/transform/__init__.py'
p20
S'C:/pab/workspace/PYWAFO/src/wafo/transform/models.py'
p21
tp22
sS'private'
p23
I1
sS'prj_url'
p24
S'http://www.maths.lth.se/matstat/wafo/'
p25
sS'frames'
p26
I1
sS'css'
p27
S'default'
p28
sS'outdir'
p29
S'html'
p30
s.

@ -0,0 +1,456 @@
"""
Data package in WAFO Toolbox.
Contents
--------
atlantic - Significant wave-height data recorded in the Atlantic Ocean
gfaks89 - Surface elevation measured at Gullfaks C 24.12.1989
gfaksr89 - Reconstructed surface elevation measured at Gullfaks C 24.12.1989.
japansea - coastline map of The Japan Sea
northsea - coastline map of The Nortsea
sea - Surface elevation dataset used in WAT version 1.1.
sfa89 - Wind measurements at Statfjord A 24.12.1989
sn - Fatigue experiment, constant-amplitude loading.
yura87 - Surface elevation measured off the coast of Yura
This module gives gives detailed information and easy access to all datasets
included in WAFO
"""
#from pylab import load
#from scipy.io import read_array
from numpy import (loadtxt,nan)
import os
__path2data = os.path.dirname( os.path.realpath(__file__))
__all__ =['atlantic','gfaks89','gfaksr89','japansea','northsea','sea','sfa89',
'sn','yura87']
def _load(file):
""" local load function
"""
return loadtxt(os.path.join(__path2data,file))
def _tofloat(x):
if x=='nan' or x=='NaN':
y = nan
else:
y = float(x or 0)
return y
def _loadnan(file):
""" local load function accepting nan's
"""
myconverter = {0: _tofloat, 1: _tofloat}
return loadtxt(os.path.join(__path2data,file),converters=myconverter)
def atlantic():
"""
Return Significant wave-height data recorded in the Atlantic Ocean
Data summary
------------
Size : 582 X 1
Sampling Rate : ~ 14 times a month
Device :
Source :
Format : ascii
Description
------------
atlantic.dat contains average significant wave-height data recorded
approximately 14 times a month in December-February during 7 years and
at 2 locations in the Atlantic Ocean
Example
--------
>>> import pylab
>>> import wafo
>>> Hs = wafo.data.atlantic()
>>> h = pylab.plot(Hs)
Acknowledgement:
---------------
This dataset were made available by Dr. David Carter
and Dr. David Cotton, Satellite Observing Systems, UK.
"""
return _load('atlantic.dat')
def gfaks89():
"""
Return Surface elevation measured at Gullfaks C 24.12.1989
Data summary
------------
Size : 39000 X 2
Sampling Rate : 2.5 Hz
Device : EMI laser
Source : STATOIL
Format : ascii, c1: time c2: surface elevation
Description
------------
The wave data was measured 24th December 1989 at the Gullfaks C platform
in the North Sea from 17.00 to 21.20. The period from 20.00 to 20.20
is missing and contains NaNs. The water depth of 218 m is
regarded as deep water for the most important wave components.
There are two EMI laser sensors named 219 and 220. This data set is
obtained from sensor 219, which is located in the Northwest
corner approximately two platform leg diameters away from
the closest leg.
Thus the wave elevation is not expected to be significantly
affected by diffraction effects for incoming waves in the western sector.
The wind direction for this period is from the south.
Some difficulties in calibration of the instruments have been reported
resulting in several consecutive measured values being equal or almost equal
in the observed data set.
This dataset is for non-commercial use only.
Hm0 = 6.8m, Tm02 = 8s, Tp = 10.5
Example
-------
>>> import pylab
>>> import wafo
>>> x = wafo.data.gfaks89()
>>> h = pylab.plot(x[:,0],x[:,1])
Acknowledgement:
---------------
This dataset were prepared and made available by Dr. S. Haver,
STATOIL, Norway
See also
--------
gfaksr89, northsea
"""
return _loadnan('gfaks89.dat')
def gfaksr89():
"""
Return a reconstruction of surface elevation measured at Gullfaks C 24.12.1989.
Data summary
------------
Size : 39000 X 2
Sampling Rate : 2.5 Hz
Device : EMI laser
Source : STATOIL
Format : ascii, c1: time c2: surface elevation
Description
-----------
This is a reconstructed version of the data in the GFAKS89.DAT file.
The following calls were made to reconstruct the data:
inds = findoutliers(gfaks89,.02,2,1.23);
gfaksr89 = reconstruct(gfaks89,inds,6);
The wave data was measured 24th December 1989 at the Gullfaks C platform
in the North Sea from 17.00 to 21.20. The period from 20.00 to 20.20
is missing in the original data. The water depth of 218 m is
regarded as deep water for the most important wave components.
There are two EMI laser sensors named 219 and 220. This data set is
obtained from sensor 219, which is located in the Northwest
corner approximately two platform leg diameters away from
the closest leg.
Thus the wave elevation is not expected to be significantly
affected by diffraction effects for incoming waves in the western sector.
The wind direction for this period is from the south.
Some difficulties in calibration of the instruments have been reported
resulting in several consecutive measured values being equal or almost equal
in the observed data set.
Hm0 = 6.8m, Tm02 = 8s, Tp = 10.5
Example
-------
>>> import pylab
>>> import wafo
>>> x = wafo.data.gfaksr89()
>>> h = pylab.plot(x[:,0],x[:,1])
See also
--------
gfaks89
"""
return _loadnan('gfaksr89.dat')
def japansea():
"""
Return coastline map of The Japan Sea
Data summary
------------
Size : 692 X 2
Sampling Rate :
Device :
Source : http://crusty.er.usgs.gov/coast/getcoast.html
Format : ascii, c1: longitude c2: latitude
Description
-----------
JAPANSEA.DAT contains data for plotting a map of The Japan Sea.
The data is obtained from USGS coastline extractor.
Example:
-------
#the map is seen by
>>> import pylab
>>> import wafo
>>> map1 = wafo.data.japansea()
>>> h = pylab.plot(map1[:,0],map1[:,1])
>>> lon_loc = [131,132,132,135,139.5,139]
>>> lat_loc = [46, 43, 40, 35, 38.3, 35.7]
>>> loc = ['China','Vladivostok','Japan Sea', 'Japan', 'Yura','Tokyo']
>>> algn = 'right'
>>> for lon, lat, name in zip(lon_loc,lat_loc,loc):
pylab.text(lon,lat,name,horizontalalignment=algn)
# If you have the m_map toolbox (see http://www.ocgy.ubc.ca/~rich/):
m_proj('lambert','long',[130 148],'lat',[30 48]);
m_line(map(:,1),map(:,2));
m_grid('box','fancy','tickdir','out');
m_text(131,46,'China');
m_text(132,43,'Vladivostok');
m_text(132,40,'Japan Sea');
m_text(135,35,'Japan');
m_text(139.5,38.3,'Yura');
m_text(139,35.7,'Tokyo');
"""
return _loadnan('japansea.dat')
def northsea():
"""
NORTHSEA coastline map of The Nortsea
Data summary
-------------
Size : 60646 X 2
Sampling Rate :
Device :
Source : http://crusty.er.usgs.gov/coast/getcoast.html
Format : ascii, c1: longitude c2: latitude
Description
-----------
NORTHSEA.DAT contains data for plotting a map of The Northsea.
The data is obtained from USGS coastline extractor.
Example
-------
# the map is seen by
>>> import pylab
>>> import wafo
>>> map1 = wafo.data.northsea()
>>> h = pylab.plot(map1[:,0],map1[:,1])
>>> lon_pltfrm = [1.8, 2.3, 2., 1.9, 2.6]
>>> lat_pltfrm = [61.2, 61.2, 59.9, 58.4, 57.7]
>>> pltfrm = ['Statfjord A', 'Gullfaks C', 'Frigg', 'Sleipner', 'Draupner']
>>> h = pylab.scatter(lon_pltfrm,lat_pltfrm);
>>> algn = 'right'
>>> for lon, lat, name in zip(lon_pltfrm,lat_pltfrm,pltfrm):
pylab.text(lon,lat,name,horizontalalignment=algn); algn = 'left'
>>> lon_city = [10.8, 10.8, 5.52, 5.2]
>>> lat_city = [59.85, 63.4, 58.9, 60.3]
>>> city = ['Oslo','Trondheim','Stavanger', 'Bergen']
>>> h = pylab.scatter(lon_city,lat_city);
>>> algn = 'right'
>>> for lon, lat, name in zip(lon_city,lat_city,city):
pylab.text(lon,lat,name,horizontalalignment=algn)
>>> from mpl_toolkits.basemap import Basemap
>>> import matplotlib.pyplot as plt
# setup Lambert Conformal basemap.
>>> m = Basemap(width=1200000,height=900000,projection='lcc',
resolution='f',lat_1=56.,lat_2=64,lat_0=58,lon_0=5.)
# draw coastlines.
>>> m.drawcoastlines()
>>> h = m.scatter(lon_pltfrm,lat_pltfrm);
>>> algn = 'right'
>>> for lon, lat, name in zip(lon_pltfrm,lat_pltfrm,pltfrm):
m.text(lon,lat,name,horizontalalignment=algn); algn = 'left'
>>> m.scatter(lon_city,lat_city)
>>> m.scatter()
# If you have the m_map toolbox (see http://www.ocgy.ubc.ca/~rich/):
m_proj('lambert','long',[-2 12],'lat',[56 64]);
m_line(map(:,1),map(:,2));
m_grid('box','fancy','tickdir','out');
m_text( 1,62 ,'Statfjord A') ;
m_line([1.8, 1.8], [62 ,61.2 ]);
m_text(1.7,61.2,'x') ;
m_text(1,59.5,'Gullfaks C') ;
m_line([1.8, 2.3 ], [59.50 ,61.20 ]);
m_text(2.20,61.20,'x') ;
m_text(10.10,60.05,'Oslo');
m_text(8.5,63.5,'Trondheim');
m_text(4.00,58.80,'Stavanger');
m_text(3.50,60.30,'Bergen') ;
m_text(8,61,'Norway');
"""
return _loadnan('northsea.dat')
def sea():
"""
Return Surface elevation dataset used in WAT version 1.1.
Data summary
------------
Size : 9524 X 2
Sampling Rate : 4.0 Hz
Device : unknown
Source : unknown
Format : ascii, c1: time c2: surface elevation
Description
-----------
The wave data was used in one of WAFO predecessors, i.e. the Wave
Analysis Toolbox version 1.1 (WAT)
Hm0 = 1.9m, Tm02 = 4.0s, Tp2 = 11.5s Tp1=5.6s
Example
-------
>>> import pylab
>>> import wafo
>>> x = wafo.data.sea()
>>> h = pylab.plot(x[:,0],x[:,1])
"""
return _load('sea.dat')
def sfa89():
"""
Return Wind measurements at Statfjord A 24.12.1989
Data summary
------------
Size : 144 X 3
Sampling Rate : 1/600 Hz
Device :
Source : DNMI (The Norwegian Meteorological Institute)
Format : ascii, c1: time (hours)
c2: velocity (m/s)
c3: direction (degrees)
Description
-----------
The registration of wind speeds at the Gullfaks field
started up on Statfjord A in 1978 and continued until 1990.
The dataregistration was transferred to Gullfaks C in Nov 1989.
Due to some difficulties of the windregistration on Gullfaks C in
the beginning, they continued to use the registered data from
Statfjord A.
The windspeed is measured in (meter/second), 110 m above mean water
level (MWL) and the wind direction is given in degrees for the data.
The data are a mean value of every 10 minutes.
Wind directions are defined in the meteorological convention, i.e.,
0 degrees = wind approaching from North, 90 degrees = wind from East, etc.
This dataset is for non-commercial use only.
Example
-------
>>> import pylab
>>> import wafo
>>> x = wafo.data.sfa89()
>>> h = pylab.plot(x[:,0],x[:,1])
Acknowledgement
----------------
These data are made available by Knut A. Iden, DNMI.
See also
--------
northsea
"""
return _load('sfa89.dat')
def sn():
"""
Return SN Fatigue experiment, constant-amplitude loading.
Data summary
------------
Size : 40 X 2
Source : unknown
Format : ascii, c1: Amplitude MPa c2: Number of cycles
Description
-----------
A fatigue experiment with constant amplitudes at five levels:
10,15,20,25 and 30 MPa. For each level is related 8 observations of
the number of cycles to failure.
The origin of the data is unknown.
Example
-------
>>> import pylab
>>> import wafo
>>> x = wafo.data.sn()
>>> h = pylab.plot(x[:,0],x[:,1])
See also
--------
The same data appear in the directory wdemos/itmkurs/
as SN.mat.
"""
return _load('sn.dat')
def yura87():
"""
Return Surface elevation measured off the coast of Yura.
Data summary
-----------
Size : 85547 X 4
Sampling Rate : 1 Hz
Device : ultrasonic wave gauges
Source : SRI, Ministry of Transport, Japan
Format : ascii, c1: time (sec) c2-4: surface elevation (m)
Description
-----------
The wave data was measured at the Poseidon platform
in the Japan Sea from 24th November 1987 08.12 hours to 25th November
1987 07.57 hours. Poseidon was located 3 km off the coast of Yura
in the Yamagata prefecture, in the Japan Sea during the measurements.
The most important wave components are to some extent influenced by the
water depth of 42 m. The data are measured with three ultrasonic wave
gauges located at the sea floor and the relative coordinates of the
gauges are as follows (x-axis points to the East, y-axis points to
the North):
X (m) Y (m)
c2: -4.93, 25.02
c3: 5.80, 92.12
c4: 0.00, 0.00
This dataset is for non-commercial use only.
Hm0 = 5.1m, Tm02 = 7.7s, Tp = 12.8s
Example
-------
>>> import pylab
>>> import wafo
>>> x = wafo.data.yura87()
>>> h = pylab.plot(x[:,0],x[:,1])
Acknowledgement:
-----------------
This dataset were prepared and made available by Dr. Sc. H. Tomita,
Ship Research Institute, Ministry of Transport, Japan.
See also
--------
japansea
"""
return _load('yura87.dat')
if __name__=='__main__':
import doctest
doctest.testmod()

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

@ -2,7 +2,7 @@ import numpy as np
from numpy import (r_, minimum, maximum, atleast_1d, atleast_2d, mod, zeros, #@UnresolvedImport
ones, floor, random, eye, nonzero, repeat, sqrt, inf, diag, triu) #@UnresolvedImport
from scipy.special import ndtri as invnorm
import rindmod
import wafo.rindmod as rindmod
class Rind(object):

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -8,7 +8,7 @@ def compile_all():
#compile_format = 'f2py %s %s -c --fcompiler=gnu95 --compiler=mingw32 -lmsvcr71'
# Install microsoft visual c++ .NET 2003 and run the following to build the module:
compile_format = 'f2py %s %s -c'
compile_format = 'f2py.py %s %s -c'
pyfs = ('c_library.pyf',)
files =('c_functions.c',)

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save