Created
March 22, 2018 21:30
-
-
Save lagru/1a69ef0bd0513865958f65b21a09202c to your computer and use it in GitHub Desktop.
eval_peak_widths.ipynb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Compare peak_widths" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"%load_ext Cython\n", | |
"\n", | |
"import numpy as np\n", | |
"import matplotlib.pyplot as plt\n", | |
"from scipy.signal import find_peaks, peak_prominences" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Definitions" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Import old version written with NumPy\n", | |
"from scipy.signal import peak_widths as old" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<!DOCTYPE html>\n", | |
"<!-- Generated by Cython 0.27.3 -->\n", | |
"<html>\n", | |
"<head>\n", | |
" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n", | |
" <title>Cython: _cython_magic_24aa845e29962e629f6f28ce60eb8ec5.pyx</title>\n", | |
" <style type=\"text/css\">\n", | |
" \n", | |
"body.cython { font-family: courier; font-size: 12; }\n", | |
"\n", | |
".cython.tag { }\n", | |
".cython.line { margin: 0em }\n", | |
".cython.code { font-size: 9; color: #444444; display: none; margin: 0px 0px 0px 8px; border-left: 8px none; }\n", | |
"\n", | |
".cython.line .run { background-color: #B0FFB0; }\n", | |
".cython.line .mis { background-color: #FFB0B0; }\n", | |
".cython.code.run { border-left: 8px solid #B0FFB0; }\n", | |
".cython.code.mis { border-left: 8px solid #FFB0B0; }\n", | |
"\n", | |
".cython.code .py_c_api { color: red; }\n", | |
".cython.code .py_macro_api { color: #FF7000; }\n", | |
".cython.code .pyx_c_api { color: #FF3000; }\n", | |
".cython.code .pyx_macro_api { color: #FF7000; }\n", | |
".cython.code .refnanny { color: #FFA000; }\n", | |
".cython.code .trace { color: #FFA000; }\n", | |
".cython.code .error_goto { color: #FFA000; }\n", | |
"\n", | |
".cython.code .coerce { color: #008000; border: 1px dotted #008000 }\n", | |
".cython.code .py_attr { color: #FF0000; font-weight: bold; }\n", | |
".cython.code .c_attr { color: #0000FF; }\n", | |
".cython.code .py_call { color: #FF0000; font-weight: bold; }\n", | |
".cython.code .c_call { color: #0000FF; }\n", | |
"\n", | |
".cython.score-0 {background-color: #FFFFff;}\n", | |
".cython.score-1 {background-color: #FFFFe7;}\n", | |
".cython.score-2 {background-color: #FFFFd4;}\n", | |
".cython.score-3 {background-color: #FFFFc4;}\n", | |
".cython.score-4 {background-color: #FFFFb6;}\n", | |
".cython.score-5 {background-color: #FFFFaa;}\n", | |
".cython.score-6 {background-color: #FFFF9f;}\n", | |
".cython.score-7 {background-color: #FFFF96;}\n", | |
".cython.score-8 {background-color: #FFFF8d;}\n", | |
".cython.score-9 {background-color: #FFFF86;}\n", | |
".cython.score-10 {background-color: #FFFF7f;}\n", | |
".cython.score-11 {background-color: #FFFF79;}\n", | |
".cython.score-12 {background-color: #FFFF73;}\n", | |
".cython.score-13 {background-color: #FFFF6e;}\n", | |
".cython.score-14 {background-color: #FFFF6a;}\n", | |
".cython.score-15 {background-color: #FFFF66;}\n", | |
".cython.score-16 {background-color: #FFFF62;}\n", | |
".cython.score-17 {background-color: #FFFF5e;}\n", | |
".cython.score-18 {background-color: #FFFF5b;}\n", | |
".cython.score-19 {background-color: #FFFF57;}\n", | |
".cython.score-20 {background-color: #FFFF55;}\n", | |
".cython.score-21 {background-color: #FFFF52;}\n", | |
".cython.score-22 {background-color: #FFFF4f;}\n", | |
".cython.score-23 {background-color: #FFFF4d;}\n", | |
".cython.score-24 {background-color: #FFFF4b;}\n", | |
".cython.score-25 {background-color: #FFFF48;}\n", | |
".cython.score-26 {background-color: #FFFF46;}\n", | |
".cython.score-27 {background-color: #FFFF44;}\n", | |
".cython.score-28 {background-color: #FFFF43;}\n", | |
".cython.score-29 {background-color: #FFFF41;}\n", | |
".cython.score-30 {background-color: #FFFF3f;}\n", | |
".cython.score-31 {background-color: #FFFF3e;}\n", | |
".cython.score-32 {background-color: #FFFF3c;}\n", | |
".cython.score-33 {background-color: #FFFF3b;}\n", | |
".cython.score-34 {background-color: #FFFF39;}\n", | |
".cython.score-35 {background-color: #FFFF38;}\n", | |
".cython.score-36 {background-color: #FFFF37;}\n", | |
".cython.score-37 {background-color: #FFFF36;}\n", | |
".cython.score-38 {background-color: #FFFF35;}\n", | |
".cython.score-39 {background-color: #FFFF34;}\n", | |
".cython.score-40 {background-color: #FFFF33;}\n", | |
".cython.score-41 {background-color: #FFFF32;}\n", | |
".cython.score-42 {background-color: #FFFF31;}\n", | |
".cython.score-43 {background-color: #FFFF30;}\n", | |
".cython.score-44 {background-color: #FFFF2f;}\n", | |
".cython.score-45 {background-color: #FFFF2e;}\n", | |
".cython.score-46 {background-color: #FFFF2d;}\n", | |
".cython.score-47 {background-color: #FFFF2c;}\n", | |
".cython.score-48 {background-color: #FFFF2b;}\n", | |
".cython.score-49 {background-color: #FFFF2b;}\n", | |
".cython.score-50 {background-color: #FFFF2a;}\n", | |
".cython.score-51 {background-color: #FFFF29;}\n", | |
".cython.score-52 {background-color: #FFFF29;}\n", | |
".cython.score-53 {background-color: #FFFF28;}\n", | |
".cython.score-54 {background-color: #FFFF27;}\n", | |
".cython.score-55 {background-color: #FFFF27;}\n", | |
".cython.score-56 {background-color: #FFFF26;}\n", | |
".cython.score-57 {background-color: #FFFF26;}\n", | |
".cython.score-58 {background-color: #FFFF25;}\n", | |
".cython.score-59 {background-color: #FFFF24;}\n", | |
".cython.score-60 {background-color: #FFFF24;}\n", | |
".cython.score-61 {background-color: #FFFF23;}\n", | |
".cython.score-62 {background-color: #FFFF23;}\n", | |
".cython.score-63 {background-color: #FFFF22;}\n", | |
".cython.score-64 {background-color: #FFFF22;}\n", | |
".cython.score-65 {background-color: #FFFF22;}\n", | |
".cython.score-66 {background-color: #FFFF21;}\n", | |
".cython.score-67 {background-color: #FFFF21;}\n", | |
".cython.score-68 {background-color: #FFFF20;}\n", | |
".cython.score-69 {background-color: #FFFF20;}\n", | |
".cython.score-70 {background-color: #FFFF1f;}\n", | |
".cython.score-71 {background-color: #FFFF1f;}\n", | |
".cython.score-72 {background-color: #FFFF1f;}\n", | |
".cython.score-73 {background-color: #FFFF1e;}\n", | |
".cython.score-74 {background-color: #FFFF1e;}\n", | |
".cython.score-75 {background-color: #FFFF1e;}\n", | |
".cython.score-76 {background-color: #FFFF1d;}\n", | |
".cython.score-77 {background-color: #FFFF1d;}\n", | |
".cython.score-78 {background-color: #FFFF1c;}\n", | |
".cython.score-79 {background-color: #FFFF1c;}\n", | |
".cython.score-80 {background-color: #FFFF1c;}\n", | |
".cython.score-81 {background-color: #FFFF1c;}\n", | |
".cython.score-82 {background-color: #FFFF1b;}\n", | |
".cython.score-83 {background-color: #FFFF1b;}\n", | |
".cython.score-84 {background-color: #FFFF1b;}\n", | |
".cython.score-85 {background-color: #FFFF1a;}\n", | |
".cython.score-86 {background-color: #FFFF1a;}\n", | |
".cython.score-87 {background-color: #FFFF1a;}\n", | |
".cython.score-88 {background-color: #FFFF1a;}\n", | |
".cython.score-89 {background-color: #FFFF19;}\n", | |
".cython.score-90 {background-color: #FFFF19;}\n", | |
".cython.score-91 {background-color: #FFFF19;}\n", | |
".cython.score-92 {background-color: #FFFF19;}\n", | |
".cython.score-93 {background-color: #FFFF18;}\n", | |
".cython.score-94 {background-color: #FFFF18;}\n", | |
".cython.score-95 {background-color: #FFFF18;}\n", | |
".cython.score-96 {background-color: #FFFF18;}\n", | |
".cython.score-97 {background-color: #FFFF17;}\n", | |
".cython.score-98 {background-color: #FFFF17;}\n", | |
".cython.score-99 {background-color: #FFFF17;}\n", | |
".cython.score-100 {background-color: #FFFF17;}\n", | |
".cython.score-101 {background-color: #FFFF16;}\n", | |
".cython.score-102 {background-color: #FFFF16;}\n", | |
".cython.score-103 {background-color: #FFFF16;}\n", | |
".cython.score-104 {background-color: #FFFF16;}\n", | |
".cython.score-105 {background-color: #FFFF16;}\n", | |
".cython.score-106 {background-color: #FFFF15;}\n", | |
".cython.score-107 {background-color: #FFFF15;}\n", | |
".cython.score-108 {background-color: #FFFF15;}\n", | |
".cython.score-109 {background-color: #FFFF15;}\n", | |
".cython.score-110 {background-color: #FFFF15;}\n", | |
".cython.score-111 {background-color: #FFFF15;}\n", | |
".cython.score-112 {background-color: #FFFF14;}\n", | |
".cython.score-113 {background-color: #FFFF14;}\n", | |
".cython.score-114 {background-color: #FFFF14;}\n", | |
".cython.score-115 {background-color: #FFFF14;}\n", | |
".cython.score-116 {background-color: #FFFF14;}\n", | |
".cython.score-117 {background-color: #FFFF14;}\n", | |
".cython.score-118 {background-color: #FFFF13;}\n", | |
".cython.score-119 {background-color: #FFFF13;}\n", | |
".cython.score-120 {background-color: #FFFF13;}\n", | |
".cython.score-121 {background-color: #FFFF13;}\n", | |
".cython.score-122 {background-color: #FFFF13;}\n", | |
".cython.score-123 {background-color: #FFFF13;}\n", | |
".cython.score-124 {background-color: #FFFF13;}\n", | |
".cython.score-125 {background-color: #FFFF12;}\n", | |
".cython.score-126 {background-color: #FFFF12;}\n", | |
".cython.score-127 {background-color: #FFFF12;}\n", | |
".cython.score-128 {background-color: #FFFF12;}\n", | |
".cython.score-129 {background-color: #FFFF12;}\n", | |
".cython.score-130 {background-color: #FFFF12;}\n", | |
".cython.score-131 {background-color: #FFFF12;}\n", | |
".cython.score-132 {background-color: #FFFF11;}\n", | |
".cython.score-133 {background-color: #FFFF11;}\n", | |
".cython.score-134 {background-color: #FFFF11;}\n", | |
".cython.score-135 {background-color: #FFFF11;}\n", | |
".cython.score-136 {background-color: #FFFF11;}\n", | |
".cython.score-137 {background-color: #FFFF11;}\n", | |
".cython.score-138 {background-color: #FFFF11;}\n", | |
".cython.score-139 {background-color: #FFFF11;}\n", | |
".cython.score-140 {background-color: #FFFF11;}\n", | |
".cython.score-141 {background-color: #FFFF10;}\n", | |
".cython.score-142 {background-color: #FFFF10;}\n", | |
".cython.score-143 {background-color: #FFFF10;}\n", | |
".cython.score-144 {background-color: #FFFF10;}\n", | |
".cython.score-145 {background-color: #FFFF10;}\n", | |
".cython.score-146 {background-color: #FFFF10;}\n", | |
".cython.score-147 {background-color: #FFFF10;}\n", | |
".cython.score-148 {background-color: #FFFF10;}\n", | |
".cython.score-149 {background-color: #FFFF10;}\n", | |
".cython.score-150 {background-color: #FFFF0f;}\n", | |
".cython.score-151 {background-color: #FFFF0f;}\n", | |
".cython.score-152 {background-color: #FFFF0f;}\n", | |
".cython.score-153 {background-color: #FFFF0f;}\n", | |
".cython.score-154 {background-color: #FFFF0f;}\n", | |
".cython.score-155 {background-color: #FFFF0f;}\n", | |
".cython.score-156 {background-color: #FFFF0f;}\n", | |
".cython.score-157 {background-color: #FFFF0f;}\n", | |
".cython.score-158 {background-color: #FFFF0f;}\n", | |
".cython.score-159 {background-color: #FFFF0f;}\n", | |
".cython.score-160 {background-color: #FFFF0f;}\n", | |
".cython.score-161 {background-color: #FFFF0e;}\n", | |
".cython.score-162 {background-color: #FFFF0e;}\n", | |
".cython.score-163 {background-color: #FFFF0e;}\n", | |
".cython.score-164 {background-color: #FFFF0e;}\n", | |
".cython.score-165 {background-color: #FFFF0e;}\n", | |
".cython.score-166 {background-color: #FFFF0e;}\n", | |
".cython.score-167 {background-color: #FFFF0e;}\n", | |
".cython.score-168 {background-color: #FFFF0e;}\n", | |
".cython.score-169 {background-color: #FFFF0e;}\n", | |
".cython.score-170 {background-color: #FFFF0e;}\n", | |
".cython.score-171 {background-color: #FFFF0e;}\n", | |
".cython.score-172 {background-color: #FFFF0e;}\n", | |
".cython.score-173 {background-color: #FFFF0d;}\n", | |
".cython.score-174 {background-color: #FFFF0d;}\n", | |
".cython.score-175 {background-color: #FFFF0d;}\n", | |
".cython.score-176 {background-color: #FFFF0d;}\n", | |
".cython.score-177 {background-color: #FFFF0d;}\n", | |
".cython.score-178 {background-color: #FFFF0d;}\n", | |
".cython.score-179 {background-color: #FFFF0d;}\n", | |
".cython.score-180 {background-color: #FFFF0d;}\n", | |
".cython.score-181 {background-color: #FFFF0d;}\n", | |
".cython.score-182 {background-color: #FFFF0d;}\n", | |
".cython.score-183 {background-color: #FFFF0d;}\n", | |
".cython.score-184 {background-color: #FFFF0d;}\n", | |
".cython.score-185 {background-color: #FFFF0d;}\n", | |
".cython.score-186 {background-color: #FFFF0d;}\n", | |
".cython.score-187 {background-color: #FFFF0c;}\n", | |
".cython.score-188 {background-color: #FFFF0c;}\n", | |
".cython.score-189 {background-color: #FFFF0c;}\n", | |
".cython.score-190 {background-color: #FFFF0c;}\n", | |
".cython.score-191 {background-color: #FFFF0c;}\n", | |
".cython.score-192 {background-color: #FFFF0c;}\n", | |
".cython.score-193 {background-color: #FFFF0c;}\n", | |
".cython.score-194 {background-color: #FFFF0c;}\n", | |
".cython.score-195 {background-color: #FFFF0c;}\n", | |
".cython.score-196 {background-color: #FFFF0c;}\n", | |
".cython.score-197 {background-color: #FFFF0c;}\n", | |
".cython.score-198 {background-color: #FFFF0c;}\n", | |
".cython.score-199 {background-color: #FFFF0c;}\n", | |
".cython.score-200 {background-color: #FFFF0c;}\n", | |
".cython.score-201 {background-color: #FFFF0c;}\n", | |
".cython.score-202 {background-color: #FFFF0c;}\n", | |
".cython.score-203 {background-color: #FFFF0b;}\n", | |
".cython.score-204 {background-color: #FFFF0b;}\n", | |
".cython.score-205 {background-color: #FFFF0b;}\n", | |
".cython.score-206 {background-color: #FFFF0b;}\n", | |
".cython.score-207 {background-color: #FFFF0b;}\n", | |
".cython.score-208 {background-color: #FFFF0b;}\n", | |
".cython.score-209 {background-color: #FFFF0b;}\n", | |
".cython.score-210 {background-color: #FFFF0b;}\n", | |
".cython.score-211 {background-color: #FFFF0b;}\n", | |
".cython.score-212 {background-color: #FFFF0b;}\n", | |
".cython.score-213 {background-color: #FFFF0b;}\n", | |
".cython.score-214 {background-color: #FFFF0b;}\n", | |
".cython.score-215 {background-color: #FFFF0b;}\n", | |
".cython.score-216 {background-color: #FFFF0b;}\n", | |
".cython.score-217 {background-color: #FFFF0b;}\n", | |
".cython.score-218 {background-color: #FFFF0b;}\n", | |
".cython.score-219 {background-color: #FFFF0b;}\n", | |
".cython.score-220 {background-color: #FFFF0b;}\n", | |
".cython.score-221 {background-color: #FFFF0b;}\n", | |
".cython.score-222 {background-color: #FFFF0a;}\n", | |
".cython.score-223 {background-color: #FFFF0a;}\n", | |
".cython.score-224 {background-color: #FFFF0a;}\n", | |
".cython.score-225 {background-color: #FFFF0a;}\n", | |
".cython.score-226 {background-color: #FFFF0a;}\n", | |
".cython.score-227 {background-color: #FFFF0a;}\n", | |
".cython.score-228 {background-color: #FFFF0a;}\n", | |
".cython.score-229 {background-color: #FFFF0a;}\n", | |
".cython.score-230 {background-color: #FFFF0a;}\n", | |
".cython.score-231 {background-color: #FFFF0a;}\n", | |
".cython.score-232 {background-color: #FFFF0a;}\n", | |
".cython.score-233 {background-color: #FFFF0a;}\n", | |
".cython.score-234 {background-color: #FFFF0a;}\n", | |
".cython.score-235 {background-color: #FFFF0a;}\n", | |
".cython.score-236 {background-color: #FFFF0a;}\n", | |
".cython.score-237 {background-color: #FFFF0a;}\n", | |
".cython.score-238 {background-color: #FFFF0a;}\n", | |
".cython.score-239 {background-color: #FFFF0a;}\n", | |
".cython.score-240 {background-color: #FFFF0a;}\n", | |
".cython.score-241 {background-color: #FFFF0a;}\n", | |
".cython.score-242 {background-color: #FFFF0a;}\n", | |
".cython.score-243 {background-color: #FFFF0a;}\n", | |
".cython.score-244 {background-color: #FFFF0a;}\n", | |
".cython.score-245 {background-color: #FFFF0a;}\n", | |
".cython.score-246 {background-color: #FFFF09;}\n", | |
".cython.score-247 {background-color: #FFFF09;}\n", | |
".cython.score-248 {background-color: #FFFF09;}\n", | |
".cython.score-249 {background-color: #FFFF09;}\n", | |
".cython.score-250 {background-color: #FFFF09;}\n", | |
".cython.score-251 {background-color: #FFFF09;}\n", | |
".cython.score-252 {background-color: #FFFF09;}\n", | |
".cython.score-253 {background-color: #FFFF09;}\n", | |
".cython.score-254 {background-color: #FFFF09;}\n", | |
".cython .hll { background-color: #ffffcc }\n", | |
".cython { background: #f8f8f8; }\n", | |
".cython .c { color: #408080; font-style: italic } /* Comment */\n", | |
".cython .err { border: 1px solid #FF0000 } /* Error */\n", | |
".cython .k { color: #008000; font-weight: bold } /* Keyword */\n", | |
".cython .o { color: #666666 } /* Operator */\n", | |
".cython .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n", | |
".cython .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n", | |
".cython .cp { color: #BC7A00 } /* Comment.Preproc */\n", | |
".cython .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n", | |
".cython .c1 { color: #408080; font-style: italic } /* Comment.Single */\n", | |
".cython .cs { color: #408080; font-style: italic } /* Comment.Special */\n", | |
".cython .gd { color: #A00000 } /* Generic.Deleted */\n", | |
".cython .ge { font-style: italic } /* Generic.Emph */\n", | |
".cython .gr { color: #FF0000 } /* Generic.Error */\n", | |
".cython .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n", | |
".cython .gi { color: #00A000 } /* Generic.Inserted */\n", | |
".cython .go { color: #888888 } /* Generic.Output */\n", | |
".cython .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n", | |
".cython .gs { font-weight: bold } /* Generic.Strong */\n", | |
".cython .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n", | |
".cython .gt { color: #0044DD } /* Generic.Traceback */\n", | |
".cython .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n", | |
".cython .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n", | |
".cython .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n", | |
".cython .kp { color: #008000 } /* Keyword.Pseudo */\n", | |
".cython .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n", | |
".cython .kt { color: #B00040 } /* Keyword.Type */\n", | |
".cython .m { color: #666666 } /* Literal.Number */\n", | |
".cython .s { color: #BA2121 } /* Literal.String */\n", | |
".cython .na { color: #7D9029 } /* Name.Attribute */\n", | |
".cython .nb { color: #008000 } /* Name.Builtin */\n", | |
".cython .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n", | |
".cython .no { color: #880000 } /* Name.Constant */\n", | |
".cython .nd { color: #AA22FF } /* Name.Decorator */\n", | |
".cython .ni { color: #999999; font-weight: bold } /* Name.Entity */\n", | |
".cython .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n", | |
".cython .nf { color: #0000FF } /* Name.Function */\n", | |
".cython .nl { color: #A0A000 } /* Name.Label */\n", | |
".cython .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n", | |
".cython .nt { color: #008000; font-weight: bold } /* Name.Tag */\n", | |
".cython .nv { color: #19177C } /* Name.Variable */\n", | |
".cython .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n", | |
".cython .w { color: #bbbbbb } /* Text.Whitespace */\n", | |
".cython .mb { color: #666666 } /* Literal.Number.Bin */\n", | |
".cython .mf { color: #666666 } /* Literal.Number.Float */\n", | |
".cython .mh { color: #666666 } /* Literal.Number.Hex */\n", | |
".cython .mi { color: #666666 } /* Literal.Number.Integer */\n", | |
".cython .mo { color: #666666 } /* Literal.Number.Oct */\n", | |
".cython .sa { color: #BA2121 } /* Literal.String.Affix */\n", | |
".cython .sb { color: #BA2121 } /* Literal.String.Backtick */\n", | |
".cython .sc { color: #BA2121 } /* Literal.String.Char */\n", | |
".cython .dl { color: #BA2121 } /* Literal.String.Delimiter */\n", | |
".cython .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n", | |
".cython .s2 { color: #BA2121 } /* Literal.String.Double */\n", | |
".cython .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n", | |
".cython .sh { color: #BA2121 } /* Literal.String.Heredoc */\n", | |
".cython .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n", | |
".cython .sx { color: #008000 } /* Literal.String.Other */\n", | |
".cython .sr { color: #BB6688 } /* Literal.String.Regex */\n", | |
".cython .s1 { color: #BA2121 } /* Literal.String.Single */\n", | |
".cython .ss { color: #19177C } /* Literal.String.Symbol */\n", | |
".cython .bp { color: #008000 } /* Name.Builtin.Pseudo */\n", | |
".cython .fm { color: #0000FF } /* Name.Function.Magic */\n", | |
".cython .vc { color: #19177C } /* Name.Variable.Class */\n", | |
".cython .vg { color: #19177C } /* Name.Variable.Global */\n", | |
".cython .vi { color: #19177C } /* Name.Variable.Instance */\n", | |
".cython .vm { color: #19177C } /* Name.Variable.Magic */\n", | |
".cython .il { color: #666666 } /* Literal.Number.Integer.Long */\n", | |
" </style>\n", | |
" <script>\n", | |
" function toggleDiv(id) {\n", | |
" theDiv = id.nextElementSibling\n", | |
" if (theDiv.style.display != 'block') theDiv.style.display = 'block';\n", | |
" else theDiv.style.display = 'none';\n", | |
" }\n", | |
" </script>\n", | |
"</head>\n", | |
"<body class=\"cython\">\n", | |
"<p><span style=\"border-bottom: solid 1px grey;\">Generated by Cython 0.27.3</span></p>\n", | |
"<p>\n", | |
" <span style=\"background-color: #FFFF00\">Yellow lines</span> hint at Python interaction.<br />\n", | |
" Click on a line that starts with a \"<code>+</code>\" to see the C code that Cython generated for it.\n", | |
"</p>\n", | |
"<div class=\"cython\"><pre class=\"cython line score-0\"> <span class=\"\">01</span>: </pre>\n", | |
"<pre class=\"cython line score-16\" onclick='toggleDiv(this)'>+<span class=\"\">02</span>: <span class=\"k\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span></pre>\n", | |
"<pre class='cython code score-16 '> __pyx_t_1 = <span class='pyx_c_api'>__Pyx_Import</span>(__pyx_n_s_numpy, 0, 0);<span class='error_goto'> if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) <span class='error_goto'>__PYX_ERR(0, 2, __pyx_L1_error)</span>\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
"/* … */\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyDict_NewPresized</span>(0);<span class='error_goto'> if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) <span class='error_goto'>__PYX_ERR(0, 2, __pyx_L1_error)</span>\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">03</span>: <span class=\"k\">cimport</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">04</span>: <span class=\"k\">import</span> <span class=\"nn\">cython</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">05</span>: </pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">06</span>: </pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">07</span>: <span class=\"nd\">@cython</span><span class=\"o\">.</span><span class=\"n\">wraparound</span><span class=\"p\">(</span><span class=\"bp\">False</span><span class=\"p\">)</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">08</span>: <span class=\"nd\">@cython</span><span class=\"o\">.</span><span class=\"n\">boundscheck</span><span class=\"p\">(</span><span class=\"bp\">False</span><span class=\"p\">)</span></pre>\n", | |
"<pre class=\"cython line score-121\" onclick='toggleDiv(this)'>+<span class=\"\">09</span>: <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float64_t</span><span class=\"p\">[::</span><span class=\"mf\">1</span><span class=\"p\">]</span> <span class=\"n\">x</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">,</span></pre>\n", | |
"<pre class='cython code score-121 '>/* Python wrapper */\n", | |
"static PyObject *__pyx_pw_46_cython_magic_24aa845e29962e629f6f28ce60eb8ec5_1inner(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/\n", | |
"static PyMethodDef __pyx_mdef_46_cython_magic_24aa845e29962e629f6f28ce60eb8ec5_1inner = {\"inner\", (PyCFunction)__pyx_pw_46_cython_magic_24aa845e29962e629f6f28ce60eb8ec5_1inner, METH_VARARGS|METH_KEYWORDS, 0};\n", | |
"static PyObject *__pyx_pw_46_cython_magic_24aa845e29962e629f6f28ce60eb8ec5_1inner(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {\n", | |
" __Pyx_memviewslice __pyx_v_x = { 0, 0, { 0 }, { 0 }, { 0 } };\n", | |
" __Pyx_memviewslice __pyx_v_peaks = { 0, 0, { 0 }, { 0 }, { 0 } };\n", | |
" __pyx_t_5numpy_float64_t __pyx_v_rel_height;\n", | |
" __Pyx_memviewslice __pyx_v_prominences = { 0, 0, { 0 }, { 0 }, { 0 } };\n", | |
" __Pyx_memviewslice __pyx_v_left_bases = { 0, 0, { 0 }, { 0 }, { 0 } };\n", | |
" __Pyx_memviewslice __pyx_v_right_bases = { 0, 0, { 0 }, { 0 }, { 0 } };\n", | |
" PyObject *__pyx_r = 0;\n", | |
" <span class='refnanny'>__Pyx_RefNannyDeclarations</span>\n", | |
" <span class='refnanny'>__Pyx_RefNannySetupContext</span>(\"inner (wrapper)\", 0);\n", | |
" {\n", | |
" static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,&__pyx_n_s_peaks,&__pyx_n_s_rel_height,&__pyx_n_s_prominences,&__pyx_n_s_left_bases,&__pyx_n_s_right_bases,0};\n", | |
" PyObject* values[6] = {0,0,0,0,0,0};\n", | |
" if (unlikely(__pyx_kwds)) {\n", | |
" Py_ssize_t kw_args;\n", | |
" const Py_ssize_t pos_args = <span class='py_macro_api'>PyTuple_GET_SIZE</span>(__pyx_args);\n", | |
" switch (pos_args) {\n", | |
" case 6: values[5] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 5);\n", | |
" CYTHON_FALLTHROUGH;\n", | |
" case 5: values[4] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 4);\n", | |
" CYTHON_FALLTHROUGH;\n", | |
" case 4: values[3] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 3);\n", | |
" CYTHON_FALLTHROUGH;\n", | |
" case 3: values[2] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 2);\n", | |
" CYTHON_FALLTHROUGH;\n", | |
" case 2: values[1] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 1);\n", | |
" CYTHON_FALLTHROUGH;\n", | |
" case 1: values[0] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 0);\n", | |
" CYTHON_FALLTHROUGH;\n", | |
" case 0: break;\n", | |
" default: goto __pyx_L5_argtuple_error;\n", | |
" }\n", | |
" kw_args = <span class='py_c_api'>PyDict_Size</span>(__pyx_kwds);\n", | |
" switch (pos_args) {\n", | |
" case 0:\n", | |
" if (likely((values[0] = <span class='py_c_api'>PyDict_GetItem</span>(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;\n", | |
" else goto __pyx_L5_argtuple_error;\n", | |
" CYTHON_FALLTHROUGH;\n", | |
" case 1:\n", | |
" if (likely((values[1] = <span class='py_c_api'>PyDict_GetItem</span>(__pyx_kwds, __pyx_n_s_peaks)) != 0)) kw_args--;\n", | |
" else {\n", | |
" <span class='pyx_c_api'>__Pyx_RaiseArgtupleInvalid</span>(\"inner\", 1, 6, 6, 1); <span class='error_goto'>__PYX_ERR(0, 9, __pyx_L3_error)</span>\n", | |
" }\n", | |
" CYTHON_FALLTHROUGH;\n", | |
" case 2:\n", | |
" if (likely((values[2] = <span class='py_c_api'>PyDict_GetItem</span>(__pyx_kwds, __pyx_n_s_rel_height)) != 0)) kw_args--;\n", | |
" else {\n", | |
" <span class='pyx_c_api'>__Pyx_RaiseArgtupleInvalid</span>(\"inner\", 1, 6, 6, 2); <span class='error_goto'>__PYX_ERR(0, 9, __pyx_L3_error)</span>\n", | |
" }\n", | |
" CYTHON_FALLTHROUGH;\n", | |
" case 3:\n", | |
" if (likely((values[3] = <span class='py_c_api'>PyDict_GetItem</span>(__pyx_kwds, __pyx_n_s_prominences)) != 0)) kw_args--;\n", | |
" else {\n", | |
" <span class='pyx_c_api'>__Pyx_RaiseArgtupleInvalid</span>(\"inner\", 1, 6, 6, 3); <span class='error_goto'>__PYX_ERR(0, 9, __pyx_L3_error)</span>\n", | |
" }\n", | |
" CYTHON_FALLTHROUGH;\n", | |
" case 4:\n", | |
" if (likely((values[4] = <span class='py_c_api'>PyDict_GetItem</span>(__pyx_kwds, __pyx_n_s_left_bases)) != 0)) kw_args--;\n", | |
" else {\n", | |
" <span class='pyx_c_api'>__Pyx_RaiseArgtupleInvalid</span>(\"inner\", 1, 6, 6, 4); <span class='error_goto'>__PYX_ERR(0, 9, __pyx_L3_error)</span>\n", | |
" }\n", | |
" CYTHON_FALLTHROUGH;\n", | |
" case 5:\n", | |
" if (likely((values[5] = <span class='py_c_api'>PyDict_GetItem</span>(__pyx_kwds, __pyx_n_s_right_bases)) != 0)) kw_args--;\n", | |
" else {\n", | |
" <span class='pyx_c_api'>__Pyx_RaiseArgtupleInvalid</span>(\"inner\", 1, 6, 6, 5); <span class='error_goto'>__PYX_ERR(0, 9, __pyx_L3_error)</span>\n", | |
" }\n", | |
" }\n", | |
" if (unlikely(kw_args > 0)) {\n", | |
" if (unlikely(<span class='pyx_c_api'>__Pyx_ParseOptionalKeywords</span>(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, \"inner\") < 0)) <span class='error_goto'>__PYX_ERR(0, 9, __pyx_L3_error)</span>\n", | |
" }\n", | |
" } else if (<span class='py_macro_api'>PyTuple_GET_SIZE</span>(__pyx_args) != 6) {\n", | |
" goto __pyx_L5_argtuple_error;\n", | |
" } else {\n", | |
" values[0] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 0);\n", | |
" values[1] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 1);\n", | |
" values[2] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 2);\n", | |
" values[3] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 3);\n", | |
" values[4] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 4);\n", | |
" values[5] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 5);\n", | |
" }\n", | |
" __pyx_v_x = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_5numpy_float64_t(values[0]);<span class='error_goto'> if (unlikely(!__pyx_v_x.memview)) __PYX_ERR(0, 9, __pyx_L3_error)</span>\n", | |
" __pyx_v_peaks = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_5numpy_intp_t(values[1]);<span class='error_goto'> if (unlikely(!__pyx_v_peaks.memview)) __PYX_ERR(0, 10, __pyx_L3_error)</span>\n", | |
" __pyx_v_rel_height = __pyx_<span class='py_c_api'>PyFloat_AsDouble</span>(values[2]); if (unlikely((__pyx_v_rel_height == ((npy_float64)-1)) && <span class='py_c_api'>PyErr_Occurred</span>())) <span class='error_goto'>__PYX_ERR(0, 11, __pyx_L3_error)</span>\n", | |
" __pyx_v_prominences = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_5numpy_float64_t(values[3]);<span class='error_goto'> if (unlikely(!__pyx_v_prominences.memview)) __PYX_ERR(0, 12, __pyx_L3_error)</span>\n", | |
" __pyx_v_left_bases = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_5numpy_intp_t(values[4]);<span class='error_goto'> if (unlikely(!__pyx_v_left_bases.memview)) __PYX_ERR(0, 13, __pyx_L3_error)</span>\n", | |
" __pyx_v_right_bases = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_5numpy_intp_t(values[5]);<span class='error_goto'> if (unlikely(!__pyx_v_right_bases.memview)) __PYX_ERR(0, 14, __pyx_L3_error)</span>\n", | |
" }\n", | |
" goto __pyx_L4_argument_unpacking_done;\n", | |
" __pyx_L5_argtuple_error:;\n", | |
" <span class='pyx_c_api'>__Pyx_RaiseArgtupleInvalid</span>(\"inner\", 1, 6, 6, <span class='py_macro_api'>PyTuple_GET_SIZE</span>(__pyx_args)); <span class='error_goto'>__PYX_ERR(0, 9, __pyx_L3_error)</span>\n", | |
" __pyx_L3_error:;\n", | |
" <span class='pyx_c_api'>__Pyx_AddTraceback</span>(\"_cython_magic_24aa845e29962e629f6f28ce60eb8ec5.inner\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n", | |
" <span class='refnanny'>__Pyx_RefNannyFinishContext</span>();\n", | |
" return NULL;\n", | |
" __pyx_L4_argument_unpacking_done:;\n", | |
" if (unlikely(((PyObject *)__pyx_v_x.memview) == Py_None)) {\n", | |
" <span class='py_c_api'>PyErr_Format</span>(PyExc_TypeError, \"Argument '%.200s' must not be None\", \"x\"); <span class='error_goto'>__PYX_ERR(0, 9, __pyx_L1_error)</span>\n", | |
" }\n", | |
" if (unlikely(((PyObject *)__pyx_v_peaks.memview) == Py_None)) {\n", | |
" <span class='py_c_api'>PyErr_Format</span>(PyExc_TypeError, \"Argument '%.200s' must not be None\", \"peaks\"); <span class='error_goto'>__PYX_ERR(0, 10, __pyx_L1_error)</span>\n", | |
" }\n", | |
" if (unlikely(((PyObject *)__pyx_v_prominences.memview) == Py_None)) {\n", | |
" <span class='py_c_api'>PyErr_Format</span>(PyExc_TypeError, \"Argument '%.200s' must not be None\", \"prominences\"); <span class='error_goto'>__PYX_ERR(0, 12, __pyx_L1_error)</span>\n", | |
" }\n", | |
" if (unlikely(((PyObject *)__pyx_v_left_bases.memview) == Py_None)) {\n", | |
" <span class='py_c_api'>PyErr_Format</span>(PyExc_TypeError, \"Argument '%.200s' must not be None\", \"left_bases\"); <span class='error_goto'>__PYX_ERR(0, 13, __pyx_L1_error)</span>\n", | |
" }\n", | |
" if (unlikely(((PyObject *)__pyx_v_right_bases.memview) == Py_None)) {\n", | |
" <span class='py_c_api'>PyErr_Format</span>(PyExc_TypeError, \"Argument '%.200s' must not be None\", \"right_bases\"); <span class='error_goto'>__PYX_ERR(0, 14, __pyx_L1_error)</span>\n", | |
" }\n", | |
" __pyx_r = __pyx_pf_46_cython_magic_24aa845e29962e629f6f28ce60eb8ec5_inner(__pyx_self, __pyx_v_x, __pyx_v_peaks, __pyx_v_rel_height, __pyx_v_prominences, __pyx_v_left_bases, __pyx_v_right_bases);\n", | |
"\n", | |
" /* function exit code */\n", | |
" goto __pyx_L0;\n", | |
" __pyx_L1_error:;\n", | |
" __pyx_r = NULL;\n", | |
" __pyx_L0:;\n", | |
" <span class='refnanny'>__Pyx_RefNannyFinishContext</span>();\n", | |
" return __pyx_r;\n", | |
"}\n", | |
"\n", | |
"static PyObject *__pyx_pf_46_cython_magic_24aa845e29962e629f6f28ce60eb8ec5_inner(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_x, __Pyx_memviewslice __pyx_v_peaks, __pyx_t_5numpy_float64_t __pyx_v_rel_height, __Pyx_memviewslice __pyx_v_prominences, __Pyx_memviewslice __pyx_v_left_bases, __Pyx_memviewslice __pyx_v_right_bases) {\n", | |
" __Pyx_memviewslice __pyx_v_widths = { 0, 0, { 0 }, { 0 }, { 0 } };\n", | |
" __Pyx_memviewslice __pyx_v_width_heights = { 0, 0, { 0 }, { 0 }, { 0 } };\n", | |
" __Pyx_memviewslice __pyx_v_left_ips = { 0, 0, { 0 }, { 0 }, { 0 } };\n", | |
" __Pyx_memviewslice __pyx_v_right_ips = { 0, 0, { 0 }, { 0 }, { 0 } };\n", | |
" __pyx_t_5numpy_float64_t __pyx_v_height;\n", | |
" __pyx_t_5numpy_float64_t __pyx_v_left_ip;\n", | |
" __pyx_t_5numpy_float64_t __pyx_v_right_ip;\n", | |
" __pyx_t_5numpy_intp_t __pyx_v_p;\n", | |
" __pyx_t_5numpy_intp_t __pyx_v_peak;\n", | |
" __pyx_t_5numpy_intp_t __pyx_v_i;\n", | |
" __pyx_t_5numpy_intp_t __pyx_v_i_max;\n", | |
" __pyx_t_5numpy_intp_t __pyx_v_i_min;\n", | |
" int __pyx_v_raise_error;\n", | |
" PyObject *__pyx_r = NULL;\n", | |
" <span class='refnanny'>__Pyx_RefNannyDeclarations</span>\n", | |
" <span class='refnanny'>__Pyx_RefNannySetupContext</span>(\"inner\", 0);\n", | |
"/* … */\n", | |
" /* function exit code */\n", | |
" __pyx_L1_error:;\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_1);\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_2);\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_3);\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_4);\n", | |
" <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_5);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_t_6, 1);\n", | |
" <span class='pyx_c_api'>__Pyx_AddTraceback</span>(\"_cython_magic_24aa845e29962e629f6f28ce60eb8ec5.inner\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n", | |
" __pyx_r = NULL;\n", | |
" __pyx_L0:;\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_v_widths, 1);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_v_width_heights, 1);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_v_left_ips, 1);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_v_right_ips, 1);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_v_x, 1);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_v_peaks, 1);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_v_prominences, 1);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_v_left_bases, 1);\n", | |
" __PYX_XDEC_MEMVIEW(&__pyx_v_right_bases, 1);\n", | |
" <span class='refnanny'>__Pyx_XGIVEREF</span>(__pyx_r);\n", | |
" <span class='refnanny'>__Pyx_RefNannyFinishContext</span>();\n", | |
" return __pyx_r;\n", | |
"}\n", | |
"/* … */\n", | |
" __pyx_tuple__29 = <span class='py_c_api'>PyTuple_Pack</span>(19, __pyx_n_s_x, __pyx_n_s_peaks, __pyx_n_s_rel_height, __pyx_n_s_prominences, __pyx_n_s_left_bases, __pyx_n_s_right_bases, __pyx_n_s_widths, __pyx_n_s_width_heights, __pyx_n_s_left_ips, __pyx_n_s_right_ips, __pyx_n_s_height, __pyx_n_s_left_ip, __pyx_n_s_right_ip, __pyx_n_s_p, __pyx_n_s_peak, __pyx_n_s_i, __pyx_n_s_i_max, __pyx_n_s_i_min, __pyx_n_s_raise_error);<span class='error_goto'> if (unlikely(!__pyx_tuple__29)) __PYX_ERR(0, 9, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_tuple__29);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_tuple__29);\n", | |
"/* … */\n", | |
" __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_24aa845e29962e629f6f28ce60eb8ec5_1inner, NULL, __pyx_n_s_cython_magic_24aa845e29962e629f);<span class='error_goto'> if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 9, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_d, __pyx_n_s_inner, __pyx_t_1) < 0) <span class='error_goto'>__PYX_ERR(0, 9, __pyx_L1_error)</span>\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
" __pyx_codeobj__30 = (PyObject*)<span class='pyx_c_api'>__Pyx_PyCode_New</span>(6, 0, 19, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__29, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_lg_cache_ipython_cython__c, __pyx_n_s_inner, 9, __pyx_empty_bytes);<span class='error_goto'> if (unlikely(!__pyx_codeobj__30)) __PYX_ERR(0, 9, __pyx_L1_error)</span>\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">10</span>: <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">intp_t</span><span class=\"p\">[::</span><span class=\"mf\">1</span><span class=\"p\">]</span> <span class=\"n\">peaks</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">,</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">11</span>: <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float64_t</span> <span class=\"n\">rel_height</span><span class=\"p\">,</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">12</span>: <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float64_t</span><span class=\"p\">[::</span><span class=\"mf\">1</span><span class=\"p\">]</span> <span class=\"n\">prominences</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">,</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">13</span>: <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">intp_t</span><span class=\"p\">[::</span><span class=\"mf\">1</span><span class=\"p\">]</span> <span class=\"n\">left_bases</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">,</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">14</span>: <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">intp_t</span><span class=\"p\">[::</span><span class=\"mf\">1</span><span class=\"p\">]</span> <span class=\"n\">right_bases</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">):</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">15</span>: <span class=\"k\">cdef</span><span class=\"p\">:</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">16</span>: <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float64_t</span><span class=\"p\">[::</span><span class=\"mf\">1</span><span class=\"p\">]</span> <span class=\"n\">widths</span><span class=\"p\">,</span> <span class=\"n\">width_heights</span><span class=\"p\">,</span> <span class=\"n\">left_ips</span><span class=\"p\">,</span> <span class=\"n\">right_ips</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">17</span>: <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float64_t</span> <span class=\"n\">height</span><span class=\"p\">,</span> <span class=\"n\">left_ip</span><span class=\"p\">,</span> <span class=\"n\">right_ip</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">18</span>: <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">intp_t</span> <span class=\"n\">p</span><span class=\"p\">,</span> <span class=\"n\">peak</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">i_max</span><span class=\"p\">,</span> <span class=\"n\">i_min</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">19</span>: <span class=\"n\">bint</span> <span class=\"n\">raise_error</span></pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">20</span>: </pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">21</span>: <span class=\"n\">raise_error</span> <span class=\"o\">=</span> <span class=\"bp\">False</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_raise_error = 0;\n", | |
"</pre><pre class=\"cython line score-35\" onclick='toggleDiv(this)'>+<span class=\"\">22</span>: <span class=\"n\">widths</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">empty</span><span class=\"p\">(</span><span class=\"n\">peaks</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mf\">0</span><span class=\"p\">],</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float64</span><span class=\"p\">)</span></pre>\n", | |
"<pre class='cython code score-35 '> __pyx_t_1 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np);<span class='error_goto'> if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" __pyx_t_2 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_1, __pyx_n_s_empty);<span class='error_goto'> if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 22, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
" __pyx_t_1 = <span class='py_c_api'>PyInt_FromSsize_t</span>((__pyx_v_peaks.shape[0]));<span class='error_goto'> if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" __pyx_t_3 = <span class='py_c_api'>PyTuple_New</span>(1);<span class='error_goto'> if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 22, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_1);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_3, 0, __pyx_t_1);\n", | |
" __pyx_t_1 = 0;\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyDict_NewPresized</span>(1);<span class='error_goto'> if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" __pyx_t_4 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np);<span class='error_goto'> if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 22, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n", | |
" __pyx_t_5 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_4, __pyx_n_s_float64);<span class='error_goto'> if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 22, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_5);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n", | |
" if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) <span class='error_goto'>__PYX_ERR(0, 22, __pyx_L1_error)</span>\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_5); __pyx_t_5 = 0;\n", | |
" __pyx_t_5 = <span class='pyx_c_api'>__Pyx_PyObject_Call</span>(__pyx_t_2, __pyx_t_3, __pyx_t_1);<span class='error_goto'> if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 22, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_5);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_3); __pyx_t_3 = 0;\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
" __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_5numpy_float64_t(__pyx_t_5);\n", | |
" if (unlikely(!__pyx_t_6.memview)) <span class='error_goto'>__PYX_ERR(0, 22, __pyx_L1_error)</span>\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_5); __pyx_t_5 = 0;\n", | |
" __pyx_v_widths = __pyx_t_6;\n", | |
" __pyx_t_6.memview = NULL;\n", | |
" __pyx_t_6.data = NULL;\n", | |
"</pre><pre class=\"cython line score-35\" onclick='toggleDiv(this)'>+<span class=\"\">23</span>: <span class=\"n\">width_heights</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">empty</span><span class=\"p\">(</span><span class=\"n\">peaks</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mf\">0</span><span class=\"p\">],</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float64</span><span class=\"p\">)</span></pre>\n", | |
"<pre class='cython code score-35 '> __pyx_t_5 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np);<span class='error_goto'> if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 23, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_5);\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_5, __pyx_n_s_empty);<span class='error_goto'> if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 23, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_5); __pyx_t_5 = 0;\n", | |
" __pyx_t_5 = <span class='py_c_api'>PyInt_FromSsize_t</span>((__pyx_v_peaks.shape[0]));<span class='error_goto'> if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 23, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_5);\n", | |
" __pyx_t_3 = <span class='py_c_api'>PyTuple_New</span>(1);<span class='error_goto'> if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 23, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_5);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_3, 0, __pyx_t_5);\n", | |
" __pyx_t_5 = 0;\n", | |
" __pyx_t_5 = <span class='pyx_c_api'>__Pyx_PyDict_NewPresized</span>(1);<span class='error_goto'> if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 23, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_5);\n", | |
" __pyx_t_2 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np);<span class='error_goto'> if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 23, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" __pyx_t_4 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_2, __pyx_n_s_float64);<span class='error_goto'> if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 23, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_4) < 0) <span class='error_goto'>__PYX_ERR(0, 23, __pyx_L1_error)</span>\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n", | |
" __pyx_t_4 = <span class='pyx_c_api'>__Pyx_PyObject_Call</span>(__pyx_t_1, __pyx_t_3, __pyx_t_5);<span class='error_goto'> if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 23, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_3); __pyx_t_3 = 0;\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_5); __pyx_t_5 = 0;\n", | |
" __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_5numpy_float64_t(__pyx_t_4);\n", | |
" if (unlikely(!__pyx_t_6.memview)) <span class='error_goto'>__PYX_ERR(0, 23, __pyx_L1_error)</span>\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n", | |
" __pyx_v_width_heights = __pyx_t_6;\n", | |
" __pyx_t_6.memview = NULL;\n", | |
" __pyx_t_6.data = NULL;\n", | |
"</pre><pre class=\"cython line score-35\" onclick='toggleDiv(this)'>+<span class=\"\">24</span>: <span class=\"n\">left_ips</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">empty</span><span class=\"p\">(</span><span class=\"n\">peaks</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mf\">0</span><span class=\"p\">],</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float64</span><span class=\"p\">)</span></pre>\n", | |
"<pre class='cython code score-35 '> __pyx_t_4 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np);<span class='error_goto'> if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 24, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n", | |
" __pyx_t_5 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_4, __pyx_n_s_empty);<span class='error_goto'> if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 24, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_5);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n", | |
" __pyx_t_4 = <span class='py_c_api'>PyInt_FromSsize_t</span>((__pyx_v_peaks.shape[0]));<span class='error_goto'> if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 24, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n", | |
" __pyx_t_3 = <span class='py_c_api'>PyTuple_New</span>(1);<span class='error_goto'> if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 24, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_4);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_3, 0, __pyx_t_4);\n", | |
" __pyx_t_4 = 0;\n", | |
" __pyx_t_4 = <span class='pyx_c_api'>__Pyx_PyDict_NewPresized</span>(1);<span class='error_goto'> if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 24, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np);<span class='error_goto'> if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 24, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" __pyx_t_2 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_1, __pyx_n_s_float64);<span class='error_goto'> if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
" if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_2) < 0) <span class='error_goto'>__PYX_ERR(0, 24, __pyx_L1_error)</span>\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" __pyx_t_2 = <span class='pyx_c_api'>__Pyx_PyObject_Call</span>(__pyx_t_5, __pyx_t_3, __pyx_t_4);<span class='error_goto'> if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_5); __pyx_t_5 = 0;\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_3); __pyx_t_3 = 0;\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n", | |
" __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_5numpy_float64_t(__pyx_t_2);\n", | |
" if (unlikely(!__pyx_t_6.memview)) <span class='error_goto'>__PYX_ERR(0, 24, __pyx_L1_error)</span>\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" __pyx_v_left_ips = __pyx_t_6;\n", | |
" __pyx_t_6.memview = NULL;\n", | |
" __pyx_t_6.data = NULL;\n", | |
"</pre><pre class=\"cython line score-35\" onclick='toggleDiv(this)'>+<span class=\"\">25</span>: <span class=\"n\">right_ips</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">empty</span><span class=\"p\">(</span><span class=\"n\">peaks</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mf\">0</span><span class=\"p\">],</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float64</span><span class=\"p\">)</span></pre>\n", | |
"<pre class='cython code score-35 '> __pyx_t_2 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np);<span class='error_goto'> if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" __pyx_t_4 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_2, __pyx_n_s_empty);<span class='error_goto'> if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 25, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" __pyx_t_2 = <span class='py_c_api'>PyInt_FromSsize_t</span>((__pyx_v_peaks.shape[0]));<span class='error_goto'> if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" __pyx_t_3 = <span class='py_c_api'>PyTuple_New</span>(1);<span class='error_goto'> if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 25, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_2);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_3, 0, __pyx_t_2);\n", | |
" __pyx_t_2 = 0;\n", | |
" __pyx_t_2 = <span class='pyx_c_api'>__Pyx_PyDict_NewPresized</span>(1);<span class='error_goto'> if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" __pyx_t_5 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np);<span class='error_goto'> if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 25, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_5);\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_5, __pyx_n_s_float64);<span class='error_goto'> if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_5); __pyx_t_5 = 0;\n", | |
" if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_1) < 0) <span class='error_goto'>__PYX_ERR(0, 25, __pyx_L1_error)</span>\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_Call</span>(__pyx_t_4, __pyx_t_3, __pyx_t_2);<span class='error_goto'> if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_3); __pyx_t_3 = 0;\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_5numpy_float64_t(__pyx_t_1);\n", | |
" if (unlikely(!__pyx_t_6.memview)) <span class='error_goto'>__PYX_ERR(0, 25, __pyx_L1_error)</span>\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
" __pyx_v_right_ips = __pyx_t_6;\n", | |
" __pyx_t_6.memview = NULL;\n", | |
" __pyx_t_6.data = NULL;\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">26</span>: </pre>\n", | |
"<pre class=\"cython line score-6\" onclick='toggleDiv(this)'>+<span class=\"\">27</span>: <span class=\"k\">with</span> <span class=\"k\">nogil</span><span class=\"p\">:</span></pre>\n", | |
"<pre class='cython code score-6 '> {\n", | |
" #ifdef WITH_THREAD\n", | |
" PyThreadState *_save;\n", | |
" Py_UNBLOCK_THREADS\n", | |
" <span class='pyx_c_api'>__Pyx_FastGIL_Remember</span>();\n", | |
" #endif\n", | |
" /*try:*/ {\n", | |
"/* … */\n", | |
" /*finally:*/ {\n", | |
" /*normal exit:*/{\n", | |
" #ifdef WITH_THREAD\n", | |
" <span class='pyx_c_api'>__Pyx_FastGIL_Forget</span>();\n", | |
" Py_BLOCK_THREADS\n", | |
" #endif\n", | |
" goto __pyx_L5;\n", | |
" }\n", | |
" __pyx_L4_error: {\n", | |
" #ifdef WITH_THREAD\n", | |
" <span class='pyx_c_api'>__Pyx_FastGIL_Forget</span>();\n", | |
" Py_BLOCK_THREADS\n", | |
" #endif\n", | |
" goto __pyx_L1_error;\n", | |
" }\n", | |
" __pyx_L5:;\n", | |
" }\n", | |
" }\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">28</span>: <span class=\"k\">for</span> <span class=\"n\">p</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">peaks</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mf\">0</span><span class=\"p\">]):</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_7 = (__pyx_v_peaks.shape[0]);\n", | |
" for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {\n", | |
" __pyx_v_p = __pyx_t_8;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">29</span>: <span class=\"n\">i_min</span> <span class=\"o\">=</span> <span class=\"n\">left_bases</span><span class=\"p\">[</span><span class=\"n\">p</span><span class=\"p\">]</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_9 = __pyx_v_p;\n", | |
" __pyx_v_i_min = (*((__pyx_t_5numpy_intp_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_intp_t *) __pyx_v_left_bases.data) + __pyx_t_9)) )));\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">30</span>: <span class=\"n\">i_max</span> <span class=\"o\">=</span> <span class=\"n\">right_bases</span><span class=\"p\">[</span><span class=\"n\">p</span><span class=\"p\">]</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_10 = __pyx_v_p;\n", | |
" __pyx_v_i_max = (*((__pyx_t_5numpy_intp_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_intp_t *) __pyx_v_right_bases.data) + __pyx_t_10)) )));\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">31</span>: <span class=\"n\">peak</span> <span class=\"o\">=</span> <span class=\"n\">peaks</span><span class=\"p\">[</span><span class=\"n\">p</span><span class=\"p\">]</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_11 = __pyx_v_p;\n", | |
" __pyx_v_peak = (*((__pyx_t_5numpy_intp_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_intp_t *) __pyx_v_peaks.data) + __pyx_t_11)) )));\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">32</span>: <span class=\"c\"># Validate bounds and order</span></pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">33</span>: <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"mf\">0</span> <span class=\"o\"><=</span> <span class=\"n\">i_min</span> <span class=\"o\"><=</span> <span class=\"n\">peak</span> <span class=\"o\"><=</span> <span class=\"n\">i_max</span> <span class=\"o\"><</span> <span class=\"n\">x</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mf\">0</span><span class=\"p\">]:</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_12 = (0 <= __pyx_v_i_min);\n", | |
" if (__pyx_t_12) {\n", | |
" __pyx_t_12 = (__pyx_v_i_min <= __pyx_v_peak);\n", | |
" if (__pyx_t_12) {\n", | |
" __pyx_t_12 = (__pyx_v_peak <= __pyx_v_i_max);\n", | |
" if (__pyx_t_12) {\n", | |
" __pyx_t_12 = (__pyx_v_i_max < (__pyx_v_x.shape[0]));\n", | |
" }\n", | |
" }\n", | |
" }\n", | |
" __pyx_t_13 = ((!(__pyx_t_12 != 0)) != 0);\n", | |
" if (__pyx_t_13) {\n", | |
"/* … */\n", | |
" }\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">34</span>: <span class=\"n\">raise_error</span> <span class=\"o\">=</span> <span class=\"bp\">True</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_raise_error = 1;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">35</span>: <span class=\"k\">break</span></pre>\n", | |
"<pre class='cython code score-0 '> goto __pyx_L7_break;\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">36</span>: </pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">37</span>: <span class=\"n\">height</span> <span class=\"o\">=</span> <span class=\"n\">width_heights</span><span class=\"p\">[</span><span class=\"n\">p</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">x</span><span class=\"p\">[</span><span class=\"n\">peak</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">prominences</span><span class=\"p\">[</span><span class=\"n\">p</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"n\">rel_height</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_14 = __pyx_v_peak;\n", | |
" __pyx_t_15 = __pyx_v_p;\n", | |
" __pyx_t_16 = ((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_float64_t *) __pyx_v_x.data) + __pyx_t_14)) ))) - ((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_float64_t *) __pyx_v_prominences.data) + __pyx_t_15)) ))) * __pyx_v_rel_height));\n", | |
" __pyx_v_height = __pyx_t_16;\n", | |
" __pyx_t_17 = __pyx_v_p;\n", | |
" *((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_float64_t *) __pyx_v_width_heights.data) + __pyx_t_17)) )) = __pyx_t_16;\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">38</span>: </pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">39</span>: <span class=\"c\"># Find intersection point on left side</span></pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">40</span>: <span class=\"n\">i</span> <span class=\"o\">=</span> <span class=\"n\">peak</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_i = __pyx_v_peak;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">41</span>: <span class=\"k\">while</span> <span class=\"n\">i_min</span> <span class=\"o\"><</span> <span class=\"n\">i</span> <span class=\"ow\">and</span> <span class=\"n\">height</span> <span class=\"o\"><</span> <span class=\"n\">x</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]:</span></pre>\n", | |
"<pre class='cython code score-0 '> while (1) {\n", | |
" __pyx_t_12 = ((__pyx_v_i_min < __pyx_v_i) != 0);\n", | |
" if (__pyx_t_12) {\n", | |
" } else {\n", | |
" __pyx_t_13 = __pyx_t_12;\n", | |
" goto __pyx_L11_bool_binop_done;\n", | |
" }\n", | |
" __pyx_t_18 = __pyx_v_i;\n", | |
" __pyx_t_12 = ((__pyx_v_height < (*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_float64_t *) __pyx_v_x.data) + __pyx_t_18)) )))) != 0);\n", | |
" __pyx_t_13 = __pyx_t_12;\n", | |
" __pyx_L11_bool_binop_done:;\n", | |
" if (!__pyx_t_13) break;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">42</span>: <span class=\"n\">i</span> <span class=\"o\">-=</span> <span class=\"mf\">1</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_i = (__pyx_v_i - 1);\n", | |
" }\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">43</span>: <span class=\"n\">left_ip</span> <span class=\"o\">=</span> <span class=\"o\"><</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float64_t</span><span class=\"o\">></span><span class=\"n\">i</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_left_ip = ((__pyx_t_5numpy_float64_t)__pyx_v_i);\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">44</span>: <span class=\"k\">if</span> <span class=\"n\">x</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\"><</span> <span class=\"n\">height</span><span class=\"p\">:</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_19 = __pyx_v_i;\n", | |
" __pyx_t_13 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_float64_t *) __pyx_v_x.data) + __pyx_t_19)) ))) < __pyx_v_height) != 0);\n", | |
" if (__pyx_t_13) {\n", | |
"/* … */\n", | |
" }\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">45</span>: <span class=\"c\"># Interpolate if true intersection height is between samples</span></pre>\n", | |
"<pre class=\"cython line score-9\" onclick='toggleDiv(this)'>+<span class=\"\">46</span>: <span class=\"n\">left_ip</span> <span class=\"o\">+=</span> <span class=\"p\">(</span><span class=\"n\">height</span> <span class=\"o\">-</span> <span class=\"n\">x</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">])</span> <span class=\"o\">/</span> <span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">[</span><span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"mf\">1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">x</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">])</span></pre>\n", | |
"<pre class='cython code score-9 '> __pyx_t_20 = __pyx_v_i;\n", | |
" __pyx_t_16 = (__pyx_v_height - (*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_float64_t *) __pyx_v_x.data) + __pyx_t_20)) ))));\n", | |
" __pyx_t_21 = (__pyx_v_i + 1);\n", | |
" __pyx_t_22 = __pyx_v_i;\n", | |
" __pyx_t_23 = ((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_float64_t *) __pyx_v_x.data) + __pyx_t_21)) ))) - (*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_float64_t *) __pyx_v_x.data) + __pyx_t_22)) ))));\n", | |
" if (unlikely(__pyx_t_23 == 0)) {\n", | |
" #ifdef WITH_THREAD\n", | |
" PyGILState_STATE __pyx_gilstate_save = <span class='pyx_c_api'>__Pyx_PyGILState_Ensure</span>();\n", | |
" #endif\n", | |
" <span class='py_c_api'>PyErr_SetString</span>(PyExc_ZeroDivisionError, \"float division\");\n", | |
" #ifdef WITH_THREAD\n", | |
" <span class='pyx_c_api'>__Pyx_PyGILState_Release</span>(__pyx_gilstate_save);\n", | |
" #endif\n", | |
" <span class='error_goto'>__PYX_ERR(0, 46, __pyx_L4_error)</span>\n", | |
" }\n", | |
" __pyx_v_left_ip = (__pyx_v_left_ip + (__pyx_t_16 / __pyx_t_23));\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">47</span>: </pre>\n", | |
"<pre class=\"cython line score-0\"> <span class=\"\">48</span>: <span class=\"c\"># Find intersection point on right side</span></pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">49</span>: <span class=\"n\">i</span> <span class=\"o\">=</span> <span class=\"n\">peak</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_i = __pyx_v_peak;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">50</span>: <span class=\"k\">while</span> <span class=\"n\">i</span> <span class=\"o\"><</span> <span class=\"n\">i_max</span> <span class=\"ow\">and</span> <span class=\"n\">height</span> <span class=\"o\"><</span> <span class=\"n\">x</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]:</span></pre>\n", | |
"<pre class='cython code score-0 '> while (1) {\n", | |
" __pyx_t_12 = ((__pyx_v_i < __pyx_v_i_max) != 0);\n", | |
" if (__pyx_t_12) {\n", | |
" } else {\n", | |
" __pyx_t_13 = __pyx_t_12;\n", | |
" goto __pyx_L16_bool_binop_done;\n", | |
" }\n", | |
" __pyx_t_24 = __pyx_v_i;\n", | |
" __pyx_t_12 = ((__pyx_v_height < (*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_float64_t *) __pyx_v_x.data) + __pyx_t_24)) )))) != 0);\n", | |
" __pyx_t_13 = __pyx_t_12;\n", | |
" __pyx_L16_bool_binop_done:;\n", | |
" if (!__pyx_t_13) break;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">51</span>: <span class=\"n\">i</span> <span class=\"o\">+=</span> <span class=\"mf\">1</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_i = (__pyx_v_i + 1);\n", | |
" }\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">52</span>: <span class=\"n\">right_ip</span> <span class=\"o\">=</span> <span class=\"o\"><</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float64_t</span><span class=\"o\">></span><span class=\"n\">i</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_v_right_ip = ((__pyx_t_5numpy_float64_t)__pyx_v_i);\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">53</span>: <span class=\"k\">if</span> <span class=\"n\">x</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\"><</span> <span class=\"n\">height</span><span class=\"p\">:</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_25 = __pyx_v_i;\n", | |
" __pyx_t_13 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_float64_t *) __pyx_v_x.data) + __pyx_t_25)) ))) < __pyx_v_height) != 0);\n", | |
" if (__pyx_t_13) {\n", | |
"/* … */\n", | |
" }\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">54</span>: <span class=\"c\"># Interpolate if true intersection height is between samples</span></pre>\n", | |
"<pre class=\"cython line score-9\" onclick='toggleDiv(this)'>+<span class=\"\">55</span>: <span class=\"n\">right_ip</span> <span class=\"o\">-=</span> <span class=\"p\">(</span><span class=\"n\">height</span> <span class=\"o\">-</span> <span class=\"n\">x</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">])</span> <span class=\"o\">/</span> <span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">[</span><span class=\"n\">i</span> <span class=\"o\">-</span> <span class=\"mf\">1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">x</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">])</span></pre>\n", | |
"<pre class='cython code score-9 '> __pyx_t_26 = __pyx_v_i;\n", | |
" __pyx_t_23 = (__pyx_v_height - (*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_float64_t *) __pyx_v_x.data) + __pyx_t_26)) ))));\n", | |
" __pyx_t_27 = (__pyx_v_i - 1);\n", | |
" __pyx_t_28 = __pyx_v_i;\n", | |
" __pyx_t_16 = ((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_float64_t *) __pyx_v_x.data) + __pyx_t_27)) ))) - (*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_float64_t *) __pyx_v_x.data) + __pyx_t_28)) ))));\n", | |
" if (unlikely(__pyx_t_16 == 0)) {\n", | |
" #ifdef WITH_THREAD\n", | |
" PyGILState_STATE __pyx_gilstate_save = <span class='pyx_c_api'>__Pyx_PyGILState_Ensure</span>();\n", | |
" #endif\n", | |
" <span class='py_c_api'>PyErr_SetString</span>(PyExc_ZeroDivisionError, \"float division\");\n", | |
" #ifdef WITH_THREAD\n", | |
" <span class='pyx_c_api'>__Pyx_PyGILState_Release</span>(__pyx_gilstate_save);\n", | |
" #endif\n", | |
" <span class='error_goto'>__PYX_ERR(0, 55, __pyx_L4_error)</span>\n", | |
" }\n", | |
" __pyx_v_right_ip = (__pyx_v_right_ip - (__pyx_t_23 / __pyx_t_16));\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">56</span>: </pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">57</span>: <span class=\"n\">widths</span><span class=\"p\">[</span><span class=\"n\">p</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">right_ip</span> <span class=\"o\">-</span> <span class=\"n\">left_ip</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_29 = __pyx_v_p;\n", | |
" *((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_float64_t *) __pyx_v_widths.data) + __pyx_t_29)) )) = (__pyx_v_right_ip - __pyx_v_left_ip);\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">58</span>: <span class=\"n\">left_ips</span><span class=\"p\">[</span><span class=\"n\">p</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">left_ip</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_30 = __pyx_v_p;\n", | |
" *((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_float64_t *) __pyx_v_left_ips.data) + __pyx_t_30)) )) = __pyx_v_left_ip;\n", | |
"</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">59</span>: <span class=\"n\">right_ips</span><span class=\"p\">[</span><span class=\"n\">p</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">right_ip</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_31 = __pyx_v_p;\n", | |
" *((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_float64_t *) __pyx_v_right_ips.data) + __pyx_t_31)) )) = __pyx_v_right_ip;\n", | |
" }\n", | |
" __pyx_L7_break:;\n", | |
" }\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">60</span>: </pre>\n", | |
"<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">61</span>: <span class=\"k\">if</span> <span class=\"n\">raise_error</span> <span class=\"ow\">is</span> <span class=\"bp\">True</span><span class=\"p\">:</span></pre>\n", | |
"<pre class='cython code score-0 '> __pyx_t_13 = ((__pyx_v_raise_error == 1) != 0);\n", | |
" if (__pyx_t_13) {\n", | |
"/* … */\n", | |
" }\n", | |
"</pre><pre class=\"cython line score-26\" onclick='toggleDiv(this)'>+<span class=\"\">62</span>: <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s\">"prominence data is invalid for peak "</span> <span class=\"o\">+</span> <span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">peak</span><span class=\"p\">))</span></pre>\n", | |
"<pre class='cython code score-26 '> __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyInt_From_Py_intptr_t</span>(__pyx_v_peak);<span class='error_goto'> if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 62, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" __pyx_t_2 = <span class='py_c_api'>PyTuple_New</span>(1);<span class='error_goto'> if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 62, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_1);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_2, 0, __pyx_t_1);\n", | |
" __pyx_t_1 = 0;\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_Call</span>(((PyObject *)(&PyUnicode_Type)), __pyx_t_2, NULL);<span class='error_goto'> if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 62, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" __pyx_t_2 = <span class='pyx_c_api'>__Pyx_PyUnicode_Concat</span>(__pyx_kp_u_prominence_data_is_invalid_for_p, __pyx_t_1);<span class='error_goto'> if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 62, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
" __pyx_t_1 = <span class='py_c_api'>PyTuple_New</span>(1);<span class='error_goto'> if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 62, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_2);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_1, 0, __pyx_t_2);\n", | |
" __pyx_t_2 = 0;\n", | |
" __pyx_t_2 = <span class='pyx_c_api'>__Pyx_PyObject_Call</span>(__pyx_builtin_ValueError, __pyx_t_1, NULL);<span class='error_goto'> if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 62, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n", | |
" <span class='pyx_c_api'>__Pyx_Raise</span>(__pyx_t_2, 0, 0, 0);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" <span class='error_goto'>__PYX_ERR(0, 62, __pyx_L1_error)</span>\n", | |
"</pre><pre class=\"cython line score-0\"> <span class=\"\">63</span>: </pre>\n", | |
"<pre class=\"cython line score-22\" onclick='toggleDiv(this)'>+<span class=\"\">64</span>: <span class=\"k\">return</span> <span class=\"n\">widths</span><span class=\"o\">.</span><span class=\"n\">base</span><span class=\"p\">,</span> <span class=\"n\">width_heights</span><span class=\"o\">.</span><span class=\"n\">base</span><span class=\"p\">,</span> <span class=\"n\">left_ips</span><span class=\"o\">.</span><span class=\"n\">base</span><span class=\"p\">,</span> <span class=\"n\">right_ips</span><span class=\"o\">.</span><span class=\"n\">base</span></pre>\n", | |
"<pre class='cython code score-22 '> <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_r);\n", | |
" __pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_widths, 1, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_5numpy_float64_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_5numpy_float64_t, 0);;<span class='error_goto'> if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 64, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_2, __pyx_n_s_base);<span class='error_goto'> if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 64, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" __pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_width_heights, 1, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_5numpy_float64_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_5numpy_float64_t, 0);;<span class='error_goto'> if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 64, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" __pyx_t_3 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_2, __pyx_n_s_base);<span class='error_goto'> if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 64, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" __pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_left_ips, 1, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_5numpy_float64_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_5numpy_float64_t, 0);;<span class='error_goto'> if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 64, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" __pyx_t_4 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_2, __pyx_n_s_base);<span class='error_goto'> if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 64, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" __pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_right_ips, 1, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_5numpy_float64_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_5numpy_float64_t, 0);;<span class='error_goto'> if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 64, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" __pyx_t_5 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_2, __pyx_n_s_base);<span class='error_goto'> if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 64, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_5);\n", | |
" <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n", | |
" __pyx_t_2 = <span class='py_c_api'>PyTuple_New</span>(4);<span class='error_goto'> if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 64, __pyx_L1_error)</span>\n", | |
" <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_1);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_2, 0, __pyx_t_1);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_3);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_2, 1, __pyx_t_3);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_4);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_2, 2, __pyx_t_4);\n", | |
" <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_5);\n", | |
" <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_2, 3, __pyx_t_5);\n", | |
" __pyx_t_1 = 0;\n", | |
" __pyx_t_3 = 0;\n", | |
" __pyx_t_4 = 0;\n", | |
" __pyx_t_5 = 0;\n", | |
" __pyx_r = __pyx_t_2;\n", | |
" __pyx_t_2 = 0;\n", | |
" goto __pyx_L0;\n", | |
"</pre></div></body></html>" | |
], | |
"text/plain": [ | |
"<IPython.core.display.HTML object>" | |
] | |
}, | |
"execution_count": 3, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"%%cython -a\n", | |
"\n", | |
"import numpy as np\n", | |
"cimport numpy as np\n", | |
"import cython\n", | |
"\n", | |
"\n", | |
"@cython.wraparound(False)\n", | |
"@cython.boundscheck(False)\n", | |
"def inner(np.float64_t[::1] x not None,\n", | |
" np.intp_t[::1] peaks not None,\n", | |
" np.float64_t rel_height,\n", | |
" np.float64_t[::1] prominences not None,\n", | |
" np.intp_t[::1] left_bases not None,\n", | |
" np.intp_t[::1] right_bases not None):\n", | |
" cdef:\n", | |
" np.float64_t[::1] widths, width_heights, left_ips, right_ips\n", | |
" np.float64_t height, left_ip, right_ip\n", | |
" np.intp_t p, peak, i, i_max, i_min\n", | |
" bint raise_error\n", | |
"\n", | |
" raise_error = False\n", | |
" widths = np.empty(peaks.shape[0], dtype=np.float64)\n", | |
" width_heights = np.empty(peaks.shape[0], dtype=np.float64)\n", | |
" left_ips = np.empty(peaks.shape[0], dtype=np.float64)\n", | |
" right_ips = np.empty(peaks.shape[0], dtype=np.float64)\n", | |
"\n", | |
" with nogil:\n", | |
" for p in range(peaks.shape[0]):\n", | |
" i_min = left_bases[p]\n", | |
" i_max = right_bases[p]\n", | |
" peak = peaks[p]\n", | |
" # Validate bounds and order\n", | |
" if not 0 <= i_min <= peak <= i_max < x.shape[0]:\n", | |
" raise_error = True\n", | |
" break\n", | |
"\n", | |
" height = width_heights[p] = x[peak] - prominences[p] * rel_height\n", | |
"\n", | |
" # Find intersection point on left side\n", | |
" i = peak\n", | |
" while i_min < i and height < x[i]:\n", | |
" i -= 1\n", | |
" left_ip = <np.float64_t>i\n", | |
" if x[i] < height:\n", | |
" # Interpolate if true intersection height is between samples\n", | |
" left_ip += (height - x[i]) / (x[i + 1] - x[i])\n", | |
"\n", | |
" # Find intersection point on right side\n", | |
" i = peak\n", | |
" while i < i_max and height < x[i]:\n", | |
" i += 1\n", | |
" right_ip = <np.float64_t>i\n", | |
" if x[i] < height:\n", | |
" # Interpolate if true intersection height is between samples\n", | |
" right_ip -= (height - x[i]) / (x[i - 1] - x[i])\n", | |
"\n", | |
" widths[p] = right_ip - left_ip\n", | |
" left_ips[p] = left_ip\n", | |
" right_ips[p] = right_ip\n", | |
"\n", | |
" if raise_error is True:\n", | |
" raise ValueError(\"prominence data is invalid for peak \" + str(peak))\n", | |
"\n", | |
" return widths.base, width_heights.base, left_ips.base, right_ips.base" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def new(x, peaks, rel_height=0.5, prominence_data=None, wlen=None):\n", | |
" # Inner function expects `x` to be C-contiguous\n", | |
" x = np.asarray(x, order='C', dtype=np.float64)\n", | |
" if x.ndim != 1:\n", | |
" raise ValueError('`x` must have exactly one dimension')\n", | |
"\n", | |
" peaks = np.asarray(peaks)\n", | |
" try:\n", | |
" # Safely convert to C-contiguous array of type np.intp\n", | |
" peaks = peaks.astype(np.intp, order='C', casting='safe',\n", | |
" subok=False, copy=False)\n", | |
" except TypeError:\n", | |
" if peaks.size == 0:\n", | |
" # Empty arrays default to np.float64 but are valid input\n", | |
" peaks = np.array([], dtype=np.intp)\n", | |
" else:\n", | |
" raise TypeError(\"Cannot safely cast `peaks` to dtype('intp')\")\n", | |
" if peaks.ndim != 1:\n", | |
" raise ValueError('`peaks` must have exactly one dimension')\n", | |
"\n", | |
" if rel_height < 0.0:\n", | |
" raise ValueError('`rel_height` must be greater or equal to 0.0')\n", | |
"\n", | |
" if prominence_data is None:\n", | |
" # Calculate prominence if not supplied and use wlen if supplied.\n", | |
" prominence_data = peak_prominences(x, peaks, wlen)\n", | |
"\n", | |
" return inner(x, peaks, rel_height, *prominence_data)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Compare" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Peaks: 10896\n" | |
] | |
}, | |
{ | |
"data": { | |
"image/png": "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\n", | |
"text/plain": [ | |
"<Figure size 432x288 with 1 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"np.random.seed(20180322)\n", | |
"x1 = np.random.normal(size=2 ** 15)\n", | |
"\n", | |
"peaks1 = find_peaks(x1)[0]\n", | |
"print(\"Peaks:\", peaks1.size)\n", | |
"pdata1 = peak_prominences(x1, peaks1)\n", | |
"\n", | |
"plt.plot(x1)\n", | |
"plt.plot(peaks1, x1[peaks1], \"x\")\n", | |
"plt.xlim(0, 100);" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"237 ms ± 6.89 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", | |
"280 µs ± 1.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n" | |
] | |
} | |
], | |
"source": [ | |
"%timeit old(x1, peaks1, prominence_data=pdata1)\n", | |
"%timeit new(x1, peaks1, prominence_data=pdata1)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": { | |
"scrolled": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"216 ms ± 7.37 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", | |
"427 µs ± 3.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n" | |
] | |
} | |
], | |
"source": [ | |
"%timeit old(x1, peaks1, rel_height=1, prominence_data=pdata1)\n", | |
"%timeit new(x1, peaks1, rel_height=1, prominence_data=pdata1)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Not exactly the same because of numeric errors during width calculation\n", | |
"np.testing.assert_almost_equal(old(x1, peaks1, prominence_data=pdata1),\n", | |
" new(x1, peaks1, prominence_data=pdata1))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Peaks: 890\n" | |
] | |
}, | |
{ | |
"data": { | |
"text/plain": [ | |
"(0, 2000)" | |
] | |
}, | |
"execution_count": 9, | |
"metadata": {}, | |
"output_type": "execute_result" | |
}, | |
{ | |
"data": { | |
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYoAAAD8CAYAAABpcuN4AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4wLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvFvnyVgAAIABJREFUeJzsnXd4VFX+/19nZjLpDQJJCC10CKB0EEREBBsqKupSFNe1fAXBtuqqu6urrrsWEMSCKyyuNFHERdeKiCxrRIoIhCJIlN5b+szce35/3DuTSQgx6h0I/D6v58nzzJy5M7l35pz7Pp9yPkdprREEQRCEE+E61ScgCIIg1G5EKARBEIRqEaEQBEEQqkWEQhAEQagWEQpBEAShWkQoBEEQhGoRoRAEQRCqRYRCEARBqBYRCkEQBKFaPKf6BKojLS1NN23a9FSfhiAIwmnFypUrD2it6zn1ebVaKJo2bcqKFStO9WkIgiCcViilfnTy88T1JAiCIFSLCIUgCIJQLSIUgiAIQrWIUAiCIAjVIkIhCIIgVIsIhSAIglAtIhSCIAhCtfykUCilGimlPldKbVBK5SmlxtntjyqldiqlVtt/l4S95w9KqS1KqU1KqUFh7RfZbVuUUg9G5pIEQRAEJ6nJgrsAcK/WepVSKhFYqZT61H5tgtb62fCDlVLtgOuBHKABsFAp1cp++UXgQmAHsFwptUBrvd6JCxEEQRAiw08KhdZ6N7DbflyglNoAZFXzliuAOVrrMiBfKbUF6G6/tkVrvRVAKTXHPlaEQhAEoRbzs2IUSqmmQCdgmd00Rim1Rik1TSmVardlAdvD3rbDbjtRuyAIglCLqbFQKKUSgHnAXVrrY8DLQHPgbCyL47ngoVW8XVfTXvn/3KqUWqGUWrF///6anp4gCIIQIWokFEqpKCyRmKm1fgdAa71Xa21orU3gH5S7l3YAjcLe3hDYVU17BbTWr2qtu2qtu9ar51jxQ0EQBOEXUpOsJwVMBTZorceHtWeGHTYEWGc/XgBcr5SKVkplAy2Br4HlQEulVLZSyosV8F7gzGUIgiAIkaImWU+9gZHAWqXUarvtIeA3SqmzsdxHPwC3AWit85RSc7GC1AFgtNbaAFBKjQE+BtzANK11noPXIgiCIEQApfVxYYJaQ9euXbXsRyEIgvDzUEqt1Fp3derzZGW2IAiCUC0iFIIgCEK1iFAIgiAI1SJCIQiCIFSLCIUgCIJQLSIUgiAIQrWIUAiCIAjVIkIhCIIgVIsIhSAIglAtIhSCIAhCtYhQCIIgCNUiQiEIgiBUiwiF0yx9HvKXVGzLX2K1C4IgnIaIUDhNVmd4a1S5WOQvsZ5ndT6VZyUIgvCLqcl+FMLPIbsvDJ2O8eaNLK83hB4H30UNnW61C4IgnIaIRREJsvsyzzWIntuncrjdCBEJQRBOa0QoIkH+EgYW/4eJgSEkrn3j+JiFIAjCaYQIhdPYMYk/Rt3HhMBQVvecUDFmIQiCcJohQuE0O1fB0OksIweAbUldYeh0q10QnEKy64STiAiF0/S5C7L74jdMAIp9AStG0eeuU3xiwhmFZNcJJxHJeooQRT4DgLKAeYrPRDgjsbPrzLmjWJ42hO4H5qOunS6JE0JEEIsiAmit8dkC4Tf0KT4b4Ywluy9fJA2mx/bXyM++XkRCiBgiFBGgsCwQeuwTi0KIFPlL6Lp/PhMDQ8jaMksSJoSIIUIRAY4U+0OPg7EKQXAUOybxcr0/MiEwlK+6PCfZdULEEKGIAOFC4ROhECKBnV2XF30WAD8kdpHsOiFiSDA7Ahwp8YUei+tJiAh2Fp3x2TLAdndm95U4hRARxKKIAEVhMQpxPQmRpNRvZdeFx8UEwWlEKCJAQakEs4WTw7FSy81ZJEIhRBARiggQHLSJMR6xKISIcrTEEgrpZ0Ik+UmhUEo1Ukp9rpTaoJTKU0qNq/T6fUoprZRKs58rpdQkpdQWpdQapVTnsGNvVEpttv9udP5yagfBxXapcV4JZgsRJSgUvoCs1xEiR02C2QHgXq31KqVUIrBSKfWp1nq9UqoRcCGwLez4i4GW9l8P4GWgh1KqDvBnoCug7c9ZoLU+7OD11AoKywJEuRXx0R4ZwELEKAsYlPqDCztlQiJEjp+0KLTWu7XWq+zHBcAGIMt+eQJwP9aNP8gVwL+0xVdAilIqExgEfKq1PmSLw6fARc5dSu2hsDRAfLQHr8clFoUQMY6VlMclAqb0MyFy/KwYhVKqKdAJWKaUuhzYqbX+ttJhWcD2sOc77LYTtZ9xFJUFSIj24HUr/BLMFiJExQoAYrkKkaPG6yiUUgnAPOAuLHfUw8DAqg6tok1X0175/9wK3ArQuHHjmp5eraLQFgqPy4VhygAWIkNhqVgUwsmhRhaFUioKSyRmaq3fAZoD2cC3SqkfgIbAKqVUBpal0Cjs7Q2BXdW0V0Br/arWuqvWumu9evV+/hXVAop8luvJ41YygIWIUVAmpWKEk0NNsp4UMBXYoLUeD6C1Xqu1rq+1bqq1boolAp211nuABcANdvZTT+Co1no38DEwUCmVqpRKxbJGPo7MZZ1agjEKt0uJRSFEjKBFkRDtkSrFQkSpieupNzASWKuUWm23PaS1/uAEx38AXAJsAYqBmwC01oeUUo8Dy+3j/qK1PvSLz7wWU1gWoGFqHGUBg4AIhRAhgjGK1PgosSiEiPKTQqG1XkrV8YXwY5qGPdbA6BMcNw2Y9vNO8fSjqMwgPtqN3zDFohAiRkgo4rwExKIQIoiszI4ARb4Acd5gjEIGsBAZgqViUuO8YlEIEUWEIgKUBUyio1y4XS5MEQohQhSWBfC6XXaMQoRCiBwiFA4T3AY12u3C4xKLQogcBaV+EmI8RLmVBLOFiCJC4TDBldjRUW7JehIiSmGpvV7H7SIgFoUQQUQoHCZYVtwbsihkAAuRIbiwM8rtwicWhRBBRCgcpiwQtChcYlEIEaWgNCgUMiERIosIhcMELYpoj8QohMhiVQBw41IyIREiiwiFwwQtCq/HynoyxCUgRIjiMiNUAUCy64RIIkLhMOUWhRu3C7EohIhRWBYg3muXitHSz4TIIULhMGUBa3c7r9u2KEQohAhR7LMsCpdSSIhCiCQ1LjMu1AxfWDDbIzM9IUJorSnyBUiIdmNqpJ8JEUUsCocpC0uPDWY9aRnEgsOU+A20hrhoDy7pZ0KEEaFwmGBMwmOvowDE/SQ4TlGZ5eKM97pxK6ufSTcTIoUIhcMYtrPY41K43dYAloC24DTBCgBWdp3VJhMSIVKIUDhMsNyz26XEohAihj8sDdvlCloU0s+EyCBC4TDBwep2Kdwu6+sVi0JwmmC12Ci3K+R6kgmJEClEKBwmKApul8L2PMkAFhwnmDQRZSdNgExIhMghQuEwRrhQ2M5jEQrBaYIWhTdMKGR1thApRCgcJigKHpcSl4AQMYL7T1jBbLufSYxCiBAiFA4TNP9dSpVno8gAFhwmPEbhUmJRCJFFhMJhzNA6CiUDWIgYvpBQKLEohIgjQuEwFYLZkh4rRAhfeJVicXEKEUaEwmFCwWwlMz0hclQVzBahECKFCIXDlAezZQALkaPCOgrpZ0KEEaFwmJBF4ZasJyFy+ANWn4qSldnCSUCEwmECYa4nl8z0hAhRFu56Ck1ITuUZCWcyIhQOU6GEh5KZnhAZ/BXK2VttMiERIoUIhcOEFwUU37EQKUIxCk95TTGZkAiRQoTCYYJlxl0KEQohYlTMerLapNaTECl+UiiUUo2UUp8rpTYopfKUUuPs9seVUmuUUquVUp8opRrY7UopNUkptcV+vXPYZ92olNps/90Yucs6dRha43EplBKLQogcPkOj7MmIS5ImhAhTE4siANyrtW4L9ARGK6XaAc9orTtqrc8G3gf+ZB9/MdDS/rsVeBlAKVUH+DPQA+gO/FkplerkxdQGAqYOBbFDA1hcAoLD+AImUW5XhQmJuJ6ESPGTQqG13q21XmU/LgA2AFla62Nhh8UDwV56BfAvbfEVkKKUygQGAZ9qrQ9prQ8DnwIXOXgttQLT1KENi8qrep7KMxLORPyGidf2OUkathBpPD/nYKVUU6ATsMx+/iRwA3AUON8+LAvYHva2HXbbidrPKAKmDgmEFAUUIoXfMPF6rA7mkjLjQoSpcTBbKZUAzAPuCloTWuuHtdaNgJnAmOChVbxdV9Ne+f/cqpRaoZRasX///pqeXq3BqCAUdjaKDGDBYfxGeT/zSKkYIcLUSCiUUlFYIjFTa/1OFYfMAq62H+8AGoW91hDYVU17BbTWr2qtu2qtu9arV68mp1erMMJdT0p2HhMig2GaoX4WtCiknwmRoiZZTwqYCmzQWo8Pa28ZdtjlwEb78QLgBjv7qSdwVGu9G/gYGKiUSrWD2APttjMKw9ShILZLFkIJEcIwy2NgbilnL0SYmsQoegMjgbVKqdV220PAzUqp1oAJ/Ajcbr/2AXAJsAUoBm4C0FofUko9Diy3j/uL1vqQI1dRiwhUFcwWl4DgMIZphrk4JZgtRJafFAqt9VKqji98cILjNTD6BK9NA6b9nBM83TBNjdtdcaYnA1hwGkOXC4RLSsUIEUZWZjtMwNQhgRCLQogUhmke18+kKKAQKUQoHMbQ+jiXQLD+kyA4RcXsOsl6EiKLCIXDGIbGY0exZWW2ECmqFApZ2SlECBEKhwkv4eGWhVBChKggFLIfhRBhRCgcxtTHZz2JRSE4TXgFgGAatkxIhEghQuEwFQaw5LcLEcLUxydNyIREiBQiFA4Tnt/ukRWzQoQIGFW5nqSfCZFBhMJhjAouARnAQmQwq8iuk34mRAoRCocxZB2FcBIIVJn1JP1MiAwiFA4TMDWe41Zmn8ozEs5EzCosV5mQCJFChMJhzKqyUWQACw4TXlNMtkIVIo0IhcOEl/AILryTldmC04RXKXbLwk4hwohQOEyFYLZdSlEGsOA0RpiLU9ZRCJFGhMJhwgewUgqXkgEsOI+hq7AoJBYmRAgRCocJdwmAlZEiFoXgNBV2UpRgthBhRCgcxggr4QFWoFEsCsFpjLCaYkoplBKhECKHCIXDBIzyAQzW6mzJRhGcJtyiAMv9JP1MiBQiFA5TeQC7XEpKeAiOE540AVY/ExenEClEKBzG2rio/Gt1u5S4BATHqSwUbnFxChFEhMJhrAFc/lxcAkIkMMKqx4KdNCFZT0KEEKFwGMv1VP61usSiECKAYVS0XF0SzBYiiAiFw1R2CUgwW4gElouz/Llb+pkQQUQoHCYQth8FWOmxEswWnMaqHlsxFibBbCFSiFA4jGlSMcjokiCj4DxmpViYrNcRIokIhcMETLNifrtLITUBBaep0qIQoRAihAiFg2itMTUVSnhIrSfBaYL9ya0qujjF9SREChEKBwnO6I6zKEQoBAcJxryCxSdBXJxCZBGhcJDgAHZVEAqXBLMFRwmmwR5ffPJUnZFwpiNC4SBVWxSS3y44S6CKfiYuTiGS/KRQKKUaKaU+V0ptUErlKaXG2e3PKKU2KqXWKKXmK6VSwt7zB6XUFqXUJqXUoLD2i+y2LUqpByNzSaeOoI+4cmkFcT0JTmJUablKPxMiR00sigBwr9a6LdATGK2Uagd8CrTXWncEvgP+AGC/dj2QA1wEvKSUciul3MCLwMVAO+A39rFnDIZxvFDIymzBaYxQMLu8TYLZQiT5SaHQWu/WWq+yHxcAG4AsrfUnWuuAfdhXQEP78RXAHK11mdY6H9gCdLf/tmitt2qtfcAc+9gzhuBAlfLPQiQJCYW7UvFJ6WdChPhZMQqlVFOgE7Cs0ku/BT60H2cB28Ne22G3naj9jCE0gCW/XYggRhXpsbIyW4gkNRYKpVQCMA+4S2t9LKz9YSz31MxgUxVv19W0V/4/tyqlViilVuzfv7+mp1crCISEorxNhEJwmqosV5dYrkIEqZFQKKWisERiptb6nbD2G4HLgOFah6YzO4BGYW9vCOyqpr0CWutXtdZdtdZd69Wr93Ou5ZRjnsiikJme4CDBWFjlYLbEwoRIUZOsJwVMBTZorceHtV8EPABcrrUuDnvLAuB6pVS0UiobaAl8DSwHWiqlspVSXqyA9wLnLuXUU5VFITV4BKeRWJhwsvHU4JjewEhgrVJqtd32EDAJiAY+tbSEr7TWt2ut85RSc4H1WC6p0VprA0ApNQb4GHAD07TWeY5ezSnGMK2dY8SiECJJsJ+5KmTXWQUpBSES/KRQaK2XUnV84YNq3vMk8GQV7R9U977TneAOY8eX8DhFJySckZyon/mlowkRQlZmO0ggONNTlV0CMoAF56iqn0kwW4gkIhQOYp7QopABLDjHifqZBLOFSCFC4SDBmZ7bXXll9qk6I+FMJNTPJJgtnCREKBykyoVQChnAgqOYVdQUc4nlKkQQEQoHqap6rAxgwWkCVdQUcytxPQmRQ4TCQcpLeJQPYI8IheAwVVYpln4mRBARCgcJVCEUso5CcJqqJiQSCxMiiQiFg1Q105OV2YLTVCUUEgsTIokIhYNUtR+FWBSC00gsTDjZiFA4SFWuJ1kIJThNaG92JcFs4eQgQuEgZqhYW/nXKsFswWmCrkyPW4LZwslBhMJBZD8K4WQQOIHrSSwKIVKIUDhIVftRyAAWnCbYn46vKSb9TIgMIhQOUtVMTwaw4DTBBXce2XJXOEmIUDhI1fsEWPntWqwKwSGCguCqvEGWdDEhQohQOEhV+wQEH8sgFpzCqCJpwu2SdRRC5BChcBCjqv0obKEIyJ4UgkNUmYYt63WECCJC4SBVZqPYoiE6ITiFYVRdZlwqAAiRQoTCQUKlFSrkt9uvyWxPcAg7li0VAISThgiFg1S1H0XQohD/seAUQRdnZctVS9KEECFEKBzkROWfAXELCI4RTJqoqp/JhESIBCIUDmIYx8coPKFgtgxgwRmMqrZCDQqFWBRCBBChcJATZaMAsjpbcIxANS5OSZoQIoEIhYOYWuNSoCqVVoBa6BJY+jzkL6nYlr/EahdqNaapUariwk5JmhAiiQiFgwRMXWERFJQP5lonFFmd4a1RFG9aZD3PXwJvjbLahVqN1c9UhTZJmhAiiedUn8CZhGFqKulEyKI45a6npc9bIpDd13qe3ZddHe4gZdb15LW8iZxdb8HQ6eWvC7UWQ+sK7k2QpAkhsohF4SBGFRZFcM+AUx7Mti0I4/sv2HesFPKXkLrqBT40u5Gz5RXoerOIxGmCYegK8QmoxcFscXGeEYhQOIhhWjGKcMqDjKd4AGf3haHT8c25gdlP347x5o28n/Qb+rm+ZaWrIyx7peKAlsFcawmYJ7YoTrnrqbIwZHWGOcMx/j3Wei4uztMSEQoHCZgmHnfFr7RWzfSy+zLHvJBxnvl8l9iTgYdmMsY/lgm+y9EAc4ZbA1kGc63GrML1FGX3O79xitOebMs1XCwMU1O06i02zX7Qek1cnKcdPykUSqlGSqnPlVIblFJ5SqlxdvtQ+7mplOpa6T1/UEptUUptUkoNCmu/yG7bopR60PnLObUYJscN4FMaZKw0uzO+/4KrA/9hqZFDswOLeI0h5Jo5LA20Y9uF/6CwLMDBD/8qg7mWY1kUFYeuNyQUtcNyLZ11AzOfuhU9dxQftX+OfxqDaL3pZXFxnqbUxKIIAPdqrdsCPYHRSql2wDrgKqCCA9J+7XogB7gIeEkp5VZKuYEXgYuBdsBv7GPPGAzTPKHv+JTkt4fP7vKXoN4cgUbzonElf015lFHmO1yV+j0AE7/PYGpgEHX35cpgruWYVWQ91RqLAiC7L1NK+jG87E12tRpG/oEiRrgX8kGdkbBi6vExC6HW85NCobXerbVeZT8uADYAWVrrDVrrTVW85Qpgjta6TGudD2wButt/W7TWW7XWPmCOfewZQ8DQFTa8h/KV2afE9RSMS8y+gUMf/RVTa27338MaT0dm72/KGP9Y+sbvAKD4u88Z4V7IdM+1MphrOVXFKIL9zhc4BUJRyXLVW7/gJvfHLDVyqJf3T0Ztf5gx/rHsK/VAn3squqYkFnZa8LNiFEqppkAnYFk1h2UB28Oe77DbTtR+xuA3dWhmF6R8HcUpmull9+Xl4n7U2ZvLjy1Gkmvm0KFhMr6ASa6Zw9HOd9DLlceTgecY4x/L38quQl/zz+P8zELtwahCKIKup1OSXWdbrr4tizG//wIdZrmurzMgNEnKLW0CS8dbYrFzlcTCTiNqLBRKqQRgHnCX1vpYdYdW0aaraa/8f25VSq1QSq3Yv39/TU+vVhAwzONcAuUrs0/FGUGpbSlMDAyhwZbZ9HLlcVbDlNDrXZqkcpZrK2P8Y8k1cyj1mxQ0OMeKUexcdWpOWqgWo7a5nrL74r/qnxS8MYLv3n4UbVqWa66Zw1Pu27ndfw/9EnbwcXErDl3yKoWfPU1hwVGJhZ1G1GjBnVIqCkskZmqt3/mJw3cAjcKeNwR22Y9P1B5Ca/0q8CpA165da0GqUM2pyiUQjDmekh3u8pfgmndTSATK6vRmsu8xjKxOTLEPaZgay79cV1IcMMhKiWXnkRL2HSsjKbuvDOBairWws7JQWM/9p8L1BGxP7sJ7xgDGlcxnS5s7yF2dA8Dq7UcoM3PIaD4QvtnJq9sbElvWn3HLxkPf+6WPnSbUJOtJAVOBDVrr8TX4zAXA9UqpaKVUNtAS+BpYDrRUSmUrpbxYAe8Fv/zUax8BwzzO9RTtcQOnyHe8cxWfd3iaXNMatK9uz+IP7nupX5DH41e25+L2GaTEeflw3Llkp8Uz7oKWAOwrKD355yrUmIB5vOUa5bEtilO0jqJ08+Iwy3UWf/W8xsiMHymz+31OgyR6ufLosOpPEtg+DamJRdEbGAmsVUqtttseAqKBF4B6wH+UUqu11oO01nlKqbnAeqyMqdFaawNAKTUG+BhwA9O01nnOXs6pJWAeH8yOibIGcKn/JAlFeKmOPnex4j/rOTfqAzrwPS/5L+OHxM7Q5zxGAiN7NgGgSd14Pr+vH1v2FQKwv6Ds5Jyr8IuoKg07yjZdT4lFkb+E5ovHMMq2XH1pvbl19x+5quBrtrjGkWvm0Mu1nqFR41E+xW3+uzmie3HJ0GvF/XSa8JNCobVeStXxBYD5J3jPk8CTVbR/AHzwc07wdMJvmKEBGyQmyrIoygLGyTmJYEqsPfiS9nzFC+6JPBF3PxyC9KSYE761flI0APuOiVDUZgzTPF4oPLbr6WTEKCrXDdu5im+a/JaO67eSSw7/2tOYze4HuDdzLZO3T2KGMYC2S5cwx+jFe2Yvcs0ckg4XQ/ag8liYCEWtRlZmO0hV2SixtlCU+E6SUGT3xTdkGgUzRnDgvT9x485HeTb5D/yY1AWArk3qnPCtidEeotyKg0W+k3Ouwi/C0FVYFLbL03cyhKLy6uusznTMn8oa3QyAgtIA25K6sKvP35hhDGCcZz6ubjfzr7S7yTVzSIj2cKw0wNESf8jyFX4lVdXUcpAzWyhOckEyfxXrKIIWRan/JAkFsEK1Z1pZf9JWTuQ/0RezK7Ubf7miPSN7NuGO85uf8H1KKerEezlUJBZFbaaqhZ2h9NiTsTLbXp9jzh3F4lfGYcy9kekN/sy2pK6k21Zp/aQY+nk3cJN3EWub3wYrptLLtR6Ark1TAdgvsTDnCBfvpc+TmaDqO/nxZ7ZQVJ75vDfOqmcUnrftoHAEzOOD2UGLovQk+o73rfmUEe6FTOFqLir5gK56HW0zk3j8yvbHnV9l6sRHc0gsilpNwDjxgruTlh6b3ZdV9a+i357pLK87hFydQ73EaBrXiQOglysP9fZNJI2cQYeRT8PQ6dxf8Dd6ufLo0yINgIOF0s8cwxbvstk3ULJjLQ0SVaOfflPNOT2FoqaWgv3l6bdGsWv+H2HdO8e/x8EFPwHj+Pz2aDsbJWKup8rfRf4SBq67l4+Mbvyt7Gru8N3JjTsfrbFZWjfeK66nX0uELdnqigJGzPVURT9rv30WS40ccna9Teah5dRLjKZ/m3RcCvol7KgYpM7ui/f613n5fEWv5nUBOFws/ew4Kn/PS5+HLydX7Dsn6EvbkrrySnE/Yje+zZFSfdDJ06rdGxeVFZY/Xvo8uDxgBsothT73WM8P51sicP3M8uPzl1hBsj53sST5cs77dhKHut5FdMvzUDNH4up2MzHfTnc046KqrCeXS+H1uCiNVDC7UvCadfMwTc37Zi+0hlydw6c5f+PKGgYMh5bOY1FBQ6xkN5uw71I4AeEBXvs3Odb1TpK8quJvVJP3Bx9D+fce9hv4Aibx0RWHbmykXZyVr2HOcEwNLxpXUi8umseK/s489QS/63cjt/Vthst16XEf4W5+HinNz6P0qOVykgmJTRV9J3Rvc3ngk0dg4BPl98Cl46Ht4HJBCfaLpZO4xf0BEwNDSIx+I9nJU6zdFsXh/PIvI/iFuTx2AOwe9CePsH/r6oqWQlCBg5ZC/hI6736TpUYO8WteZ97Knfyj9Hxicp+DFgPKB2awvHZQqYOPf8bs0FqZffxXGhvlpjRSFkWwWufsG/j3hDvQG95jjHkvRpNzQ4eUNexd45v80Tod+HPp0+itX1h7aEiZhZoR7ubM7svO9v9HwhePsW3jiqpTQE+wbwMLxpU/DrpJK/0GZQEzFJMIEud1oxQUlgYic312PzPevJEjHz8FwOeePgAsONqCO3x30sbYbC3y/HJitR+VGh8FwCFxPVlU6jvBe9v/cv+L/u94jAsfp2Dh09a97pNHLBFpf3Woj5iZneDLyTT/5m88F7iGCYGh7C3Uu508xdptUaRmY84dxWcJl9G/8D3cA5+g5PNnOLhnDw23zOIjV18u3jofX+/7iGreF+PNG3G3uhC1Zq6lwICeMxytrbozVzRvwDWb7ifg1qxKHUTnNXMho2P5wATLKnlvXEULJajwWxdDs36WogdnVmEzvaqC2QDJsVEcLvY7971Usa3pQl8HrvDNZGOr21m8pi13N09j5+ES9heU0bXpiTOdKmM26cPodWN5+Y0RfBB9CcNcn0qee5DK3ztU+P0PXjKF6BkjcHf/HSkrpzLf7M3VO96DjtcdbykcyocvJ5XPHO12c907lHrrEAeYwP41C0lMGBpyAAAgAElEQVTfNKPCb+AzzNACuyBKKRKiPRSURUgoALL7Mq2sP7fseZsj3e7ineVJvOR9njt8d5Jr5nBz/ZKftpywFqEmRnv+/7IoKvedcA9Jn7us5IDZw/Gnn0X0wfX8L64/fYoWsq7FbZQ1HMFS30rGbZ0PHa+jbPGzbGl8HTlYCyxffX06/+f9kCVNxzJ1Yw96ufLYmKAynTz92m1RRCfwddqVXLj/dRYnDmZfh9/xasn5NFzzArrFALobq5gYGIJr5TS+2X6EFwvPQ615EzpeS8FnT7NzweNoDbfZdWf2HCtFa3jP6MnExPtg4BPoTx5h9+LXAKvC64rFC9C2hVJQGqig8Bt2HS5X9Oy+x830Aubx6ygAbnEtIO1ApTqKv8ZnfSi/fJMhwPjfC1yil7DWbErD7616ThnJ0Sz+fT/WPDqQ5vUSavzRTdPiyTVzeN1/AcNK52B0/u2ZLxLhs/tw63LGNRUtzfBZf2XLFXgjdxurfQ2JzX2O9fHd6ef6li/jB8CauZT9dxK+jLPLLYUOV4f61UefL8I/50a4fiYvFF9A3FfjocftzPNcSvo3Eyk5a1SF38BvmERXkZSQGO1x1qKoIi5xnfkBS40cYr59nWKfwetZjzI5ahJ3e96i77f31XhSMdr7PnX3OzgmajuVE2tsD0lJQKHtoollZaVEb/8vtBhAx9IVTAwMoWn+HPz/ncQI90KmuYfCloW8X5JDzpZXMLvfxkfxVzDa9Q7LMoYx2305AB3VVvIPm1udPP3aLRRlheTsfJuJgSF0P/Au+z56jhHuhcwz+sCaubwUuJwJgaEs6/Ic7b74P25yf8ySzJswNy/kE18Hsg5/zb52o0IlLFKPrOMe9XseDvyOHYeLMXuO5h2jN5k//ht63M673sF0/fEf7G5zI/kXvopvzg1smPkAeul43jF607Z4BWaHaylb/Czzx9+BOXdUhYFhmBp3FRbFweQcxh56smJp5V/jzulwtfX1zPgN+a8Ox/XpH/Hj5l2jN/eru5kcNYkWRd8QtW0pMcte+Fkf3SwtgV6uvFA5hv8vyiyED+Jwt0+zfjBnODpo3mNVsfSvnYe5d/1xk4Zbdv6Rjq581qVdTJdjn/JS4HIecd1Jaf/HiFr4J75+ZxJgWQqbl32IXjqeTfUv5iLjCz5LuAzD1KHvXX/1CoMK/83EwBDcq6ZV+A18AROv5/ihmxDjodBJi6LSfibmnOGhqrCvpv+JyVGTOKthSmitxLH2N9R4UrEzvm3FJIszwcVZXSDadt0FZg1j09Pno5eO52DvP1H8+TMsn3Yfes5w/HiYZ/RBr5nLDPdVTAgM5b2k6+mxZQIvBS5nfGAoJT3HMcT1P+u4r16h/9H5TAwMof2ut6l34GuyUmKZYgzmaBkFTl5a7RaKw/n80XsfEwJDme29hpy8Z3gpcDnfmY3Y2PEB7vAsoJcrj91HSzFsS2F+yii+b3Nr6MtMXf8GvVx5tMlI5PmSS/i4uBUAOw6X8OOqj+jn+paJgSGYX73ChQXvMjEwhDrrZ7Bs60FrRenmVyhtfH7oOL35UxYFOjLk2Ezym15Xaaaniaq8aTZwJL0X95h3Ybx5Iyx68teXLcjui75uBkbAR/au9zFdHp4OXM8dngUcLvYzxj+Wxrs+/EUDL+vIciZHTbK2SA0MZeO5L5wZJcdPZDXYg7iw+1iKp1/D1uUfAVBmmGzethOwAsSvvfE6eu4olveYxEslA3CttSzXks+fZdPsBy0xQXOb/242Gg2Z7L6ROzwLaHJsJV9nDGO+2Zs+xZ/h63orX6RcRcuNL7G7Xh8aHvwfEwND6HPwbXhzOGP8Y/nKbIehNRrNV2Y7/t3iyQq/QZVCsfR5eqo8ywoO8mtn6PbNrWTWSA5/9BTaX8qkwFXkmjlM39WIMf6xdNo5IxRArbthRo37ye7UbjwZ9wBH/jWcL6bcdXqV8jhRXzqUb11HUBzC46o2AX8ZrYtXsa3Zb3jbewUzjAF03/4aGH5u89/Nd2Yj9vZ8hOt9b9PLlUdpWRlv170dDyYd/N/iXjqBJwPDKNVeTK0xtdVH/prwAPcefYorU76PyCXXbqFIbcrHRdaNvai0jH/X/z88mEwxBvO29wrG+MfSUW3Fs+cb/i9wDw8HfkfSnlwarnuZJwPD+M5sxIxGjzE5ahJXpW4NxQnObpRCZ3Mt6R/dHhqYZtjAfKPRowzecD83uT/mffoSs3FeyHrZ3OpWBhlLmGf0ocHmWTWa6dVLjGZRWRsmF54HS552ZAe5oyXlNwRDu1ivm/Ji3UeYHDWJnq711Nn28S8aeO7d3/B29uMkt70AgI0xZ58ZJcersBr0nOH40s+G/CV4v3yeD81uNFv/IqWdb+GV0gtpufEl6HE7r/oGcivz2N1qGHuOlTHCvZC3E4Zhbl7IB6U5tN70Mv76Z3Grz1p5PLHsEiaWDGJcYBytAps5lLcwNNFwfz2F7vveYp7Rh8wfF/Bu/HVMCAxlQaBnaLvcjmorbzb/G7f776Gj2mpZxGG/gS9w/Hodsjpz37G/0fTYCivz6ZfM0KtI3Nh7rIyVpVmk7v2SbRmDuMOzgMFJWzhU5KOd+oHkHZ9T2udBuo16FjV0eo0nFXXivbx/rDmv+y/gvN3/PL12VTxBXypqfUXInfjZksUEljwHA5+gaNEzfPriWLCthomBIdTbOIOmm6czwr2Q5aoDprLEZIoxmE+Sr2G0fW97JTCYGa7BTDEG01Ft5Z8N/sxU41K26XTebf0Mt/rupqPaykeFLbkzMJYuUfnHJTo4gfvRRx91/EOd4uXXpj9akN2P1LgoFpc0Z3dSR77yt6TEb2CYmpVHk/BndWdhYTPWFVt7LFyov2Rrsxt4bs9ZrNStOeDJYHFBQ67J2Mebe619kq7slEX69g9ZUuca3i9oyaWuZRzqeAt/35FDR7WVo1Fp9CpezAKjJ5uNTBLaX8SAgzMxcHHxkdn83Xc1h3US32WPoOvye6BBJ8zkxjz36Xf0aVkvlCce5IcDRRRuWsSDntnkNbmBrC2zoEEnSG3yy76Y/CV43hpJqWF1rLNcW7nM9RW7G1/C1/sU4zzzCfQYjbvLDT//sxv3pOvZnRjQLp3Jn2+hfVYyPTp3hsY9f9m5niqWPg+Gr/w7Tm2CVi78797JlpIE0o6sxRcwmbKygG5bJvKflN/Qt+gT3ou/mpwds2ivt/CKcRnd975FjrmZV4zLOO/wPLL3fMxtvnHkJl1C7xbp9Nozi3fMPrT25fGurxv1GrVi055CtIaMpq3Zf6SAcYf+yv/57mSHrseV3mX4AgYbzKZsrDeIi4/M5lszm9eNi4hr1oPkQ+uYYgymIKYByw4nslK3JjXey9UX9A79Bs8v/I5u2XVCC9eC1/fyd0nctv9x/vn5Orptfh7Xta//vJuv4bNugMG+mb+EmHk3UMc8xCvGZfQt+4JJvsE85HqdGF3CaM+7eAY+Rly/u2hUJ856T4NOlqD9RH9Zvf0IZv4SHvTM5h/GpfQ48C4q61eMCScI7zPBx0d+hLz5sO0r2LECfvwSzroOGnTCmD2Mkr2b8Rbvwxcwee2bIrruns2WtP50O/oJb3mvpM3QR5mycA3DSudgKhe3+O7jzcB5NKqbyOX7XmJ84Br+4PstXXpfyKhdj7FWN2OPK50v9sVRktGN7YdL8BsmbTISef9IEw54MjhQ6GOlbo1OacKS/XEUpXdlx+EStpn1OOuci1i/+xg7F/1r96OPPvqqU19NrbYoguUIzmpkicC324/QuYm1/H/NjqPERrnp2qQOO4+UANCsXjzPFV/MUqNtKK98/e5jbE3oTOz594Y+t3eLukwxBjN9d2MSYzxMMQazqKwNuWYO82Kvoe7RPEYb9zI++g6mGIOZ476cMf6x9HatY3LdR5hqXMoUYzBLjXahmV5wnUSc133cdTQ4XO7O+VfsCOs9P8edU3mmt24eKlDCPp3KV2Y7bvHdjVIwrPB1bnO/z1e0x/vNP3+Vuygmyk2deC+7j55GZRbCv6fgrC/oBshfgrlkPO/5u9J608vQ43amBQYx1jOf3Wl9OG/vG/a+He3QGjSaYzqOgGmGLM0NdQcQ3NG2WeFKMte9FLJc5zR5nMlRk7iubn7odDo3TqWj2sp93M0ybU1CFrR+htv89/CjTme6eRnjjHFcmGy5uKbuaMT7ideSlRLLih8PA9AmI5E9Yb+BaWr8hq5y1rg7tVsoXrCh4dCfP0O3XU3+OTcy/YlbMGcPx9SWO21CYCgTUh5iTNQC8lN6Mc4zn9eMS3H1vvP4z6hBKnY3nVfBxbntgpdOjYvzRH3GThjRc4ZztE6HKt1IPl8Z8Tv/h+5+G1MDg7jT/Q5708+l4QHLnTio5D8ULZ7ICPdClho5BHCH9qUpKSvl9YTf4cF6/lFRy5CHZKX92+c0SMIwNQcKfXS0NxvbuKeApBgP6UnRbNht7R/XqXH5RmT1k6JpkHLiwp+/lFotFH77Sz27UfkX0bxeAqlxVh52VmoszevHh17r3DgVrWHlj4fp0DCZtASr7kx6UgxtM5O4oE19+rRIo1tYumj7Bta6lE17yr/0Zwov4gt/25Aordx2mHXes3go9s+8fSjb/sxodh0pCQ2MYnudRFCgwukV+yMru41HNz2XbYeKQwOyxu6cMFPXtN0TATxkuQ4yJWoCAP+N6UfUrhVEe6PoNOzJny9GVVA33svh0ymF8QT56FvXL0fPHcXWtrdViEkN50MmBoZQf+fHvGxcQa6ZQ4OiDbzV4u/c7r+H3q51vN74ryEX0Btp9/Bo3EN0VFtpXLKR1zL+HJo0LDjanDH+sXSP/jF0Op0bpzDFGMzHxa1on5XMFGMwHxS2INfM4aOU69iyv5Av/G3Z2vp3ABwoLKNF/QQyk2NCgtS5SaqdrWc1BFdeV+XibOdbHQqGZ+e/WbPfvvIkJLsvy9ydGRWYy/7Etmyqe2Hopdd3N2ZuzLV0PPY5S40cRrgX/uL+1cK/KbShFkB+YufIuTirWwt1gj5z8OhRwIpPTZ/1BsaS56z1DJ89zfZ5D1uprNoT6ksj+DDkTlxUbwQTAkN50X85Sf99jJcClzPC/zBzmv2NyVGTON+7gX8Yl/Na4BI+TL4OgBU/HGaVqwOL04aFSui0zypfM9c2MzG0Gr9+Ugx146NDE+Tw+2P9xBhG9nLeKqvdQmEcLxQNUmKol2gJQGZyTIXUzx7ZlgAcKPSRkRRDq3TrtaDiTh3VjRm/60FMlDtUvKxpWjzJsVF8t9daBX5Ww/Ifp4stFFv2FZKVEkt6cgz77L0azm6Uwu6j5QM4WKIjtgqLwn3u3Qy87FrSEqIpKLHXU/ycqplhM70X/nQTgbwFPF//cR5P/DNKwdSoZxhY+jFExaGGvUl0q34/X4yqIDXOW/vLLITfBIIlW+YM59iUi2HpeH7Muoxmu94n19WJRuteCcWkwi2FV7Ke4lbXuwxO3MJL/sv4sLAlG2PO5rf+B5h3KJtcM4e3Yq5m99ESPixsydzoq3g5MJg3DzSlRX2rj63bdZRcM4f6Fz8QOrXgRAOgRb0E4rxu1u60bkDtGySHNrMK35q2QUoMmSmxgFXoL7tuPMU+g2N2kDo4Jo6zKPKXcO3WP4Zm6JPTHq7ZRKFy2uaXkzmn+DPmGX1IOLqJH1QWk6Mm0cuVRxe9lpFlc1DuaPS595J//ou/eDISe/695Jo5JNorzPcdK3OukuzS5621UOGWwpzhMPNaK+U5PK05uy+lPcdRPP0a1r5xfyjDse7386HH7bxhXsQ4z3zWZF7DqqzhTCvrT6O1k9GGj9v8d9vxTcsCLdNePml4J333Wgk0Lm3wv2Z3hayGd480Y4x/LP2TdnKgyMe+gtLQvW2zfY8J3tvAsiiCZKXEkZbgBaB+YjRpYccNaJseetykbhzntqz367/DStRqoQi6PcIHXIPkWK7r1hiwNt5pWb9cKM4J89lmJMdwUfsMAK63jw+nVXoiAE3rxlHf/tK9bhdtMsp/nM6Ny/9vVkos2XXjQs87NkypMIBL/Cd2PQVJjo3iSEk1C+9+IjNnc1IPxnnmsyjhMr402rEjpSvTAoOIUz48GNBrTEV3w68ceClxURxxcqFgZaq73vDUwuDgDl/b8OVk63H42gYbv6+MpN1fcqzhedTb+18mBobQqei/fNngBnJNywX0RpNyS+HNA00Z4x/LBck7AFi17TCt0hOJjXKzcY+VZdi5cQqb9hRSUBagk90vdhwuoZk90Sj1myTFeEiI9vDIpW25qlMWaQnRocGdkRxDRthEIyervJ81rhMXspLrJcZwaQer3/oMk/Rky42w95g1FoLicpxFsXMV5tB/cvXVw+jbqh5f+NrWbKIQTNt880byXx0BnzzCqzE3ca//Dp5PeYjz9r3B/PhrmRw1idHud1EKuH4m5w68mq79rvjFk5G6CdFMGdmFd+44p8L1/WIqu5DWvQOzrgv1C20G0Js/5vt9R+CTR9B97uZIek/IX4L7f1YiQ4fvp1TMcFz2CsNsq7PV9rnoLyczwr2QL3V7DHutcke1lXdbP83ttjvxbe8VPBF7P53cW5liDOZ1LmOKMZjYKDertx8h18xhc8ub8QVM/IamY8PkkKWQlRob6i/JsVFW3McmMyUm5P2onxhNWrx1XJzXTd2EaN6+vRdTb+xKelJMyJPiJLV6ZbapNQPa1icpJoqzG6WwevsRWqUnMqBdOoM7ZlLf3oTnqas6oLBu5kHSk2IY0aMJF7XPoH7i8T67J65sz6xl27iuWyN2HSlh875C4qLdNAkTg6Z140iKsWrnZ6XGUi/sBwget/toCcmxUdW6nso/L55DRT4OFfmoY//QFQivpxO2Wty8dgauLyfTZv9HzDP6cMHBd3kvqgVt4hK5NfZTin1eYjwuXMtegexzHcseSY3z8u2OI458VpWc4Hq5fibsXlNe46ZZP+txVCyc/7B1A/AXw0BrbywNBNbMIxBdl9hV/6DUdPOe2YervpvPvxJvYUJhPzbFnM3TO8bTx51oZZAcTWaNmcbhjJ7s2FPADnIYcHY72LGeYp+1f/jeY6X8cLCY+onRNK4Tz8IN+wDo1CiFRRutx5nJMWQmx3C0xB8aoL87t1noEoPZSdlp8WQmx7B1fxHRHhe9m6cBmwCrrybEeDhc7Ccx2sOgnAzOapjMOS3SyLD7+J6jpbRKTwxVIY6uLBR97iIeuAbL9Zq38yhkX1izvpDdlxcLz2Nc6XwKWl3NS99dBARYVNaaQzG/p3fMNmYcs2IfSzN+S5/Kk5Ff2N8G5ViCmBoXxZ5fKxSVa56d9wD6k4cxvpmJe82baFcU840+XH1sKbrjdZQsepbXP1jJmIQv+KL+SPptm8Yi7/mcv3EezwaGsV43ZYxeGEo/zUrJ4OrvxvNEYBhTjUt5su1hJm94kDH+sfxQ2opcM5lccmhzqJivi1vRPLMTbDvCt9uPkBoXRVZqLOt2Wu7t8Mlow9RYMpNj2HG4hAbJsSTbE4ajJX7qJ0bzh4vb4AuYNEuLp0ezOny2cR8aQve+4MT051Rf+CXUaouifYNkXruxGwCzb+nJv0f3prF9g64ftlPbb7o35vrultUQtA66NU3F5VJVigRY23/+4ZK2pMR5GdmrKQCXn9WAlumJ1I33khIXRd2E6JArqUd2Xa7v3pjYKDcXt88gM9kSpd1HrA5e7LMsi6pcT0Ey7NnhgcIT7PcQVrdp+6qPAWtW+f4bz6A/eYRJrhu4138H95h38WTZU9yy4w9EuVzEjZqHa8Rb1meErdj+taTGezlc5A+51xzhBK6iskV/B6yb/t41C9FLx6MHPk7xomc4cng/RMWi/SUUfPsu+IsxPXF8/u1mzLmj2Nz/FV4qHUBs7nPosHz0L5qO4/KCOfRy5fFhUUv+nvggA1OswPGaHUdxKULWAZS7LsGawTWpG28/jq0QIAwflI3qxNHUPq4q8c+xZ4FtM5NonW7dIMoCJmc1Sgm5XdKTYvj71R2tc2hWB6UU/x7ThwcuakNmcrlQABTbC+oqFwUMJyMphoNFvhPv017JZ+/bvJib3B+z1Mgh6odFPBh4JbQ+6aPClhSkdWB07ELWRJ1Nr0PvOh5wrpvwC0vbV9GXArOGsfuFgbB0PFszL8Oj/ahACQcbXlAen/ruUz72dWCcZz7fJ/eix67pjPGPZVVpJnk5v7dSgF25LO0ykdtsq7O4tIzp8TeH3EgfFrbkj1H30SP6x5DVmdMgic37Cjla4g8Fn/cVlNEgJZaMJOt+UTfeS0Zy+YQzPSkmNBlIS/QyzL6PNa8Xj1KK285rzp0XtEQpxXmtrC0mzmlel0tsqzMrtXxiG0lqtUURTqzXHcp+qo65t/Vi096C0A9VE1rUT2D9XwYR47Fu8rl/uCC0W917Y/rwVf4hLu1olU5Z9ccL8Xpc7LM3Xdl11AooBTt6alwVloJNapyX29zvYXyvIf0yq7FSzZeSrN58UJLD1WsnQ9/7+cfiLYx2vcOeplcwadMgvB4Xi8ra8L6nF/0T95Jx9d/KZ3TXz4S18xzbWrL/wVk0Vmsp3BhNYtv+VmP+Eut/1MmumVurco2boOWQcxVcbhWP85WVEb19KYE+97E8/zC9vpnIjo53Yra+mfkfrGTc8ueh7/18vfjf9Ni7nLKsHqx2deD87a/xdaPfUXCoJJRZ0sNjBZOnGIP5XqUzxRfPuXHbyS3M4Y09Tbiq0zmkluzjcLGfjKQYmqWVJ0O0yUikXmI0+wvKyEyOpU1GEl98t59jJX76t6nPE//ZAEDL9AQG5aTzcd5eMpNj6dPSzUd5e0Lux3AeuyKHC9rWJ6dBEkkxUUz7X37o5v/ZfefxzbYjxHrdnNM8je+euPg4l1Jwe9rgjDu48jqhGqFIT4rmNvd7HF3vpV7HC4+vRhv+G3S4Gs9bI0Mrri9slM7VWx7gcs9X3OK7G4Drt07E43bR8frHrc9weHHcjea75B9uDXQpb6xJxeLKVgSW2zHz4DIKW19D1uYPKdZePMokbet8nggMZ6pxKRe3ac0V3/ydeUYfBu//jBmxI8gtyiHXl4M/oRlr/FF0VFtZXdCCXDOGdTFnkRSIosRv4IlTUFDG2p1HaVq3K9/5OvGjvdd8lyap5O2yrIZ2DZJQCrSGBimxNEy1hOJgkY9ezSq6yP9+TUfunPUN/dvUp2laPM8OPatCXDZI64xE1v9lEHFe67efcN1ZoYlIpKnVFsUvoWlafMik/TnEeT24bF+h1+MKWQb1k2K4/KwGoeNivW7ctqXidqmQRbHtUDFABb9iZVLiolijm9F88Ziqq+IChYsnlC/RX/YKI9VHTAwMIWnHF/RQeaEO9FDgdyzuO+f4mMTlEx0rBx7I6MSl7lzi5t9QHj+YMxzy3qn5Qq7KwdLgZ6+dR/FHj8Gc4ZRpNxMDQ1DLptBx1xx7le8bHF40vrykRe5kuqlNLDNb4925jLN3zGBiYAgdds6m94pxjPGPZYT/YWZmP8XkqEkMTtrCks37yTVz2NLy5tD/bZASG9o3PDMllqs6Z4Ve87hdtLCTIxqkxISCzN2aptIsLGkiLSGaRy5tx297Z3NuqzTObZmG1+Pikg7H12HLSonlN90bo5Sicd047hvYiueGngVYGSrhfbWqTKZoj5u6YWnKwZhYdRZFenIMa3QzUv5z6/FlSezfTQMlq99i54LHMbXmdrse2oJjLbjdfw/rUi8oj0uANQkJupkczk7ak9Dul5W4CYuvlH7yl9CCtnlGH+I3vY3SBjf7f8+nURfgd8UwzjOfm93/oVHeK6G05tcaPcWQormc77UmASt/sDIcp+rLWf6DlabapUkqO4+UcKjIF8qYPFrirxBTgEqWZmocjezZflZKLKPPbwFA+6wkYr1uhnTKon1WEumJVkLOB+POpYu9TfE1XRqGkiQqExQJgCGdGoZirZHmtLEoahtulyI9MTpkUWw/VEKdeG+1M73UeC+5Zg7/6/Qs3WaM4MOYSxiqP8E/4C8EPn8Gz85vSct7iydsH+kV5rehzJyDCd2Z7P8ryzKb8nW+NQtuXI0oOYGn+XncvugeprmfR0+/mmiPC7fHW37TOBHhVkQwY2vmMFYFmtI1Zic7B/6D+fPnMO6r8ZieWG7z3wPAaBaibZ9w45RMrsx7licCw6wblb+EYrx8YnSls2cbUWYJx3QcX3jPpW/Zf61YgAlvH8rmY/9YbsjczXvHrMHZs1ld3vnGcjkFZ3cb9xSEAoF/uqwdiTHW7/bAxW144bPNdGqUSmq8lzdv7RmyZD+/r1/IDdeoThx/GtwOgKSYKDY9fhFKHV++pTJj+rf82b/DaO/7HNjbHujA6m1WzKhl8SpYuq7KSUG9hGhyzRxW95xA6zdGkJt6BYOwYn5ffjqf3kf+zff9p/Cf9+Yy7vB8NrX+P3K/tdJU1+08SsDMYdSAG5gx+0HGeeazu/1YMh2KS1TFvrrdeejAvYyfdQMzjQHcFL0I17XTj/8fVVTv9QVMvi7KpM+Xz6HtvtRRbWVLnd5kHv0GgAd8N7O/1WXEbHyX3q51vFDnEaYWWJO/3kZd/ucfy2Vpu/l8b1tW/HiYP6V+wuroZiw4YPWfzo1TKdu8mI5qK2mN7uc/a60K3lkpsUTbXoh4r7tCxmRmcgydGqew7VAxCdEe0hKieW9MH7Jsy2L8tdZkoSZ9pjZwxlkUJ5PMlFj2HC2l1G8w++tt1VoTACmxVqBqtacjU8v6M7RoNr5ON/HU4QG8WnI+UXlzWZM6iKnGpday/PbPhTJz/rWniVVbx72Vsf1b0D27Dl2aplb7/34tLeonkGvm8KpvIHHKh9sohR63//RNogorwgz46MFa1mZew7qdx0KuIkNZA62j2sqisydwh3EvHdVWDhcWh0q2nONax6LGY7nF/3t6u9YxrfFTPOkfTm/XOowD+nYAABcKSURBVH5f+lsejXuIi+tYg3fdzmN86+lIYdfRof8dvlI+PSk6FJMKDtLf9slmaFdr58izG6UwdVQ3Uu14Q49mdUP7nmenxVewLMKJ5IA/kNSe2/b9BfKX8OG63ZwbtcGyFk4w4w7GSr4yc/inrz+DDv6LQLdbmeu+lD67prGy3lVst911EwNDaGRXHG6TkUjAXqfTU+Ux0mO9nvHdzIguhKsT72VhaWum+fpzs/kWWyvVUAsR1q/KAlaZEjV3OB1d+Sw1ctAua3xNMQbzQsaT3O+5n45qK4VlAT4qasnU1HHc7XmEWfutdQaN68SxaU8B/zPasaPdLaF/cyilPU/4n6OXK4+EaA89WMfkqEms0c0quL8bpMTS2860LPIZFSZuGckxjD6/Bc3qxTOgnZW+2qFhcui3UUqdNiIBYlH8KjKSY1i/6xiPvWdtGt+/dfX7mcd53XjdLvat+ZT77EE6euU0OiaXcK57IYszRtFl/3x6ubowxRjMhUfTyTUTcLc4D7YcINfMwX3uBdyTVHWA3mnqxHs537uBUeojy9frUnhPlFlVhRVhzh5Oab2OxB1YQ0B5eMV/Cbf+OJM222Zxk38cuWYO488+xuQ1v2eMfywHilqxxB/HEtqSUhZFq5REvjYOMcUYzDlGXZbpg+xP7YHrMHxn1GdF5jAKdhxlbmk2nh7nkVa0lwOFZWQkxdAyzCTPTI7h4Uva8uQHG8hpYA3W3/XJ5qY+2Sfle/y1HMnoye/338Ok2TdwcXE/boz6DDX0xFZd8Ga0bdVHPBjsZ8umcJnfYGJgCLdun4XaMTv0GxxN7smL/ieYk5zGxj3p9HGvJ+n9lym67l8MzeyFOrw8okX7GqTE0sVcy3XuT5gYGMItm2dB/sUV9/AI61eBWcNYXtqYbt4frICv36qx9f4gk8mf/h9j/GPZdiiFb4ta0Tq9C+wpYPkPhznHnjBstmMKZzdKYcG3uwAr6SDR3s+jMPMcpug/Mnn3Y8wwBtBl+ReMtBcHTkyLo1ezuuRuPUhWSiw9sq3PbJWegFKK13/bnW0Hi4iJctMqPZFF9/Zz/Ps6FYhF8StokBxD/oEi5q3aQYesZMYNqN6toJRiQOxG7jv2VGhh1Petb+XyvS/xUuByXnFdT673HF71TqCXK4/lPxwiNsrNFcnfc5v7PcDKEDlp5C/hefUsCsXN/t/zTF07mFlVZpU92yvcsCjU5POVErdzKdrw84DnfiYEhrI8vl9odTnAB4UtudM/lnPjtvPVVmub3+5N63Ck2M93ewtob683WL39CHXio2mYGhtaHNmreXlQMD0xJhQwzEyJqbBYyeN2cUvfZuQ/dQkZyTF4PS4euaxdhXTq2kxmUgyfFLdiSnE/K1OnyQlm3DYxUW76eTfwYOHfKxS9DKZ65saeV+E3mLO/KY/F3E/v2O0A5PA9auh0Etr2p0FKbETiEuF08H1boZzH8pje5X3M7leBpS9QtOhZ6w2Gnz7uPNbRnPfbPhta3f3uEWt1fP/EHazefgSt/197Zx4fVXX28e8zk8lM9o1sZIEEwhaIEhMCAgG3sLwFXKrFouBSShcUAVtcal1aW22rvq9Vq7aoUEUrFSt8XlukfvBVK2jZQ6TIroQQEDFBQJLMnPePe2YyQRgITGYmer6fz3zm5sy9M7977s157nnOc57TGsnm9iiyk1y+4ICUWAfd/ULhMxKcPo9AbkoMlVWX+9Kh2MtvZIWnmOgoG13inDx7fTlPXnMel/TLJCnWwfM3VrBgqpXbakSvdF+P9euEMRRngTdEtqnFw+1j+5zWMYOid7VJXdB4+CgPcS1ReNj56RH+13M+dpswzr6Cz480Mzb+I769/WdsUIVkJDh9k3NCQu0a3rQNZVrzTA6kV5DeWAMj5ljRMv969CsTAg+W3oTtpYmsm/cT1IuTaFJRvOsuxiOtq5n9JvqH3Bd3J4Oireik6trP2RpXyntZ1/hSEgzWT36fH2lmUHdr+0iTmy7x0b5QVPiqS8kbZhjjsOOw2/j91QN5YlKre6YzdfX9GTMgy7dGyFtZ11G6b9EpXUFDXB8zvflmPnSeS4ls5+UeD/j89/fbpvGL+Dt9OaaONLmpTysnU88qf8o97quGKFizpk9At2Nt03kss1nrtXs2vOJLq2H/5138Y/lyPC9OokWs1BmF7p00HG0Nq31v2wFWeIr5qGdr8EK5X8hzVlIMmTpcvmtyTJsQ+7R4J9cM7kaX+GiGF6VTITXclPA2LcNuRVY/Q/WUGN6dcwE2m+By2BndP8t3Pw0r6tIhk9wiCeN6Ogu8A1PQNg1DIDb3vIEVH3xCn6wEdh04wlw1gW7Nf+RjV2/2Nn7JYulB2YAHmbD5p+Q76ik5thu59nnujy8NOFDeIQy7hdycyZy7eR9Hm9y8tyqfqe8+bKWThrYT5Ha8Tdy//4clnnKu2PE0bruLac1WmoYHB3zOYzVzuMM+m/cPFvOJKmJgt3LYvJ/6xmMMyEny9Qag7XyGHhlxvhniWUkuCvzCWf1DCLOTY5hyfnf+UbPX9087zi9arTPT8/Ba5sU/wbzc+7nhmsnIritO6QpakzeZFTX1lGXE82L9ZfRpSOQDTyo7k86jseFLlkX3oqX3MGKr6zjS5CYvJZasJBd3haGnlXLJT1ix/HXA6k2+edDFvVc9T+Ofr6F6r1DZsJhF7qFcYX8Xt9vFU9m/4pGtWXyginly+12sT76V1xp68GFdIzaBktwkFq62ZtkXZbS6IHNTYkiNdbBobS2Hj7Uwpn8WP/vbRsByT363Ip/vVuT7oq5sVz2HraASeowgYeF1JFz5HCR0klToQcb0KM6CEb3SqShI5aErzwkYruiPt3sb54wiLzWG97Z9ygZVyG+x3E1KQXKcgyhaGGav4YO0S6GgksL0+DZPQKFiUEEqc0b3oWuyi7ea+nJkwp84uuBa3llmLRfrVoqFf12A5+XrWJ13PSNt61lJf9zSWh+LGy2XwCVJtXx+pJmGo80MzGsdiM9MdPoMhU2gX7Z/jpsY39hPdlJMG+OQ6Iri0asHMjA/mdL8ZCoKUrn/sv7MuqRXh9ZJyKldQ/TV85k6eYrVozwNV1BvPfu3S7yTzEQX6z6xoqUG5idzuMnNp180kZMSw7gSy5gm6UCLG4cV+FLfhAqbTSjvnoKIpW//oWOsVMXMb7mIyrpnUT0uZqRtPe+6i2lWdg7oCav/cvfjjqjZlDt2kqrnL6XFO+nu9zDRNdnFyN5W7qPBBWlU6XDk83t2IS3eyaIfnc8fJ5f5AhYAq179jXAHu946A6ZHcRa4HHb+Mm1Iu47J1bHVVQdfoiFlAE/Ud2UFxaw87yGeev9mNngKGFS9C7vTyevx36Hq0BLY8e2wL+ridbN9nFjGG0cvYMaeZ1HDf8Lf1tZy5RcL2Jb9LUp2PMP3tAvhgdKDPFZzGzPcM1j78QAOe4oZ0v8yqPsIgIL0ODISnOw7dIyMRJeVp+uNj7CJ+CKOwHoK/N7wQt74sJ4RvdI5Jy+ZW6t6kZsSi4gw/pyubea5TKoI43oGHcWJXD6nCFH1JsR0RNnISnL5BnCHF6XzevVewJoVfP3QAuKcUfxgZI/g624Hf5pcTuOXzSyt2UuLR7Fn7VLfsseXV7/MEzp1xh099zNzx13Ux85i6ZFeLGnsiSoZTub+wxw43ERmopPBhWlMqywkJyWGBJeDuVPK2fP5Ud9D2puzR9BV38/++dx8nEF9f90xPYoQM7Z/FhPL86i6ZAw/+vQXDLHVANAzI8HXi4jCjf3qBYy9+TGivjMvIpYi9c4mXrX8NV9YpWflk1R9YS0fm1f/T16Ju8rnZ371YA9ut8/mgoTdHNZ5sC7q2xoVlpMcw/QLrTh1pRSl+SlMHtKNu/XchMk6VXJeaiz9uiay8d5Rvifd6RcWcenA1olyhq8ytEcXLu6bwdThBW16aP7uuKxEF0kxDn4+rl/YfexJsVYSvJTYaIbYahi16XamN9/sS8XiXfb4nZa+/KjpJl8qFrBWkCzToeIej5Vf6/axfZmsB5XtNmkTut4jPT5gqh3DVzmloRCRPBFZLiKbRKRGRGbo8lQRWSYiW/R7ii4XEXlURLaKyAYRKfX7ril6/y0iMqXjTityibLbeOCKEgrKx/Ba0a94zPEoM6MW0m3ZVKIc0XzRdSg2u6P1gAjp9mYluRhiq2HcljtOGEnzTP4DjG98ibHxWwBYtesge1PLWZF1LWCFBvunG8hJjqGyKJ0e6XFcXpoLwH0T+vsiRu4eV8yH943yTWgytI+UuGj+NKWcktzkNgvbxDujfEbfGwEUSaTGR1Mi25mlbmG1bQBPucfxvHyL6ToybmOtlc796KDWBZO6xDv5Lz0rfmjPtJN9teEsOB3XUwswWym1RkQSgNUisgy4DnhTKfWAiNwG3AbMAcYARfpVAfwBqBCRVOBuoAwrg8BqEVmslDoY7JPqLBxIr+D5jVYIHp4Yoie9THRBZWsKA6+fNAK6vRkJLs6xbeeHx25ihaeYafYlvFDwa5bW7KVEtvNW03D+5Z7BZam1vP5FEW6PIic5htL8FP65qd6XXXfZzEoWr99DZqITEeHNk8SZ223SJl2B4czxJj70ju88MamURWtqQ5b+oT2kxUVbUVdHYXBhMiu3f0Z1bQP1nmISu13IwZp6wJr82D8nkY21jaQnOKkoTGPpLZUnTX1hODtO+Z+olKoD6vT2IRHZBOQAE4CRerd5wFtYhmICMF9ZuQ5WikiyiGTrfZcppT4D0MZmNPBiEM+nUzE1bzf22LdQXSuRunWtH/j3IiLELxodZeOVmG+z/9Ax+mQlMHffeEoakiiX99jp7E1NbSOHmvsypORShuxdRIlspznpZs4/7gmvKDOB2VW9w3QW30wyE108fe15vvTWA/NT2mTNjSSKMhJw2IVmt6JfdhLVuxuobzxGbLRdz4q3DEXX5BjmjO7D48u3cmEfy6XZOyvyDN/XhXaNUYhId2Ag8D6QqY2I15h4HdA5wCd+h+3WZScr/2ay421i/nYj0VfPR65bYoWY+o9FdGDc+pkySIet5qVaiz1t2N3ABlXI73iE/s3rARjoruYPzt9bSeliHfTNSqRfdiIzLmp/jiND8KgqzvKl6I9kYqLtvmR6eakxvgimnOQYxvZvTbqYneRieFE6L31/SNjHV74JnLahEJF44BXgFqVUY6BdT1CmApQf/zvfF5FVIrJq//79pyuv89EJQ/BGFKUzzb6Evl+uIzPJRYtHscJTzIc9v8dcx++YGbWQsg9msevCx1nhKWZAbhI2m/D6jOHM/LqFrBo6DG9238xEly+3Vpd4JwNykxjZO52ijPi24ayGDue0nMAi4sAyEi8opRbp4noRyVZK1WnX0j5dvhvI8zs8F9ijy0ceV/7W8b+llHoaeBqgrKwsiCvmRBidMATvor4ZbHhnALMP/BLSfsZashnh2ETprmdZ7ClnRtSrfHHuLM4ZPp4PK1rMGIPhjLhnfDH3LqlhWFEXPjvcxJL1e9i63wrvnasXMjOEltOJehJgLrBJKfWw30eLAW/k0hTgNb/yyTr6aTDQoF1TS4EqEUnREVJVuszQSUiLd/LLWT8meuJ8bqi7l5lRC3nE9t/YKmcx0raeF10Tia+eBzveNkbCcMb0zkpgwdTBJLocXFWWR1KMg5+Ossa17DYJbRobAwByqmUuRWQY8A5QDXjXVrwDa5ziZSAf+Bi4Uin1mTYsj2ENVB8BrldKrdLfdYM+FuB+pdSzgX67rKxMrVq16kzOy9DBbPjzTynZ9hSvuIdxRcKmVjfa8RFbBoMh5IjIaqVUWdC+L6jrIQcZYygilB1voxZex1+likuPvorj4rvg/OltPj/lMpYGg6HDCLahMP4BQ/vQPQa58jmuLKiEHd+1ehDZJW0H5k1vwmD42mBSeBjaRyeM1jIYDGeH6VEY2kcnjNYyGAxnh+lRGAwGgyEgxlAYDAaDISDGUBgMBoMhIMZQGAwGgyEgxlAYDAaDISDGUBgMBoMhIMZQGAwGgyEgEZ3CQ0QOAZvDreM06AJ8Gm4Rp4HRGVyMzuDSGXR2Bo0AvZVSQVvJKdIn3G0OZr6SjkJEVhmdwcPoDC5GZ/DoDBrB0hnM7zOuJ4PBYDAExBgKg8FgMAQk0g3F0+EWcJoYncHF6AwuRmfw6AwaIcg6I3ow22AwGAzhJ9J7FAaDwWAIMxFrKERktIhsFpGtInJbmLXkichyEdkkIjUiMkOX3yMitSKyTr/G+h1zu9a+WURGhVDrThGp1nq8S9CmisgyEdmi31N0uYjIo1rnBhEpDYG+3n71tU5EGkXklkioSxF5RkT2ichGv7J2152ITNH7bxGRKSf6rQ7Q+VsR+Y/W8qqIJOvy7iJy1K9en/Q75jx9r2zV5xLUxahPorPd17mj24KT6PyLn8adIrJOl4elPgO0QaG5P5VSEfcC7MA2oBCIBtYD/cKoJxso1dsJwEdAP+Ae4NYT7N9Pa3YCBfpc7CHSuhPoclzZb4Db9PZtwIN6eyzwd0CAwcD7YbjOe4FukVCXQCVQCmw807oDUoHt+j1Fb6eEQGcVEKW3H/TT2d1/v+O+5wNgiD6HvwNjQqCzXdc5FG3BiXQe9/lDwM/DWZ8B2qCQ3J+R2qMYBGxVSm1XSjUBLwETwiVGKVWnlFqjtw8Bm4CcAIdMAF5SSh1TSu0AtmKdU7iYAMzT2/OAS/3K5yuLlUCyiGSHUNdFwDal1K4A+4SsLpVSbwOfneD321N3o4BlSqnPlFIHgWXA6I7WqZR6QynVov9cCeQG+g6tNVEptUJZLch8Ws+tw3QG4GTXucPbgkA6da/gKuDFQN/R0fUZoA0Kyf0ZqYYiB/jE7+/dBG6YQ4aIdAcGAu/roum6a/eMt9tHePUr4A0RWS0i39dlmUqpOrBuOCAjAnQCTKTtP2Ck1SW0v+7CrRfgBqynSS8FIrJWRP5PRIbrshytzUsodbbnOoe7PocD9UqpLX5lYa3P49qgkNyfkWooTuTbC3t4lojEA68AtyilGoE/AD2Ac4E6rC4qhFf/UKVUKTAG+LGIBFqjNGw6RSQaGA8s1EWRWJeBOJmusOoVkTuBFuAFXVQH5CulBgKzgAUikkj4dLb3Oof7+l9N24eZsNbnCdqgk+56Ej1npDNSDcVuIM/v71xgT5i0ACAiDqwL9IJSahGAUqpeKeVWSnmAP9LqEgmbfqXUHv2+D3hVa6r3upT0+75w68QyZGuUUvVab8TVpaa9dRc2vXpg8lvAJO3+QLtyDujt1Vj+/l5ap797KiQ6z+A6h7M+o4DLgb94y8JZnydqgwjR/RmphuLfQJGIFOgnz4nA4nCJ0X7KucAmpdTDfuX+/vzLAG/UxGJgoog4RaQAKMIa6OponXEikuDdxhrg3Kj1eKMbpgCv+emcrCMkBgMN3m5sCGjzpBZpdelHe+tuKVAlIinarVKlyzoUERkNzAHGK6WO+JWni4hdbxdi1d92rfWQiAzW9/dkv3PrSJ3tvc7hbAsuBv6jlPK5lMJVnydrgwjV/RmsUflgv7BG7T/Csth3hlnLMKzu2QZgnX6NBf4MVOvyxUC23zF3au2bCXI0SQCdhVhRIeuBGm+9AWnAm8AW/Z6qywV4XOusBspCpDMWOAAk+ZWFvS6xDFcd0Iz15HXjmdQd1hjBVv26PkQ6t2L5nr3355N63yv0vbAeWAOM8/ueMqyGehvwGHoCbgfrbPd17ui24EQ6dflzwA+O2zcs9cnJ26CQ3J9mZrbBYDAYAhKprieDwWAwRAjGUBgMBoMhIMZQGAwGgyEgxlAYDAaDISDGUBgMBoMhIMZQGAwGgyEgxlAYDAaDISDGUBgMBoMhIP8PVfh1hiB6l64AAAAASUVORK5CYII=\n", | |
"text/plain": [ | |
"<Figure size 432x288 with 1 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"from urllib.request import urlopen\n", | |
"\n", | |
"# A natural ecg signal (provided by the package BioSPPy)\n", | |
"ecg_txt = urlopen(\"https://raw.githubusercontent.com/PIA-Group/BioSPPy/e71ab177c4c8bdc7e644d962210cc40b1bdb41fb/examples/ecg.txt\")\n", | |
"x2 = np.loadtxt(ecg_txt)\n", | |
"\n", | |
"peaks2 = find_peaks(x2)[0]\n", | |
"print(\"Peaks:\", peaks2.size)\n", | |
"pdata2 = peak_prominences(x2, peaks2) \n", | |
"\n", | |
"plt.plot(x2)\n", | |
"plt.plot(peaks2, x2[peaks2], \"x\")\n", | |
"plt.xlim(0, 2000)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 10, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"21.6 ms ± 535 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", | |
"43.2 µs ± 177 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n" | |
] | |
} | |
], | |
"source": [ | |
"%timeit old(x2, peaks2, prominence_data=pdata2)\n", | |
"%timeit new(x2, peaks2, prominence_data=pdata2)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 11, | |
"metadata": { | |
"scrolled": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"18.1 ms ± 542 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", | |
"73.3 µs ± 192 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n" | |
] | |
} | |
], | |
"source": [ | |
"%timeit old(x2, peaks2, rel_height=1, prominence_data=pdata2)\n", | |
"%timeit new(x2, peaks2, rel_height=1, prominence_data=pdata2)" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.6.4" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment