├── .gitignore ├── HELP ├── LICENSE.md ├── MFS-33237 NOSA.doc ├── README.md ├── notebooks └── PyTDA_Demo.ipynb ├── pytda ├── __init__.py ├── common.py ├── pytda.py ├── pytda_cython_tools.c ├── pytda_cython_tools.pyx └── rsl_tools.py └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | notebooks/PyTDA_Demo-AMS_OSRSC.ipynb 3 | notebooks/*.uf 4 | .ipynb_checkpoints 5 | dist 6 | old 7 | output 8 | release_docs 9 | screenshots 10 | pytda.egg-info 11 | notebooks/*.nc 12 | references 13 | -------------------------------------------------------------------------------- /HELP: -------------------------------------------------------------------------------- 1 | Help on module pytda: 2 | 3 | NAME 4 | pytda 5 | 6 | DESCRIPTION 7 | Python Turbulence Detection Algorithm (PyTDA) 8 | Version 1.1.2 9 | Last Updated 07/31/2019 10 | 11 | 12 | Major References 13 | ---------------- 14 | Bohne, A. R. (1982). Radar detection of turbulence in precipitation 15 | environments. Journal of the Atmospheric Sciences, 39(8), 1819-1837. 16 | Doviak, R. J., and D. S. Zrnic, 1993: Doppler Radar and Weather Observations, 17 | Academic Press, 562 pp. 18 | Labitt, M. (1981). Coordinated radar and aircraft observations of turbulence 19 | (No. ATC-108). Federal Aviation Administration, Systems Research and 20 | Development Service. 21 | Williams, J. K., L. B. Cornman, J. Yee, S. G. Carson, G. Blackburn, and 22 | J. Craig, 2006: NEXRAD detection of hazardous turbulence. 44th AIAA 23 | Aerospace Sciences Meeting and Exhibit, Reno, NV. 24 | 25 | 26 | Author 27 | ------ 28 | Timothy James Lang 29 | timothy.j.lang@nasa.gov 30 | (256) 961-7861 31 | 32 | 33 | Overview 34 | -------- 35 | This software will estimate the cubic root of eddy dissipation rate, given 36 | input radar data containing reflectivity and spectrum width. Can be done 37 | on an individual sweep basis or by processing a full volume at once. If 38 | the latter, a new turbulence field is created within the Py-ART radar object. 39 | Based on the NCAR Turbulence Detection Algorithm (NTDA). For 2010 and older 40 | NEXRAD data (V06 and earlier), recommend running on UFs produced from the 41 | native Level 2 files via Radx due to conflicts between PyART and older NEXRAD 42 | data models. 43 | 44 | 45 | Change Log 46 | ---------- 47 | Version 1.1.2 Major Changes (07/31/2019): 48 | 1. Fixed a bug in the RHI code that was preventing processing when 49 | use_ntda=False. 50 | 51 | Version 1.1.1 Major Changes (11/27/2015): 52 | 1. Added common sub-module with old radar_coords_to_cart function that was 53 | in old version of Py-ART. Recent upgrade of Py-ART removed this function, 54 | breaking PyTDA in the process. 55 | 56 | Version 1.1 Major Changes (10/29/2015): 57 | 1. Fixed more issues for when radar object fields lack masks or fill values. 58 | 2. Enabled RHI functionality 59 | 60 | Version 1.0 Major Changes (08/28/2015): 61 | 1. Fixed issues for when radar object fields lack masks or fill values. 62 | 2. Fixed failure when radar.sweep_number attribute is not sequential 63 | 64 | Version 0.9 Major Changes (08/03/2015): 65 | 1. Made compliant with Python 3. 66 | 67 | Version 0.8 Major Changes (07/02/2015): 68 | 1. Made all code pep8 compliant. 69 | 70 | Version 0.7 Major Changes (03/16/2015): 71 | 1. Minor edits to improve documentation and reduce number of local variables. 72 | 73 | Version 0.6 Major Changes (11/26/2014): 74 | 1. Changed from NTDA's lookup table to basic equations for relating spectrum 75 | width to EDR. Now can account for radars with other beamwidths and 76 | gate spacings than NEXRAD. 77 | 2. Added use_ntda flag to turn on/off NTDA-based filtering (i.e., can turn off 78 | to straight up convert SW to EDR). 79 | 3. Performance improvements leading to significant code speedup. 80 | 4. Removed variables and imports related to NTDA lookup tables. 81 | 5. Changed name of different_sweeps flag to split_cut for improved clarity. 82 | 6. Changed atan2_cython function's name to atan2c_longitude to better indicate 83 | its specialized nature. Added more generic atan2c function to 84 | pytda_cython_tools, although this is not currently used. 85 | 86 | Version 0.5 Major Changes: 87 | 1. Fixed a bug that prevented actual filtering of DZ/SW fields before 88 | turbulence calculations in certain radar volumes. Performance improved 89 | considerably! 90 | 2. Fixed bug that set turbulence to 0 where it was never calculated to 91 | begin with. Should instead be the bad data fill value for spectrum width. 92 | 3. Fixed bug that caused a crash when running calc_turb_vol() with 93 | different_sweeps keyword set to True. 94 | 95 | Version 0.4 Major Changes: 96 | 1. Refactoring to reduce number of local variables in calc_turb_sweep() proper. 97 | 2. Added calc_turb_vol(), which leverages calc_turb_sweep() to process and 98 | entire volume at once, and add the turbulence field to the Py-ART radar 99 | object. 100 | 3. Added add_turbulence_field() to create a Py-ART radar field for turbulence 101 | 102 | Version 0.3 Major Changes: 103 | 1. Refactoring of calc_turb_sweep() to drastically speed up processing. 104 | 105 | Version 0.2 Functionality: 106 | 1. calc_turb_sweep() - Input Py-ART radar object, receive back turbulence on 107 | the specified sweep plus longitude and latitude in that coordinate system. 108 | 109 | FUNCTIONS 110 | add_turbulence_field(radar, turbulence, turb_name='turbulence') 111 | 112 | atan2c_longitude(...) 113 | 114 | calc_cartesian_coords_radians(lon1r, lat1r, lon2r, lat2r) 115 | Assumes conversion to radians has already occurred 116 | 117 | calc_cswv_cython(...) 118 | 119 | calc_turb_sweep(radar, sweep_number, radius=2.0, split_cut=False, xran=[-300.0, 300.0], yran=[-300.0, 300.0], verbose=False, name_dz='reflectivity', name_sw='spectrum_width', use_ntda=True, beamwidth=0.96, gate_spacing=0.25) 120 | Provide a Py-ART radar object containing reflectivity and spectrum width 121 | variables as an argument, along with the sweep number and any necessary 122 | changes to the keywords, and receive back turbulence for the same sweep 123 | as spectrum width (along with longitude and latitude on the same coordinate 124 | system). 125 | radar = Py-ART radar object 126 | sweep_number = Can be as low as 0, as high as # of sweeps minus 1 127 | radius = radius of influence (km) 128 | split_cut = Set to True if using NEXRAD or similar radar that has two 129 | separate low-level sweeps at the same tilt angle for DZ & SW 130 | verbose = Set to True to get more information about calculation progress. 131 | xran = [Min X from radar, Max X from radar], subsectioning improves 132 | performance 133 | yran = [Min Y from radar, Max Y from radar], subsectioning improves 134 | performance 135 | name_dz = Name of reflectivity field, used by Py-ART to access field 136 | name_sw = Name of spectrum width field, used by Py-ART to access field 137 | use_ntda = Flag to use the spatial averaging and weighting employed by NTDA 138 | beamwidth = Beamwidth of radar in degrees 139 | gate_spacing = Gate spacing of radar in km 140 | 141 | calc_turb_vol(radar, radius=2.0, split_cut=False, xran=[-300.0, 300.0], yran=[-300.0, 300.0], verbose=False, name_dz='reflectivity', name_sw='spectrum_width', turb_name='turbulence', max_split_cut=2, use_ntda=True, beamwidth=0.96, gate_spacing=0.25) 142 | Leverages calc_turb_sweep() to process an entire radar volume for 143 | turbulence. Has ability to account for split-cut sweeps in a volume 144 | (i.e., DZ & SW on different, mismatched sweeps). 145 | radar = Py-ART radar object 146 | radius = Search radius for calculating EDR 147 | split_cut = Set to True for split-cut volumes 148 | xran = Spatial range in X to consider 149 | yran = Spatial range in Y to consider 150 | verbose = Set to True to get more information on calculation status 151 | name_dz = Name of reflectivity field 152 | name_sw = Name of spectrum width field 153 | turb_name = Name for created turbulence field 154 | max_split_cut = Total number of tilts that are affected by split cuts 155 | use_ntda = Flag to use the spatial averaging and weighting employed by NTDA 156 | beamwidth = Beamwidth of radar in degrees 157 | gate_spacing = Gate spacing of radar in km 158 | 159 | edr_long_range(sw, rng, theta, gs) 160 | For gate spacing < range * beamwidth 161 | sw (spectrum width) in m/s, 162 | rng (range) in km, 163 | theta (beamwidth) in deg, 164 | gs (gate spacing) in km 165 | 166 | edr_short_range(sw, rng, theta, gs) 167 | For gate spacing > range * beamwidth 168 | sw (spectrum width) in m/s, 169 | rng (range) in km, 170 | theta (beamwidth) in deg, 171 | gs (gate spacing) in km 172 | 173 | flatten_and_reduce_data_array(array, condition) 174 | 175 | get_radar_latlon_plus_radians(radar) 176 | Input Py-ART radar object, get lat/lon first in deg then in radians 177 | 178 | get_range_adjusted_nexrad_sweep(file, sweep) 179 | Function under construction, not used yet. 180 | Credit: JJ Helmus, DOE 181 | file: Path and name of original radar file 182 | sweep: Number of sweep needing range adjustment 183 | Function will return sweep as radar object with modified range. 184 | 185 | get_sweep_azimuths(radar, sweep_number) 186 | 187 | get_sweep_data(radar, field_name, sweep_number) 188 | 189 | get_sweep_elevations(radar, sweep_number) 190 | 191 | polar_coords_to_latlon(radar, sweep_number) 192 | Function under construction, not currently used 193 | 194 | DATA 195 | CONSTANT = 2.1665887030822408 196 | DEFAULT_BEAMWIDTH = 0.96 197 | DEFAULT_DZ = 'reflectivity' 198 | DEFAULT_GATE_SPACING = 0.25 199 | DEFAULT_RADIUS = 2.0 200 | DEFAULT_SW = 'spectrum_width' 201 | DEFAULT_TURB = 'turbulence' 202 | KOLMOGOROV_CONSTANT = 1.6 203 | MAX_INT = [-300.0, 300.0] 204 | RNG_MULT = 1000.0 205 | RRV_SCALING_FACTOR = 3.3302184446307908 206 | SPLIT_CUT_MAX = 2 207 | VARIANCE_RADIUS_SW = 1.0 208 | VERSION = '0.8' 209 | __warningregistry__ = {'version': 54, ('invalid value encountered in s... 210 | gamma = 211 | hypergeometric_gaussian = 212 | print_function = _Feature((2, 6, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0)... 213 | re = 6371.1 214 | 215 | FILE 216 | /Users/tjlang/Documents/Python/pytda/pytda.py -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | NASA OPEN SOURCE AGREEMENT VERSION 1.3 2 | 3 | THIS OPEN SOURCE AGREEMENT (“AGREEMENT”) DEFINES THE RIGHTS OF USE, REPRODUCTION, DISTRIBUTION, MODIFICATION AND REDISTRIBUTION OF CERTAIN COMPUTER SOFTWARE ORIGINALLY RELEASED BY THE UNITED STATES GOVERNMENT AS REPRESENTED BY THE GOVERNMENT AGENCY LISTED BELOW ("GOVERNMENT AGENCY"). THE UNITED STATES GOVERNMENT, AS REPRESENTED BY GOVERNMENT AGENCY, IS AN INTENDED THIRD-PARTY BENEFICIARY OF ALL SUBSEQUENT DISTRIBUTIONS OR REDISTRIBUTIONS OF THE SUBJECT SOFTWARE. ANYONE WHO USES, REPRODUCES, DISTRIBUTES, MODIFIES OR REDISTRIBUTES THE SUBJECT SOFTWARE, AS DEFINED HEREIN, OR ANY PART THEREOF, IS, BY THAT ACTION, ACCEPTING IN FULL THE RESPONSIBILITIES AND OBLIGATIONS CONTAINED IN THIS AGREEMENT. 4 | 5 | Government Agency: NASA Marshall Space Flight Center 6 | Government Agency Original Software Designation: MFS-33237-1 7 | Government Agency Original Software Title: Python Turbulence Detection Algorithm (PyTDA) 8 | User Registration Requested. Please visit https://github.com/nasa/pytda 9 | Government Agency Point of Contact for Original Software: timothy.j.lang@nasa.gov 10 | 11 | 12 | 1. DEFINITIONS 13 | 14 | A. “Contributor” means Government Agency, as the developer of the Original Software, and any entity that makes a Modification. 15 | B. “Covered Patents” mean patent claims licensable by a Contributor that are necessarily infringed by the use or sale of its Modification alone or when combined with the Subject Software. 16 | C. “Display” means the showing of a copy of the Subject Software, either directly or by means of an image, or any other device. 17 | D. “Distribution” means conveyance or transfer of the Subject Software, regardless of means, to another. 18 | E. “Larger Work” means computer software that combines Subject Software, or portions thereof, with software separate from the Subject Software that is not governed by the terms of this Agreement. 19 | F. “Modification” means any alteration of, including addition to or deletion from, the substance or structure of either the Original Software or Subject Software, and includes derivative works, as that term is defined in the Copyright Statute, 17 USC 101. However, the act of including Subject Software as part of a Larger Work does not in and of itself constitute a Modification. 20 | G. “Original Software” means the computer software first released under this Agreement by Government Agency with Government Agency designation MFS-33237-1 and entitled Python Turbulence Detection Algorithm (PyTDA) including source code, object code and accompanying documentation, if any. 21 | H. “Recipient” means anyone who acquires the Subject Software under this Agreement, including all Contributors. 22 | I. “Redistribution” means Distribution of the Subject Software after a Modification has been made. 23 | J. “Reproduction” means the making of a counterpart, image or copy of the Subject Software. 24 | K. “Sale” means the exchange of the Subject Software for money or equivalent value. 25 | L. “Subject Software” means the Original Software, Modifications, or any respective parts thereof. 26 | M. “Use” means the application or employment of the Subject Software for any purpose. 27 | 28 | 2. GRANT OF RIGHTS 29 | 30 | A. Under Non-Patent Rights: Subject to the terms and conditions of this Agreement, each Contributor, with respect to its own contribution to the Subject Software, hereby grants to each Recipient a non-exclusive, world-wide, royalty-free license to engage in the following activities pertaining to the Subject Software: 31 | 32 | 1. Use 33 | 2. Distribution 34 | 3. Reproduction 35 | 4. Modification 36 | 5. Redistribution 37 | 6. Display 38 | 39 | B. Under Patent Rights: Subject to the terms and conditions of this Agreement, each Contributor, with respect to its own contribution to the Subject Software, hereby grants to each Recipient under Covered Patents a non-exclusive, world-wide, royalty-free license to engage in the following activities pertaining to the Subject Software: 40 | 41 | 1. Use 42 | 2. Distribution 43 | 3. Reproduction 44 | 4. Sale 45 | 5. Offer for Sale 46 | 47 | C. The rights granted under Paragraph B. also apply to the combination of a Contributor’s Modification and the Subject Software if, at the time the Modification is added by the Contributor, the addition of such Modification causes the combination to be covered by the Covered Patents. It does not apply to any other combinations that include a Modification. 48 | 49 | D. The rights granted in Paragraphs A. and B. allow the Recipient to sublicense those same rights. Such sublicense must be under the same terms and conditions of this Agreement. 50 | 51 | 3. OBLIGATIONS OF RECIPIENT 52 | 53 | A. Distribution or Redistribution of the Subject Software must be made under this Agreement except for additions covered under paragraph 3H. 54 | 55 | 1. Whenever a Recipient distributes or redistributes the Subject Software, a copy of this Agreement must be included with each copy of the Subject Software; and 56 | 2. If Recipient distributes or redistributes the Subject Software in any form other than source code, Recipient must also make the source code freely available, and must provide with each copy of the Subject Software information on how to obtain the source code in a reasonable manner on or through a medium customarily used for software exchange. 57 | 58 | B. Each Recipient must ensure that the following copyright notice appears prominently in the Subject Software: 59 | 60 | Copyright © {2014} United States Government as represented by 61 | Marshall Space Flight Center. 62 | No copyright is claimed in the United States under Title 17, U.S.Code. 63 | All Other Rights Reserved. 64 | 65 | C. Each Contributor must characterize its alteration of the Subject Software as a Modification and must identify itself as the originator of its Modification in a manner that reasonably allows subsequent Recipients to identify the originator of the Modification. In fulfillment of these requirements, Contributor must include a file (e.g., a change log file) that describes the alterations made and the date of the alterations, identifies Contributor as originator of the alterations, and consents to characterization of the alterations as a Modification, for example, by including a statement that the Modification is derived, directly or indirectly, from Original Software provided by Government Agency. Once consent is granted, it may not thereafter be revoked. 66 | 67 | D. A Contributor may add its own copyright notice to the Subject Software. Once a copyright notice has been added to the Subject Software, a Recipient may not remove it without the express permission of the Contributor who added the notice. 68 | 69 | E. A Recipient may not make any representation in the Subject Software or in any promotional, advertising or other material that may be construed as an endorsement by Government Agency or by any prior Recipient of any product or service provided by Recipient, or that may seek to obtain commercial advantage by the fact of Government Agency's or a prior Recipient’s participation in this Agreement. 70 | 71 | 72 | F. In an effort to track usage and maintain accurate records of the Subject Software, each Recipient, upon receipt of the Subject Software, is requested to provide Government Agency, by e-mail to the Government Agency Point of Contact listed in clause 5.F., the following information: Timothy Lang, timothy.j.lang@nasa.gov Recipient’s name and personal information shall be used for statistical purposes only. Once a Recipient makes a Modification available, it is requested that the Recipient inform Government Agency, by e-mail to the Government Agency Point of Contact listed in clause 5.F., how to access the Modification. 73 | 74 | G. Each Contributor represents that that its Modification is believed to be Contributor’s original creation and does not violate any existing agreements, regulations, statutes or rules, and further that Contributor has sufficient rights to grant the rights conveyed by this Agreement. 75 | 76 | H. A Recipient may choose to offer, and to charge a fee for, warranty, support, indemnity and/or liability obligations to one or more other Recipients of the Subject Software. A Recipient may do so, however, only on its own behalf and not on behalf of Government Agency or any other Recipient. Such a Recipient must make it absolutely clear that any such warranty, support, indemnity and/or liability obligation is offered by that Recipient alone. Further, such Recipient agrees to indemnify Government Agency and every other Recipient for any liability incurred by them as a result of warranty, support, indemnity and/or liability offered by such Recipient. 77 | 78 | I. A Recipient may create a Larger Work by combining Subject Software with separate software not governed by the terms of this agreement and distribute the Larger Work as a single product. In such case, the Recipient must make sure Subject Software, or portions thereof, included in the Larger Work is subject to this Agreement. 79 | 80 | J. Notwithstanding any provisions contained herein, Recipient is hereby put on notice that export of any goods or technical data from the United States may require some form of export license from the U.S. Government. Failure to obtain necessary export licenses may result in criminal liability under U.S. laws. Government Agency neither represents that a license shall not be required nor that, if required, it shall be issued. Nothing granted herein provides any such export license. 81 | 82 | 4. DISCLAIMER OF WARRANTIES AND LIABILITIES; WAIVER AND INDEMNIFICATION 83 | 84 | A. No Warranty: THE SUBJECT SOFTWARE IS PROVIDED “AS IS” WITHOUT ANY WARRANTY OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. THIS AGREEMENT DOES NOT, IN ANY MANNER, CONSTITUTE AN ENDORSEMENT BY GOVERNMENT AGENCY OR ANY PRIOR RECIPIENT OF ANY RESULTS, RESULTING DESIGNS, HARDWARE, SOFTWARE PRODUCTS OR ANY OTHER APPLICATIONS RESULTING FROM USE OF THE SUBJECT SOFTWARE. FURTHER, GOVERNMENT AGENCY DISCLAIMS ALL WARRANTIES AND LIABILITIES REGARDING THIRD-PARTY SOFTWARE, IF PRESENT IN THE ORIGINAL SOFTWARE, AND DISTRIBUTES IT “AS IS.” 85 | 86 | B. Waiver and Indemnity: RECIPIENT AGREES TO WAIVE ANY AND ALL CLAIMS AGAINST THE UNITED STATES GOVERNMENT, ITS CONTRACTORS AND SUBCONTRACTORS, AS WELL AS ANY PRIOR RECIPIENT. IF RECIPIENT'S USE OF THE SUBJECT SOFTWARE RESULTS IN ANY LIABILITIES, DEMANDS, DAMAGES, EXPENSES OR LOSSES ARISING FROM SUCH USE, INCLUDING ANY DAMAGES FROM PRODUCTS BASED ON, OR RESULTING FROM, RECIPIENT'S USE OF THE SUBJECT SOFTWARE, RECIPIENT SHALL INDEMNIFY AND HOLD HARMLESS THE UNITED STATES GOVERNMENT, ITS CONTRACTORS AND SUBCONTRACTORS, AS WELL AS ANY PRIOR RECIPIENT, TO THE EXTENT PERMITTED BY LAW. RECIPIENT'S SOLE REMEDY FOR ANY SUCH MATTER SHALL BE THE IMMEDIATE, UNILATERAL TERMINATION OF THIS AGREEMENT. 87 | 88 | 89 | 5. GENERAL TERMS 90 | 91 | A. Termination: This Agreement and the rights granted hereunder will terminate automatically if a Recipient fails to comply with these terms and conditions, and fails to cure such noncompliance within thirty (30) days of becoming aware of such noncompliance. Upon termination, a Recipient agrees to immediately cease use and distribution of the Subject Software. All sublicenses to the Subject Software properly granted by the breaching Recipient shall survive any such termination of this Agreement. 92 | 93 | B. Severability: If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement. 94 | 95 | C. Applicable Law: This Agreement shall be subject to United States federal law only for all purposes, including, but not limited to, determining the validity of this Agreement, the meaning of its provisions and the rights, obligations and remedies of the parties. 96 | 97 | D. Entire Understanding: This Agreement constitutes the entire understanding and agreement of the parties relating to release of the Subject Software and may not be superseded, modified or amended except by further written agreement duly executed by the parties. 98 | 99 | E. Binding Authority: By accepting and using the Subject Software under this Agreement, a Recipient affirms its authority to bind the Recipient to all terms and conditions of this Agreement and that that Recipient hereby agrees to all terms and conditions herein. 100 | 101 | F. Point of Contact: Any Recipient contact with Government Agency is to be directed to the designated representative as follows: __Timothy Lang, timothy.j.lang@nasa.gov 102 | 103 | -------------------------------------------------------------------------------- /MFS-33237 NOSA.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjlang/PyTDA/bf99795560f227df02eebc0bb6ac845621f965f9/MFS-33237 NOSA.doc -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PyTDA README 2 | ------------ 3 | 4 | This software provides Python functions that will estimate turbulence from 5 | Doppler radar data. It is tested and working under Python 2.7-3.7. 6 | 7 | For help see `HELP` file. For license see `LICENSE.md`. 8 | 9 | 10 | Installation 11 | ------------ 12 | 13 | Install [Py-ART](https://github.com/ARM-DOE/pyart). 14 | 15 | Run `python setup.py install` from the command line in the main PyTDA folder. 16 | 17 | 18 | Using PyTDA 19 | ----------- 20 | ``` 21 | import pytda 22 | ``` 23 | 24 | PyTDA (among other modules) is discussed in this [conference presentation] 25 | (https://ams.confex.com/ams/95Annual/webprogram/Paper262779.html) 26 | 27 | See the notebooks directory for a demonstration Jupyter notebook. 28 | -------------------------------------------------------------------------------- /pytda/__init__.py: -------------------------------------------------------------------------------- 1 | # ============================= 2 | """ 3 | PyTDA - Python Turbulence Detection Algorithm 4 | ================================== 5 | Top-level package (:mod:'pytda') 6 | ================================== 7 | 8 | .. currentmodule:: pytda 9 | 10 | """ 11 | 12 | from .pytda import ( 13 | calc_turb_sweep, calc_turb_vol, get_sweep_data, get_sweep_azimuths, 14 | get_sweep_elevations, flatten_and_reduce_data_array, calc_turb_rhi) 15 | -------------------------------------------------------------------------------- /pytda/common.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | def radar_coords_to_cart(rng, az, ele, debug=False): 5 | """ 6 | TJL - taken from old Py-ART version 7 | Calculate Cartesian coordinate from radar coordinates 8 | Parameters 9 | ---------- 10 | rng : array 11 | Distances to the center of the radar gates (bins) in kilometers. 12 | az : array 13 | Azimuth angle of the radar in degrees. 14 | ele : array 15 | Elevation angle of the radar in degrees. 16 | Returns 17 | ------- 18 | x, y, z : array 19 | Cartesian coordinates in meters from the radar. 20 | Notes 21 | ----- 22 | The calculation for Cartesian coordinate is adapted from equations 23 | 2.28(b) and 2.28(c) of Doviak and Zrnic [1]_ assuming a 24 | standard atmosphere (4/3 Earth's radius model). 25 | .. math:: 26 | z = \\sqrt{r^2+R^2+r*R*sin(\\theta_e)} - R 27 | s = R * arcsin(\\frac{r*cos(\\theta_e)}{R+z}) 28 | x = s * sin(\\theta_a) 29 | y = s * cos(\\theta_a) 30 | Where r is the distance from the radar to the center of the gate, 31 | :math:`\\theta_a` is the azimuth angle, :math:`\\theta_e` is the 32 | elevation angle, s is the arc length, and R is the effective radius 33 | of the earth, taken to be 4/3 the mean radius of earth (6371 km). 34 | References 35 | ---------- 36 | .. [1] Doviak and Zrnic, Doppler Radar and Weather Observations, Second 37 | Edition, 1993, p. 21. 38 | """ 39 | theta_e = ele * np.pi / 180.0 # elevation angle in radians. 40 | theta_a = az * np.pi / 180.0 # azimuth angle in radians. 41 | R = 6371.0 * 1000.0 * 4.0 / 3.0 # effective radius of earth in meters. 42 | r = rng * 1000.0 # distances to gates in meters. 43 | 44 | z = (r ** 2 + R ** 2 + 2.0 * r * R * np.sin(theta_e)) ** 0.5 - R 45 | s = R * np.arcsin(r * np.cos(theta_e) / (R + z)) # arc length in m. 46 | x = s * np.sin(theta_a) 47 | y = s * np.cos(theta_a) 48 | return x, y, z 49 | -------------------------------------------------------------------------------- /pytda/pytda.py: -------------------------------------------------------------------------------- 1 | """ 2 | Python Turbulence Detection Algorithm (PyTDA) 3 | Version 1.1.2 4 | Last Updated 07/31/2019 5 | 6 | 7 | Major References 8 | ---------------- 9 | Bohne, A. R. (1982). Radar detection of turbulence in precipitation 10 | environments. Journal of the Atmospheric Sciences, 39(8), 1819-1837. 11 | Doviak, R. J., and D. S. Zrnic, 1993: Doppler Radar and Weather Observations, 12 | Academic Press, 562 pp. 13 | Labitt, M. (1981). Coordinated radar and aircraft observations of turbulence 14 | (No. ATC-108). Federal Aviation Administration, Systems Research and 15 | Development Service. 16 | Williams, J. K., L. B. Cornman, J. Yee, S. G. Carson, G. Blackburn, and 17 | J. Craig, 2006: NEXRAD detection of hazardous turbulence. 44th AIAA 18 | Aerospace Sciences Meeting and Exhibit, Reno, NV. 19 | 20 | 21 | Author 22 | ------ 23 | Timothy James Lang 24 | timothy.j.lang@nasa.gov 25 | (256) 961-7861 26 | 27 | 28 | Overview 29 | -------- 30 | This software will estimate the cubic root of eddy dissipation rate, given 31 | input radar data containing reflectivity and spectrum width. Can be done 32 | on an individual sweep basis or by processing a full volume at once. If 33 | the latter, a new turbulence field is created within the Py-ART radar object. 34 | Based on the NCAR Turbulence Detection Algorithm (NTDA). For 2010 and older 35 | NEXRAD data (V06 and earlier), recommend running on CF Radials produced from 36 | native Level 2 files via Radx due to conflicts between Py-ART and older NEXRAD 37 | data models. 38 | 39 | 40 | Change Log 41 | ---------- 42 | Version 1.1.2 Major Changes (07/31/2019): 43 | 1. Fixed a bug in the RHI code that was preventing processing when 44 | use_ntda=False. 45 | 46 | Version 1.1.1 Major Changes (11/27/2015): 47 | 1. Added common sub-module with old radar_coords_to_cart function that was 48 | in old version of Py-ART. Recent upgrade of Py-ART removed this function, 49 | breaking PyTDA in the process. 50 | 51 | Version 1.1 Major Changes (10/29/2015): 52 | 1. Fixed more issues for when radar object fields lack masks or fill values. 53 | 2. Enabled RHI functionality 54 | 55 | Version 1.0 Major Changes (08/28/2015): 56 | 1. Fixed issues for when radar object fields lack masks or fill values. 57 | 2. Fixed failure when radar.sweep_number attribute is not sequential 58 | 59 | Version 0.9 Major Changes (08/03/2015): 60 | 1. Made compliant with Python 3. 61 | 62 | Version 0.8 Major Changes (07/02/2015): 63 | 1. Made all code pep8 compliant. 64 | 65 | Version 0.7 Major Changes (03/16/2015): 66 | 1. Minor edits to improve documentation and reduce number of local variables. 67 | 68 | Version 0.6 Major Changes (11/26/2014): 69 | 1. Changed from NTDA's lookup table to basic equations for relating spectrum 70 | width to EDR. Now can account for radars with other beamwidths and 71 | gate spacings than NEXRAD. 72 | 2. Added use_ntda flag to turn on/off NTDA-based filtering (i.e., can turn off 73 | to straight up convert SW to EDR). 74 | 3. Performance improvements leading to significant code speedup. 75 | 4. Removed variables and imports related to NTDA lookup tables. 76 | 5. Changed name of different_sweeps flag to split_cut for improved clarity. 77 | 6. Changed atan2_cython function's name to atan2c_longitude to better indicate 78 | its specialized nature. Added more generic atan2c function to 79 | pytda_cython_tools, although this is not currently used. 80 | 81 | Version 0.5 Major Changes: 82 | 1. Fixed a bug that prevented actual filtering of DZ/SW fields before 83 | turbulence calculations in certain radar volumes. Performance improved 84 | considerably! 85 | 2. Fixed bug that set turbulence to 0 where it was never calculated to 86 | begin with. Should instead be the bad data fill value for spectrum width. 87 | 3. Fixed bug that caused a crash when running calc_turb_vol() with 88 | different_sweeps keyword set to True. 89 | 90 | Version 0.4 Major Changes: 91 | 1. Refactoring to reduce number of local variables in calc_turb_sweep() proper. 92 | 2. Added calc_turb_vol(), which leverages calc_turb_sweep() to process and 93 | entire volume at once, and add the turbulence field to the Py-ART radar 94 | object. 95 | 3. Added add_turbulence_field() to create a Py-ART radar field for turbulence 96 | 97 | Version 0.3 Major Changes: 98 | 1. Refactoring of calc_turb_sweep() to drastically speed up processing. 99 | 100 | Version 0.2 Functionality: 101 | 1. calc_turb_sweep() - Input Py-ART radar object, receive back turbulence on 102 | the specified sweep plus longitude and latitude in that coordinate system. 103 | 104 | """ 105 | 106 | from __future__ import print_function 107 | import numpy as np 108 | from sklearn.neighbors import BallTree 109 | from scipy.special import gamma as gamma 110 | from scipy.special import hyp2f1 as hypergeometric_gaussian 111 | import time 112 | import pyart 113 | from .common import radar_coords_to_cart 114 | from .rsl_tools import rsl_get_groundr_and_h 115 | from .pytda_cython_tools import calc_cswv_cython, atan2c_longitude 116 | 117 | VERSION = '1.1.1' 118 | 119 | # sw_* as prefix = related to sweep 120 | # *_sw as suffix = related to spectrum width 121 | re = 6371.1 # km 122 | MAX_INT = [-300.0, 300.0] # km 123 | VARIANCE_RADIUS_SW = 1.0 # km 124 | DEFAULT_RADIUS = 2.0 # km 125 | DEFAULT_DZ = 'reflectivity' 126 | DEFAULT_SW = 'spectrum_width' 127 | DEFAULT_TURB = 'turbulence' 128 | DEFAULT_BEAMWIDTH = 0.96 # deg 129 | DEFAULT_GATE_SPACING = 0.25 # km 130 | RNG_MULT = 1000.0 # m per km 131 | SPLIT_CUT_MAX = 2 # maximum number of split cut sweeps 132 | RRV_SCALING_FACTOR = (8.0 * np.log(4.0))**0.5 # From Bohne (1982) 133 | KOLMOGOROV_CONSTANT = 1.6 134 | CONSTANT = KOLMOGOROV_CONSTANT * gamma(2.0/3.0) 135 | BAD_DATA_VAL = -32768 136 | 137 | # TO DO: Class definition here to simplify calc_turb_sweep() code? 138 | 139 | 140 | def calc_turb_sweep(radar, sweep_number, radius=DEFAULT_RADIUS, 141 | split_cut=False, 142 | xran=MAX_INT, yran=MAX_INT, verbose=False, 143 | name_dz=DEFAULT_DZ, name_sw=DEFAULT_SW, 144 | use_ntda=True, beamwidth=DEFAULT_BEAMWIDTH, 145 | gate_spacing=DEFAULT_GATE_SPACING): 146 | """ 147 | Provide a Py-ART radar object containing reflectivity and spectrum width 148 | variables as an argument, along with the sweep number and any necessary 149 | changes to the keywords, and receive back turbulence for the same sweep 150 | as spectrum width (along with longitude and latitude on the same coordinate 151 | system). 152 | radar = Py-ART radar object 153 | sweep_number = Can be as low as 0, as high as # of sweeps minus 1 154 | radius = radius of influence (km) 155 | split_cut = Set to True if using NEXRAD or similar radar that has two 156 | separate low-level sweeps at the same tilt angle for DZ & SW 157 | verbose = Set to True to get more information about calculation progress. 158 | xran = [Min X from radar, Max X from radar], subsectioning improves 159 | performance 160 | yran = [Min Y from radar, Max Y from radar], subsectioning improves 161 | performance 162 | name_dz = Name of reflectivity field, used by Py-ART to access field 163 | name_sw = Name of spectrum width field, used by Py-ART to access field 164 | use_ntda = Flag to use the spatial averaging and weighting employed by NTDA 165 | beamwidth = Beamwidth of radar in degrees 166 | gate_spacing = Gate spacing of radar in km 167 | 168 | """ 169 | 170 | if verbose: 171 | overall_time = time.time() 172 | begin_time = time.time() 173 | 174 | sweep_dz = get_sweep_data(radar, name_dz, sweep_number) 175 | try: 176 | fill_val_sw = radar.fields[name_sw]['_FillValue'] 177 | except KeyError: 178 | fill_val_sw = BAD_DATA_VAL 179 | try: 180 | fill_val_dz = radar.fields[name_dz]['_FillValue'] 181 | except KeyError: 182 | fill_val_dz = BAD_DATA_VAL 183 | sweep_sw, sweep_az_sw, sweep_elev_sw, dz_sw = \ 184 | _retrieve_sweep_fields(radar, name_sw, name_dz, sweep_number, 185 | sweep_dz, split_cut) 186 | 187 | # Radar location needed to get lat/lon 188 | # of every gate for distance calculations 189 | klat, klon, klatr, klonr = get_radar_latlon_plus_radians(radar) 190 | 191 | # Initialize information on sweep geometry 192 | sw_lonr = 0.0 * sweep_sw 193 | sw_azr_1d = np.deg2rad(sweep_az_sw) 194 | sw_sr_1d = radar.range['data'][:] / RNG_MULT 195 | result = np.meshgrid(sw_sr_1d, sweep_az_sw) 196 | sw_azr_2d = np.deg2rad(result[1]) 197 | sw_sr_2d = result[0] 198 | result = np.meshgrid(sw_sr_1d, sweep_elev_sw) 199 | sw_el = result[1] 200 | sweep_size = radar.sweep_end_ray_index['data'][sweep_number] + 1 - \ 201 | radar.sweep_start_ray_index['data'][sweep_number] 202 | sw_gr, sw_ht = rsl_get_groundr_and_h(sw_sr_2d, sw_el) 203 | sw_latr = np.arcsin((np.sin(klatr) * np.cos(sw_gr/re)) + 204 | (np.cos(klatr) * np.sin(sw_gr/re) * np.cos(sw_azr_2d))) 205 | 206 | if verbose: 207 | print(time.time() - begin_time, 208 | 'seconds to complete all preliminary processing') 209 | begin_time = time.time() 210 | 211 | # Get longitude at every gate 212 | for j in np.arange(sweep_size): 213 | for i in np.arange(radar.ngates): 214 | sw_lonr[j, i] = klonr +\ 215 | atan2c_longitude(sw_azr_1d[j], sw_gr[j, i], 216 | klatr, sw_latr[j, i]) 217 | sw_lat = np.rad2deg(sw_latr) 218 | sw_lon = np.rad2deg(sw_lonr) 219 | 220 | # Determine NTDA interest fields 221 | csnr_sw = _calc_csnr_for_every_gate(dz_sw, sw_sr_2d) 222 | crng_sw = _calc_crng_for_every_gate(sw_sr_2d) 223 | czh_sw = _calc_czh_for_every_gate(dz_sw, sw_ht) 224 | cpr = 1.0 # Not calculating Cpr, user must remove second trip manually. 225 | 226 | if verbose: 227 | print(time.time() - begin_time, 228 | 'seconds to compute longitudes and precompute Csnr, Crng, Czh') 229 | begin_time = time.time() 230 | 231 | xx, yy = calc_cartesian_coords_radians(sw_lonr, sw_latr, klonr, klatr) 232 | 233 | # Flatten all arrays to avoid performance buzzkill of nested loops. 234 | # Then reduce the data using masks to make the job manageable. 235 | sweep_sw = sweep_sw.ravel() 236 | dz_sw = dz_sw.ravel() 237 | condition = np.logical_and(dz_sw != fill_val_dz, sweep_sw != fill_val_sw) 238 | sweep_sw = sweep_sw[condition] 239 | dz_sw = dz_sw[condition] 240 | 241 | # Brief detour to get eps and check to see if that's all user wants. 242 | # Placing this code here with reduced sweep_sw improves performance. 243 | sr_1d = flatten_and_reduce_data_array(sw_sr_2d, condition) 244 | cond = gate_spacing >= sr_1d * np.deg2rad(beamwidth) 245 | eps_sw = edr_long_range(sweep_sw, sr_1d, beamwidth, gate_spacing) 246 | eps_sw[cond] = edr_short_range(sweep_sw[cond], sr_1d[cond], 247 | beamwidth, gate_spacing) 248 | if not use_ntda: 249 | turb_radar_f = 1.0 * eps_sw 250 | turb_radar = sw_lat.flatten() * 0.0 + fill_val_sw 251 | turb_radar[condition] = turb_radar_f 252 | eps_sw = np.reshape(turb_radar, (len(sweep_az_sw), radar.ngates)) 253 | if verbose: 254 | print(time.time() - overall_time, 255 | 'seconds to process radar sweep') 256 | return eps_sw, sw_lat, sw_lon 257 | 258 | # Provided NTDA is wanted, continue flattening/reducing arrays 259 | xx = flatten_and_reduce_data_array(xx, condition) 260 | yy = flatten_and_reduce_data_array(yy, condition) 261 | csnr_sw = flatten_and_reduce_data_array(csnr_sw, condition) 262 | crng_sw = flatten_and_reduce_data_array(crng_sw, condition) 263 | czh_sw = flatten_and_reduce_data_array(czh_sw, condition) 264 | turb_radar_f = 0.0 * sweep_sw + fill_val_sw 265 | 266 | # Find the distance to every other good gate 267 | ind, ind_sw = _calc_tree(xx, yy, radius) 268 | cswv_sw = _calc_cswv_for_every_gate(xx, sweep_sw, ind_sw) 269 | if verbose: 270 | print(time.time() - begin_time, 271 | 'seconds to get eps, reduce data,', 272 | 'compute BallTree, and get Cswv') 273 | begin_time = time.time() 274 | 275 | # Loop thru data and do NTDA filtering 276 | for i in np.arange(len(xx)): 277 | if verbose: 278 | if i % 50000 == 0: 279 | print('i =', i, 'of', len(xx) - 1, 280 | time.time() - begin_time, 'seconds elapsed during loop') 281 | if xran[0] < xx[i] < xran[1] and yran[0] < yy[i] < yran[1]: 282 | # Broadcating employed to minimize the amount of looping 283 | eps = eps_sw[ind[i]]**2 284 | csnr = csnr_sw[ind[i]]**0.6667 285 | crng = crng_sw[ind[i]] 286 | czh = czh_sw[ind[i]] 287 | cswv = cswv_sw[ind[i]] 288 | # Begin NTDA-specific calculation 289 | tot = csnr * cpr * cswv * czh * crng 290 | num = tot * eps 291 | tot = np.sum(tot) 292 | num = np.sum(num) 293 | if tot > 0: 294 | turb_radar_f[i] = np.sqrt(num/tot) 295 | 296 | # Restore turbulence to a full 2-D sweep array and return along w/ lat/lon. 297 | turb_radar = sw_lat.flatten() * 0.0 + fill_val_sw 298 | turb_radar[condition] = turb_radar_f 299 | turb_radar = np.reshape(turb_radar, (len(sweep_az_sw), radar.ngates)) 300 | if verbose: 301 | print(time.time() - overall_time, 'seconds to process radar sweep') 302 | return turb_radar, sw_lat, sw_lon 303 | 304 | ####################################### 305 | 306 | 307 | def calc_turb_vol(radar, radius=DEFAULT_RADIUS, split_cut=False, 308 | xran=MAX_INT, yran=MAX_INT, verbose=False, 309 | name_dz=DEFAULT_DZ, name_sw=DEFAULT_SW, 310 | turb_name=DEFAULT_TURB, max_split_cut=SPLIT_CUT_MAX, 311 | use_ntda=True, beamwidth=DEFAULT_BEAMWIDTH, 312 | gate_spacing=DEFAULT_GATE_SPACING): 313 | """ 314 | Leverages calc_turb_sweep() to process an entire radar volume for 315 | turbulence. Has ability to account for split-cut sweeps in a volume 316 | (i.e., DZ & SW on different, mismatched sweeps). 317 | radar = Py-ART radar object 318 | radius = Search radius for calculating EDR 319 | split_cut = Set to True for split-cut volumes 320 | xran = Spatial range in X to consider 321 | yran = Spatial range in Y to consider 322 | verbose = Set to True to get more information on calculation status 323 | name_dz = Name of reflectivity field 324 | name_sw = Name of spectrum width field 325 | turb_name = Name for created turbulence field 326 | max_split_cut = Total number of tilts that are affected by split cuts 327 | use_ntda = Flag to use the spatial averaging and weighting employed by NTDA 328 | beamwidth = Beamwidth of radar in degrees 329 | gate_spacing = Gate spacing of radar in km 330 | """ 331 | 332 | if verbose: 333 | vol_time = time.time() 334 | fill_value, turbulence = _initialize_turb_field(radar, name_sw) 335 | 336 | # Commented section fails if sweep_number not [0, 1, 2, 3 ...] 337 | # index = np.min(radar.sweep_number['data']) 338 | # while index <= np.max(radar.sweep_number['data']): 339 | index = 0 340 | while index < radar.nsweeps: 341 | if verbose: 342 | print('Sweep number:', index) 343 | if split_cut and index < max_split_cut: 344 | ind_adj = index + 1 345 | dsw = True 346 | else: 347 | ind_adj = index 348 | dsw = False 349 | try: 350 | sweep_range = [radar.sweep_start_ray_index['data'][ind_adj], 351 | radar.sweep_end_ray_index['data'][ind_adj]+1] 352 | turbulence[sweep_range[0]:sweep_range[1]], glat, glon = \ 353 | calc_turb_sweep(radar, index, radius=radius, split_cut=dsw, 354 | verbose=verbose, xran=xran, yran=yran, 355 | name_dz=name_dz, name_sw=name_sw, 356 | use_ntda=use_ntda, beamwidth=beamwidth, 357 | gate_spacing=gate_spacing) 358 | except IndexError: 359 | print('Ran out of sweeps') 360 | finally: 361 | index += 1 362 | if split_cut and index < max_split_cut: 363 | index += 1 364 | 365 | turbulence = _finalize_turb_field(radar, turbulence, name_dz, name_sw) 366 | add_turbulence_field(radar, turbulence, turb_name) 367 | if verbose: 368 | print((time.time()-vol_time)/60.0, 'minutes to process volume') 369 | 370 | ################################### 371 | 372 | 373 | def calc_turb_rhi(radar, radius=1.0, verbose=False, 374 | name_dz=DEFAULT_DZ, name_sw=DEFAULT_SW, 375 | turb_name=DEFAULT_TURB, max_split_cut=SPLIT_CUT_MAX, 376 | use_ntda=True, beamwidth=None, 377 | gate_spacing=DEFAULT_GATE_SPACING): 378 | """ 379 | Processes an entire RHI radar volume for turbulence. 380 | radar = Py-ART radar object 381 | radius = Search radius for calculating EDR 382 | verbose = Set to True to get more information on calculation status 383 | name_dz = Name of reflectivity field 384 | name_sw = Name of spectrum width field 385 | turb_name = Name for created turbulence field 386 | use_ntda = Flag to use the spatial averaging and weighting employed by NTDA 387 | beamwidth = Beamwidth of radar in degrees 388 | gate_spacing = Gate spacing of radar in km 389 | """ 390 | if verbose: 391 | vol_time = time.time() 392 | 393 | fill_value, turbulence = _initialize_turb_field(radar, name_sw) 394 | if beamwidth is None: 395 | beamwidth = radar.instrument_parameters['radar_beam_width_v']['data'] 396 | 397 | index = 0 398 | while index < radar.nsweeps: 399 | if verbose: 400 | print('Sweep number:', index) 401 | ind_adj = index 402 | try: 403 | sweep_range = [radar.sweep_start_ray_index['data'][ind_adj], 404 | radar.sweep_end_ray_index['data'][ind_adj]+1] 405 | turbulence[sweep_range[0]:sweep_range[1]] = \ 406 | _calc_turb_rhi_sweep( 407 | radar, index, radius=radius, verbose=verbose, 408 | name_dz=name_dz, name_sw=name_sw, 409 | use_ntda=use_ntda, beamwidth=beamwidth, 410 | gate_spacing=gate_spacing) 411 | except IndexError: 412 | print('Ran out of sweeps') 413 | finally: 414 | index += 1 415 | 416 | turbulence = _finalize_turb_field(radar, turbulence, name_dz, name_sw) 417 | add_turbulence_field(radar, turbulence, turb_name) 418 | if verbose: 419 | print((time.time()-vol_time)/60.0, 'minutes to process volume') 420 | 421 | ################################### 422 | 423 | 424 | def edr_long_range(sw, rng, theta, gs): 425 | """ 426 | For gate spacing < range * beamwidth 427 | sw (spectrum width) in m/s, 428 | rng (range) in km, 429 | theta (beamwidth) in deg, 430 | gs (gate spacing) in km 431 | 432 | """ 433 | beta = gs * RNG_MULT / RRV_SCALING_FACTOR 434 | alpha = rng * RNG_MULT * np.deg2rad(theta) / RRV_SCALING_FACTOR 435 | z = 1.0 - (beta**2 / alpha**2) # beta always <= alpha 436 | series = hypergeometric_gaussian(-0.3333, 0.5, 2.5, z) 437 | edr = sw**3 * (1.0/alpha) * (CONSTANT * series)**(-1.5) 438 | return edr**0.33333 439 | 440 | 441 | def edr_short_range(sw, rng, theta, gs): 442 | """ 443 | For gate spacing > range * beamwidth 444 | sw (spectrum width) in m/s, 445 | rng (range) in km, 446 | theta (beamwidth) in deg, 447 | gs (gate spacing) in km 448 | 449 | """ 450 | beta = gs * RNG_MULT / RRV_SCALING_FACTOR 451 | alpha = rng * RNG_MULT * np.deg2rad(theta) / RRV_SCALING_FACTOR 452 | z = 1.0 - (alpha**2 / beta**2) # alpha always <= beta 453 | series = hypergeometric_gaussian(-0.3333, 2.0, 2.5, z) 454 | edr = sw**3 * (1.0/beta) * (CONSTANT * series)**(-1.5) 455 | return edr**0.33333 456 | 457 | 458 | def add_turbulence_field(radar, turbulence, turb_name='turbulence'): 459 | field_dict = {'data': turbulence, 460 | 'units': 'm^2/3 s^-1', 461 | 'long_name': 'Cubic Root of Eddy Dissipation Rate', 462 | 'standard_name': "EDR^1/3"} 463 | radar.add_field(turb_name, field_dict, replace_existing=True) 464 | 465 | 466 | def get_sweep_data(radar, field_name, sweep_number): 467 | # Check if _FillValue exists 468 | try: 469 | fill_value = radar.fields[field_name]['_FillValue'] 470 | except KeyError: 471 | fill_value = BAD_DATA_VAL 472 | # Check if masked array 473 | try: 474 | return radar.fields[field_name]['data'][ 475 | radar.sweep_start_ray_index['data'][sweep_number]: 476 | radar.sweep_end_ray_index['data'][sweep_number]+1][:].filled( 477 | fill_value=fill_value) 478 | except AttributeError: 479 | return radar.fields[field_name]['data'][ 480 | radar.sweep_start_ray_index['data'][sweep_number]: 481 | radar.sweep_end_ray_index['data'][sweep_number]+1][:] 482 | 483 | 484 | def get_sweep_azimuths(radar, sweep_number): 485 | return radar.azimuth['data'][ 486 | radar.sweep_start_ray_index['data'][sweep_number]: 487 | radar.sweep_end_ray_index['data'][sweep_number]+1][:] 488 | 489 | 490 | def get_sweep_elevations(radar, sweep_number): 491 | return radar.elevation['data'][ 492 | radar.sweep_start_ray_index['data'][sweep_number]: 493 | radar.sweep_end_ray_index['data'][sweep_number]+1][:] 494 | 495 | 496 | def calc_cartesian_coords_radians(lon1r, lat1r, lon2r, lat2r): 497 | """Assumes conversion to radians has already occurred""" 498 | yy = re * (lat1r - lat2r) 499 | mlat = (lat1r + lat2r) / 2.0 500 | xx = re * np.cos(mlat) * (lon1r - lon2r) 501 | return xx, yy 502 | 503 | 504 | def get_radar_latlon_plus_radians(radar): 505 | """Input Py-ART radar object, get lat/lon first in deg then in radians""" 506 | klat = radar.latitude['data'][0] 507 | klon = radar.longitude['data'][0] 508 | klatr = np.deg2rad(klat) 509 | klonr = np.deg2rad(klon) 510 | return klat, klon, klatr, klonr 511 | 512 | 513 | def flatten_and_reduce_data_array(array, condition): 514 | array = array.ravel() 515 | return array[condition] 516 | 517 | ################################### 518 | # INTERNAL FUNCTIONS FOLLOW 519 | ################################### 520 | 521 | 522 | def _calc_turb_rhi_sweep(radar, sweep_number, radius=1.0, 523 | verbose=False, name_dz=DEFAULT_DZ, 524 | name_sw=DEFAULT_SW, use_ntda=True, 525 | beamwidth=DEFAULT_BEAMWIDTH, 526 | gate_spacing=DEFAULT_GATE_SPACING): 527 | """ 528 | radar = Py-ART radar object 529 | sweep_number = Can be as low as 0, as high as # of sweeps minus 1 530 | radius = radius of influence (km) 531 | verbose = Set to True to get more information about calculation progress. 532 | name_dz = Name of reflectivity field, used by Py-ART to access field 533 | name_sw = Name of spectrum width field, used by Py-ART to access field 534 | use_ntda = Flag to use the spatial averaging and weighting employed by NTDA 535 | beamwidth = Beamwidth of radar in degrees 536 | gate_spacing = Gate spacing of radar in km 537 | """ 538 | if verbose: 539 | overall_time = time.time() 540 | begin_time = time.time() 541 | 542 | dz_sw = get_sweep_data(radar, name_dz, sweep_number) 543 | try: 544 | fill_val_sw = radar.fields[name_sw]['_FillValue'] 545 | except KeyError: 546 | fill_val_sw = BAD_DATA_VAL 547 | try: 548 | fill_val_dz = radar.fields[name_dz]['_FillValue'] 549 | except KeyError: 550 | fill_val_dz = BAD_DATA_VAL 551 | sweep_sw = get_sweep_data(radar, name_sw, sweep_number) 552 | sweep_elev_sw = get_sweep_elevations(radar, sweep_number) 553 | 554 | sw_sr_1d = radar.range['data'][:] / RNG_MULT 555 | result = np.meshgrid(sw_sr_1d, sweep_elev_sw) 556 | sw_sr_2d = result[0] 557 | sw_el = result[1] 558 | sweep_size = radar.sweep_end_ray_index['data'][sweep_number] + 1 - \ 559 | radar.sweep_start_ray_index['data'][sweep_number] 560 | xx, yy = rsl_get_groundr_and_h(sw_sr_2d, sw_el) 561 | 562 | if verbose: 563 | print(time.time() - begin_time, 564 | 'seconds to complete all preliminary processing') 565 | begin_time = time.time() 566 | 567 | # Determine NTDA interest fields 568 | csnr_sw = _calc_csnr_for_every_gate(dz_sw, sw_sr_2d) 569 | crng_sw = _calc_crng_for_every_gate(sw_sr_2d) 570 | czh_sw = _calc_czh_for_every_gate(dz_sw, yy) 571 | cpr = 1.0 # Not calculating Cpr, user must remove second trip manually. 572 | 573 | if verbose: 574 | print(time.time() - begin_time, 575 | 'seconds to precompute Csnr, Crng, Czh') 576 | begin_time = time.time() 577 | 578 | # Flatten all arrays to avoid performance buzzkill of nested loops. 579 | # Then reduce the data using masks to make the job manageable. 580 | sweep_sw = sweep_sw.ravel() 581 | dz_sw = dz_sw.ravel() 582 | condition = np.logical_and(dz_sw != fill_val_dz, sweep_sw != fill_val_sw) 583 | sweep_sw = sweep_sw[condition] 584 | dz_sw = dz_sw[condition] 585 | 586 | # Brief detour to get eps and check to see if that's all user wants. 587 | # Placing this code here with reduced sweep_sw improves performance. 588 | sr_1d = flatten_and_reduce_data_array(sw_sr_2d, condition) 589 | cond = gate_spacing >= sr_1d * np.deg2rad(beamwidth) 590 | eps_sw = edr_long_range(sweep_sw, sr_1d, beamwidth, gate_spacing) 591 | eps_sw[cond] = edr_short_range(sweep_sw[cond], sr_1d[cond], 592 | beamwidth, gate_spacing) 593 | if not use_ntda: 594 | turb_radar_f = 1.0 * eps_sw 595 | turb_radar = sw_sr_2d.flatten() * 0.0 + fill_val_sw 596 | turb_radar[condition] = turb_radar_f 597 | eps_sw = np.reshape(turb_radar, (len(sweep_elev_sw), radar.ngates)) 598 | if verbose: 599 | print(time.time() - overall_time, 600 | 'seconds to process radar sweep') 601 | return eps_sw 602 | 603 | # Provided NTDA is wanted, continue flattening/reducing arrays 604 | xx = flatten_and_reduce_data_array(xx, condition) 605 | yy = flatten_and_reduce_data_array(yy, condition) 606 | csnr_sw = flatten_and_reduce_data_array(csnr_sw, condition) 607 | crng_sw = flatten_and_reduce_data_array(crng_sw, condition) 608 | czh_sw = flatten_and_reduce_data_array(czh_sw, condition) 609 | turb_radar_f = 0.0 * sweep_sw + fill_val_sw 610 | 611 | # Find the distance to every other good gate 612 | ind, ind_sw = _calc_tree(xx, yy, radius) 613 | cswv_sw = _calc_cswv_for_every_gate(xx, sweep_sw, ind_sw) 614 | if verbose: 615 | print(time.time() - begin_time, 616 | 'seconds to get eps, reduce data,', 617 | 'compute BallTree, and get Cswv') 618 | begin_time = time.time() 619 | 620 | # Loop thru data and do NTDA filtering 621 | for i in np.arange(len(xx)): 622 | if verbose: 623 | if i % 50000 == 0: 624 | print('i =', i, 'of', len(xx) - 1, 625 | time.time() - begin_time, 'seconds elapsed during loop') 626 | # Broadcating employed to minimize the amount of looping 627 | eps = eps_sw[ind[i]]**2 628 | csnr = csnr_sw[ind[i]]**0.6667 629 | crng = crng_sw[ind[i]] 630 | czh = czh_sw[ind[i]] 631 | cswv = cswv_sw[ind[i]] 632 | # Begin NTDA-specific calculation 633 | tot = csnr * cpr * cswv * czh * crng 634 | num = tot * eps 635 | tot = np.sum(tot) 636 | num = np.sum(num) 637 | if tot > 0: 638 | turb_radar_f[i] = np.sqrt(num/tot) 639 | 640 | # Restore turbulence to a full 2-D sweep array and return along w/ lat/lon. 641 | turb_radar = sw_sr_2d.flatten() * 0.0 + fill_val_sw 642 | turb_radar[condition] = turb_radar_f 643 | turb_radar = np.reshape(turb_radar, (len(sweep_elev_sw), radar.ngates)) 644 | if verbose: 645 | print(time.time() - overall_time, 'seconds to process radar sweep') 646 | return turb_radar 647 | 648 | ################################### 649 | 650 | 651 | def _initialize_turb_field(radar, name_sw): 652 | try: 653 | fill_value = radar.fields[name_sw]['_FillValue'] 654 | except KeyError: 655 | fill_value = BAD_DATA_VAL 656 | try: 657 | turbulence = 0.0 * radar.fields[name_sw]['data'][:].filled( 658 | fill_value=fill_value) + fill_value 659 | except AttributeError: 660 | turbulence = 0.0 * radar.fields[name_sw]['data'][:] + fill_value 661 | return fill_value, turbulence 662 | 663 | 664 | def _finalize_turb_field(radar, turbulence, name_dz, name_sw): 665 | # Combine DZ and SW masks if available 666 | if hasattr(radar.fields[name_dz]['data'], 'mask'): 667 | mask1 = radar.fields[name_dz]['data'].mask 668 | else: 669 | try: 670 | fill_val_dz = radar.fields[name_dz]['_FillValue'] 671 | except KeyError: 672 | fill_val_dz = BAD_DATA_VAL 673 | mask1 = radar.fields[name_dz]['data'] == fill_val_dz 674 | if hasattr(radar.fields[name_sw]['data'], 'mask'): 675 | mask2 = radar.fields[name_sw]['data'].mask 676 | else: 677 | mask2 = radar.fields[name_sw]['data'] == fill_value 678 | combine = np.ma.mask_or(mask1, mask2) 679 | return np.ma.array(turbulence, mask=combine) 680 | 681 | 682 | def _retrieve_sweep_fields(radar, name_sw, name_dz, sweep_number, 683 | sweep_dz, split_cut): 684 | if split_cut: 685 | # Low-level NEXRAD tilts can report DZ and SW from different sweeps 686 | sweep_sw = get_sweep_data(radar, name_sw, sweep_number+1) 687 | sweep_az_dz = get_sweep_azimuths(radar, sweep_number) 688 | sweep_az_sw = get_sweep_azimuths(radar, sweep_number+1) 689 | sweep_elev_sw = get_sweep_elevations(radar, sweep_number+1) 690 | dz_sw = 0.0 * sweep_sw 691 | # Map DZ to SW sweep arrangement 692 | for inaz1 in np.arange(len(sweep_az_sw)): 693 | inaz2 = np.argmin(np.abs(sweep_az_sw[inaz1]-sweep_az_dz)) 694 | dz_sw[inaz1][:] = sweep_dz[inaz2][:] 695 | else: 696 | sweep_sw = get_sweep_data(radar, name_sw, sweep_number) 697 | sweep_az_sw = get_sweep_azimuths(radar, sweep_number) 698 | sweep_elev_sw = get_sweep_elevations(radar, sweep_number) 699 | dz_sw = 1.0 * sweep_dz 700 | return sweep_sw, sweep_az_sw, sweep_elev_sw, dz_sw 701 | 702 | 703 | def _calc_csnr_for_every_gate(dz_sw, sw_sr): 704 | """TO DO: Turn thresholds into global variables changeable elsewhere""" 705 | csnr_sw = 0.0 * dz_sw 706 | snr_sw = dz_sw + 20.0 * np.log10(230.0 / sw_sr) 707 | condition = np.logical_and(snr_sw >= 10, snr_sw < 20) 708 | csnr_sw[condition] = 0.1 * (snr_sw[condition] - 10.0) 709 | condition = np.logical_and(snr_sw >= 20, snr_sw < 70) 710 | csnr_sw[condition] = 1.0 711 | condition = np.logical_and(snr_sw >= 70, snr_sw < 80) 712 | csnr_sw[condition] = 1.0 - 0.1 * (snr_sw[condition] - 70.0) 713 | return csnr_sw 714 | 715 | 716 | def _calc_crng_for_every_gate(sw_sr): 717 | """TO DO: Turn thresholds into global variables changeable elsewhere""" 718 | crng_sw = 0.0 * sw_sr 719 | condition = np.logical_and(sw_sr >= 0, sw_sr < 5) 720 | crng_sw[condition] = 0.2 * (sw_sr[condition] - 5.0) 721 | condition = np.logical_and(sw_sr >= 5, sw_sr < 140) 722 | crng_sw[condition] = 1.0 723 | condition = np.logical_and(sw_sr >= 140, sw_sr < 275) 724 | crng_sw[condition] = 1.0 - (1.0 / 135.0) * (sw_sr[condition] - 140.0) 725 | return crng_sw 726 | 727 | 728 | def _calc_czh_for_every_gate(dz_sw, sw_ht): 729 | """TO DO: Turn thresholds into global variables changeable elsewhere""" 730 | czh_sw = 0.0 * dz_sw 731 | dummy = dz_sw + 3.5 * sw_ht 732 | condition = np.logical_and(dummy >= 15, dummy < 25) 733 | czh_sw[condition] = 0.1 * (dummy[condition] - 15.0) 734 | condition = dummy >= 25 735 | czh_sw[condition] = 1.0 736 | return czh_sw 737 | 738 | 739 | def _calc_cswv_for_every_gate(xx, sweep_sw, ind_sw): 740 | cswv_sw = 0.0 * xx 741 | for i in np.arange(len(xx)): 742 | # Get spectrum width variance via np.dot() 743 | # Provides ~30% speed improvement over var() 744 | a = sweep_sw[ind_sw[i]] 745 | m = a.mean() 746 | c = a - m 747 | dummy = np.dot(c, c) / a.size 748 | cswv_sw[i] = calc_cswv_cython(dummy) 749 | return cswv_sw 750 | 751 | 752 | def _calc_tree(xx, yy, radius): 753 | X = np.zeros((len(xx), 2), dtype='float') 754 | X[:, 0] = xx[:] 755 | X[:, 1] = yy[:] 756 | tree = BallTree(X, metric='euclidean') 757 | ind = tree.query_radius(X, r=radius) 758 | ind_sw = tree.query_radius(X, r=VARIANCE_RADIUS_SW) 759 | return ind, ind_sw 760 | -------------------------------------------------------------------------------- /pytda/pytda_cython_tools.c: -------------------------------------------------------------------------------- 1 | /* Generated by Cython 0.22.1 */ 2 | 3 | #define PY_SSIZE_T_CLEAN 4 | #ifndef CYTHON_USE_PYLONG_INTERNALS 5 | #ifdef PYLONG_BITS_IN_DIGIT 6 | #define CYTHON_USE_PYLONG_INTERNALS 0 7 | #else 8 | #include "pyconfig.h" 9 | #ifdef PYLONG_BITS_IN_DIGIT 10 | #define CYTHON_USE_PYLONG_INTERNALS 1 11 | #else 12 | #define CYTHON_USE_PYLONG_INTERNALS 0 13 | #endif 14 | #endif 15 | #endif 16 | #include "Python.h" 17 | #ifndef Py_PYTHON_H 18 | #error Python headers needed to compile C extensions, please install development version of Python. 19 | #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000) 20 | #error Cython requires Python 2.6+ or Python 3.2+. 21 | #else 22 | #define CYTHON_ABI "0_22_1" 23 | #include 24 | #ifndef offsetof 25 | #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) 26 | #endif 27 | #if !defined(WIN32) && !defined(MS_WINDOWS) 28 | #ifndef __stdcall 29 | #define __stdcall 30 | #endif 31 | #ifndef __cdecl 32 | #define __cdecl 33 | #endif 34 | #ifndef __fastcall 35 | #define __fastcall 36 | #endif 37 | #endif 38 | #ifndef DL_IMPORT 39 | #define DL_IMPORT(t) t 40 | #endif 41 | #ifndef DL_EXPORT 42 | #define DL_EXPORT(t) t 43 | #endif 44 | #ifndef PY_LONG_LONG 45 | #define PY_LONG_LONG LONG_LONG 46 | #endif 47 | #ifndef Py_HUGE_VAL 48 | #define Py_HUGE_VAL HUGE_VAL 49 | #endif 50 | #ifdef PYPY_VERSION 51 | #define CYTHON_COMPILING_IN_PYPY 1 52 | #define CYTHON_COMPILING_IN_CPYTHON 0 53 | #else 54 | #define CYTHON_COMPILING_IN_PYPY 0 55 | #define CYTHON_COMPILING_IN_CPYTHON 1 56 | #endif 57 | #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) 58 | #define Py_OptimizeFlag 0 59 | #endif 60 | #define __PYX_BUILD_PY_SSIZE_T "n" 61 | #define CYTHON_FORMAT_SSIZE_T "z" 62 | #if PY_MAJOR_VERSION < 3 63 | #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" 64 | #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \ 65 | PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) 66 | #define __Pyx_DefaultClassType PyClass_Type 67 | #else 68 | #define __Pyx_BUILTIN_MODULE_NAME "builtins" 69 | #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \ 70 | PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) 71 | #define __Pyx_DefaultClassType PyType_Type 72 | #endif 73 | #ifndef Py_TPFLAGS_CHECKTYPES 74 | #define Py_TPFLAGS_CHECKTYPES 0 75 | #endif 76 | #ifndef Py_TPFLAGS_HAVE_INDEX 77 | #define Py_TPFLAGS_HAVE_INDEX 0 78 | #endif 79 | #ifndef Py_TPFLAGS_HAVE_NEWBUFFER 80 | #define Py_TPFLAGS_HAVE_NEWBUFFER 0 81 | #endif 82 | #ifndef Py_TPFLAGS_HAVE_FINALIZE 83 | #define Py_TPFLAGS_HAVE_FINALIZE 0 84 | #endif 85 | #if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) 86 | #define CYTHON_PEP393_ENABLED 1 87 | #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ? \ 88 | 0 : _PyUnicode_Ready((PyObject *)(op))) 89 | #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) 90 | #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) 91 | #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) 92 | #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) 93 | #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) 94 | #else 95 | #define CYTHON_PEP393_ENABLED 0 96 | #define __Pyx_PyUnicode_READY(op) (0) 97 | #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) 98 | #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) 99 | #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) 100 | #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) 101 | #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) 102 | #endif 103 | #if CYTHON_COMPILING_IN_PYPY 104 | #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) 105 | #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) 106 | #define __Pyx_PyFrozenSet_Size(s) PyObject_Size(s) 107 | #else 108 | #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) 109 | #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \ 110 | PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) 111 | #define __Pyx_PyFrozenSet_Size(s) PySet_Size(s) 112 | #endif 113 | #if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) 114 | #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) 115 | #endif 116 | #define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) 117 | #define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) 118 | #if PY_MAJOR_VERSION >= 3 119 | #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) 120 | #else 121 | #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) 122 | #endif 123 | #if PY_MAJOR_VERSION >= 3 124 | #define PyBaseString_Type PyUnicode_Type 125 | #define PyStringObject PyUnicodeObject 126 | #define PyString_Type PyUnicode_Type 127 | #define PyString_Check PyUnicode_Check 128 | #define PyString_CheckExact PyUnicode_CheckExact 129 | #endif 130 | #if PY_MAJOR_VERSION >= 3 131 | #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) 132 | #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) 133 | #else 134 | #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) 135 | #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) 136 | #endif 137 | #ifndef PySet_CheckExact 138 | #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) 139 | #endif 140 | #define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) 141 | #if PY_MAJOR_VERSION >= 3 142 | #define PyIntObject PyLongObject 143 | #define PyInt_Type PyLong_Type 144 | #define PyInt_Check(op) PyLong_Check(op) 145 | #define PyInt_CheckExact(op) PyLong_CheckExact(op) 146 | #define PyInt_FromString PyLong_FromString 147 | #define PyInt_FromUnicode PyLong_FromUnicode 148 | #define PyInt_FromLong PyLong_FromLong 149 | #define PyInt_FromSize_t PyLong_FromSize_t 150 | #define PyInt_FromSsize_t PyLong_FromSsize_t 151 | #define PyInt_AsLong PyLong_AsLong 152 | #define PyInt_AS_LONG PyLong_AS_LONG 153 | #define PyInt_AsSsize_t PyLong_AsSsize_t 154 | #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask 155 | #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask 156 | #define PyNumber_Int PyNumber_Long 157 | #endif 158 | #if PY_MAJOR_VERSION >= 3 159 | #define PyBoolObject PyLongObject 160 | #endif 161 | #if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY 162 | #ifndef PyUnicode_InternFromString 163 | #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) 164 | #endif 165 | #endif 166 | #if PY_VERSION_HEX < 0x030200A4 167 | typedef long Py_hash_t; 168 | #define __Pyx_PyInt_FromHash_t PyInt_FromLong 169 | #define __Pyx_PyInt_AsHash_t PyInt_AsLong 170 | #else 171 | #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t 172 | #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t 173 | #endif 174 | #if PY_MAJOR_VERSION >= 3 175 | #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func)) 176 | #else 177 | #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) 178 | #endif 179 | #ifndef CYTHON_INLINE 180 | #if defined(__GNUC__) 181 | #define CYTHON_INLINE __inline__ 182 | #elif defined(_MSC_VER) 183 | #define CYTHON_INLINE __inline 184 | #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 185 | #define CYTHON_INLINE inline 186 | #else 187 | #define CYTHON_INLINE 188 | #endif 189 | #endif 190 | #ifndef CYTHON_RESTRICT 191 | #if defined(__GNUC__) 192 | #define CYTHON_RESTRICT __restrict__ 193 | #elif defined(_MSC_VER) && _MSC_VER >= 1400 194 | #define CYTHON_RESTRICT __restrict 195 | #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 196 | #define CYTHON_RESTRICT restrict 197 | #else 198 | #define CYTHON_RESTRICT 199 | #endif 200 | #endif 201 | #ifdef NAN 202 | #define __PYX_NAN() ((float) NAN) 203 | #else 204 | static CYTHON_INLINE float __PYX_NAN() { 205 | /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and 206 | a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is 207 | a quiet NaN. */ 208 | float value; 209 | memset(&value, 0xFF, sizeof(value)); 210 | return value; 211 | } 212 | #endif 213 | #define __Pyx_void_to_None(void_result) (void_result, Py_INCREF(Py_None), Py_None) 214 | #ifdef __cplusplus 215 | template 216 | void __Pyx_call_destructor(T* x) { 217 | x->~T(); 218 | } 219 | template 220 | class __Pyx_FakeReference { 221 | public: 222 | __Pyx_FakeReference() : ptr(NULL) { } 223 | __Pyx_FakeReference(T& ref) : ptr(&ref) { } 224 | T *operator->() { return ptr; } 225 | operator T&() { return *ptr; } 226 | private: 227 | T *ptr; 228 | }; 229 | #endif 230 | 231 | 232 | #if PY_MAJOR_VERSION >= 3 233 | #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) 234 | #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) 235 | #else 236 | #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) 237 | #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) 238 | #endif 239 | 240 | #ifndef __PYX_EXTERN_C 241 | #ifdef __cplusplus 242 | #define __PYX_EXTERN_C extern "C" 243 | #else 244 | #define __PYX_EXTERN_C extern 245 | #endif 246 | #endif 247 | 248 | #if defined(WIN32) || defined(MS_WINDOWS) 249 | #define _USE_MATH_DEFINES 250 | #endif 251 | #include 252 | #define __PYX_HAVE__pytda_cython_tools 253 | #define __PYX_HAVE_API__pytda_cython_tools 254 | #include "math.h" 255 | #ifdef _OPENMP 256 | #include 257 | #endif /* _OPENMP */ 258 | 259 | #ifdef PYREX_WITHOUT_ASSERTIONS 260 | #define CYTHON_WITHOUT_ASSERTIONS 261 | #endif 262 | 263 | #ifndef CYTHON_UNUSED 264 | # if defined(__GNUC__) 265 | # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) 266 | # define CYTHON_UNUSED __attribute__ ((__unused__)) 267 | # else 268 | # define CYTHON_UNUSED 269 | # endif 270 | # elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) 271 | # define CYTHON_UNUSED __attribute__ ((__unused__)) 272 | # else 273 | # define CYTHON_UNUSED 274 | # endif 275 | #endif 276 | #ifndef CYTHON_NCP_UNUSED 277 | # if CYTHON_COMPILING_IN_CPYTHON 278 | # define CYTHON_NCP_UNUSED 279 | # else 280 | # define CYTHON_NCP_UNUSED CYTHON_UNUSED 281 | # endif 282 | #endif 283 | typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding; 284 | const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; 285 | 286 | #define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 287 | #define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0 288 | #define __PYX_DEFAULT_STRING_ENCODING "" 289 | #define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString 290 | #define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize 291 | #define __Pyx_fits_Py_ssize_t(v, type, is_signed) ( \ 292 | (sizeof(type) < sizeof(Py_ssize_t)) || \ 293 | (sizeof(type) > sizeof(Py_ssize_t) && \ 294 | likely(v < (type)PY_SSIZE_T_MAX || \ 295 | v == (type)PY_SSIZE_T_MAX) && \ 296 | (!is_signed || likely(v > (type)PY_SSIZE_T_MIN || \ 297 | v == (type)PY_SSIZE_T_MIN))) || \ 298 | (sizeof(type) == sizeof(Py_ssize_t) && \ 299 | (is_signed || likely(v < (type)PY_SSIZE_T_MAX || \ 300 | v == (type)PY_SSIZE_T_MAX))) ) 301 | static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*); 302 | static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); 303 | #define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) 304 | #define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) 305 | #define __Pyx_PyBytes_FromString PyBytes_FromString 306 | #define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize 307 | static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); 308 | #if PY_MAJOR_VERSION < 3 309 | #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString 310 | #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize 311 | #else 312 | #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString 313 | #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize 314 | #endif 315 | #define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) 316 | #define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) 317 | #define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) 318 | #define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) 319 | #define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) 320 | #define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) 321 | #define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) 322 | #if PY_MAJOR_VERSION < 3 323 | static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) 324 | { 325 | const Py_UNICODE *u_end = u; 326 | while (*u_end++) ; 327 | return (size_t)(u_end - u - 1); 328 | } 329 | #else 330 | #define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen 331 | #endif 332 | #define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) 333 | #define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode 334 | #define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode 335 | #define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None) 336 | #define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False)) 337 | static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); 338 | static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x); 339 | static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); 340 | static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); 341 | #if CYTHON_COMPILING_IN_CPYTHON 342 | #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) 343 | #else 344 | #define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) 345 | #endif 346 | #define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) 347 | #if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 348 | static int __Pyx_sys_getdefaultencoding_not_ascii; 349 | static int __Pyx_init_sys_getdefaultencoding_params(void) { 350 | PyObject* sys; 351 | PyObject* default_encoding = NULL; 352 | PyObject* ascii_chars_u = NULL; 353 | PyObject* ascii_chars_b = NULL; 354 | const char* default_encoding_c; 355 | sys = PyImport_ImportModule("sys"); 356 | if (!sys) goto bad; 357 | default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); 358 | Py_DECREF(sys); 359 | if (!default_encoding) goto bad; 360 | default_encoding_c = PyBytes_AsString(default_encoding); 361 | if (!default_encoding_c) goto bad; 362 | if (strcmp(default_encoding_c, "ascii") == 0) { 363 | __Pyx_sys_getdefaultencoding_not_ascii = 0; 364 | } else { 365 | char ascii_chars[128]; 366 | int c; 367 | for (c = 0; c < 128; c++) { 368 | ascii_chars[c] = c; 369 | } 370 | __Pyx_sys_getdefaultencoding_not_ascii = 1; 371 | ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); 372 | if (!ascii_chars_u) goto bad; 373 | ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); 374 | if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { 375 | PyErr_Format( 376 | PyExc_ValueError, 377 | "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", 378 | default_encoding_c); 379 | goto bad; 380 | } 381 | Py_DECREF(ascii_chars_u); 382 | Py_DECREF(ascii_chars_b); 383 | } 384 | Py_DECREF(default_encoding); 385 | return 0; 386 | bad: 387 | Py_XDECREF(default_encoding); 388 | Py_XDECREF(ascii_chars_u); 389 | Py_XDECREF(ascii_chars_b); 390 | return -1; 391 | } 392 | #endif 393 | #if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 394 | #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) 395 | #else 396 | #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) 397 | #if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 398 | static char* __PYX_DEFAULT_STRING_ENCODING; 399 | static int __Pyx_init_sys_getdefaultencoding_params(void) { 400 | PyObject* sys; 401 | PyObject* default_encoding = NULL; 402 | char* default_encoding_c; 403 | sys = PyImport_ImportModule("sys"); 404 | if (!sys) goto bad; 405 | default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); 406 | Py_DECREF(sys); 407 | if (!default_encoding) goto bad; 408 | default_encoding_c = PyBytes_AsString(default_encoding); 409 | if (!default_encoding_c) goto bad; 410 | __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c)); 411 | if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; 412 | strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); 413 | Py_DECREF(default_encoding); 414 | return 0; 415 | bad: 416 | Py_XDECREF(default_encoding); 417 | return -1; 418 | } 419 | #endif 420 | #endif 421 | 422 | 423 | /* Test for GCC > 2.95 */ 424 | #if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) 425 | #define likely(x) __builtin_expect(!!(x), 1) 426 | #define unlikely(x) __builtin_expect(!!(x), 0) 427 | #else /* !__GNUC__ or GCC < 2.95 */ 428 | #define likely(x) (x) 429 | #define unlikely(x) (x) 430 | #endif /* __GNUC__ */ 431 | 432 | static PyObject *__pyx_m; 433 | static PyObject *__pyx_d; 434 | static PyObject *__pyx_b; 435 | static PyObject *__pyx_empty_tuple; 436 | static PyObject *__pyx_empty_bytes; 437 | static int __pyx_lineno; 438 | static int __pyx_clineno = 0; 439 | static const char * __pyx_cfilenm= __FILE__; 440 | static const char *__pyx_filename; 441 | 442 | 443 | static const char *__pyx_f[] = { 444 | "pytda_cython_tools.pyx", 445 | }; 446 | 447 | /*--- Type declarations ---*/ 448 | 449 | /* --- Runtime support code (head) --- */ 450 | #ifndef CYTHON_REFNANNY 451 | #define CYTHON_REFNANNY 0 452 | #endif 453 | #if CYTHON_REFNANNY 454 | typedef struct { 455 | void (*INCREF)(void*, PyObject*, int); 456 | void (*DECREF)(void*, PyObject*, int); 457 | void (*GOTREF)(void*, PyObject*, int); 458 | void (*GIVEREF)(void*, PyObject*, int); 459 | void* (*SetupContext)(const char*, int, const char*); 460 | void (*FinishContext)(void**); 461 | } __Pyx_RefNannyAPIStruct; 462 | static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; 463 | static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); 464 | #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; 465 | #ifdef WITH_THREAD 466 | #define __Pyx_RefNannySetupContext(name, acquire_gil) \ 467 | if (acquire_gil) { \ 468 | PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \ 469 | __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \ 470 | PyGILState_Release(__pyx_gilstate_save); \ 471 | } else { \ 472 | __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \ 473 | } 474 | #else 475 | #define __Pyx_RefNannySetupContext(name, acquire_gil) \ 476 | __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) 477 | #endif 478 | #define __Pyx_RefNannyFinishContext() \ 479 | __Pyx_RefNanny->FinishContext(&__pyx_refnanny) 480 | #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) 481 | #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) 482 | #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) 483 | #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) 484 | #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) 485 | #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) 486 | #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) 487 | #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) 488 | #else 489 | #define __Pyx_RefNannyDeclarations 490 | #define __Pyx_RefNannySetupContext(name, acquire_gil) 491 | #define __Pyx_RefNannyFinishContext() 492 | #define __Pyx_INCREF(r) Py_INCREF(r) 493 | #define __Pyx_DECREF(r) Py_DECREF(r) 494 | #define __Pyx_GOTREF(r) 495 | #define __Pyx_GIVEREF(r) 496 | #define __Pyx_XINCREF(r) Py_XINCREF(r) 497 | #define __Pyx_XDECREF(r) Py_XDECREF(r) 498 | #define __Pyx_XGOTREF(r) 499 | #define __Pyx_XGIVEREF(r) 500 | #endif 501 | #define __Pyx_XDECREF_SET(r, v) do { \ 502 | PyObject *tmp = (PyObject *) r; \ 503 | r = v; __Pyx_XDECREF(tmp); \ 504 | } while (0) 505 | #define __Pyx_DECREF_SET(r, v) do { \ 506 | PyObject *tmp = (PyObject *) r; \ 507 | r = v; __Pyx_DECREF(tmp); \ 508 | } while (0) 509 | #define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) 510 | #define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) 511 | 512 | static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, 513 | Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); 514 | 515 | static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); 516 | 517 | static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \ 518 | PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \ 519 | const char* function_name); 520 | 521 | #ifndef __PYX_FORCE_INIT_THREADS 522 | #define __PYX_FORCE_INIT_THREADS 0 523 | #endif 524 | 525 | typedef struct { 526 | int code_line; 527 | PyCodeObject* code_object; 528 | } __Pyx_CodeObjectCacheEntry; 529 | struct __Pyx_CodeObjectCache { 530 | int count; 531 | int max_count; 532 | __Pyx_CodeObjectCacheEntry* entries; 533 | }; 534 | static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; 535 | static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); 536 | static PyCodeObject *__pyx_find_code_object(int code_line); 537 | static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); 538 | 539 | static void __Pyx_AddTraceback(const char *funcname, int c_line, 540 | int py_line, const char *filename); 541 | 542 | static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); 543 | 544 | static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); 545 | 546 | static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); 547 | 548 | static int __Pyx_check_binary_version(void); 549 | 550 | static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); 551 | 552 | 553 | /* Module declarations from 'pytda_cython_tools' */ 554 | #define __Pyx_MODULE_NAME "pytda_cython_tools" 555 | int __pyx_module_is_main_pytda_cython_tools = 0; 556 | 557 | /* Implementation of 'pytda_cython_tools' */ 558 | static PyObject *__pyx_pf_18pytda_cython_tools_atan2c_longitude(CYTHON_UNUSED PyObject *__pyx_self, float __pyx_v_azr, float __pyx_v_gr, float __pyx_v_klatr, float __pyx_v_glatr); /* proto */ 559 | static PyObject *__pyx_pf_18pytda_cython_tools_2calc_turb_cython(CYTHON_UNUSED PyObject *__pyx_self, float __pyx_v_csnr, float __pyx_v_cpr, float __pyx_v_cswv, float __pyx_v_czh, float __pyx_v_crng, float __pyx_v_eps, float __pyx_v_num, float __pyx_v_tot); /* proto */ 560 | static PyObject *__pyx_pf_18pytda_cython_tools_4calc_cswv_cython(CYTHON_UNUSED PyObject *__pyx_self, float __pyx_v_dummy); /* proto */ 561 | static PyObject *__pyx_pf_18pytda_cython_tools_6atan2c(CYTHON_UNUSED PyObject *__pyx_self, float __pyx_v_y, float __pyx_v_x); /* proto */ 562 | static char __pyx_k_x[] = "x"; 563 | static char __pyx_k_y[] = "y"; 564 | static char __pyx_k_gr[] = "gr"; 565 | static char __pyx_k_re[] = "re"; 566 | static char __pyx_k_azr[] = "azr"; 567 | static char __pyx_k_cpr[] = "cpr"; 568 | static char __pyx_k_csw[] = "csw"; 569 | static char __pyx_k_czh[] = "czh"; 570 | static char __pyx_k_eps[] = "eps"; 571 | static char __pyx_k_num[] = "num"; 572 | static char __pyx_k_tot[] = "tot"; 573 | static char __pyx_k_crng[] = "crng"; 574 | static char __pyx_k_csnr[] = "csnr"; 575 | static char __pyx_k_cswv[] = "cswv"; 576 | static char __pyx_k_main[] = "__main__"; 577 | static char __pyx_k_test[] = "__test__"; 578 | static char __pyx_k_dummy[] = "dummy"; 579 | static char __pyx_k_glatr[] = "glatr"; 580 | static char __pyx_k_klatr[] = "klatr"; 581 | static char __pyx_k_atan2c[] = "atan2c"; 582 | static char __pyx_k_atan2c_longitude[] = "atan2c_longitude"; 583 | static char __pyx_k_calc_cswv_cython[] = "calc_cswv_cython"; 584 | static char __pyx_k_calc_turb_cython[] = "calc_turb_cython"; 585 | static char __pyx_k_pytda_cython_tools[] = "pytda_cython_tools"; 586 | static char __pyx_k_Users_tjlang_Documents_Python_p[] = "/Users/tjlang/Documents/Python/pytda/pytda_cython_tools.pyx"; 587 | static PyObject *__pyx_kp_s_Users_tjlang_Documents_Python_p; 588 | static PyObject *__pyx_n_s_atan2c; 589 | static PyObject *__pyx_n_s_atan2c_longitude; 590 | static PyObject *__pyx_n_s_azr; 591 | static PyObject *__pyx_n_s_calc_cswv_cython; 592 | static PyObject *__pyx_n_s_calc_turb_cython; 593 | static PyObject *__pyx_n_s_cpr; 594 | static PyObject *__pyx_n_s_crng; 595 | static PyObject *__pyx_n_s_csnr; 596 | static PyObject *__pyx_n_s_csw; 597 | static PyObject *__pyx_n_s_cswv; 598 | static PyObject *__pyx_n_s_czh; 599 | static PyObject *__pyx_n_s_dummy; 600 | static PyObject *__pyx_n_s_eps; 601 | static PyObject *__pyx_n_s_glatr; 602 | static PyObject *__pyx_n_s_gr; 603 | static PyObject *__pyx_n_s_klatr; 604 | static PyObject *__pyx_n_s_main; 605 | static PyObject *__pyx_n_s_num; 606 | static PyObject *__pyx_n_s_pytda_cython_tools; 607 | static PyObject *__pyx_n_s_re; 608 | static PyObject *__pyx_n_s_test; 609 | static PyObject *__pyx_n_s_tot; 610 | static PyObject *__pyx_n_s_x; 611 | static PyObject *__pyx_n_s_y; 612 | static PyObject *__pyx_tuple_; 613 | static PyObject *__pyx_tuple__3; 614 | static PyObject *__pyx_tuple__5; 615 | static PyObject *__pyx_tuple__7; 616 | static PyObject *__pyx_codeobj__2; 617 | static PyObject *__pyx_codeobj__4; 618 | static PyObject *__pyx_codeobj__6; 619 | static PyObject *__pyx_codeobj__8; 620 | 621 | /* "pytda_cython_tools.pyx":7 622 | * 623 | * 624 | * def atan2c_longitude(float azr, float gr, float klatr, float glatr): # <<<<<<<<<<<<<< 625 | * cdef float re = 6371.1 626 | * return atan2f(sinf(azr)*sinf(gr/re)*cosf(klatr), 627 | */ 628 | 629 | /* Python wrapper */ 630 | static PyObject *__pyx_pw_18pytda_cython_tools_1atan2c_longitude(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ 631 | static PyMethodDef __pyx_mdef_18pytda_cython_tools_1atan2c_longitude = {"atan2c_longitude", (PyCFunction)__pyx_pw_18pytda_cython_tools_1atan2c_longitude, METH_VARARGS|METH_KEYWORDS, 0}; 632 | static PyObject *__pyx_pw_18pytda_cython_tools_1atan2c_longitude(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { 633 | float __pyx_v_azr; 634 | float __pyx_v_gr; 635 | float __pyx_v_klatr; 636 | float __pyx_v_glatr; 637 | int __pyx_lineno = 0; 638 | const char *__pyx_filename = NULL; 639 | int __pyx_clineno = 0; 640 | PyObject *__pyx_r = 0; 641 | __Pyx_RefNannyDeclarations 642 | __Pyx_RefNannySetupContext("atan2c_longitude (wrapper)", 0); 643 | { 644 | static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_azr,&__pyx_n_s_gr,&__pyx_n_s_klatr,&__pyx_n_s_glatr,0}; 645 | PyObject* values[4] = {0,0,0,0}; 646 | if (unlikely(__pyx_kwds)) { 647 | Py_ssize_t kw_args; 648 | const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); 649 | switch (pos_args) { 650 | case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); 651 | case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); 652 | case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); 653 | case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); 654 | case 0: break; 655 | default: goto __pyx_L5_argtuple_error; 656 | } 657 | kw_args = PyDict_Size(__pyx_kwds); 658 | switch (pos_args) { 659 | case 0: 660 | if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_azr)) != 0)) kw_args--; 661 | else goto __pyx_L5_argtuple_error; 662 | case 1: 663 | if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_gr)) != 0)) kw_args--; 664 | else { 665 | __Pyx_RaiseArgtupleInvalid("atan2c_longitude", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 666 | } 667 | case 2: 668 | if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_klatr)) != 0)) kw_args--; 669 | else { 670 | __Pyx_RaiseArgtupleInvalid("atan2c_longitude", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 671 | } 672 | case 3: 673 | if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_glatr)) != 0)) kw_args--; 674 | else { 675 | __Pyx_RaiseArgtupleInvalid("atan2c_longitude", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 676 | } 677 | } 678 | if (unlikely(kw_args > 0)) { 679 | if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "atan2c_longitude") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 680 | } 681 | } else if (PyTuple_GET_SIZE(__pyx_args) != 4) { 682 | goto __pyx_L5_argtuple_error; 683 | } else { 684 | values[0] = PyTuple_GET_ITEM(__pyx_args, 0); 685 | values[1] = PyTuple_GET_ITEM(__pyx_args, 1); 686 | values[2] = PyTuple_GET_ITEM(__pyx_args, 2); 687 | values[3] = PyTuple_GET_ITEM(__pyx_args, 3); 688 | } 689 | __pyx_v_azr = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_azr == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 690 | __pyx_v_gr = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_gr == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 691 | __pyx_v_klatr = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_klatr == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 692 | __pyx_v_glatr = __pyx_PyFloat_AsFloat(values[3]); if (unlikely((__pyx_v_glatr == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 693 | } 694 | goto __pyx_L4_argument_unpacking_done; 695 | __pyx_L5_argtuple_error:; 696 | __Pyx_RaiseArgtupleInvalid("atan2c_longitude", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 697 | __pyx_L3_error:; 698 | __Pyx_AddTraceback("pytda_cython_tools.atan2c_longitude", __pyx_clineno, __pyx_lineno, __pyx_filename); 699 | __Pyx_RefNannyFinishContext(); 700 | return NULL; 701 | __pyx_L4_argument_unpacking_done:; 702 | __pyx_r = __pyx_pf_18pytda_cython_tools_atan2c_longitude(__pyx_self, __pyx_v_azr, __pyx_v_gr, __pyx_v_klatr, __pyx_v_glatr); 703 | 704 | /* function exit code */ 705 | __Pyx_RefNannyFinishContext(); 706 | return __pyx_r; 707 | } 708 | 709 | static PyObject *__pyx_pf_18pytda_cython_tools_atan2c_longitude(CYTHON_UNUSED PyObject *__pyx_self, float __pyx_v_azr, float __pyx_v_gr, float __pyx_v_klatr, float __pyx_v_glatr) { 710 | float __pyx_v_re; 711 | PyObject *__pyx_r = NULL; 712 | __Pyx_RefNannyDeclarations 713 | PyObject *__pyx_t_1 = NULL; 714 | int __pyx_lineno = 0; 715 | const char *__pyx_filename = NULL; 716 | int __pyx_clineno = 0; 717 | __Pyx_RefNannySetupContext("atan2c_longitude", 0); 718 | 719 | /* "pytda_cython_tools.pyx":8 720 | * 721 | * def atan2c_longitude(float azr, float gr, float klatr, float glatr): 722 | * cdef float re = 6371.1 # <<<<<<<<<<<<<< 723 | * return atan2f(sinf(azr)*sinf(gr/re)*cosf(klatr), 724 | * cosf(gr/re)-sinf(klatr)*sinf(glatr)) 725 | */ 726 | __pyx_v_re = 6371.1; 727 | 728 | /* "pytda_cython_tools.pyx":9 729 | * def atan2c_longitude(float azr, float gr, float klatr, float glatr): 730 | * cdef float re = 6371.1 731 | * return atan2f(sinf(azr)*sinf(gr/re)*cosf(klatr), # <<<<<<<<<<<<<< 732 | * cosf(gr/re)-sinf(klatr)*sinf(glatr)) 733 | * 734 | */ 735 | __Pyx_XDECREF(__pyx_r); 736 | if (unlikely(__pyx_v_re == 0)) { 737 | #ifdef WITH_THREAD 738 | PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); 739 | #endif 740 | PyErr_SetString(PyExc_ZeroDivisionError, "float division"); 741 | #ifdef WITH_THREAD 742 | PyGILState_Release(__pyx_gilstate_save); 743 | #endif 744 | {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 745 | } 746 | 747 | /* "pytda_cython_tools.pyx":10 748 | * cdef float re = 6371.1 749 | * return atan2f(sinf(azr)*sinf(gr/re)*cosf(klatr), 750 | * cosf(gr/re)-sinf(klatr)*sinf(glatr)) # <<<<<<<<<<<<<< 751 | * 752 | * 753 | */ 754 | if (unlikely(__pyx_v_re == 0)) { 755 | #ifdef WITH_THREAD 756 | PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); 757 | #endif 758 | PyErr_SetString(PyExc_ZeroDivisionError, "float division"); 759 | #ifdef WITH_THREAD 760 | PyGILState_Release(__pyx_gilstate_save); 761 | #endif 762 | {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 763 | } 764 | 765 | /* "pytda_cython_tools.pyx":9 766 | * def atan2c_longitude(float azr, float gr, float klatr, float glatr): 767 | * cdef float re = 6371.1 768 | * return atan2f(sinf(azr)*sinf(gr/re)*cosf(klatr), # <<<<<<<<<<<<<< 769 | * cosf(gr/re)-sinf(klatr)*sinf(glatr)) 770 | * 771 | */ 772 | __pyx_t_1 = PyFloat_FromDouble(atan2f(((sinf(__pyx_v_azr) * sinf((__pyx_v_gr / __pyx_v_re))) * cosf(__pyx_v_klatr)), (cosf((__pyx_v_gr / __pyx_v_re)) - (sinf(__pyx_v_klatr) * sinf(__pyx_v_glatr))))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 773 | __Pyx_GOTREF(__pyx_t_1); 774 | __pyx_r = __pyx_t_1; 775 | __pyx_t_1 = 0; 776 | goto __pyx_L0; 777 | 778 | /* "pytda_cython_tools.pyx":7 779 | * 780 | * 781 | * def atan2c_longitude(float azr, float gr, float klatr, float glatr): # <<<<<<<<<<<<<< 782 | * cdef float re = 6371.1 783 | * return atan2f(sinf(azr)*sinf(gr/re)*cosf(klatr), 784 | */ 785 | 786 | /* function exit code */ 787 | __pyx_L1_error:; 788 | __Pyx_XDECREF(__pyx_t_1); 789 | __Pyx_AddTraceback("pytda_cython_tools.atan2c_longitude", __pyx_clineno, __pyx_lineno, __pyx_filename); 790 | __pyx_r = NULL; 791 | __pyx_L0:; 792 | __Pyx_XGIVEREF(__pyx_r); 793 | __Pyx_RefNannyFinishContext(); 794 | return __pyx_r; 795 | } 796 | 797 | /* "pytda_cython_tools.pyx":13 798 | * 799 | * 800 | * def calc_turb_cython(float csnr, float cpr, float cswv, float czh, float crng, # <<<<<<<<<<<<<< 801 | * float eps, float num, float tot): 802 | * cdef float csw 803 | */ 804 | 805 | /* Python wrapper */ 806 | static PyObject *__pyx_pw_18pytda_cython_tools_3calc_turb_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ 807 | static PyMethodDef __pyx_mdef_18pytda_cython_tools_3calc_turb_cython = {"calc_turb_cython", (PyCFunction)__pyx_pw_18pytda_cython_tools_3calc_turb_cython, METH_VARARGS|METH_KEYWORDS, 0}; 808 | static PyObject *__pyx_pw_18pytda_cython_tools_3calc_turb_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { 809 | float __pyx_v_csnr; 810 | float __pyx_v_cpr; 811 | float __pyx_v_cswv; 812 | float __pyx_v_czh; 813 | float __pyx_v_crng; 814 | float __pyx_v_eps; 815 | float __pyx_v_num; 816 | float __pyx_v_tot; 817 | int __pyx_lineno = 0; 818 | const char *__pyx_filename = NULL; 819 | int __pyx_clineno = 0; 820 | PyObject *__pyx_r = 0; 821 | __Pyx_RefNannyDeclarations 822 | __Pyx_RefNannySetupContext("calc_turb_cython (wrapper)", 0); 823 | { 824 | static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_csnr,&__pyx_n_s_cpr,&__pyx_n_s_cswv,&__pyx_n_s_czh,&__pyx_n_s_crng,&__pyx_n_s_eps,&__pyx_n_s_num,&__pyx_n_s_tot,0}; 825 | PyObject* values[8] = {0,0,0,0,0,0,0,0}; 826 | if (unlikely(__pyx_kwds)) { 827 | Py_ssize_t kw_args; 828 | const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); 829 | switch (pos_args) { 830 | case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); 831 | case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); 832 | case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); 833 | case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); 834 | case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); 835 | case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); 836 | case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); 837 | case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); 838 | case 0: break; 839 | default: goto __pyx_L5_argtuple_error; 840 | } 841 | kw_args = PyDict_Size(__pyx_kwds); 842 | switch (pos_args) { 843 | case 0: 844 | if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_csnr)) != 0)) kw_args--; 845 | else goto __pyx_L5_argtuple_error; 846 | case 1: 847 | if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_cpr)) != 0)) kw_args--; 848 | else { 849 | __Pyx_RaiseArgtupleInvalid("calc_turb_cython", 1, 8, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 850 | } 851 | case 2: 852 | if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_cswv)) != 0)) kw_args--; 853 | else { 854 | __Pyx_RaiseArgtupleInvalid("calc_turb_cython", 1, 8, 8, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 855 | } 856 | case 3: 857 | if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_czh)) != 0)) kw_args--; 858 | else { 859 | __Pyx_RaiseArgtupleInvalid("calc_turb_cython", 1, 8, 8, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 860 | } 861 | case 4: 862 | if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_crng)) != 0)) kw_args--; 863 | else { 864 | __Pyx_RaiseArgtupleInvalid("calc_turb_cython", 1, 8, 8, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 865 | } 866 | case 5: 867 | if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_eps)) != 0)) kw_args--; 868 | else { 869 | __Pyx_RaiseArgtupleInvalid("calc_turb_cython", 1, 8, 8, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 870 | } 871 | case 6: 872 | if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_num)) != 0)) kw_args--; 873 | else { 874 | __Pyx_RaiseArgtupleInvalid("calc_turb_cython", 1, 8, 8, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 875 | } 876 | case 7: 877 | if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_tot)) != 0)) kw_args--; 878 | else { 879 | __Pyx_RaiseArgtupleInvalid("calc_turb_cython", 1, 8, 8, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 880 | } 881 | } 882 | if (unlikely(kw_args > 0)) { 883 | if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "calc_turb_cython") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 884 | } 885 | } else if (PyTuple_GET_SIZE(__pyx_args) != 8) { 886 | goto __pyx_L5_argtuple_error; 887 | } else { 888 | values[0] = PyTuple_GET_ITEM(__pyx_args, 0); 889 | values[1] = PyTuple_GET_ITEM(__pyx_args, 1); 890 | values[2] = PyTuple_GET_ITEM(__pyx_args, 2); 891 | values[3] = PyTuple_GET_ITEM(__pyx_args, 3); 892 | values[4] = PyTuple_GET_ITEM(__pyx_args, 4); 893 | values[5] = PyTuple_GET_ITEM(__pyx_args, 5); 894 | values[6] = PyTuple_GET_ITEM(__pyx_args, 6); 895 | values[7] = PyTuple_GET_ITEM(__pyx_args, 7); 896 | } 897 | __pyx_v_csnr = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_csnr == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 898 | __pyx_v_cpr = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_cpr == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 899 | __pyx_v_cswv = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_cswv == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 900 | __pyx_v_czh = __pyx_PyFloat_AsFloat(values[3]); if (unlikely((__pyx_v_czh == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 901 | __pyx_v_crng = __pyx_PyFloat_AsFloat(values[4]); if (unlikely((__pyx_v_crng == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 902 | __pyx_v_eps = __pyx_PyFloat_AsFloat(values[5]); if (unlikely((__pyx_v_eps == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 903 | __pyx_v_num = __pyx_PyFloat_AsFloat(values[6]); if (unlikely((__pyx_v_num == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 904 | __pyx_v_tot = __pyx_PyFloat_AsFloat(values[7]); if (unlikely((__pyx_v_tot == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 905 | } 906 | goto __pyx_L4_argument_unpacking_done; 907 | __pyx_L5_argtuple_error:; 908 | __Pyx_RaiseArgtupleInvalid("calc_turb_cython", 1, 8, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 909 | __pyx_L3_error:; 910 | __Pyx_AddTraceback("pytda_cython_tools.calc_turb_cython", __pyx_clineno, __pyx_lineno, __pyx_filename); 911 | __Pyx_RefNannyFinishContext(); 912 | return NULL; 913 | __pyx_L4_argument_unpacking_done:; 914 | __pyx_r = __pyx_pf_18pytda_cython_tools_2calc_turb_cython(__pyx_self, __pyx_v_csnr, __pyx_v_cpr, __pyx_v_cswv, __pyx_v_czh, __pyx_v_crng, __pyx_v_eps, __pyx_v_num, __pyx_v_tot); 915 | 916 | /* function exit code */ 917 | __Pyx_RefNannyFinishContext(); 918 | return __pyx_r; 919 | } 920 | 921 | static PyObject *__pyx_pf_18pytda_cython_tools_2calc_turb_cython(CYTHON_UNUSED PyObject *__pyx_self, float __pyx_v_csnr, float __pyx_v_cpr, float __pyx_v_cswv, float __pyx_v_czh, float __pyx_v_crng, float __pyx_v_eps, float __pyx_v_num, float __pyx_v_tot) { 922 | float __pyx_v_csw; 923 | PyObject *__pyx_r = NULL; 924 | __Pyx_RefNannyDeclarations 925 | PyObject *__pyx_t_1 = NULL; 926 | PyObject *__pyx_t_2 = NULL; 927 | PyObject *__pyx_t_3 = NULL; 928 | int __pyx_lineno = 0; 929 | const char *__pyx_filename = NULL; 930 | int __pyx_clineno = 0; 931 | __Pyx_RefNannySetupContext("calc_turb_cython", 0); 932 | 933 | /* "pytda_cython_tools.pyx":16 934 | * float eps, float num, float tot): 935 | * cdef float csw 936 | * csw = (csnr**0.6667) * cpr * cswv * czh * crng # <<<<<<<<<<<<<< 937 | * return num + csw * eps**2, tot + csw 938 | * 939 | */ 940 | __pyx_v_csw = ((((pow(((double)__pyx_v_csnr), 0.6667) * __pyx_v_cpr) * __pyx_v_cswv) * __pyx_v_czh) * __pyx_v_crng); 941 | 942 | /* "pytda_cython_tools.pyx":17 943 | * cdef float csw 944 | * csw = (csnr**0.6667) * cpr * cswv * czh * crng 945 | * return num + csw * eps**2, tot + csw # <<<<<<<<<<<<<< 946 | * 947 | * 948 | */ 949 | __Pyx_XDECREF(__pyx_r); 950 | __pyx_t_1 = PyFloat_FromDouble((__pyx_v_num + (__pyx_v_csw * powf(__pyx_v_eps, 2.0)))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 951 | __Pyx_GOTREF(__pyx_t_1); 952 | __pyx_t_2 = PyFloat_FromDouble((__pyx_v_tot + __pyx_v_csw)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 953 | __Pyx_GOTREF(__pyx_t_2); 954 | __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 955 | __Pyx_GOTREF(__pyx_t_3); 956 | __Pyx_GIVEREF(__pyx_t_1); 957 | PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); 958 | __Pyx_GIVEREF(__pyx_t_2); 959 | PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2); 960 | __pyx_t_1 = 0; 961 | __pyx_t_2 = 0; 962 | __pyx_r = __pyx_t_3; 963 | __pyx_t_3 = 0; 964 | goto __pyx_L0; 965 | 966 | /* "pytda_cython_tools.pyx":13 967 | * 968 | * 969 | * def calc_turb_cython(float csnr, float cpr, float cswv, float czh, float crng, # <<<<<<<<<<<<<< 970 | * float eps, float num, float tot): 971 | * cdef float csw 972 | */ 973 | 974 | /* function exit code */ 975 | __pyx_L1_error:; 976 | __Pyx_XDECREF(__pyx_t_1); 977 | __Pyx_XDECREF(__pyx_t_2); 978 | __Pyx_XDECREF(__pyx_t_3); 979 | __Pyx_AddTraceback("pytda_cython_tools.calc_turb_cython", __pyx_clineno, __pyx_lineno, __pyx_filename); 980 | __pyx_r = NULL; 981 | __pyx_L0:; 982 | __Pyx_XGIVEREF(__pyx_r); 983 | __Pyx_RefNannyFinishContext(); 984 | return __pyx_r; 985 | } 986 | 987 | /* "pytda_cython_tools.pyx":20 988 | * 989 | * 990 | * def calc_cswv_cython(float dummy): # <<<<<<<<<<<<<< 991 | * cdef float cswv 992 | * cswv = 0.0 993 | */ 994 | 995 | /* Python wrapper */ 996 | static PyObject *__pyx_pw_18pytda_cython_tools_5calc_cswv_cython(PyObject *__pyx_self, PyObject *__pyx_arg_dummy); /*proto*/ 997 | static PyMethodDef __pyx_mdef_18pytda_cython_tools_5calc_cswv_cython = {"calc_cswv_cython", (PyCFunction)__pyx_pw_18pytda_cython_tools_5calc_cswv_cython, METH_O, 0}; 998 | static PyObject *__pyx_pw_18pytda_cython_tools_5calc_cswv_cython(PyObject *__pyx_self, PyObject *__pyx_arg_dummy) { 999 | float __pyx_v_dummy; 1000 | int __pyx_lineno = 0; 1001 | const char *__pyx_filename = NULL; 1002 | int __pyx_clineno = 0; 1003 | PyObject *__pyx_r = 0; 1004 | __Pyx_RefNannyDeclarations 1005 | __Pyx_RefNannySetupContext("calc_cswv_cython (wrapper)", 0); 1006 | assert(__pyx_arg_dummy); { 1007 | __pyx_v_dummy = __pyx_PyFloat_AsFloat(__pyx_arg_dummy); if (unlikely((__pyx_v_dummy == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 1008 | } 1009 | goto __pyx_L4_argument_unpacking_done; 1010 | __pyx_L3_error:; 1011 | __Pyx_AddTraceback("pytda_cython_tools.calc_cswv_cython", __pyx_clineno, __pyx_lineno, __pyx_filename); 1012 | __Pyx_RefNannyFinishContext(); 1013 | return NULL; 1014 | __pyx_L4_argument_unpacking_done:; 1015 | __pyx_r = __pyx_pf_18pytda_cython_tools_4calc_cswv_cython(__pyx_self, ((float)__pyx_v_dummy)); 1016 | 1017 | /* function exit code */ 1018 | __Pyx_RefNannyFinishContext(); 1019 | return __pyx_r; 1020 | } 1021 | 1022 | static PyObject *__pyx_pf_18pytda_cython_tools_4calc_cswv_cython(CYTHON_UNUSED PyObject *__pyx_self, float __pyx_v_dummy) { 1023 | float __pyx_v_cswv; 1024 | PyObject *__pyx_r = NULL; 1025 | __Pyx_RefNannyDeclarations 1026 | int __pyx_t_1; 1027 | int __pyx_t_2; 1028 | PyObject *__pyx_t_3 = NULL; 1029 | int __pyx_lineno = 0; 1030 | const char *__pyx_filename = NULL; 1031 | int __pyx_clineno = 0; 1032 | __Pyx_RefNannySetupContext("calc_cswv_cython", 0); 1033 | 1034 | /* "pytda_cython_tools.pyx":22 1035 | * def calc_cswv_cython(float dummy): 1036 | * cdef float cswv 1037 | * cswv = 0.0 # <<<<<<<<<<<<<< 1038 | * if dummy >= 0 and dummy < 4: 1039 | * cswv = 1.0 1040 | */ 1041 | __pyx_v_cswv = 0.0; 1042 | 1043 | /* "pytda_cython_tools.pyx":23 1044 | * cdef float cswv 1045 | * cswv = 0.0 1046 | * if dummy >= 0 and dummy < 4: # <<<<<<<<<<<<<< 1047 | * cswv = 1.0 1048 | * elif dummy >= 4 and dummy < 16: 1049 | */ 1050 | __pyx_t_2 = ((__pyx_v_dummy >= 0.0) != 0); 1051 | if (__pyx_t_2) { 1052 | } else { 1053 | __pyx_t_1 = __pyx_t_2; 1054 | goto __pyx_L4_bool_binop_done; 1055 | } 1056 | __pyx_t_2 = ((__pyx_v_dummy < 4.0) != 0); 1057 | __pyx_t_1 = __pyx_t_2; 1058 | __pyx_L4_bool_binop_done:; 1059 | if (__pyx_t_1) { 1060 | 1061 | /* "pytda_cython_tools.pyx":24 1062 | * cswv = 0.0 1063 | * if dummy >= 0 and dummy < 4: 1064 | * cswv = 1.0 # <<<<<<<<<<<<<< 1065 | * elif dummy >= 4 and dummy < 16: 1066 | * cswv = 1.0 - (1.0 / 12.0) * (dummy - 4.0) 1067 | */ 1068 | __pyx_v_cswv = 1.0; 1069 | goto __pyx_L3; 1070 | } 1071 | 1072 | /* "pytda_cython_tools.pyx":25 1073 | * if dummy >= 0 and dummy < 4: 1074 | * cswv = 1.0 1075 | * elif dummy >= 4 and dummy < 16: # <<<<<<<<<<<<<< 1076 | * cswv = 1.0 - (1.0 / 12.0) * (dummy - 4.0) 1077 | * return cswv 1078 | */ 1079 | __pyx_t_2 = ((__pyx_v_dummy >= 4.0) != 0); 1080 | if (__pyx_t_2) { 1081 | } else { 1082 | __pyx_t_1 = __pyx_t_2; 1083 | goto __pyx_L6_bool_binop_done; 1084 | } 1085 | __pyx_t_2 = ((__pyx_v_dummy < 16.0) != 0); 1086 | __pyx_t_1 = __pyx_t_2; 1087 | __pyx_L6_bool_binop_done:; 1088 | if (__pyx_t_1) { 1089 | 1090 | /* "pytda_cython_tools.pyx":26 1091 | * cswv = 1.0 1092 | * elif dummy >= 4 and dummy < 16: 1093 | * cswv = 1.0 - (1.0 / 12.0) * (dummy - 4.0) # <<<<<<<<<<<<<< 1094 | * return cswv 1095 | * 1096 | */ 1097 | __pyx_v_cswv = (1.0 - ((1.0 / 12.0) * (__pyx_v_dummy - 4.0))); 1098 | goto __pyx_L3; 1099 | } 1100 | __pyx_L3:; 1101 | 1102 | /* "pytda_cython_tools.pyx":27 1103 | * elif dummy >= 4 and dummy < 16: 1104 | * cswv = 1.0 - (1.0 / 12.0) * (dummy - 4.0) 1105 | * return cswv # <<<<<<<<<<<<<< 1106 | * 1107 | * 1108 | */ 1109 | __Pyx_XDECREF(__pyx_r); 1110 | __pyx_t_3 = PyFloat_FromDouble(__pyx_v_cswv); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1111 | __Pyx_GOTREF(__pyx_t_3); 1112 | __pyx_r = __pyx_t_3; 1113 | __pyx_t_3 = 0; 1114 | goto __pyx_L0; 1115 | 1116 | /* "pytda_cython_tools.pyx":20 1117 | * 1118 | * 1119 | * def calc_cswv_cython(float dummy): # <<<<<<<<<<<<<< 1120 | * cdef float cswv 1121 | * cswv = 0.0 1122 | */ 1123 | 1124 | /* function exit code */ 1125 | __pyx_L1_error:; 1126 | __Pyx_XDECREF(__pyx_t_3); 1127 | __Pyx_AddTraceback("pytda_cython_tools.calc_cswv_cython", __pyx_clineno, __pyx_lineno, __pyx_filename); 1128 | __pyx_r = NULL; 1129 | __pyx_L0:; 1130 | __Pyx_XGIVEREF(__pyx_r); 1131 | __Pyx_RefNannyFinishContext(); 1132 | return __pyx_r; 1133 | } 1134 | 1135 | /* "pytda_cython_tools.pyx":30 1136 | * 1137 | * 1138 | * def atan2c(float y, float x): # <<<<<<<<<<<<<< 1139 | * return atan2f(y, x) 1140 | */ 1141 | 1142 | /* Python wrapper */ 1143 | static PyObject *__pyx_pw_18pytda_cython_tools_7atan2c(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ 1144 | static PyMethodDef __pyx_mdef_18pytda_cython_tools_7atan2c = {"atan2c", (PyCFunction)__pyx_pw_18pytda_cython_tools_7atan2c, METH_VARARGS|METH_KEYWORDS, 0}; 1145 | static PyObject *__pyx_pw_18pytda_cython_tools_7atan2c(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { 1146 | float __pyx_v_y; 1147 | float __pyx_v_x; 1148 | int __pyx_lineno = 0; 1149 | const char *__pyx_filename = NULL; 1150 | int __pyx_clineno = 0; 1151 | PyObject *__pyx_r = 0; 1152 | __Pyx_RefNannyDeclarations 1153 | __Pyx_RefNannySetupContext("atan2c (wrapper)", 0); 1154 | { 1155 | static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_y,&__pyx_n_s_x,0}; 1156 | PyObject* values[2] = {0,0}; 1157 | if (unlikely(__pyx_kwds)) { 1158 | Py_ssize_t kw_args; 1159 | const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); 1160 | switch (pos_args) { 1161 | case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); 1162 | case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); 1163 | case 0: break; 1164 | default: goto __pyx_L5_argtuple_error; 1165 | } 1166 | kw_args = PyDict_Size(__pyx_kwds); 1167 | switch (pos_args) { 1168 | case 0: 1169 | if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_y)) != 0)) kw_args--; 1170 | else goto __pyx_L5_argtuple_error; 1171 | case 1: 1172 | if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--; 1173 | else { 1174 | __Pyx_RaiseArgtupleInvalid("atan2c", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 1175 | } 1176 | } 1177 | if (unlikely(kw_args > 0)) { 1178 | if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "atan2c") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 1179 | } 1180 | } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { 1181 | goto __pyx_L5_argtuple_error; 1182 | } else { 1183 | values[0] = PyTuple_GET_ITEM(__pyx_args, 0); 1184 | values[1] = PyTuple_GET_ITEM(__pyx_args, 1); 1185 | } 1186 | __pyx_v_y = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_y == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 1187 | __pyx_v_x = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_x == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 1188 | } 1189 | goto __pyx_L4_argument_unpacking_done; 1190 | __pyx_L5_argtuple_error:; 1191 | __Pyx_RaiseArgtupleInvalid("atan2c", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L3_error;} 1192 | __pyx_L3_error:; 1193 | __Pyx_AddTraceback("pytda_cython_tools.atan2c", __pyx_clineno, __pyx_lineno, __pyx_filename); 1194 | __Pyx_RefNannyFinishContext(); 1195 | return NULL; 1196 | __pyx_L4_argument_unpacking_done:; 1197 | __pyx_r = __pyx_pf_18pytda_cython_tools_6atan2c(__pyx_self, __pyx_v_y, __pyx_v_x); 1198 | 1199 | /* function exit code */ 1200 | __Pyx_RefNannyFinishContext(); 1201 | return __pyx_r; 1202 | } 1203 | 1204 | static PyObject *__pyx_pf_18pytda_cython_tools_6atan2c(CYTHON_UNUSED PyObject *__pyx_self, float __pyx_v_y, float __pyx_v_x) { 1205 | PyObject *__pyx_r = NULL; 1206 | __Pyx_RefNannyDeclarations 1207 | PyObject *__pyx_t_1 = NULL; 1208 | int __pyx_lineno = 0; 1209 | const char *__pyx_filename = NULL; 1210 | int __pyx_clineno = 0; 1211 | __Pyx_RefNannySetupContext("atan2c", 0); 1212 | 1213 | /* "pytda_cython_tools.pyx":31 1214 | * 1215 | * def atan2c(float y, float x): 1216 | * return atan2f(y, x) # <<<<<<<<<<<<<< 1217 | */ 1218 | __Pyx_XDECREF(__pyx_r); 1219 | __pyx_t_1 = PyFloat_FromDouble(atan2f(__pyx_v_y, __pyx_v_x)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1220 | __Pyx_GOTREF(__pyx_t_1); 1221 | __pyx_r = __pyx_t_1; 1222 | __pyx_t_1 = 0; 1223 | goto __pyx_L0; 1224 | 1225 | /* "pytda_cython_tools.pyx":30 1226 | * 1227 | * 1228 | * def atan2c(float y, float x): # <<<<<<<<<<<<<< 1229 | * return atan2f(y, x) 1230 | */ 1231 | 1232 | /* function exit code */ 1233 | __pyx_L1_error:; 1234 | __Pyx_XDECREF(__pyx_t_1); 1235 | __Pyx_AddTraceback("pytda_cython_tools.atan2c", __pyx_clineno, __pyx_lineno, __pyx_filename); 1236 | __pyx_r = NULL; 1237 | __pyx_L0:; 1238 | __Pyx_XGIVEREF(__pyx_r); 1239 | __Pyx_RefNannyFinishContext(); 1240 | return __pyx_r; 1241 | } 1242 | 1243 | static PyMethodDef __pyx_methods[] = { 1244 | {0, 0, 0, 0} 1245 | }; 1246 | 1247 | #if PY_MAJOR_VERSION >= 3 1248 | static struct PyModuleDef __pyx_moduledef = { 1249 | #if PY_VERSION_HEX < 0x03020000 1250 | { PyObject_HEAD_INIT(NULL) NULL, 0, NULL }, 1251 | #else 1252 | PyModuleDef_HEAD_INIT, 1253 | #endif 1254 | "pytda_cython_tools", 1255 | 0, /* m_doc */ 1256 | -1, /* m_size */ 1257 | __pyx_methods /* m_methods */, 1258 | NULL, /* m_reload */ 1259 | NULL, /* m_traverse */ 1260 | NULL, /* m_clear */ 1261 | NULL /* m_free */ 1262 | }; 1263 | #endif 1264 | 1265 | static __Pyx_StringTabEntry __pyx_string_tab[] = { 1266 | {&__pyx_kp_s_Users_tjlang_Documents_Python_p, __pyx_k_Users_tjlang_Documents_Python_p, sizeof(__pyx_k_Users_tjlang_Documents_Python_p), 0, 0, 1, 0}, 1267 | {&__pyx_n_s_atan2c, __pyx_k_atan2c, sizeof(__pyx_k_atan2c), 0, 0, 1, 1}, 1268 | {&__pyx_n_s_atan2c_longitude, __pyx_k_atan2c_longitude, sizeof(__pyx_k_atan2c_longitude), 0, 0, 1, 1}, 1269 | {&__pyx_n_s_azr, __pyx_k_azr, sizeof(__pyx_k_azr), 0, 0, 1, 1}, 1270 | {&__pyx_n_s_calc_cswv_cython, __pyx_k_calc_cswv_cython, sizeof(__pyx_k_calc_cswv_cython), 0, 0, 1, 1}, 1271 | {&__pyx_n_s_calc_turb_cython, __pyx_k_calc_turb_cython, sizeof(__pyx_k_calc_turb_cython), 0, 0, 1, 1}, 1272 | {&__pyx_n_s_cpr, __pyx_k_cpr, sizeof(__pyx_k_cpr), 0, 0, 1, 1}, 1273 | {&__pyx_n_s_crng, __pyx_k_crng, sizeof(__pyx_k_crng), 0, 0, 1, 1}, 1274 | {&__pyx_n_s_csnr, __pyx_k_csnr, sizeof(__pyx_k_csnr), 0, 0, 1, 1}, 1275 | {&__pyx_n_s_csw, __pyx_k_csw, sizeof(__pyx_k_csw), 0, 0, 1, 1}, 1276 | {&__pyx_n_s_cswv, __pyx_k_cswv, sizeof(__pyx_k_cswv), 0, 0, 1, 1}, 1277 | {&__pyx_n_s_czh, __pyx_k_czh, sizeof(__pyx_k_czh), 0, 0, 1, 1}, 1278 | {&__pyx_n_s_dummy, __pyx_k_dummy, sizeof(__pyx_k_dummy), 0, 0, 1, 1}, 1279 | {&__pyx_n_s_eps, __pyx_k_eps, sizeof(__pyx_k_eps), 0, 0, 1, 1}, 1280 | {&__pyx_n_s_glatr, __pyx_k_glatr, sizeof(__pyx_k_glatr), 0, 0, 1, 1}, 1281 | {&__pyx_n_s_gr, __pyx_k_gr, sizeof(__pyx_k_gr), 0, 0, 1, 1}, 1282 | {&__pyx_n_s_klatr, __pyx_k_klatr, sizeof(__pyx_k_klatr), 0, 0, 1, 1}, 1283 | {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, 1284 | {&__pyx_n_s_num, __pyx_k_num, sizeof(__pyx_k_num), 0, 0, 1, 1}, 1285 | {&__pyx_n_s_pytda_cython_tools, __pyx_k_pytda_cython_tools, sizeof(__pyx_k_pytda_cython_tools), 0, 0, 1, 1}, 1286 | {&__pyx_n_s_re, __pyx_k_re, sizeof(__pyx_k_re), 0, 0, 1, 1}, 1287 | {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, 1288 | {&__pyx_n_s_tot, __pyx_k_tot, sizeof(__pyx_k_tot), 0, 0, 1, 1}, 1289 | {&__pyx_n_s_x, __pyx_k_x, sizeof(__pyx_k_x), 0, 0, 1, 1}, 1290 | {&__pyx_n_s_y, __pyx_k_y, sizeof(__pyx_k_y), 0, 0, 1, 1}, 1291 | {0, 0, 0, 0, 0, 0, 0} 1292 | }; 1293 | static int __Pyx_InitCachedBuiltins(void) { 1294 | return 0; 1295 | } 1296 | 1297 | static int __Pyx_InitCachedConstants(void) { 1298 | __Pyx_RefNannyDeclarations 1299 | __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); 1300 | 1301 | /* "pytda_cython_tools.pyx":7 1302 | * 1303 | * 1304 | * def atan2c_longitude(float azr, float gr, float klatr, float glatr): # <<<<<<<<<<<<<< 1305 | * cdef float re = 6371.1 1306 | * return atan2f(sinf(azr)*sinf(gr/re)*cosf(klatr), 1307 | */ 1308 | __pyx_tuple_ = PyTuple_Pack(5, __pyx_n_s_azr, __pyx_n_s_gr, __pyx_n_s_klatr, __pyx_n_s_glatr, __pyx_n_s_re); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1309 | __Pyx_GOTREF(__pyx_tuple_); 1310 | __Pyx_GIVEREF(__pyx_tuple_); 1311 | __pyx_codeobj__2 = (PyObject*)__Pyx_PyCode_New(4, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple_, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_tjlang_Documents_Python_p, __pyx_n_s_atan2c_longitude, 7, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1312 | 1313 | /* "pytda_cython_tools.pyx":13 1314 | * 1315 | * 1316 | * def calc_turb_cython(float csnr, float cpr, float cswv, float czh, float crng, # <<<<<<<<<<<<<< 1317 | * float eps, float num, float tot): 1318 | * cdef float csw 1319 | */ 1320 | __pyx_tuple__3 = PyTuple_Pack(9, __pyx_n_s_csnr, __pyx_n_s_cpr, __pyx_n_s_cswv, __pyx_n_s_czh, __pyx_n_s_crng, __pyx_n_s_eps, __pyx_n_s_num, __pyx_n_s_tot, __pyx_n_s_csw); if (unlikely(!__pyx_tuple__3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1321 | __Pyx_GOTREF(__pyx_tuple__3); 1322 | __Pyx_GIVEREF(__pyx_tuple__3); 1323 | __pyx_codeobj__4 = (PyObject*)__Pyx_PyCode_New(8, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__3, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_tjlang_Documents_Python_p, __pyx_n_s_calc_turb_cython, 13, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1324 | 1325 | /* "pytda_cython_tools.pyx":20 1326 | * 1327 | * 1328 | * def calc_cswv_cython(float dummy): # <<<<<<<<<<<<<< 1329 | * cdef float cswv 1330 | * cswv = 0.0 1331 | */ 1332 | __pyx_tuple__5 = PyTuple_Pack(3, __pyx_n_s_dummy, __pyx_n_s_dummy, __pyx_n_s_cswv); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1333 | __Pyx_GOTREF(__pyx_tuple__5); 1334 | __Pyx_GIVEREF(__pyx_tuple__5); 1335 | __pyx_codeobj__6 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__5, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_tjlang_Documents_Python_p, __pyx_n_s_calc_cswv_cython, 20, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1336 | 1337 | /* "pytda_cython_tools.pyx":30 1338 | * 1339 | * 1340 | * def atan2c(float y, float x): # <<<<<<<<<<<<<< 1341 | * return atan2f(y, x) 1342 | */ 1343 | __pyx_tuple__7 = PyTuple_Pack(2, __pyx_n_s_y, __pyx_n_s_x); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1344 | __Pyx_GOTREF(__pyx_tuple__7); 1345 | __Pyx_GIVEREF(__pyx_tuple__7); 1346 | __pyx_codeobj__8 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__7, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_tjlang_Documents_Python_p, __pyx_n_s_atan2c, 30, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1347 | __Pyx_RefNannyFinishContext(); 1348 | return 0; 1349 | __pyx_L1_error:; 1350 | __Pyx_RefNannyFinishContext(); 1351 | return -1; 1352 | } 1353 | 1354 | static int __Pyx_InitGlobals(void) { 1355 | if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; 1356 | return 0; 1357 | __pyx_L1_error:; 1358 | return -1; 1359 | } 1360 | 1361 | #if PY_MAJOR_VERSION < 3 1362 | PyMODINIT_FUNC initpytda_cython_tools(void); /*proto*/ 1363 | PyMODINIT_FUNC initpytda_cython_tools(void) 1364 | #else 1365 | PyMODINIT_FUNC PyInit_pytda_cython_tools(void); /*proto*/ 1366 | PyMODINIT_FUNC PyInit_pytda_cython_tools(void) 1367 | #endif 1368 | { 1369 | PyObject *__pyx_t_1 = NULL; 1370 | int __pyx_lineno = 0; 1371 | const char *__pyx_filename = NULL; 1372 | int __pyx_clineno = 0; 1373 | __Pyx_RefNannyDeclarations 1374 | #if CYTHON_REFNANNY 1375 | __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); 1376 | if (!__Pyx_RefNanny) { 1377 | PyErr_Clear(); 1378 | __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); 1379 | if (!__Pyx_RefNanny) 1380 | Py_FatalError("failed to import 'refnanny' module"); 1381 | } 1382 | #endif 1383 | __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_pytda_cython_tools(void)", 0); 1384 | if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1385 | __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1386 | __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1387 | #ifdef __Pyx_CyFunction_USED 1388 | if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1389 | #endif 1390 | #ifdef __Pyx_FusedFunction_USED 1391 | if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1392 | #endif 1393 | #ifdef __Pyx_Generator_USED 1394 | if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1395 | #endif 1396 | /*--- Library function declarations ---*/ 1397 | /*--- Threads initialization code ---*/ 1398 | #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS 1399 | #ifdef WITH_THREAD /* Python build with threading support? */ 1400 | PyEval_InitThreads(); 1401 | #endif 1402 | #endif 1403 | /*--- Module creation code ---*/ 1404 | #if PY_MAJOR_VERSION < 3 1405 | __pyx_m = Py_InitModule4("pytda_cython_tools", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); 1406 | #else 1407 | __pyx_m = PyModule_Create(&__pyx_moduledef); 1408 | #endif 1409 | if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1410 | __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1411 | Py_INCREF(__pyx_d); 1412 | __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1413 | #if CYTHON_COMPILING_IN_PYPY 1414 | Py_INCREF(__pyx_b); 1415 | #endif 1416 | if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; 1417 | /*--- Initialize various global constants etc. ---*/ 1418 | if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1419 | #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) 1420 | if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1421 | #endif 1422 | if (__pyx_module_is_main_pytda_cython_tools) { 1423 | if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; 1424 | } 1425 | #if PY_MAJOR_VERSION >= 3 1426 | { 1427 | PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1428 | if (!PyDict_GetItemString(modules, "pytda_cython_tools")) { 1429 | if (unlikely(PyDict_SetItemString(modules, "pytda_cython_tools", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1430 | } 1431 | } 1432 | #endif 1433 | /*--- Builtin init code ---*/ 1434 | if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1435 | /*--- Constants init code ---*/ 1436 | if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1437 | /*--- Global init code ---*/ 1438 | /*--- Variable export code ---*/ 1439 | /*--- Function export code ---*/ 1440 | /*--- Type init code ---*/ 1441 | /*--- Type import code ---*/ 1442 | /*--- Variable import code ---*/ 1443 | /*--- Function import code ---*/ 1444 | /*--- Execution code ---*/ 1445 | 1446 | /* "pytda_cython_tools.pyx":7 1447 | * 1448 | * 1449 | * def atan2c_longitude(float azr, float gr, float klatr, float glatr): # <<<<<<<<<<<<<< 1450 | * cdef float re = 6371.1 1451 | * return atan2f(sinf(azr)*sinf(gr/re)*cosf(klatr), 1452 | */ 1453 | __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_18pytda_cython_tools_1atan2c_longitude, NULL, __pyx_n_s_pytda_cython_tools); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1454 | __Pyx_GOTREF(__pyx_t_1); 1455 | if (PyDict_SetItem(__pyx_d, __pyx_n_s_atan2c_longitude, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1456 | __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; 1457 | 1458 | /* "pytda_cython_tools.pyx":13 1459 | * 1460 | * 1461 | * def calc_turb_cython(float csnr, float cpr, float cswv, float czh, float crng, # <<<<<<<<<<<<<< 1462 | * float eps, float num, float tot): 1463 | * cdef float csw 1464 | */ 1465 | __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_18pytda_cython_tools_3calc_turb_cython, NULL, __pyx_n_s_pytda_cython_tools); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1466 | __Pyx_GOTREF(__pyx_t_1); 1467 | if (PyDict_SetItem(__pyx_d, __pyx_n_s_calc_turb_cython, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1468 | __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; 1469 | 1470 | /* "pytda_cython_tools.pyx":20 1471 | * 1472 | * 1473 | * def calc_cswv_cython(float dummy): # <<<<<<<<<<<<<< 1474 | * cdef float cswv 1475 | * cswv = 0.0 1476 | */ 1477 | __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_18pytda_cython_tools_5calc_cswv_cython, NULL, __pyx_n_s_pytda_cython_tools); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1478 | __Pyx_GOTREF(__pyx_t_1); 1479 | if (PyDict_SetItem(__pyx_d, __pyx_n_s_calc_cswv_cython, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1480 | __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; 1481 | 1482 | /* "pytda_cython_tools.pyx":30 1483 | * 1484 | * 1485 | * def atan2c(float y, float x): # <<<<<<<<<<<<<< 1486 | * return atan2f(y, x) 1487 | */ 1488 | __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_18pytda_cython_tools_7atan2c, NULL, __pyx_n_s_pytda_cython_tools); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1489 | __Pyx_GOTREF(__pyx_t_1); 1490 | if (PyDict_SetItem(__pyx_d, __pyx_n_s_atan2c, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1491 | __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; 1492 | 1493 | /* "pytda_cython_tools.pyx":1 1494 | * cdef extern from "math.h": # <<<<<<<<<<<<<< 1495 | * float cosf(float theta) 1496 | * float sinf(float theta) 1497 | */ 1498 | __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1499 | __Pyx_GOTREF(__pyx_t_1); 1500 | if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 1501 | __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; 1502 | 1503 | /*--- Wrapped vars code ---*/ 1504 | 1505 | goto __pyx_L0; 1506 | __pyx_L1_error:; 1507 | __Pyx_XDECREF(__pyx_t_1); 1508 | if (__pyx_m) { 1509 | if (__pyx_d) { 1510 | __Pyx_AddTraceback("init pytda_cython_tools", __pyx_clineno, __pyx_lineno, __pyx_filename); 1511 | } 1512 | Py_DECREF(__pyx_m); __pyx_m = 0; 1513 | } else if (!PyErr_Occurred()) { 1514 | PyErr_SetString(PyExc_ImportError, "init pytda_cython_tools"); 1515 | } 1516 | __pyx_L0:; 1517 | __Pyx_RefNannyFinishContext(); 1518 | #if PY_MAJOR_VERSION < 3 1519 | return; 1520 | #else 1521 | return __pyx_m; 1522 | #endif 1523 | } 1524 | 1525 | /* --- Runtime support code --- */ 1526 | #if CYTHON_REFNANNY 1527 | static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { 1528 | PyObject *m = NULL, *p = NULL; 1529 | void *r = NULL; 1530 | m = PyImport_ImportModule((char *)modname); 1531 | if (!m) goto end; 1532 | p = PyObject_GetAttrString(m, (char *)"RefNannyAPI"); 1533 | if (!p) goto end; 1534 | r = PyLong_AsVoidPtr(p); 1535 | end: 1536 | Py_XDECREF(p); 1537 | Py_XDECREF(m); 1538 | return (__Pyx_RefNannyAPIStruct *)r; 1539 | } 1540 | #endif 1541 | 1542 | static void __Pyx_RaiseArgtupleInvalid( 1543 | const char* func_name, 1544 | int exact, 1545 | Py_ssize_t num_min, 1546 | Py_ssize_t num_max, 1547 | Py_ssize_t num_found) 1548 | { 1549 | Py_ssize_t num_expected; 1550 | const char *more_or_less; 1551 | if (num_found < num_min) { 1552 | num_expected = num_min; 1553 | more_or_less = "at least"; 1554 | } else { 1555 | num_expected = num_max; 1556 | more_or_less = "at most"; 1557 | } 1558 | if (exact) { 1559 | more_or_less = "exactly"; 1560 | } 1561 | PyErr_Format(PyExc_TypeError, 1562 | "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", 1563 | func_name, more_or_less, num_expected, 1564 | (num_expected == 1) ? "" : "s", num_found); 1565 | } 1566 | 1567 | static void __Pyx_RaiseDoubleKeywordsError( 1568 | const char* func_name, 1569 | PyObject* kw_name) 1570 | { 1571 | PyErr_Format(PyExc_TypeError, 1572 | #if PY_MAJOR_VERSION >= 3 1573 | "%s() got multiple values for keyword argument '%U'", func_name, kw_name); 1574 | #else 1575 | "%s() got multiple values for keyword argument '%s'", func_name, 1576 | PyString_AsString(kw_name)); 1577 | #endif 1578 | } 1579 | 1580 | static int __Pyx_ParseOptionalKeywords( 1581 | PyObject *kwds, 1582 | PyObject **argnames[], 1583 | PyObject *kwds2, 1584 | PyObject *values[], 1585 | Py_ssize_t num_pos_args, 1586 | const char* function_name) 1587 | { 1588 | PyObject *key = 0, *value = 0; 1589 | Py_ssize_t pos = 0; 1590 | PyObject*** name; 1591 | PyObject*** first_kw_arg = argnames + num_pos_args; 1592 | while (PyDict_Next(kwds, &pos, &key, &value)) { 1593 | name = first_kw_arg; 1594 | while (*name && (**name != key)) name++; 1595 | if (*name) { 1596 | values[name-argnames] = value; 1597 | continue; 1598 | } 1599 | name = first_kw_arg; 1600 | #if PY_MAJOR_VERSION < 3 1601 | if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) { 1602 | while (*name) { 1603 | if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) 1604 | && _PyString_Eq(**name, key)) { 1605 | values[name-argnames] = value; 1606 | break; 1607 | } 1608 | name++; 1609 | } 1610 | if (*name) continue; 1611 | else { 1612 | PyObject*** argname = argnames; 1613 | while (argname != first_kw_arg) { 1614 | if ((**argname == key) || ( 1615 | (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) 1616 | && _PyString_Eq(**argname, key))) { 1617 | goto arg_passed_twice; 1618 | } 1619 | argname++; 1620 | } 1621 | } 1622 | } else 1623 | #endif 1624 | if (likely(PyUnicode_Check(key))) { 1625 | while (*name) { 1626 | int cmp = (**name == key) ? 0 : 1627 | #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 1628 | (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 : 1629 | #endif 1630 | PyUnicode_Compare(**name, key); 1631 | if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; 1632 | if (cmp == 0) { 1633 | values[name-argnames] = value; 1634 | break; 1635 | } 1636 | name++; 1637 | } 1638 | if (*name) continue; 1639 | else { 1640 | PyObject*** argname = argnames; 1641 | while (argname != first_kw_arg) { 1642 | int cmp = (**argname == key) ? 0 : 1643 | #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 1644 | (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 : 1645 | #endif 1646 | PyUnicode_Compare(**argname, key); 1647 | if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; 1648 | if (cmp == 0) goto arg_passed_twice; 1649 | argname++; 1650 | } 1651 | } 1652 | } else 1653 | goto invalid_keyword_type; 1654 | if (kwds2) { 1655 | if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; 1656 | } else { 1657 | goto invalid_keyword; 1658 | } 1659 | } 1660 | return 0; 1661 | arg_passed_twice: 1662 | __Pyx_RaiseDoubleKeywordsError(function_name, key); 1663 | goto bad; 1664 | invalid_keyword_type: 1665 | PyErr_Format(PyExc_TypeError, 1666 | "%.200s() keywords must be strings", function_name); 1667 | goto bad; 1668 | invalid_keyword: 1669 | PyErr_Format(PyExc_TypeError, 1670 | #if PY_MAJOR_VERSION < 3 1671 | "%.200s() got an unexpected keyword argument '%.200s'", 1672 | function_name, PyString_AsString(key)); 1673 | #else 1674 | "%s() got an unexpected keyword argument '%U'", 1675 | function_name, key); 1676 | #endif 1677 | bad: 1678 | return -1; 1679 | } 1680 | 1681 | static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { 1682 | int start = 0, mid = 0, end = count - 1; 1683 | if (end >= 0 && code_line > entries[end].code_line) { 1684 | return count; 1685 | } 1686 | while (start < end) { 1687 | mid = (start + end) / 2; 1688 | if (code_line < entries[mid].code_line) { 1689 | end = mid; 1690 | } else if (code_line > entries[mid].code_line) { 1691 | start = mid + 1; 1692 | } else { 1693 | return mid; 1694 | } 1695 | } 1696 | if (code_line <= entries[mid].code_line) { 1697 | return mid; 1698 | } else { 1699 | return mid + 1; 1700 | } 1701 | } 1702 | static PyCodeObject *__pyx_find_code_object(int code_line) { 1703 | PyCodeObject* code_object; 1704 | int pos; 1705 | if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { 1706 | return NULL; 1707 | } 1708 | pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); 1709 | if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { 1710 | return NULL; 1711 | } 1712 | code_object = __pyx_code_cache.entries[pos].code_object; 1713 | Py_INCREF(code_object); 1714 | return code_object; 1715 | } 1716 | static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { 1717 | int pos, i; 1718 | __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; 1719 | if (unlikely(!code_line)) { 1720 | return; 1721 | } 1722 | if (unlikely(!entries)) { 1723 | entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); 1724 | if (likely(entries)) { 1725 | __pyx_code_cache.entries = entries; 1726 | __pyx_code_cache.max_count = 64; 1727 | __pyx_code_cache.count = 1; 1728 | entries[0].code_line = code_line; 1729 | entries[0].code_object = code_object; 1730 | Py_INCREF(code_object); 1731 | } 1732 | return; 1733 | } 1734 | pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); 1735 | if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { 1736 | PyCodeObject* tmp = entries[pos].code_object; 1737 | entries[pos].code_object = code_object; 1738 | Py_DECREF(tmp); 1739 | return; 1740 | } 1741 | if (__pyx_code_cache.count == __pyx_code_cache.max_count) { 1742 | int new_max = __pyx_code_cache.max_count + 64; 1743 | entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( 1744 | __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry)); 1745 | if (unlikely(!entries)) { 1746 | return; 1747 | } 1748 | __pyx_code_cache.entries = entries; 1749 | __pyx_code_cache.max_count = new_max; 1750 | } 1751 | for (i=__pyx_code_cache.count; i>pos; i--) { 1752 | entries[i] = entries[i-1]; 1753 | } 1754 | entries[pos].code_line = code_line; 1755 | entries[pos].code_object = code_object; 1756 | __pyx_code_cache.count++; 1757 | Py_INCREF(code_object); 1758 | } 1759 | 1760 | #include "compile.h" 1761 | #include "frameobject.h" 1762 | #include "traceback.h" 1763 | static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( 1764 | const char *funcname, int c_line, 1765 | int py_line, const char *filename) { 1766 | PyCodeObject *py_code = 0; 1767 | PyObject *py_srcfile = 0; 1768 | PyObject *py_funcname = 0; 1769 | #if PY_MAJOR_VERSION < 3 1770 | py_srcfile = PyString_FromString(filename); 1771 | #else 1772 | py_srcfile = PyUnicode_FromString(filename); 1773 | #endif 1774 | if (!py_srcfile) goto bad; 1775 | if (c_line) { 1776 | #if PY_MAJOR_VERSION < 3 1777 | py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); 1778 | #else 1779 | py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); 1780 | #endif 1781 | } 1782 | else { 1783 | #if PY_MAJOR_VERSION < 3 1784 | py_funcname = PyString_FromString(funcname); 1785 | #else 1786 | py_funcname = PyUnicode_FromString(funcname); 1787 | #endif 1788 | } 1789 | if (!py_funcname) goto bad; 1790 | py_code = __Pyx_PyCode_New( 1791 | 0, 1792 | 0, 1793 | 0, 1794 | 0, 1795 | 0, 1796 | __pyx_empty_bytes, /*PyObject *code,*/ 1797 | __pyx_empty_tuple, /*PyObject *consts,*/ 1798 | __pyx_empty_tuple, /*PyObject *names,*/ 1799 | __pyx_empty_tuple, /*PyObject *varnames,*/ 1800 | __pyx_empty_tuple, /*PyObject *freevars,*/ 1801 | __pyx_empty_tuple, /*PyObject *cellvars,*/ 1802 | py_srcfile, /*PyObject *filename,*/ 1803 | py_funcname, /*PyObject *name,*/ 1804 | py_line, 1805 | __pyx_empty_bytes /*PyObject *lnotab*/ 1806 | ); 1807 | Py_DECREF(py_srcfile); 1808 | Py_DECREF(py_funcname); 1809 | return py_code; 1810 | bad: 1811 | Py_XDECREF(py_srcfile); 1812 | Py_XDECREF(py_funcname); 1813 | return NULL; 1814 | } 1815 | static void __Pyx_AddTraceback(const char *funcname, int c_line, 1816 | int py_line, const char *filename) { 1817 | PyCodeObject *py_code = 0; 1818 | PyFrameObject *py_frame = 0; 1819 | py_code = __pyx_find_code_object(c_line ? c_line : py_line); 1820 | if (!py_code) { 1821 | py_code = __Pyx_CreateCodeObjectForTraceback( 1822 | funcname, c_line, py_line, filename); 1823 | if (!py_code) goto bad; 1824 | __pyx_insert_code_object(c_line ? c_line : py_line, py_code); 1825 | } 1826 | py_frame = PyFrame_New( 1827 | PyThreadState_GET(), /*PyThreadState *tstate,*/ 1828 | py_code, /*PyCodeObject *code,*/ 1829 | __pyx_d, /*PyObject *globals,*/ 1830 | 0 /*PyObject *locals*/ 1831 | ); 1832 | if (!py_frame) goto bad; 1833 | py_frame->f_lineno = py_line; 1834 | PyTraceBack_Here(py_frame); 1835 | bad: 1836 | Py_XDECREF(py_code); 1837 | Py_XDECREF(py_frame); 1838 | } 1839 | 1840 | static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { 1841 | const long neg_one = (long) -1, const_zero = 0; 1842 | const int is_unsigned = neg_one > const_zero; 1843 | if (is_unsigned) { 1844 | if (sizeof(long) < sizeof(long)) { 1845 | return PyInt_FromLong((long) value); 1846 | } else if (sizeof(long) <= sizeof(unsigned long)) { 1847 | return PyLong_FromUnsignedLong((unsigned long) value); 1848 | } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { 1849 | return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); 1850 | } 1851 | } else { 1852 | if (sizeof(long) <= sizeof(long)) { 1853 | return PyInt_FromLong((long) value); 1854 | } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { 1855 | return PyLong_FromLongLong((PY_LONG_LONG) value); 1856 | } 1857 | } 1858 | { 1859 | int one = 1; int little = (int)*(unsigned char *)&one; 1860 | unsigned char *bytes = (unsigned char *)&value; 1861 | return _PyLong_FromByteArray(bytes, sizeof(long), 1862 | little, !is_unsigned); 1863 | } 1864 | } 1865 | 1866 | #define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value) \ 1867 | { \ 1868 | func_type value = func_value; \ 1869 | if (sizeof(target_type) < sizeof(func_type)) { \ 1870 | if (unlikely(value != (func_type) (target_type) value)) { \ 1871 | func_type zero = 0; \ 1872 | if (is_unsigned && unlikely(value < zero)) \ 1873 | goto raise_neg_overflow; \ 1874 | else \ 1875 | goto raise_overflow; \ 1876 | } \ 1877 | } \ 1878 | return (target_type) value; \ 1879 | } 1880 | 1881 | #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 1882 | #if CYTHON_USE_PYLONG_INTERNALS 1883 | #include "longintrepr.h" 1884 | #endif 1885 | #endif 1886 | 1887 | static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { 1888 | const long neg_one = (long) -1, const_zero = 0; 1889 | const int is_unsigned = neg_one > const_zero; 1890 | #if PY_MAJOR_VERSION < 3 1891 | if (likely(PyInt_Check(x))) { 1892 | if (sizeof(long) < sizeof(long)) { 1893 | __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) 1894 | } else { 1895 | long val = PyInt_AS_LONG(x); 1896 | if (is_unsigned && unlikely(val < 0)) { 1897 | goto raise_neg_overflow; 1898 | } 1899 | return (long) val; 1900 | } 1901 | } else 1902 | #endif 1903 | if (likely(PyLong_Check(x))) { 1904 | if (is_unsigned) { 1905 | #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 1906 | #if CYTHON_USE_PYLONG_INTERNALS 1907 | switch (Py_SIZE(x)) { 1908 | case 0: return 0; 1909 | case 1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]); 1910 | } 1911 | #endif 1912 | #endif 1913 | #if CYTHON_COMPILING_IN_CPYTHON 1914 | if (unlikely(Py_SIZE(x) < 0)) { 1915 | goto raise_neg_overflow; 1916 | } 1917 | #else 1918 | { 1919 | int result = PyObject_RichCompareBool(x, Py_False, Py_LT); 1920 | if (unlikely(result < 0)) 1921 | return (long) -1; 1922 | if (unlikely(result == 1)) 1923 | goto raise_neg_overflow; 1924 | } 1925 | #endif 1926 | if (sizeof(long) <= sizeof(unsigned long)) { 1927 | __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x)) 1928 | } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { 1929 | __PYX_VERIFY_RETURN_INT(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) 1930 | } 1931 | } else { 1932 | #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 1933 | #if CYTHON_USE_PYLONG_INTERNALS 1934 | switch (Py_SIZE(x)) { 1935 | case 0: return 0; 1936 | case 1: __PYX_VERIFY_RETURN_INT(long, digit, +(((PyLongObject*)x)->ob_digit[0])); 1937 | case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]); 1938 | } 1939 | #endif 1940 | #endif 1941 | if (sizeof(long) <= sizeof(long)) { 1942 | __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x)) 1943 | } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { 1944 | __PYX_VERIFY_RETURN_INT(long, PY_LONG_LONG, PyLong_AsLongLong(x)) 1945 | } 1946 | } 1947 | { 1948 | #if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) 1949 | PyErr_SetString(PyExc_RuntimeError, 1950 | "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); 1951 | #else 1952 | long val; 1953 | PyObject *v = __Pyx_PyNumber_Int(x); 1954 | #if PY_MAJOR_VERSION < 3 1955 | if (likely(v) && !PyLong_Check(v)) { 1956 | PyObject *tmp = v; 1957 | v = PyNumber_Long(tmp); 1958 | Py_DECREF(tmp); 1959 | } 1960 | #endif 1961 | if (likely(v)) { 1962 | int one = 1; int is_little = (int)*(unsigned char *)&one; 1963 | unsigned char *bytes = (unsigned char *)&val; 1964 | int ret = _PyLong_AsByteArray((PyLongObject *)v, 1965 | bytes, sizeof(val), 1966 | is_little, !is_unsigned); 1967 | Py_DECREF(v); 1968 | if (likely(!ret)) 1969 | return val; 1970 | } 1971 | #endif 1972 | return (long) -1; 1973 | } 1974 | } else { 1975 | long val; 1976 | PyObject *tmp = __Pyx_PyNumber_Int(x); 1977 | if (!tmp) return (long) -1; 1978 | val = __Pyx_PyInt_As_long(tmp); 1979 | Py_DECREF(tmp); 1980 | return val; 1981 | } 1982 | raise_overflow: 1983 | PyErr_SetString(PyExc_OverflowError, 1984 | "value too large to convert to long"); 1985 | return (long) -1; 1986 | raise_neg_overflow: 1987 | PyErr_SetString(PyExc_OverflowError, 1988 | "can't convert negative value to long"); 1989 | return (long) -1; 1990 | } 1991 | 1992 | static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { 1993 | const int neg_one = (int) -1, const_zero = 0; 1994 | const int is_unsigned = neg_one > const_zero; 1995 | #if PY_MAJOR_VERSION < 3 1996 | if (likely(PyInt_Check(x))) { 1997 | if (sizeof(int) < sizeof(long)) { 1998 | __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) 1999 | } else { 2000 | long val = PyInt_AS_LONG(x); 2001 | if (is_unsigned && unlikely(val < 0)) { 2002 | goto raise_neg_overflow; 2003 | } 2004 | return (int) val; 2005 | } 2006 | } else 2007 | #endif 2008 | if (likely(PyLong_Check(x))) { 2009 | if (is_unsigned) { 2010 | #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 2011 | #if CYTHON_USE_PYLONG_INTERNALS 2012 | switch (Py_SIZE(x)) { 2013 | case 0: return 0; 2014 | case 1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]); 2015 | } 2016 | #endif 2017 | #endif 2018 | #if CYTHON_COMPILING_IN_CPYTHON 2019 | if (unlikely(Py_SIZE(x) < 0)) { 2020 | goto raise_neg_overflow; 2021 | } 2022 | #else 2023 | { 2024 | int result = PyObject_RichCompareBool(x, Py_False, Py_LT); 2025 | if (unlikely(result < 0)) 2026 | return (int) -1; 2027 | if (unlikely(result == 1)) 2028 | goto raise_neg_overflow; 2029 | } 2030 | #endif 2031 | if (sizeof(int) <= sizeof(unsigned long)) { 2032 | __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x)) 2033 | } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { 2034 | __PYX_VERIFY_RETURN_INT(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) 2035 | } 2036 | } else { 2037 | #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 2038 | #if CYTHON_USE_PYLONG_INTERNALS 2039 | switch (Py_SIZE(x)) { 2040 | case 0: return 0; 2041 | case 1: __PYX_VERIFY_RETURN_INT(int, digit, +(((PyLongObject*)x)->ob_digit[0])); 2042 | case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]); 2043 | } 2044 | #endif 2045 | #endif 2046 | if (sizeof(int) <= sizeof(long)) { 2047 | __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x)) 2048 | } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { 2049 | __PYX_VERIFY_RETURN_INT(int, PY_LONG_LONG, PyLong_AsLongLong(x)) 2050 | } 2051 | } 2052 | { 2053 | #if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) 2054 | PyErr_SetString(PyExc_RuntimeError, 2055 | "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); 2056 | #else 2057 | int val; 2058 | PyObject *v = __Pyx_PyNumber_Int(x); 2059 | #if PY_MAJOR_VERSION < 3 2060 | if (likely(v) && !PyLong_Check(v)) { 2061 | PyObject *tmp = v; 2062 | v = PyNumber_Long(tmp); 2063 | Py_DECREF(tmp); 2064 | } 2065 | #endif 2066 | if (likely(v)) { 2067 | int one = 1; int is_little = (int)*(unsigned char *)&one; 2068 | unsigned char *bytes = (unsigned char *)&val; 2069 | int ret = _PyLong_AsByteArray((PyLongObject *)v, 2070 | bytes, sizeof(val), 2071 | is_little, !is_unsigned); 2072 | Py_DECREF(v); 2073 | if (likely(!ret)) 2074 | return val; 2075 | } 2076 | #endif 2077 | return (int) -1; 2078 | } 2079 | } else { 2080 | int val; 2081 | PyObject *tmp = __Pyx_PyNumber_Int(x); 2082 | if (!tmp) return (int) -1; 2083 | val = __Pyx_PyInt_As_int(tmp); 2084 | Py_DECREF(tmp); 2085 | return val; 2086 | } 2087 | raise_overflow: 2088 | PyErr_SetString(PyExc_OverflowError, 2089 | "value too large to convert to int"); 2090 | return (int) -1; 2091 | raise_neg_overflow: 2092 | PyErr_SetString(PyExc_OverflowError, 2093 | "can't convert negative value to int"); 2094 | return (int) -1; 2095 | } 2096 | 2097 | static int __Pyx_check_binary_version(void) { 2098 | char ctversion[4], rtversion[4]; 2099 | PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); 2100 | PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion()); 2101 | if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) { 2102 | char message[200]; 2103 | PyOS_snprintf(message, sizeof(message), 2104 | "compiletime version %s of module '%.100s' " 2105 | "does not match runtime version %s", 2106 | ctversion, __Pyx_MODULE_NAME, rtversion); 2107 | return PyErr_WarnEx(NULL, message, 1); 2108 | } 2109 | return 0; 2110 | } 2111 | 2112 | static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { 2113 | while (t->p) { 2114 | #if PY_MAJOR_VERSION < 3 2115 | if (t->is_unicode) { 2116 | *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); 2117 | } else if (t->intern) { 2118 | *t->p = PyString_InternFromString(t->s); 2119 | } else { 2120 | *t->p = PyString_FromStringAndSize(t->s, t->n - 1); 2121 | } 2122 | #else 2123 | if (t->is_unicode | t->is_str) { 2124 | if (t->intern) { 2125 | *t->p = PyUnicode_InternFromString(t->s); 2126 | } else if (t->encoding) { 2127 | *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); 2128 | } else { 2129 | *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); 2130 | } 2131 | } else { 2132 | *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); 2133 | } 2134 | #endif 2135 | if (!*t->p) 2136 | return -1; 2137 | ++t; 2138 | } 2139 | return 0; 2140 | } 2141 | 2142 | static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { 2143 | return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); 2144 | } 2145 | static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) { 2146 | Py_ssize_t ignore; 2147 | return __Pyx_PyObject_AsStringAndSize(o, &ignore); 2148 | } 2149 | static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { 2150 | #if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 2151 | if ( 2152 | #if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 2153 | __Pyx_sys_getdefaultencoding_not_ascii && 2154 | #endif 2155 | PyUnicode_Check(o)) { 2156 | #if PY_VERSION_HEX < 0x03030000 2157 | char* defenc_c; 2158 | PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); 2159 | if (!defenc) return NULL; 2160 | defenc_c = PyBytes_AS_STRING(defenc); 2161 | #if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 2162 | { 2163 | char* end = defenc_c + PyBytes_GET_SIZE(defenc); 2164 | char* c; 2165 | for (c = defenc_c; c < end; c++) { 2166 | if ((unsigned char) (*c) >= 128) { 2167 | PyUnicode_AsASCIIString(o); 2168 | return NULL; 2169 | } 2170 | } 2171 | } 2172 | #endif 2173 | *length = PyBytes_GET_SIZE(defenc); 2174 | return defenc_c; 2175 | #else 2176 | if (__Pyx_PyUnicode_READY(o) == -1) return NULL; 2177 | #if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 2178 | if (PyUnicode_IS_ASCII(o)) { 2179 | *length = PyUnicode_GET_LENGTH(o); 2180 | return PyUnicode_AsUTF8(o); 2181 | } else { 2182 | PyUnicode_AsASCIIString(o); 2183 | return NULL; 2184 | } 2185 | #else 2186 | return PyUnicode_AsUTF8AndSize(o, length); 2187 | #endif 2188 | #endif 2189 | } else 2190 | #endif 2191 | #if !CYTHON_COMPILING_IN_PYPY 2192 | if (PyByteArray_Check(o)) { 2193 | *length = PyByteArray_GET_SIZE(o); 2194 | return PyByteArray_AS_STRING(o); 2195 | } else 2196 | #endif 2197 | { 2198 | char* result; 2199 | int r = PyBytes_AsStringAndSize(o, &result, length); 2200 | if (unlikely(r < 0)) { 2201 | return NULL; 2202 | } else { 2203 | return result; 2204 | } 2205 | } 2206 | } 2207 | static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { 2208 | int is_true = x == Py_True; 2209 | if (is_true | (x == Py_False) | (x == Py_None)) return is_true; 2210 | else return PyObject_IsTrue(x); 2211 | } 2212 | static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) { 2213 | PyNumberMethods *m; 2214 | const char *name = NULL; 2215 | PyObject *res = NULL; 2216 | #if PY_MAJOR_VERSION < 3 2217 | if (PyInt_Check(x) || PyLong_Check(x)) 2218 | #else 2219 | if (PyLong_Check(x)) 2220 | #endif 2221 | return Py_INCREF(x), x; 2222 | m = Py_TYPE(x)->tp_as_number; 2223 | #if PY_MAJOR_VERSION < 3 2224 | if (m && m->nb_int) { 2225 | name = "int"; 2226 | res = PyNumber_Int(x); 2227 | } 2228 | else if (m && m->nb_long) { 2229 | name = "long"; 2230 | res = PyNumber_Long(x); 2231 | } 2232 | #else 2233 | if (m && m->nb_int) { 2234 | name = "int"; 2235 | res = PyNumber_Long(x); 2236 | } 2237 | #endif 2238 | if (res) { 2239 | #if PY_MAJOR_VERSION < 3 2240 | if (!PyInt_Check(res) && !PyLong_Check(res)) { 2241 | #else 2242 | if (!PyLong_Check(res)) { 2243 | #endif 2244 | PyErr_Format(PyExc_TypeError, 2245 | "__%.4s__ returned non-%.4s (type %.200s)", 2246 | name, name, Py_TYPE(res)->tp_name); 2247 | Py_DECREF(res); 2248 | return NULL; 2249 | } 2250 | } 2251 | else if (!PyErr_Occurred()) { 2252 | PyErr_SetString(PyExc_TypeError, 2253 | "an integer is required"); 2254 | } 2255 | return res; 2256 | } 2257 | static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { 2258 | Py_ssize_t ival; 2259 | PyObject *x; 2260 | #if PY_MAJOR_VERSION < 3 2261 | if (likely(PyInt_CheckExact(b))) 2262 | return PyInt_AS_LONG(b); 2263 | #endif 2264 | if (likely(PyLong_CheckExact(b))) { 2265 | #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 2266 | #if CYTHON_USE_PYLONG_INTERNALS 2267 | switch (Py_SIZE(b)) { 2268 | case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0]; 2269 | case 0: return 0; 2270 | case 1: return ((PyLongObject*)b)->ob_digit[0]; 2271 | } 2272 | #endif 2273 | #endif 2274 | return PyLong_AsSsize_t(b); 2275 | } 2276 | x = PyNumber_Index(b); 2277 | if (!x) return -1; 2278 | ival = PyInt_AsSsize_t(x); 2279 | Py_DECREF(x); 2280 | return ival; 2281 | } 2282 | static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { 2283 | return PyInt_FromSize_t(ival); 2284 | } 2285 | 2286 | 2287 | #endif /* Py_PYTHON_H */ 2288 | -------------------------------------------------------------------------------- /pytda/pytda_cython_tools.pyx: -------------------------------------------------------------------------------- 1 | cdef extern from "math.h": 2 | float cosf(float theta) 3 | float sinf(float theta) 4 | float atan2f(float y, float x) 5 | 6 | 7 | def atan2c_longitude(float azr, float gr, float klatr, float glatr): 8 | cdef float re = 6371.1 9 | return atan2f(sinf(azr)*sinf(gr/re)*cosf(klatr), 10 | cosf(gr/re)-sinf(klatr)*sinf(glatr)) 11 | 12 | 13 | def calc_turb_cython(float csnr, float cpr, float cswv, float czh, float crng, 14 | float eps, float num, float tot): 15 | cdef float csw 16 | csw = (csnr**0.6667) * cpr * cswv * czh * crng 17 | return num + csw * eps**2, tot + csw 18 | 19 | 20 | def calc_cswv_cython(float dummy): 21 | cdef float cswv 22 | cswv = 0.0 23 | if dummy >= 0 and dummy < 4: 24 | cswv = 1.0 25 | elif dummy >= 4 and dummy < 16: 26 | cswv = 1.0 - (1.0 / 12.0) * (dummy - 4.0) 27 | return cswv 28 | 29 | 30 | def atan2c(float y, float x): 31 | return atan2f(y, x) 32 | -------------------------------------------------------------------------------- /pytda/rsl_tools.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | """ 4 | Version 1.0 5 | Last Updated 12/09/2014 6 | 7 | """ 8 | 9 | 10 | def rsl_get_groundr_and_h(slant_r, elev): 11 | 12 | """ 13 | Author: Timothy Lang (timothy.j.lang@nasa.gov) 14 | Given slant range and elevation, return ground range and height. 15 | 16 | Inputs 17 | slant_r slant range (km) 18 | elev elevation (deg) 19 | 20 | Outputs 21 | gr ground range (km) 22 | h height above radar (km) 23 | 24 | This Python function is adapted from the Radar Software Library routine 25 | RSL_get_groundr_and_h, written by John Merritt and Dennis Flanigan 26 | 27 | """ 28 | 29 | Re = 4.0/3.0 * 6371.1 # Effective earth radius in km. 30 | h = np.sqrt(Re**2 + slant_r**2 - 2.0 * Re * slant_r * 31 | np.cos((elev + 90.0) * np.pi / 180.0)) 32 | gr = Re * np.arccos((Re**2 + h**2 - slant_r**2) / (2.0 * Re * h)) 33 | h = h - Re 34 | return gr, h 35 | 36 | ################################################### 37 | 38 | 39 | def rsl_get_slantr_and_elev(gr, h): 40 | 41 | """ 42 | Author: Timothy Lang (timothy.j.lang@nasa.gov) 43 | Given ground range and height, return slant range and elevation. 44 | 45 | Inputs 46 | gr ground range (km) 47 | h height (km) 48 | 49 | Outputs 50 | slantr slant range 51 | elev elevation in degrees 52 | 53 | This Python function is adapted from the Radar Software Library routine 54 | RSL_get_slantr_and_elev, written by John Merritt and Dennis Flanigan 55 | 56 | """ 57 | 58 | Re = 4.0/3.0 * 6371.1 # Effective earth radius in km. 59 | rh = h + Re 60 | slantrsq = Re**2 + rh**2 - (2 * Re * rh * np.cos(gr/Re)) 61 | slantr = np.sqrt(slantrsq) 62 | elev = np.arccos((Re**2 + slantrsq - rh**2)/(2 * Re * slantr)) 63 | elev = elev * 180.0/np.pi 64 | elev = elev - 90.0 65 | return slantr, elev 66 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | """ 2 | Python Turbulence Detection Algorithm (PyTDA) 3 | """ 4 | 5 | import os 6 | import sys 7 | import numpy 8 | from distutils.core import setup 9 | from setuptools import find_packages 10 | from distutils.sysconfig import get_python_lib 11 | from distutils.extension import Extension 12 | from Cython.Distutils import build_ext 13 | # from distutils.core import setup 14 | 15 | # - Pull the header into a variable 16 | doclines = __doc__.split("\n") 17 | 18 | VERSION = '1.1.1' 19 | 20 | # - Set variables for setup 21 | PACKAGES = ['pytda'] 22 | package_dir = {'': 'pytda'} 23 | 24 | USE_CYTHON = True # command line option, try-import, ... 25 | 26 | ext = '.pyx' if USE_CYTHON else '.c' 27 | 28 | extensions = [Extension(PACKAGES[0]+'.pytda_cython_tools', 29 | [PACKAGES[0]+'/pytda_cython_tools'+ext])] 30 | 31 | if USE_CYTHON: 32 | from Cython.Build import cythonize 33 | extensions = cythonize(extensions) 34 | 35 | setup( 36 | name='pytda', 37 | version=VERSION, 38 | url='http://github.com/nasa/PyTDA', 39 | author='Timothy Lang', 40 | author_email='timothy.j.lang@nasa.gov', 41 | description=doclines[0], 42 | packages=PACKAGES, 43 | classifiers=[""" 44 | Development Status :: Beta, 45 | Programming Language :: Python", 46 | Topic :: Scientific/Engineering 47 | Topic :: Scientific/Engineering :: Atmospheric Science 48 | Operating System :: Unix 49 | Operating System :: POSIX :: Linux 50 | Operating System :: MacOS 51 | """], 52 | long_description="""Python Turbulence Detection Algorithm (PyTDA)""", 53 | ext_modules=extensions, 54 | include_dirs = [numpy.get_include(), '.'] 55 | ) 56 | --------------------------------------------------------------------------------