Aluode/PerceptionLabPortable
0
1from numpy import array, frombuffer, load
2from ._registry import registry, registry_urls
3
4try:
5 import pooch
6except ImportError:
7 pooch = None
8 data_fetcher = None
9else:
10 data_fetcher = pooch.create(
11 # Use the default cache folder for the operating system
12 # Pooch uses appdirs (https://github.com/ActiveState/appdirs) to
13 # select an appropriate directory for the cache on each platform.
14 path=pooch.os_cache("scipy-data"),
15
16 # The remote data is on Github
17 # base_url is a required param, even though we override this
18 # using individual urls in the registry.
19 base_url="https://github.com/scipy/",
20 registry=registry,
21 urls=registry_urls
22 )
23
24
25def fetch_data(dataset_name, data_fetcher=data_fetcher):
26 if data_fetcher is None:
27 raise ImportError("Missing optional dependency 'pooch' required "
28 "for scipy.datasets module. Please use pip or "
29 "conda to install 'pooch'.")
30 # The "fetch" method returns the full path to the downloaded data file.
31 return data_fetcher.fetch(dataset_name)
32
33
34def ascent():
35 """
36 Get an 8-bit grayscale bit-depth, 512 x 512 derived image for easy
37 use in demos.
38
39 The image is derived from
40 https://pixnio.com/people/accent-to-the-top
41
42 Parameters
43 ----------
44 None
45
46 Returns
47 -------
48 ascent : ndarray
49 convenient image to use for testing and demonstration
50
51 Examples
52 --------
53 >>> import scipy.datasets
54 >>> ascent = scipy.datasets.ascent()
55 >>> ascent.shape
56 (512, 512)
57 >>> ascent.max()
58 np.uint8(255)
59
60 >>> import matplotlib.pyplot as plt
61 >>> plt.gray()
62 >>> plt.imshow(ascent)
63 >>> plt.show()
64
65 """
66 import pickle
67
68 # The file will be downloaded automatically the first time this is run,
69 # returning the path to the downloaded file. Afterwards, Pooch finds
70 # it in the local cache and doesn't repeat the download.
71 fname = fetch_data("ascent.dat")
72 # Now we just need to load it with our standard Python tools.
73 with open(fname, 'rb') as f:
74 ascent = array(pickle.load(f))
75 return ascent
76
77
78def electrocardiogram():
79 """
80 Load an electrocardiogram as an example for a 1-D signal.
81
82 The returned signal is a 5 minute long electrocardiogram (ECG), a medical
83 recording of the heart's electrical activity, sampled at 360 Hz.
84
85 Returns
86 -------
87 ecg : ndarray
88 The electrocardiogram in millivolt (mV) sampled at 360 Hz.
89
90 Notes
91 -----
92 The provided signal is an excerpt (19:35 to 24:35) from the `record 208`_
93 (lead MLII) provided by the MIT-BIH Arrhythmia Database [1]_ on
94 PhysioNet [2]_. The excerpt includes noise induced artifacts, typical
95 heartbeats as well as pathological changes.
96
97 .. _record 208: https://physionet.org/physiobank/database/html/mitdbdir/records.htm#208
98
99 .. versionadded:: 1.1.0
100
101 References
102 ----------
103 .. [1] Moody GB, Mark RG. The impact of the MIT-BIH Arrhythmia Database.
104 IEEE Eng in Med and Biol 20(3):45-50 (May-June 2001).
105 (PMID: 11446209); :doi:`10.13026/C2F305`
106 .. [2] Goldberger AL, Amaral LAN, Glass L, Hausdorff JM, Ivanov PCh,
107 Mark RG, Mietus JE, Moody GB, Peng C-K, Stanley HE. PhysioBank,
108 PhysioToolkit, and PhysioNet: Components of a New Research Resource
109 for Complex Physiologic Signals. Circulation 101(23):e215-e220;
110 :doi:`10.1161/01.CIR.101.23.e215`
111
112 Examples
113 --------
114 >>> from scipy.datasets import electrocardiogram
115 >>> ecg = electrocardiogram()
116 >>> ecg
117 array([-0.245, -0.215, -0.185, ..., -0.405, -0.395, -0.385], shape=(108000,))
118 >>> ecg.shape, ecg.mean(), ecg.std()
119 ((108000,), -0.16510875, 0.5992473991177294)
120
121 As stated the signal features several areas with a different morphology.
122 E.g., the first few seconds show the electrical activity of a heart in
123 normal sinus rhythm as seen below.
124
125 >>> import numpy as np
126 >>> import matplotlib.pyplot as plt
127 >>> fs = 360
128 >>> time = np.arange(ecg.size) / fs
129 >>> plt.plot(time, ecg)
130 >>> plt.xlabel("time in s")
131 >>> plt.ylabel("ECG in mV")
132 >>> plt.xlim(9, 10.2)
133 >>> plt.ylim(-1, 1.5)
134 >>> plt.show()
135
136 After second 16, however, the first premature ventricular contractions,
137 also called extrasystoles, appear. These have a different morphology
138 compared to typical heartbeats. The difference can easily be observed
139 in the following plot.
140
141 >>> plt.plot(time, ecg)
142 >>> plt.xlabel("time in s")
143 >>> plt.ylabel("ECG in mV")
144 >>> plt.xlim(46.5, 50)
145 >>> plt.ylim(-2, 1.5)
146 >>> plt.show()
147
148 At several points large artifacts disturb the recording, e.g.:
149
150 >>> plt.plot(time, ecg)
151 >>> plt.xlabel("time in s")
152 >>> plt.ylabel("ECG in mV")
153 >>> plt.xlim(207, 215)
154 >>> plt.ylim(-2, 3.5)
155 >>> plt.show()
156
157 Finally, examining the power spectrum reveals that most of the biosignal is
158 made up of lower frequencies. At 60 Hz the noise induced by the mains
159 electricity can be clearly observed.
160
161 >>> from scipy.signal import welch
162 >>> f, Pxx = welch(ecg, fs=fs, nperseg=2048, scaling="spectrum")
163 >>> plt.semilogy(f, Pxx)
164 >>> plt.xlabel("Frequency in Hz")
165 >>> plt.ylabel("Power spectrum of the ECG in mV**2")
166 >>> plt.xlim(f[[0, -1]])
167 >>> plt.show()
168 """
169 fname = fetch_data("ecg.dat")
170 with load(fname) as file:
171 ecg = file["ecg"].astype(int) # np.uint16 -> int
172 # Convert raw output of ADC to mV: (ecg - adc_zero) / adc_gain
173 ecg = (ecg - 1024) / 200.0
174 return ecg
175
176
177def face(gray=False):
178 """
179 Get a 1024 x 768, color image of a raccoon face.
180
181 The image is derived from
182 https://pixnio.com/fauna-animals/raccoons/raccoon-procyon-lotor
183
184 Parameters
185 ----------
186 gray : bool, optional
187 If True return 8-bit grey-scale image, otherwise return a color image
188
189 Returns
190 -------
191 face : ndarray
192 image of a raccoon face
193
194 Examples
195 --------
196 >>> import scipy.datasets
197 >>> face = scipy.datasets.face()
198 >>> face.shape
199 (768, 1024, 3)
200 >>> face.max()
201 np.uint8(255)
202
203 >>> import matplotlib.pyplot as plt
204 >>> plt.gray()
205 >>> plt.imshow(face)
206 >>> plt.show()
207
208 """
209 import bz2
210 fname = fetch_data("face.dat")
211 with open(fname, 'rb') as f:
212 rawdata = f.read()
213 face_data = bz2.decompress(rawdata)
214 face = frombuffer(face_data, dtype='uint8')
215 face.shape = (768, 1024, 3)
216 if gray is True:
217 face = (0.21 * face[:, :, 0] + 0.71 * face[:, :, 1] +
218 0.07 * face[:, :, 2]).astype('uint8')
219 return face
220 