├── .gitignore ├── AUTHORS.md ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── LICENSE.md ├── README.md ├── docs ├── .buildinfo ├── .nojekyll ├── _sources │ ├── archive.rst.txt │ ├── archive.txt │ ├── calibrator.rst.txt │ ├── calibrator.txt │ ├── citations.rst.txt │ ├── dmx.rst.txt │ ├── dmx.txt │ ├── dynamicspectrum.rst.txt │ ├── dynamicspectrum.txt │ ├── examples.rst.txt │ ├── examples.txt │ ├── index.rst.txt │ ├── index.txt │ ├── license.rst.txt │ ├── license.txt │ ├── par.rst.txt │ ├── par.txt │ ├── rfimitigator.rst.txt │ ├── rfimitigator.txt │ ├── scripts.rst.txt │ ├── scripts.txt │ ├── singlepulse.rst.txt │ ├── singlepulse.txt │ ├── tim.rst.txt │ ├── tim.txt │ ├── utils.rst.txt │ └── utils.txt ├── _static │ ├── ajax-loader.gif │ ├── alabaster.css │ ├── basic.css │ ├── classic.css │ ├── comment-bright.png │ ├── comment-close.png │ ├── comment.png │ ├── contents.png │ ├── custom.css │ ├── doctools.js │ ├── documentation_options.js │ ├── down-pressed.png │ ├── down.png │ ├── file.png │ ├── jquery-3.5.1.js │ ├── jquery.js │ ├── language_data.js │ ├── minus.png │ ├── navigation.png │ ├── plus.png │ ├── pygments.css │ ├── searchtools.js │ ├── sidebar.js │ ├── sphinxdoc.css │ ├── underscore-1.12.0.js │ ├── underscore-1.3.1.js │ ├── underscore.js │ ├── up-pressed.png │ ├── up.png │ └── websupport.js ├── archive.html ├── calibrator.html ├── citations.html ├── dmx.html ├── dynamicspectrum.html ├── examples.html ├── genindex.html ├── index.html ├── license.html ├── objects.inv ├── par.html ├── rfimitigator.html ├── scripts.html ├── search.html ├── searchindex.js ├── singlepulse.html ├── tim.html └── utils.html ├── pypulse ├── __init__.py ├── archive.py ├── calibrator.py ├── config │ └── fluxcal.cfg ├── demo │ └── archive_demo.ipynb ├── dmx.py ├── dynamicspectrum.py ├── functionfit.py ├── par.py ├── rfimitigator.py ├── scripts │ ├── __init__.py │ ├── fits_to_npy │ ├── fitsheader_to_txt │ ├── partytricks │ └── pypav ├── singlepulse.py ├── tim.py └── utils.py ├── requirements.txt ├── setup.cfg ├── setup.py └── tests ├── data ├── J1909-3744_NANOGrav_11yv1.gls.par └── J1909-3744_NANOGrav_11yv1.tim ├── test_par.py └── test_tim.py /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.pyc -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | Development Leads 2 | ================= 3 | 4 | * Michael Lam https://github.com/mtlam 5 | 6 | Contributors 7 | ============ 8 | 9 | * Paul Baker 10 | * Shami Chatterjee 11 | * James Cordes 12 | * Steve Hawkins 13 | * Jeffrey Hazboun 14 | * Ross Jennings 15 | * Glenn Jones 16 | * Lina Levin 17 | 18 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [Unreleased] 9 | 10 | ### Changed 11 | 12 | - Allow parsing of par file values in "NAME VALUE ERROR" format rather than "NAME VALUE FIT" format for some fold ephemerides inside the PSRFITS files. 13 | - Default behavior of `Archive`'s `fitPulses()` now returns all values from `SinglePulse`'s `fitPulse()` command. Users can still supply specific indices with the `num` argument to `fitPulses()` 14 | - Filled out more of `Calibrator`'s `pacv()` plot with correct labeling and sizing. 15 | - Removed numpy warnings from `NaN`s in data array combination 16 | - Removed unnecessary reference to `scipy.fftpack`, which is in legacy. 17 | - Default behavior of `DynamicSpectrum`'s `getData()` now has `remove_baseline=False` and the internal data array is returned as is. 18 | - Improved error handling on loading a PSRFITS file. PyPulse first checks to see if the file exists, then if it fails in `pyfits.open()`, raises an exception noting the problem lies internally there. 19 | - `pypav` script allows for centering of the pulse in the format of `pav` with the `-C` flag. 20 | - `SinglePulse`'s `Uscale()` now normalizes the pulse by default, as per the definition. 21 | 22 | ### Added 23 | 24 | - In `Archive`'s `imshow()`, the y-axis can now be flipped with the `flip=True` argument. This allows inverted frequency axes to be turned right-side up. A `title` argument can now be supplied as well. 25 | - `Archive`'s `plot()` now takes arguments of `subint`, `pol`, and `chan` to specifically select individual profile rather than requiring the data be 1D. By default, these arguments are `0`. 26 | - `SinglePulse.getOffpulseRMS()` convenience function added, which calls `SinglePulse.getOffpulseNoise()` 27 | - Individual phase plot implemented in Calibrator class as `phaseplot()`. This can also be called with `plot(mode="phase")`. 28 | - `SinglePulse.component_fitting()` now offers the ability to output to PSRCHIVE's paas text file format for von Mises components. 29 | - In `DynamicSpectrum`'s `remove_baseline()` command, two flags have been added. By default, `ignorezapped=True` and so data with a value of `zapvalue` are ignored. Such dynamic spectra can result from the less-robust generation methods, i.e., not specifying a template shape, thus resulting in a spike of 0.0 values for zapped data. This should be overhauled in the future. 30 | - Allow `DynamicSpectrum`'s `imshow()` to take `**kwargs` now. 31 | - `Par`'s `getPM()` function (also used to get the transverse velocity) parses `PMELONG` and `PMELAT`. 32 | - Added a `nonnegative=True` flag to `Archive`'s `getDynamicSpectrum()`. By default, if provided a template shape to match against the data, this will enforce non-negative (flux) dynamic spectrum values 33 | - `DynamicSpectrum`'s `imshow()` now allows a `cbarlabel` argument to provide a basic label to the colorbar, and a `badcolor` argument as an additional method to recolor instead of only `alpha`. 34 | - `Par` can now return an SWX model timeseries with `getSWX()`. 35 | 36 | 37 | ### Fixed 38 | 39 | - The `DMX` class now correctly parses PINT-style `.dmx` files with no `F1` or `F2` columns. 40 | - `Archive.bscrunch()`'s `nbins` argument now works. 41 | 42 | ## [0.1.1] - 2021-06-15 43 | 44 | ### Added 45 | 46 | - Fitting errors on the 1D scintillation parameters are now added. This changes the underlying `functionfit` output but this is not part of the public API. 47 | 48 | ### Changed 49 | 50 | - Converted multiple internal `map` calls to list comprehensions. 51 | - `DynamicSpectrum` now copies colormaps with `copy.copy` to remove `MatplotlibDeprecationWarning` 52 | - Fixed scrunching and waterfall plot limits due to updates in numpy in the handling of NaNs. In waterfall plot, duplicate calls to set axis limits have been removed. 53 | - Fixed pointers to `np.str` to `np.str_` due to updates in numpy. 54 | 55 | ## [0.1.0] - 2021-05-03 56 | 57 | ### Added 58 | 59 | - Added CHANGELOG.md following [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). 60 | 61 | ### Changed 62 | 63 | - Start following [SemVer](https://semver.org) properly. 64 | 65 | 66 | 67 | [unreleased]: https://github.com/mtlam/pypulse/compare/v0.1.1...HEAD 68 | [0.1.1]: https://github.com/mtlam/pypulse/compare/v0.1.0...v0.1.1 69 | [0.1.0]: https://github.com/mtlam/pypulse/compare/v0.0.1...v0.1.0 70 | [0.0.1]: https://github.com/mtlam/pypulse/releases/tag/v0.0.1 71 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributor Covenant Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. 7 | 8 | We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. 9 | 10 | ## Our Standards 11 | 12 | Examples of behavior that contributes to a positive environment for our community include: 13 | 14 | * Demonstrating empathy and kindness toward other people 15 | * Being respectful of differing opinions, viewpoints, and experiences 16 | * Giving and gracefully accepting constructive feedback 17 | * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience 18 | * Focusing on what is best not just for us as individuals, but for the overall community 19 | 20 | Examples of unacceptable behavior include: 21 | 22 | * The use of sexualized language or imagery, and sexual attention or advances of any kind 23 | * Trolling, insulting or derogatory comments, and personal or political attacks 24 | * Public or private harassment 25 | * Publishing others' private information, such as a physical or email address, without their explicit permission 26 | * Other conduct which could reasonably be considered inappropriate in a professional setting 27 | 28 | ## Our Responsibilities 29 | 30 | Project maintainers are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. 31 | 32 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. 33 | 34 | ## Scope 35 | 36 | This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 37 | 38 | ## Enforcement 39 | 40 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at **michael . lam at nanograv . org** All complaints will be reviewed and investigated promptly and fairly. 41 | 42 | All project maintainers are obligated to respect the privacy and security of the reporter of any incident. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 43 | 44 | ## Attribution 45 | 46 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html, with some language modifications from version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct/ 47 | 48 | Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). 49 | 50 | [homepage]: https://www.contributor-covenant.org 51 | 52 | For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations. 53 | 54 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | LICENSE 2 | ------- 3 | 4 | Copyright (c) 2015-2020, Michael T. Lam 5 | 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 13 | 14 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PyPulse 2 | ======= 3 | 4 | [![License](https://img.shields.io/badge/license-3--clause_BSD-blue.svg)](LICENSE) 5 | [![Code of Conduct](https://img.shields.io/badge/code_of_conduct-Contributor_Covenant-blue.svg)](CODE_OF_CONDUCT.md) 6 | [![ASCL](https://img.shields.io/badge/ascl-1706.011-blue.svg?colorB=262255)](https://ascl.net/1706.011) 7 | 8 | A pure-Python package for handling and analyzing PSRFITS files. 9 | 10 | Read the documentation [here](https://mtlam.github.io/PyPulse/). 11 | 12 | This is an alternate code base from [PSRCHIVE](http://psrchive.sourceforge.net/). 13 | 14 | Requires:
15 | python 2.7 or 3.X
16 | numpy
17 | scipy
18 | matplotlib
19 | astropy 20 | 21 | 22 | Archive 23 | ------- 24 | 25 | A class for loading PSRFITS files 26 | 27 | Usage: 28 | 29 | ar = Archive(FILENAME) #loads archive, dedispersed and polarization averaged by default 30 | ar.tscrunch() #averages the pulse in time 31 | data = ar.getData() #returns the numpy data array for use by you 32 | ar.imshow() #plots frequency vs phase for the pulses 33 | 34 | 35 | SinglePulse 36 | ----------- 37 | 38 | A class for handling calculations on single pulses 39 | 40 | Usage: 41 | 42 | sp = SinglePulse(data,windowsize=256) #will auto-calculate an offpulse region of length 256 bins 43 | print sp.getFWHM() #prints the FWHM of the pulse 44 | print sp.getSN() #prints a crude S/N of the pulse 45 | print sp.fitPulse(template_array)[5] #prints a better S/N of the pulse using a template array 46 | 47 | DynamicSpectrum 48 | --------------- 49 | 50 | A class for handling dynamic spectra 51 | 52 | 53 | Usage: 54 | 55 | ds = DynamicSpectrum(FILENAME) #takes a 2D data array or a string to a .npz file for now 56 | acf2d = ds.acf2d() #calculates the 2D ACF of the dynamic spectrum 57 | ds.imshow() #plots the dynamic spectrum 58 | ds.save(NEWFILENAME) #saves to a .npz file, which can then be loaded again with the first line 59 | 60 | Par 61 | --- 62 | 63 | A class for parsing pulsar parameter files 64 | 65 | Usage: 66 | 67 | p = Par(FILENAME) 68 | print p.getPeriod() #prints the period in the par file (does not calculate for a specific MJD for now) 69 | t,dmx,dmxerr = p.getDMseries() #returns the DM parameters in a nice time-series. Note that errors are those given in the par file, which may not be the "correct" ones (more info to be provided later) 70 | print p.get("PX") #prints the parallax 71 | print p.get("PX",error=True) #prints the error on the parallax 72 | 73 | 74 | Tim 75 | --- 76 | 77 | A class for parsing pulsar TOA files 78 | 79 | Usage: 80 | 81 | t = Tim(FILENAME) #automatically parses each TOA with the TOA() class 82 | print t.toas[0].getMJD() #prints the MJD of the first TOA as a python Decimal 83 | print t.toas[0].get('snr') #prints the value of the -snr flag of the TOA if it is available 84 | 85 | 86 | Citations 87 | --------- 88 | 89 | See [http://ascl.net/1706.011](http://ascl.net/1706.011). You can cite as: 90 | 91 | [Lam, M. T., 2017, PyPulse, Astrophysics Source Code Library, record ascl:1706.011](http://adsabs.harvard.edu/abs/2017ascl.soft06011L) -------------------------------------------------------------------------------- /docs/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: 6892781a471a0293e981966297aa5529 4 | tags: 645f666f9bcd5a90fca523b33c5a78b7 5 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtlam/PyPulse/db9a4c2afbb03f1abb5a8c47aa9f1b28a685170f/docs/.nojekyll -------------------------------------------------------------------------------- /docs/_sources/calibrator.rst.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | 11 | 12 | Calibrator Class 13 | ================ 14 | 15 | The *Calibrator* class handles flux and polarization calibration of profile data. 16 | 17 | .. warning:: This class is under construction. 18 | 19 | .. py:class:: Calibrator(freqs, S[, Serr=None, pol_type='Coherence', fd_poln='LIN', Funit=None, Sunit=None, verbose=True, **kwargs]) 20 | 21 | :param list/numpy.ndarray freqs: Frequency array 22 | :param list/numpy.ndarray S: Array of polarization data, a 4xN shaped array 23 | :param list/numpy.ndarray Serr: Optional errors on the polarization data 24 | :param str pol_type: Form of polarization data: "Coherence" or "Stokes" 25 | :param str fd_poln: Feed design polarization: "LIN" for linear or "CIRC" for circular 26 | :param str Funit: Unit for frequencies 27 | :param str Sunit: Unit for polarization data 28 | :param bool verbose: Set `True` for verbose printing 29 | 30 | 31 | 32 | 33 | Methods 34 | ------- 35 | 36 | .. py:function:: pacv([filename=None]) 37 | 38 | Emulates PSRCHIVE's pacv . 39 | 40 | :param str filename: Filename to save image to. 41 | 42 | .. py:function:: pacv_csu([filename=None]) 43 | 44 | Emulates PSRCHIVE's pacv -n csu . 45 | 46 | :param str filename: Filename to save image to. 47 | 48 | .. py:function:: plot([mode="I", ax=None, show=True, filename=None]) 49 | 50 | Basic plotter 51 | 52 | :param str mode: Polarization parameter or parameters to plot. Options include "I", "Q", "U", and "V" for the various Stokes parameters, and "A" and "B" for the feed polarizations. Can contain multiple of these modes to plot simultaneously. 53 | :param matplotlib.axes._subplots.AxesSubplot ax: matplotlib Axes to draw on 54 | :param bool show: If True, show the figure 55 | :param str filename: Filename to save image to. 56 | :return: ax, matplotlib.axes._subplots.AxesSubplot 57 | 58 | .. py:function:: applyFluxcal(fluxcalonar[, fluxcaloffar=None]) 59 | 60 | 61 | .. py:function:: applyCalibration(ar) 62 | 63 | :param Archive ar: Archive to apply calibration to 64 | 65 | .. py:function:: buildMuellerMatrixPA(PA) 66 | 67 | Build the parallactic angle Mueller matrix 68 | 69 | :param float PA: Parallactic angle 70 | 71 | .. py:function:: buildMuellerMatrixDifferential(differential) 72 | 73 | Build the differential gain Mueller matrix. 74 | 75 | :param list/tuple/numpy.ndarray differential: The input is a two-element list/array that gives :math:`\Delta G` and :math:`\Delta \psi`, the differential gain and phase. 76 | 77 | .. py:function:: convertPolarization(S, intype, outtype[, linear=True]) 78 | 79 | Convenience function to convert a polarization vector between Stokes and Coherence mode 80 | 81 | :param array S: Polarization vector 82 | :param str intype: Input vector type, "Coherence"/"AABBCRCI" or "Stokes"/"IQUV" 83 | :param str outtype: Output vector type. For now, since only two modes are implemented, this is redundant. 84 | :param bool linear: Linear versus circular input polarization 85 | 86 | .. py:function:: buildMuellerMatrix([PA=None, feed=None, CC=None, differential=None]) 87 | 88 | Cross coupling (CC) is not implemented 89 | 90 | :param float PA: parallactic angle 91 | :param float feed: feed type 92 | :param float differential: 93 | 94 | 95 | 96 | .. py:function:: calculatePA(lat, dec, HA) 97 | 98 | Helper function to calculate the parallactic angle 99 | 100 | :param float lat: latitude of source 101 | :param float dec: declination of source 102 | :param float HA: hour angle 103 | 104 | .. py:function:: getI() 105 | 106 | :return: Stokes I 107 | 108 | .. py:function:: getQ() 109 | 110 | :return: Stokes Q 111 | 112 | .. py:function:: getU() 113 | 114 | :return: Stokes U 115 | 116 | .. py:function:: getV() 117 | 118 | :return: Stokes V 119 | 120 | .. py:function:: getA() 121 | 122 | :return: A polarization 123 | 124 | .. py:function:: getB() 125 | 126 | :return: B polarization 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /docs/_sources/calibrator.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | 11 | 12 | Calibrator Class 13 | ================ 14 | 15 | The *Calibrator* class handles flux and polarization calibration of profile data. 16 | 17 | .. warning:: This class is under heavy construction. 18 | 19 | .. py:class:: Calibrator(freqs,S[,Serr=None,pol_type='Coherence',fd_poln='LIN',verbose=True]) 20 | 21 | Methods 22 | ------- 23 | 24 | .. py:function:: pacv() 25 | 26 | Emulates PSRCHIVE's pacv . 27 | 28 | .. py:function:: pacv_csu() 29 | 30 | Emulates PSRCHIVE's pacv -n csu . 31 | 32 | .. py:function:: apply_calibration() 33 | 34 | .. py:function:: build_mueller_matrix_PA() 35 | 36 | .. py:function:: build_mueller_matrix_differential() 37 | 38 | .. py:function:: convert_polarization() 39 | 40 | .. py:function:: build_mueller_matrix() 41 | 42 | .. py:function:: calculate_PA() 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /docs/_sources/citations.rst.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | Citations & References 11 | ====================== 12 | 13 | **PyPulse** is listed on the `ASCL `_ (see also `ADS `_). It can be cited with the following BibTeX entry: 14 | 15 | .. code-block:: bibtex 16 | 17 | @MISC{2017ascl.soft06011L, 18 | author = {{Lam}, M.~T.}, 19 | title = "{PyPulse: PSRFITS handler}", 20 | keywords = {Software}, 21 | year = 2017, 22 | month = jun, 23 | eid = {ascl:1706.011}, 24 | pages = {ascl:1706.011}, 25 | archivePrefix = {ascl}, 26 | eprint = {1706.011}, 27 | adsurl = {https://ui.adsabs.harvard.edu/abs/2017ascl.soft06011L}, 28 | adsnote = {Provided by the SAO/NASA Astrophysics Data System} 29 | } 30 | 31 | or in AASTeX format: 32 | 33 | .. code-block:: RST 34 | 35 | \bibitem[Lam(2017)]{2017ascl.soft06011L} Lam, M.~T.\ 2017, Astrophysics Source Code Library 36 | 37 | **PyPulse** uses the following software packages 38 | 39 | + `Astropy` https://github.com/astropy/astropy [@astropy1] [@astropy2] 40 | + `matplotlib` https://github.com/matplotlib/matplotlib [@matplotlib] 41 | + `NumPy` https://github.com/numpy/numpy [@numpy] 42 | + `Python` https://www.python.org/ [@python] 43 | + `Scipy` https://github.com/scipy/scipy [@scipy] 44 | 45 | The BibTeX entries are as follows: 46 | 47 | .. code-block:: BibTeX 48 | 49 | @article{astropy1, 50 | Adsnote = {Provided by the SAO/NASA Astrophysics Data System}, 51 | Adsurl = {http://adsabs.harvard.edu/abs/2013A%26A...558A..33A}, 52 | Archiveprefix = {arXiv}, 53 | Author = {{Astropy Collaboration} and {Robitaille}, T.~P. and {Tollerud}, E.~J. and {Greenfield}, P. and {Droettboom}, M. and {Bray}, E. and {Aldcroft}, T. and {Davis}, M. and {Ginsburg}, A. and {Price-Whelan}, A.~M. and {Kerzendorf}, W.~E. and {Conley}, A. and {Crighton}, N. and {Barbary}, K. and {Muna}, D. and {Ferguson}, H. and {Grollier}, F. and {Parikh}, M.~M. and {Nair}, P.~H. and {Unther}, H.~M. and {Deil}, C. and {Woillez}, J. and {Conseil}, S. and {Kramer}, R. and {Turner}, J.~E.~H. and {Singer}, L. and {Fox}, R. and {Weaver}, B.~A. and {Zabalza}, V. and {Edwards}, Z.~I. and {Azalee Bostroem}, K. and {Burke}, D.~J. and {Casey}, A.~R. and {Crawford}, S.~M. and {Dencheva}, N. and {Ely}, J. and {Jenness}, T. and {Labrie}, K. and {Lim}, P.~L. and {Pierfederici}, F. and {Pontzen}, A. and {Ptak}, A. and {Refsdal}, B. and {Servillat}, M. and {Streicher}, O.}, 54 | Doi = {10.1051/0004-6361/201322068}, 55 | Eid = {A33}, 56 | Eprint = {1307.6212}, 57 | Journal = {\aap}, 58 | Keywords = {methods: data analysis, methods: miscellaneous, virtual observatory tools}, 59 | Month = oct, 60 | Pages = {A33}, 61 | Primaryclass = {astro-ph.IM}, 62 | Title = {{Astropy: A community Python package for astronomy}}, 63 | Volume = 558, 64 | Year = 2013, 65 | Bdsk-Url-1 = {https://dx.doi.org/10.1051/0004-6361/201322068}} 66 | @article{astropy2, 67 | Adsnote = {Provided by the SAO/NASA Astrophysics Data System}, 68 | Adsurl = {https://ui.adsabs.harvard.edu/#abs/2018AJ....156..123T}, 69 | Author = {{Price-Whelan}, A.~M. and {Sip{\H{o}}cz}, B.~M. and {G{\"u}nther}, H.~M. and {Lim}, P.~L. and {Crawford}, S.~M. and {Conseil}, S. and {Shupe}, D.~L. and {Craig}, M.~W. and {Dencheva}, N. and {Ginsburg}, A. and {VanderPlas}, J.~T. and {Bradley}, L.~D. and {P{\'e}rez-Su{\'a}rez}, D. and {de Val-Borro}, M. and {Paper Contributors}, (Primary and {Aldcroft}, T.~L. and {Cruz}, K.~L. and {Robitaille}, T.~P. and {Tollerud}, E.~J. and {Coordination Committee}, (Astropy and {Ardelean}, C. and {Babej}, T. and {Bach}, Y.~P. and {Bachetti}, M. and {Bakanov}, A.~V. and {Bamford}, S.~P. and {Barentsen}, G. and {Barmby}, P. and {Baumbach}, A. and {Berry}, K.~L. and {Biscani}, F. and {Boquien}, M. and {Bostroem}, K.~A. and {Bouma}, L.~G. and {Brammer}, G.~B. and {Bray}, E.~M. and {Breytenbach}, H. and {Buddelmeijer}, H. and {Burke}, D.~J. and {Calderone}, G. and {Cano Rodr{\'\i}guez}, J.~L. and {Cara}, M. and {Cardoso}, J.~V.~M. and {Cheedella}, S. and {Copin}, Y. and {Corrales}, L. and {Crichton}, D. and {D{\textquoteright}Avella}, D. and {Deil}, C. and {Depagne}, {\'E}. and {Dietrich}, J.~P. and {Donath}, A. and {Droettboom}, M. and {Earl}, N. and {Erben}, T. and {Fabbro}, S. and {Ferreira}, L.~A. and {Finethy}, T. and {Fox}, R.~T. and {Garrison}, L.~H. and {Gibbons}, S.~L.~J. and {Goldstein}, D.~A. and {Gommers}, R. and {Greco}, J.~P. and {Greenfield}, P. and {Groener}, A.~M. and {Grollier}, F. and {Hagen}, A. and {Hirst}, P. and {Homeier}, D. and {Horton}, A.~J. and {Hosseinzadeh}, G. and {Hu}, L. and {Hunkeler}, J.~S. and {Ivezi{\'c}}, {\v{Z}}. and {Jain}, A. and {Jenness}, T. and {Kanarek}, G. and {Kendrew}, S. and {Kern}, N.~S. and {Kerzendorf}, W.~E. and {Khvalko}, A. and {King}, J. and {Kirkby}, D. and {Kulkarni}, A.~M. and {Kumar}, A. and {Lee}, A. and {Lenz}, D. and {Littlefair}, S.~P. and {Ma}, Z. and {Macleod}, D.~M. and {Mastropietro}, M. and {McCully}, C. and {Montagnac}, S. and {Morris}, B.~M. and {Mueller}, M. and {Mumford}, S.~J. and {Muna}, D. and {Murphy}, N.~A. and {Nelson}, S. and {Nguyen}, G.~H. and {Ninan}, J.~P. and {N{\"o}the}, M. and {Ogaz}, S. and {Oh}, S. and {Parejko}, J.~K. and {Parley}, N. and {Pascual}, S. and {Patil}, R. and {Patil}, A.~A. and {Plunkett}, A.~L. and {Prochaska}, J.~X. and {Rastogi}, T. and {Reddy Janga}, V. and {Sabater}, J. and {Sakurikar}, P. and {Seifert}, M. and {Sherbert}, L.~E. and {Sherwood-Taylor}, H. and {Shih}, A.~Y. and {Sick}, J. and {Silbiger}, M.~T. and {Singanamalla}, S. and {Singer}, L.~P. and {Sladen}, P.~H. and {Sooley}, K.~A. and {Sornarajah}, S. and {Streicher}, O. and {Teuben}, P. and {Thomas}, S.~W. and {Tremblay}, G.~R. and {Turner}, J.~E.~H. and {Terr{\'o}n}, V. and {van Kerkwijk}, M.~H. and {de la Vega}, A. and {Watkins}, L.~L. and {Weaver}, B.~A. and {Whitmore}, J.~B. and {Woillez}, J. and {Zabalza}, V. and {Contributors}, (Astropy}, 70 | Doi = {10.3847/1538-3881/aabc4f}, 71 | Eid = {123}, 72 | Journal = {\aj}, 73 | Keywords = {methods: data analysis, methods: miscellaneous, methods: statistical, reference systems, Astrophysics - Instrumentation and Methods for Astrophysics}, 74 | Month = Sep, 75 | Pages = {123}, 76 | Primaryclass = {astro-ph.IM}, 77 | Title = {{The Astropy Project: Building an Open-science Project and Status of the v2.0 Core Package}}, 78 | Volume = {156}, 79 | Year = 2018, 80 | Bdsk-Url-1 = {https://doi.org/10.3847/1538-3881/aabc4f}} 81 | @article{matplotlib, 82 | Author = {Hunter, J. D.}, 83 | Title = {Matplotlib: A 2D graphics environment}, 84 | Journal = {Computing in Science \& Engineering}, 85 | Volume = {9}, 86 | Number = {3}, 87 | Pages = {90--95}, 88 | abstract = {Matplotlib is a 2D graphics package used for Python for 89 | application development, interactive scripting, and publication-quality 90 | image generation across user interfaces and operating systems.}, 91 | publisher = {IEEE COMPUTER SOC}, 92 | doi = {10.1109/MCSE.2007.55}, 93 | year = 2007 94 | } 95 | @article{numpy, 96 | author={S. {van der Walt} and S. C. {Colbert} and G. {Varoquaux}}, 97 | doi={10.1109/MCSE.2011.37}, 98 | journal={Computing in Science Engineering}, 99 | title={The NumPy Array: A Structure for Efficient Numerical Computation}, 100 | year={2011}, 101 | volume={13}, 102 | number={2}, 103 | pages={22-30},} 104 | @book{python, 105 | author = {Van Rossum, Guido and Drake, Fred L.}, 106 | title = {Python 3 Reference Manual}, 107 | year = {2009}, 108 | isbn = {1441412697}, 109 | publisher = {CreateSpace}, 110 | address = {Scotts Valley, CA} 111 | } 112 | @article{scipy, 113 | author = {{Virtanen}, Pauli and {Gommers}, Ralf and {Oliphant}, 114 | Travis E. and {Haberland}, Matt and {Reddy}, Tyler and 115 | {Cournapeau}, David and {Burovski}, Evgeni and {Peterson}, Pearu 116 | and {Weckesser}, Warren and {Bright}, Jonathan and {van der Walt}, 117 | St{\'e}fan J. and {Brett}, Matthew and {Wilson}, Joshua and 118 | {Jarrod Millman}, K. and {Mayorov}, Nikolay and {Nelson}, Andrew 119 | R.~J. and {Jones}, Eric and {Kern}, Robert and {Larson}, Eric and 120 | {Carey}, CJ and {Polat}, {\.I}lhan and {Feng}, Yu and {Moore}, 121 | Eric W. and {Vand erPlas}, Jake and {Laxalde}, Denis and 122 | {Perktold}, Josef and {Cimrman}, Robert and {Henriksen}, Ian and 123 | {Quintero}, E.~A. and {Harris}, Charles R and {Archibald}, Anne M. 124 | and {Ribeiro}, Ant{\^o}nio H. and {Pedregosa}, Fabian and 125 | {van Mulbregt}, Paul and {Contributors}, SciPy 1. 0}, 126 | title = "{SciPy 1.0: Fundamental Algorithms for Scientific 127 | Computing in Python}", 128 | journal = {Nature Methods}, 129 | year = "2020", 130 | volume={17}, 131 | pages={261--272}, 132 | adsurl = {https://rdcu.be/b08Wh}, 133 | doi = {10.1038/s41592-019-0686-2}, 134 | } 135 | 136 | 137 | We thank James Nightingale for the idea and collecting the initial set of references `here `_. 138 | -------------------------------------------------------------------------------- /docs/_sources/dmx.rst.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | 11 | DMX Class 12 | ========= 13 | 14 | The *DMX* class handles pulsar DMX files as output by `tempo` and `dmxparse.py`. 15 | 16 | .. py:class:: DMX(filename) 17 | 18 | :param str filename: Path to a .dmx file 19 | 20 | Usage: 21 | 22 | .. code-block:: python 23 | 24 | d = DMX(FILENAME) #automatically parses each DM line with the DM() class 25 | print d.DMs[0].getMJD() #prints the MJD of the first DM value. 26 | print d.getMJDs() #prints the values of all of the epochs. 27 | 28 | Methods 29 | ------- 30 | 31 | 32 | .. py:function:: save(filename) 33 | 34 | Save a .dmx file. 35 | 36 | :param str filename: Path to .dmx file 37 | 38 | .. warning:: :func:`save` is currently not fully implemented 39 | 40 | 41 | .. py:function:: getMJDs() 42 | 43 | Return the MJD of each DM value. Loops over :func:`getEpoch` in :class:`DM`. 44 | 45 | :rtype: numpy.ndarray 46 | 47 | .. py:function:: getEpochs() 48 | 49 | Return the MJD of each DM value. Loops over :func:`getEpoch` in :class:`DM`. 50 | 51 | :rtype: numpy.ndarray 52 | 53 | .. py:function:: getValues() 54 | 55 | Return each DM value. Loops over :func:`getValue` in :class:`DM`. 56 | 57 | :rtype: numpy.ndarray 58 | 59 | 60 | .. py:function:: getErrs() 61 | 62 | Return the DM uncertainties for each measurement. Loops over :func:`getError` in :class:`DM`. 63 | 64 | :rtype: numpy.ndarray 65 | 66 | 67 | .. py:function:: getErrors() 68 | 69 | Return the DM uncertainties for each measurement. Loops over :func:`getError` in :class:`DM`. 70 | 71 | :rtype: numpy.ndarray 72 | 73 | 74 | 75 | .. py:function:: getR1s() 76 | 77 | Return the R1 values for each measurement, the starting MJD for the bin. Loops over :func:`getR1` in :class:`DM`. 78 | 79 | :rtype: numpy.ndarray 80 | 81 | 82 | .. py:function:: getR2s() 83 | 84 | Return the R2 values for each measurement, the ending MJD for the bin. Loops over :func:`getR2` in :class:`DM`. 85 | 86 | :rtype: numpy.ndarray 87 | 88 | .. py:function:: getF1s() 89 | 90 | Return the F1 values for each measurement, the lowest frequency for the bin. Loops over :func:`getF1` in :class:`DM`. 91 | 92 | :rtype: numpy.ndarray 93 | 94 | .. py:function:: getF2s() 95 | 96 | Return the F2 values for each measurement, the highest frequency for the bin. Loops over :func:`getF2` in :class:`DM`. 97 | 98 | :rtype: numpy.ndarray 99 | 100 | .. py:function:: getBin() 101 | 102 | Return the bin string label. Loops over :func:`getDMXbin` in :class:`DM`. 103 | 104 | :rtype: numpy.ndarray 105 | 106 | .. py:function:: getDMXbin() 107 | 108 | Return the bin string label. Loops over :func:`getDMXbin` in :class:`DM`. 109 | 110 | :rtype: numpy.ndarray 111 | 112 | 113 | .. py:function:: getter(func) 114 | 115 | Generic helper function to loop over each DM value. Used internally, though hypothetically one could apply additional operations on each DM value 116 | 117 | :param function func: Function to call on each DM value 118 | 119 | :rtype: nump.ndarray 120 | 121 | .. py:function:: getDMseries() 122 | 123 | Return a tuple of the DM time series (times, DMs, DM errors). DMs are calculated as the DMX model plus the DM parameter (the fiducial value). 124 | 125 | :return: times (*numpy.ndarray*), DM (*numpy.ndarray*), DM errors (*numpy.ndarray*) 126 | 127 | .. py:function:: getTspan([years=False]) 128 | 129 | Return the total time span covered by the DM epochs. 130 | 131 | :param bool years: Divide the total time span in days by 365.25. 132 | :rtype: float 133 | 134 | 135 | DM Class 136 | ========= 137 | 138 | The *DM* class handles individual pulsar DMX measurements. 139 | 140 | .. py:class:: DM(epoch[,value=None,err=None,R1=None,R2=None,F1=None,F2=None,dmxbin=None]) 141 | 142 | Stores the entries of a DM line. 143 | 144 | :param float/str epoch: If only the epoch parameter is specified, then the parameter is the entire DM string and will be parsed. 145 | :param float value: DM value. 146 | :param float err: DM error 147 | :param float R1: R1, starting MJD for the bin 148 | :param float R2: R2, ending MJD for the bin 149 | :param float F1: F1, lowest frequency for the bin 150 | :param float F2: F2, highest frequency for the bin 151 | :param str dmxbin: bin label 152 | 153 | 154 | Methods 155 | ------- 156 | 157 | .. py:function:: getMJD() 158 | 159 | Return the value of the epoch. 160 | 161 | :rtype: float 162 | 163 | .. py:function:: getEpoch() 164 | 165 | Return the value of the epoch. 166 | 167 | :rtype: float 168 | 169 | .. py:function:: getDM() 170 | 171 | Return the value of the DM. 172 | 173 | :rtype: float 174 | 175 | .. py:function:: getValue() 176 | 177 | Return the value of the DM. 178 | 179 | :rtype: float 180 | 181 | .. py:function:: getErr() 182 | 183 | Return the error of the DM. 184 | 185 | :rtype: float 186 | 187 | .. py:function:: getError() 188 | 189 | Return the error of the DM. 190 | 191 | :rtype: float 192 | 193 | .. py:function:: getR1() 194 | 195 | Return the R1 of the DM, the starting epoch of the bin. 196 | 197 | :rtype: float 198 | 199 | .. py:function:: getR2() 200 | 201 | Return the R2 of the DM, the ending epoch of the bin. 202 | 203 | :rtype: float 204 | 205 | .. py:function:: getF1() 206 | 207 | Return the F1 of the DM, the lowest frequency. 208 | 209 | :rtype: float 210 | 211 | .. py:function:: getF2() 212 | 213 | Return the F2 of the DM, the highest frequency. 214 | 215 | :rtype: float 216 | 217 | .. py:function:: getBin() 218 | 219 | Return the label of the bin. 220 | 221 | :rtype: str 222 | 223 | .. py:function:: getDMXbin() 224 | 225 | Return the label of the bin. 226 | 227 | :rtype: str 228 | 229 | .. py:function:: setMJD(epoch) 230 | 231 | Set the epoch of the DM to a value. 232 | 233 | :param float epoch: Value to set the DM epoch to. 234 | 235 | .. py:function:: setEpoch(epoch) 236 | 237 | Set the epoch of the DM to a value. 238 | 239 | :param float epoch: Value to set the DM epoch to. 240 | 241 | .. py:function:: setDM(value) 242 | 243 | Set the epoch of the DM to a value. 244 | 245 | :param float value: Value to set the DM to. 246 | 247 | .. py:function:: setValue(value) 248 | 249 | Set the epoch of the DM to a value. 250 | 251 | :param float value: Value to set the DM to. 252 | 253 | .. py:function:: setErr(err) 254 | 255 | Set the error of the DM to a value. 256 | 257 | :param float err: Value to set the error to. 258 | 259 | .. py:function:: setError(err) 260 | 261 | Set the error of the DM to a value. 262 | 263 | :param float err: Value to set the error to. 264 | 265 | .. py:function:: setR1(R1) 266 | 267 | Set the R1 of the DM to a value. 268 | 269 | :param float R1: Value to set the R1 to. 270 | 271 | .. py:function:: setR2(R2) 272 | 273 | Set the R2 of the DM to a value. 274 | 275 | :param float R2: Value to set the R2 to. 276 | 277 | .. py:function:: setF1(F1) 278 | 279 | Set the F1 of the DM to a value. 280 | 281 | :param float F1: Value to set the F1 to. 282 | 283 | .. py:function:: setF2(F2) 284 | 285 | Set the F2 of the DM to a value. 286 | 287 | :param float F2: Value to set the F2 to. 288 | 289 | .. py:function:: setBin(dmxbin) 290 | 291 | Set the label of the DM to a value. 292 | 293 | :param str dmxbin: Value to set the bin label to. 294 | 295 | .. py:function:: setDMXbin(dmxbin) 296 | 297 | Set the label of the DM to a value. 298 | 299 | :param str dmxbin: Value to set the bin label to. 300 | 301 | -------------------------------------------------------------------------------- /docs/_sources/dmx.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | 11 | DMX Class 12 | ========= 13 | 14 | The *DMX* class handles pulsar DMX files as output by `tempo` and `dmxparse.py`. 15 | 16 | .. py:class:: DMX(filename) 17 | 18 | :param str filename: Path to a .dmx file 19 | 20 | Usage: 21 | 22 | .. code-block:: python 23 | 24 | d = DMX(FILENAME) #automatically parses each DM line with the DM() class 25 | print d.DMs[0].getMJD() #prints the MJD of the first DM value. 26 | print d.getMJDs() #prints the values of all of the epochs. 27 | 28 | Methods 29 | ------- 30 | 31 | 32 | .. py:function:: save(filename) 33 | 34 | Save a .dmx file. 35 | 36 | :param str filename: Path to .dmx file 37 | 38 | .. warning:: :func:`save` is currently not fully implemented 39 | 40 | 41 | .. py:function:: getMJDs() 42 | 43 | Return the MJD of each DM value. Loops over :func:`getEpoch` in :class:`DM`. 44 | 45 | :rtype: numpy.ndarray 46 | 47 | .. py:function:: getEpochs() 48 | 49 | Return the MJD of each DM value. Loops over :func:`getEpoch` in :class:`DM`. 50 | 51 | :rtype: numpy.ndarray 52 | 53 | .. py:function:: getValues() 54 | 55 | Return each DM value. Loops over :func:`getValue` in :class:`DM`. 56 | 57 | :rtype: numpy.ndarray 58 | 59 | 60 | .. py:function:: getErrs() 61 | 62 | Return the DM uncertainties for each measurement. Loops over :func:`getError` in :class:`DM`. 63 | 64 | :rtype: numpy.ndarray 65 | 66 | 67 | .. py:function:: getErrors() 68 | 69 | Return the DM uncertainties for each measurement. Loops over :func:`getError` in :class:`DM`. 70 | 71 | :rtype: numpy.ndarray 72 | 73 | 74 | 75 | .. py:function:: getR1s() 76 | 77 | Return the R1 values for each measurement, the starting MJD for the bin. Loops over :func:`getR1` in :class:`DM`. 78 | 79 | :rtype: numpy.ndarray 80 | 81 | 82 | .. py:function:: getR2s() 83 | 84 | Return the R2 values for each measurement, the ending MJD for the bin. Loops over :func:`getR2` in :class:`DM`. 85 | 86 | :rtype: numpy.ndarray 87 | 88 | .. py:function:: getF1s() 89 | 90 | Return the F1 values for each measurement, the lowest frequency for the bin. Loops over :func:`getF1` in :class:`DM`. 91 | 92 | :rtype: numpy.ndarray 93 | 94 | .. py:function:: getF2s() 95 | 96 | Return the F2 values for each measurement, the highest frequency for the bin. Loops over :func:`getF2` in :class:`DM`. 97 | 98 | :rtype: numpy.ndarray 99 | 100 | .. py:function:: getBin() 101 | 102 | Return the bin string label. Loops over :func:`getDMXbin` in :class:`DM`. 103 | 104 | :rtype: numpy.ndarray 105 | 106 | .. py:function:: getDMXbin() 107 | 108 | Return the bin string label. Loops over :func:`getDMXbin` in :class:`DM`. 109 | 110 | :rtype: numpy.ndarray 111 | 112 | 113 | .. py:function:: getter(func) 114 | 115 | Generic helper function to loop over each DM value. Used internally, though hypothetically one could apply additional operations on each DM value 116 | 117 | :param function func: Function to call on each DM value 118 | 119 | :rtype: nump.ndarray 120 | 121 | .. py:function:: getDMseries() 122 | 123 | Return a tuple of the DM time series (times, DMs, DM errors). DMs are calculated as the DMX model plus the DM parameter (the fiducial value). 124 | 125 | :return: times (*numpy.ndarray*), DM (*numpy.ndarray*), DM errors (*numpy.ndarray*) 126 | 127 | .. py:function:: getTspan([years=False]) 128 | 129 | Return the total time span covered by the DM epochs. 130 | 131 | :param bool years: Divide the total time span in days by 365.25. 132 | :rtype: float 133 | 134 | 135 | DM Class 136 | ========= 137 | 138 | The *DM* class handles individual pulsar DMX measurements. 139 | 140 | .. py:class:: DM(epoch[,value=None,err=None,R1=None,R2=None,F1=None,F2=None,dmxbin=None]) 141 | 142 | Stores the entries of a DM line. 143 | 144 | :param float/str epoch: If only the epoch parameter is specified, then the parameter is the entire DM string and will be parsed. 145 | :param float value: DM value. 146 | :param float err: DM error 147 | :param float R1: R1, starting MJD for the bin 148 | :param float R2: R2, ending MJD for the bin 149 | :param float F1: F1, lowest frequency for the bin 150 | :param float F2: F2, highest frequency for the bin 151 | :param str dmxbin: bin label 152 | 153 | 154 | Methods 155 | ------- 156 | 157 | .. py:function:: getMJD() 158 | 159 | Return the value of the epoch. 160 | 161 | :rtype: float 162 | 163 | .. py:function:: getEpoch() 164 | 165 | Return the value of the epoch. 166 | 167 | :rtype: float 168 | 169 | .. py:function:: getDM() 170 | 171 | Return the value of the DM. 172 | 173 | :rtype: float 174 | 175 | .. py:function:: getValue() 176 | 177 | Return the value of the DM. 178 | 179 | :rtype: float 180 | 181 | .. py:function:: getErr() 182 | 183 | Return the error of the DM. 184 | 185 | :rtype: float 186 | 187 | .. py:function:: getError() 188 | 189 | Return the error of the DM. 190 | 191 | :rtype: float 192 | 193 | .. py:function:: getR1() 194 | 195 | Return the R1 of the DM, the starting epoch of the bin. 196 | 197 | :rtype: float 198 | 199 | .. py:function:: getR2() 200 | 201 | Return the R2 of the DM, the ending epoch of the bin. 202 | 203 | :rtype: float 204 | 205 | .. py:function:: getF1() 206 | 207 | Return the F1 of the DM, the lowest frequency. 208 | 209 | :rtype: float 210 | 211 | .. py:function:: getF2() 212 | 213 | Return the F2 of the DM, the highest frequency. 214 | 215 | :rtype: float 216 | 217 | .. py:function:: getBin() 218 | 219 | Return the label of the bin. 220 | 221 | :rtype: str 222 | 223 | .. py:function:: getDMXbin() 224 | 225 | Return the label of the bin. 226 | 227 | :rtype: str 228 | 229 | .. py:function:: setMJD(epoch) 230 | 231 | Set the epoch of the DM to a value. 232 | 233 | :param float epoch: Value to set the DM epoch to. 234 | 235 | .. py:function:: setEpoch(epoch) 236 | 237 | Set the epoch of the DM to a value. 238 | 239 | :param float epoch: Value to set the DM epoch to. 240 | 241 | .. py:function:: setDM(value) 242 | 243 | Set the epoch of the DM to a value. 244 | 245 | :param float value: Value to set the DM to. 246 | 247 | .. py:function:: setValue(value) 248 | 249 | Set the epoch of the DM to a value. 250 | 251 | :param float value: Value to set the DM to. 252 | 253 | .. py:function:: setErr(err) 254 | 255 | Set the error of the DM to a value. 256 | 257 | :param float err: Value to set the error to. 258 | 259 | .. py:function:: setError(err) 260 | 261 | Set the error of the DM to a value. 262 | 263 | :param float err: Value to set the error to. 264 | 265 | .. py:function:: setR1(R1) 266 | 267 | Set the R1 of the DM to a value. 268 | 269 | :param float R1: Value to set the R1 to. 270 | 271 | .. py:function:: setR2(R2) 272 | 273 | Set the R2 of the DM to a value. 274 | 275 | :param float R2: Value to set the R2 to. 276 | 277 | .. py:function:: setF1(F1) 278 | 279 | Set the F1 of the DM to a value. 280 | 281 | :param float F1: Value to set the F1 to. 282 | 283 | .. py:function:: setF2(F2) 284 | 285 | Set the F2 of the DM to a value. 286 | 287 | :param float F2: Value to set the F2 to. 288 | 289 | .. py:function:: setBin(dmxbin) 290 | 291 | Set the label of the DM to a value. 292 | 293 | :param str dmxbin: Value to set the bin label to. 294 | 295 | .. py:function:: setDMXbin(dmxbin) 296 | 297 | Set the label of the DM to a value. 298 | 299 | :param str dmxbin: Value to set the bin label to. 300 | 301 | -------------------------------------------------------------------------------- /docs/_sources/dynamicspectrum.rst.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | DynamicSpectrum Class 11 | ===================== 12 | 13 | The *DynamicSpectrum* class handles dynamic spectra. 14 | 15 | .. py:class:: DynamicSpectra(data[,offdata=None,errdata=None,mask=None,F=None,T=None,extras=None,verbose=True]) 16 | 17 | Usage: 18 | 19 | .. code-block:: python 20 | 21 | ds = DynamicSpectrum(FILENAME) #takes a 2D data array or a string to a .npz file for now 22 | acf2d = ds.acf2d() #calculates the 2D ACF of the dynamic spectrum 23 | ds.imshow() #plots the dynamic spectrum 24 | ds.save(NEWFILENAME) #saves to a .npz file, which can then be loaded again with the first line 25 | 26 | 27 | 28 | Methods 29 | ------- 30 | 31 | 32 | .. py:function:: getValue(f,t[,df=1,dt=1,err=False,index=False]) 33 | 34 | .. py:function:: remove_baseline([function="gaussian",redo=False]) 35 | 36 | Attempts to remove the baseline amplitude from the dynamic spectrum 37 | 38 | .. py:function:: acf2d(remove_baseline=True,speed='fast',mode='full']) 39 | 40 | Calculate the two-dimensional auto-correlation function of the dynamic spectrum 41 | 42 | 43 | .. py:function:: secondary_spectrum([log=False]) 44 | 45 | .. py:function:: scintillation_parameters([plotbound=1.0]) 46 | 47 | 48 | .. py:function:: imshow([err=False,cbar=False,ax=None,show=True,border=False,ZORDER=0,cmap=cm.binary,alpha=True,cdf=True]) 49 | 50 | Basic plotting of the dynamic spectrum 51 | 52 | .. py:function:: load(filename) 53 | 54 | Load the dynamic spectrum from a .npz file 55 | 56 | :param str filename: Filename to load from 57 | 58 | .. py:function:: save(filename) 59 | 60 | Save the dynamic spectrum to a .npz file 61 | 62 | :param str filename: Filename to sae to 63 | 64 | .. py:function:: add(ds[,axis='T']) 65 | 66 | Concatenates another dynamic spectrum with this one 67 | 68 | .. warning:: basic functionality only 69 | 70 | .. py:function:: getData([remove_baseline=True]) 71 | 72 | .. py:function:: getACF([remove_baseline=True]) 73 | -------------------------------------------------------------------------------- /docs/_sources/dynamicspectrum.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | DynamicSpectrum Class 11 | ===================== 12 | 13 | The *DynamicSpectrum* class handles dynamic spectra. 14 | 15 | .. py:class:: DynamicSpectra(data[,offdata=None,errdata=None,mask=None,F=None,T=None,extras=None,verbose=True]) 16 | 17 | Usage: 18 | 19 | .. code-block:: python 20 | 21 | ds = DynamicSpectrum(FILENAME) #takes a 2D data array or a string to a .npz file for now 22 | acf2d = ds.acf2d() #calculates the 2D ACF of the dynamic spectrum 23 | ds.imshow() #plots the dynamic spectrum 24 | ds.save(NEWFILENAME) #saves to a .npz file, which can then be loaded again with the first line 25 | 26 | 27 | 28 | Methods 29 | ------- 30 | 31 | 32 | .. py:function:: getValue(f,t[,df=1,dt=1,err=False,index=False]) 33 | 34 | .. py:function:: remove_baseline([function="gaussian",redo=False]) 35 | 36 | Attempts to remove the baseline amplitude from the dynamic spectrum 37 | 38 | .. py:function:: acf2d(remove_baseline=True,speed='fast',mode='full']) 39 | 40 | Calculate the two-dimensional auto-correlation function of the dynamic spectrum 41 | 42 | 43 | .. py:function:: secondary_spectrum([log=False]) 44 | 45 | .. py:function:: scintillation_parameters([plotbound=1.0]) 46 | 47 | 48 | .. py:function:: imshow([err=False,cbar=False,ax=None,show=True,border=False,ZORDER=0,cmap=cm.binary,alpha=True,cdf=True]) 49 | 50 | Basic plotting of the dynamic spectrum 51 | 52 | .. py:function:: load(filename) 53 | 54 | Load the dynamic spectrum from a .npz file 55 | 56 | :param str filename: Filename to load from 57 | 58 | .. py:function:: save(filename) 59 | 60 | Save the dynamic spectrum to a .npz file 61 | 62 | :param str filename: Filename to sae to 63 | 64 | .. py:function:: add(ds[,axis='T']) 65 | 66 | Concatenates another dynamic spectrum with this one 67 | 68 | .. warning:: basic functionality only 69 | 70 | .. py:function:: getData([remove_baseline=True]) 71 | 72 | .. py:function:: getACF([remove_baseline=True]) 73 | -------------------------------------------------------------------------------- /docs/_sources/examples.rst.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | Examples 11 | ======== 12 | 13 | Below are some examples of tasks you may wish to perform. If you would like to see more examples, please submit an issue on github or e-mail me at michael-dot-lam-at-nanograv-dot-org. 14 | 15 | 16 | 17 | Calculating scintillation parameters 18 | ------------------------------------ 19 | 20 | Below is the very simplest way to get scintillation parameters. 21 | 22 | .. code-block:: python 23 | 24 | ar = Archive(FILENAME) #loads archive, dedispersed and polarization averaged by default 25 | ds = ar.getDynamicSpectrum() #without a template shape, this will average the data across the phase axis. One can set maketemplate=True to take the average pulse shape and make an underlying template 26 | print(ds.scintillation_parameters()) #will return the scintillation timescale, scintillation bandwidth, and drift rate (rotation) using a 2D Gaussian fit 27 | 28 | Make a Joy Division plot 29 | ------------------------ 30 | 31 | .. code-block:: python 32 | 33 | ar = Archive(FILENAME) #loads archive, dedispersed and polarization averaged by default 34 | ar.fscrunch() #frequency-average the data, if applicable. 35 | ar.joyDivision() #makes the Joy-Division-style plot for pulses in time and phase 36 | 37 | 38 | Make a template shape 39 | ------------------------ 40 | 41 | If you are starting from a PSRFITS file, the easiest thing to do is probably the following: 42 | 43 | .. code-block:: python 44 | 45 | ar = Archive(FILENAME) #loads archive, dedispersed and polarization averaged by default 46 | ar.tscrunch() #time-average the data, if applicable. 47 | template = ar.calculateTemplate() #By default, will use von Mises functions 48 | 49 | If you already have the data array extracted, then you can go straight to the underlying functionality: 50 | 51 | .. code-block:: python 52 | 53 | sp = SinglePulse(data,windowsize=len(data)//8) #windowsize will auto-calculate an off-pulse region 54 | template = sp.smooth() # By default, will use von Mises functions 55 | 56 | 57 | Comment out TOAs in a .tim file with a given condition 58 | ------------------------------------------------------ 59 | 60 | Let's say we wish to comment out TOAs with a flag representing a specific backend: "-be legacy" 61 | 62 | .. code-block:: python 63 | 64 | t = Tim(FILENAME) #load tim file 65 | 66 | def boolean_func(toa): #define a boolean function that takes in a TOA instance. 67 | be = toa.get("be") 68 | if be == "legacy": 69 | return True 70 | return False 71 | 72 | t.comment(boolean_func,cut="cut_legacy") #add a flag that says why the data were cut 73 | t.save(filename="new.tim") #saves a new tim file rather than rewrite the old one 74 | 75 | 76 | -------------------------------------------------------------------------------- /docs/_sources/examples.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | Examples 11 | ======== 12 | 13 | Below are some examples of tasks you may wish to perform. If you would like to see more examples, please submit an issue on github or e-mail me at michael-dot-lam-at-nanograv-dot-org. 14 | 15 | 16 | 17 | Calculating scintillation parameters 18 | ------------------------------------ 19 | 20 | Below is the very simplest way to get scintillation parameters. 21 | 22 | .. code-block:: python 23 | 24 | ar = Archive(FILENAME) #loads archive, dedispersed and polarization averaged by default 25 | ds = ar.getDynamicSpectrum() #without a template shape, this will average the data across the phase axis. One can set maketemplate=True to take the average pulse shape and make an underlying template 26 | print(ds.scintillation_parameters()) #will return the scintillation timescale, scintillation bandwidth, and drift rate (rotation) using a 2D Gaussian fit 27 | 28 | Make a Joy Division plot 29 | ------------------------ 30 | 31 | .. code-block:: python 32 | 33 | ar = Archive(FILENAME) #loads archive, dedispersed and polarization averaged by default 34 | ar.fscrunch() #frequency-average the data, if applicable. 35 | ar.joyDivision() #makes the Joy-Division-style plot for pulses in time and phase 36 | 37 | 38 | Make a template shape 39 | ------------------------ 40 | 41 | If you are starting from a PSRFITS file, the easiest thing to do is probably the following: 42 | 43 | .. code-block:: python 44 | 45 | ar = Archive(FILENAME) #loads archive, dedispersed and polarization averaged by default 46 | ar.tscrunch() #time-average the data, if applicable. 47 | template = ar.calculateTemplate() #By default, will use von Mises functions 48 | 49 | If you already have the data array extracted, then you can go straight to the underlying functionality: 50 | 51 | .. code-block:: python 52 | 53 | sp = SinglePulse(data,windowsize=len(data)//8) #windowsize will auto-calculate an off-pulse region 54 | template = sp.smooth() # By default, will use von Mises functions 55 | 56 | 57 | Comment out TOAs in a .tim file with a given condition 58 | ------------------------------------------------------ 59 | 60 | Let's say we wish to comment out TOAs with a flag representing a specific backend: "-be legacy" 61 | 62 | .. code-block:: python 63 | 64 | t = Tim(FILENAME) #load tim file 65 | 66 | def boolean_func(toa): #define a boolean function that takes in a TOA instance. 67 | be = toa.get("be") 68 | if be == "legacy": 69 | return True 70 | return False 71 | 72 | t.comment(boolean_func,cut="cut_legacy") #add a flag that says why the data were cut 73 | t.save(filename="new.tim") #saves a new tim file rather than rewrite the old one 74 | 75 | 76 | -------------------------------------------------------------------------------- /docs/_sources/index.rst.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | PyPulse v0.1.1 7 | ============== 8 | 9 | PyPulse is a package used to handle PSRFITS files and perform subsequent analyses on pulse profiles. 10 | 11 | Download: 12 | 13 | `Github `_ 14 | 15 | Requirements: 16 | 17 | * `python `_ 2.7 or 3.X 18 | * `numpy `_ 19 | * `scipy `_ 20 | * `matplotlib `_ 21 | * `astropy `_ 22 | 23 | 24 | Contents: 25 | 26 | .. toctree:: 27 | :hidden: 28 | 29 | archive 30 | singlepulse 31 | calibrator 32 | rfimitigator 33 | dynamicspectrum 34 | par 35 | tim 36 | dmx 37 | utils 38 | examples 39 | scripts 40 | citations 41 | license 42 | 43 | .. Classes 44 | .. ======= 45 | 46 | * :doc:`archive` 47 | * :doc:`singlepulse` 48 | * :doc:`calibrator` 49 | * :doc:`rfimitigator` 50 | * :doc:`dynamicspectrum` 51 | * :doc:`par` 52 | * :doc:`tim` 53 | * :doc:`dmx` 54 | 55 | 56 | Misc 57 | ==== 58 | 59 | * :doc:`examples` 60 | * :doc:`scripts` 61 | * :doc:`utils` 62 | * :ref:`search` 63 | * :doc:`license` 64 | 65 | 66 | 67 | Citations 68 | ========= 69 | 70 | See :doc:`citations` for more information, including how to cite PyPulse's required packages. In using PyPulse, please cite the `ASCL `_ via: 71 | 72 | `Lam, M. T., 2017, PyPulse, Astrophysics Source Code Library, record ascl:1706.011 `_ 73 | 74 | Contact 75 | ========= 76 | 77 | Please contact michael-dot-lam-at-nanograv-dot-org. 78 | -------------------------------------------------------------------------------- /docs/_sources/index.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | PyPulse v0.0.1 7 | ============== 8 | 9 | PyPulse is a package used to handle PSRFITS files and perform subsequent analyses on pulse profiles. 10 | 11 | Download: 12 | 13 | `Github `_ 14 | 15 | Requirements: 16 | 17 | * `python `_ 2.7 or 3.X 18 | * `numpy `_ 19 | * `scipy `_ 20 | * `matplotlib `_ 21 | * `astropy `_ or `pyfits `_ 22 | 23 | 24 | Contents: 25 | 26 | .. toctree:: 27 | :hidden: 28 | 29 | archive 30 | singlepulse 31 | calibrator 32 | rfimitigator 33 | dynamicspectrum 34 | par 35 | tim 36 | dmx 37 | utils 38 | license 39 | 40 | .. Classes 41 | .. ======= 42 | 43 | * :doc:`archive` 44 | * :doc:`singlepulse` 45 | * :doc:`calibrator` 46 | * :doc:`rfimitigator` 47 | * :doc:`dynamicspectrum` 48 | * :doc:`par` 49 | * :doc:`tim` 50 | * :doc:`dmx` 51 | 52 | 53 | Misc 54 | ==== 55 | 56 | * :doc:`examples` 57 | * :doc:`scripts` 58 | * :doc:`utils` 59 | * :ref:`search` 60 | * :doc:`license` 61 | 62 | 63 | 64 | Citations 65 | ========= 66 | 67 | See `ASCL `_. You can cite as: 68 | 69 | `Lam, M. T., 2017, PyPulse, Astrophysics Source Code Library, record ascl:1706.011 `_ 70 | 71 | Contact 72 | ========= 73 | 74 | Please contact michael-dot-lam-at-nanograv-dot-org. 75 | -------------------------------------------------------------------------------- /docs/_sources/license.rst.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | 11 | 12 | License 13 | ======= 14 | 15 | Copyright (c) 2015-2017, Michael T. Lam 16 | 17 | All rights reserved. 18 | 19 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 20 | 21 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 22 | 23 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 24 | 25 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /docs/_sources/license.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | 11 | 12 | License 13 | ======= 14 | 15 | Copyright (c) 2015-2017, Michael T. Lam 16 | 17 | All rights reserved. 18 | 19 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 20 | 21 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 22 | 23 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 24 | 25 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /docs/_sources/par.rst.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | Par Class 11 | ============= 12 | 13 | The *Par* class handles pulsar parameter files. 14 | 15 | .. py:class:: Par(filename[,numwrap=float,usedecimal=False]) 16 | 17 | :param str filename: Path to a .par file 18 | :param type numwrap: Type to wrap numeric values by. Float is used by default for ease but Decimal can be is used to keep numeric precision if needed, e.g., for spin period/frequency. Can set numwrap=DECIMAL or usedecimal=True. 19 | :param bool usedecimal: See above. 20 | 21 | Usage: 22 | 23 | .. code-block:: python 24 | 25 | p = Par(FILENAME) 26 | print p.getPeriod() #prints the period in the par file (does not calculate for a specific MJD for now) 27 | t,dmx,dmxerr = p.getDMseries() #returns the DM parameters in a nice time-series. Note that errors are those given in the par file, which may not be the "correct" ones (more info to be provided later) 28 | print p.get("PX") #prints the parallax 29 | print p.get("PX",error=True) #prints the error on the parallax 30 | 31 | 32 | Methods 33 | ------- 34 | 35 | 36 | .. py:function:: get(tag[,flag=None,error=False]) 37 | 38 | Return the value of a given parameter. 39 | 40 | :param str flag: Return the value of a parameter with a flag provided. For example, noise parameters can be given a backend as a flag, e.g., for parameter "JUMP -fe L-wide 0.0 1 0.0", the flag would be "L-wide". 41 | :param bool error: Return the value of the error associated with a parameter. 42 | :return: value 43 | 44 | .. py:function:: getPeriod() 45 | 46 | Return the pulsar spin period. 47 | 48 | :rtype: float 49 | 50 | .. py:function:: getPeriodDot([shklovskii=False]) 51 | 52 | Return the pulsar spin period derivative. 53 | 54 | :param bool shklovskii: Attempt to correct for the Shklovskii effect if proper motion and parallax information is provided. 55 | :rtype: float 56 | 57 | .. py:function:: getFrequency() 58 | 59 | Return the pulsar spin frequency. 60 | 61 | :rtype: float 62 | 63 | .. py:function:: getFrequencyDot([shklovskii=False]) 64 | 65 | Return the pulsar spin frequency derivative. 66 | 67 | :param bool shklovskii: Attempt to correct for the Shklovskii effect if proper motion and parallax information is provided. 68 | :rtype: float 69 | 70 | 71 | .. py:function:: getPM([error=False]) 72 | 73 | Calculate the proper motion in mas/yr. If only one of the two basis parameters is provided, return that value. 74 | 75 | :param bool error: If true, return the error on the proper motion. 76 | :rtype: float 77 | 78 | .. py:function:: getPX([error=False]) 79 | 80 | Return the parallax in mas. 81 | 82 | :param bool error: If true, return the error on the parallax. 83 | :rtype: float 84 | 85 | .. py:function:: getDIST([error=False]) 86 | 87 | Return the distance in kpc. 88 | 89 | :param bool error: If true, return the error on the distance. 90 | :rtype: float 91 | 92 | .. py:function:: getVpperp() 93 | 94 | Calculate the transverse velocity in km/s. 95 | 96 | :rtype: float 97 | 98 | 99 | 100 | .. py:function:: getDM() 101 | 102 | Return the DM parameter. 103 | 104 | :rtype: float 105 | 106 | .. py:function:: getDMX([full_output=False]) 107 | 108 | Return a tuple of the DMX time series (times, DMXs, DMX errors). 109 | 110 | :param bool full_output: Return a tuple of the times, DMXs, DMX errors, DMXR1s, DMXR2s, DMXF1s, DMXF2s 111 | :return: times (*numpy.ndarray*), DM (*numpy.ndarray*), DM errors (*numpy.ndarray*), unless full_output=True. 112 | 113 | .. py:function:: getXMX() 114 | 115 | Return a tuple of the XMX values. 116 | 117 | :return: xmxs (*numpy.ndarray*), errs (*numpy.ndarray*), R1s (*numpy.ndarray*), R2s (*numpy.ndarray*), EXPs (*numpy.ndarray*), 118 | 119 | .. warning:: This function is under construction. 120 | 121 | .. py:function:: getDMseries() 122 | 123 | Return a tuple of the DM time series (times, DMs, DM errors). DMs are calculated as the DMX model plus the DM parameter (the fiducial value). 124 | 125 | :return: times (*numpy.ndarray*), DM (*numpy.ndarray*), DM errors (*numpy.ndarray*) 126 | 127 | .. py:function:: getFD() 128 | 129 | Return the coefficients associated with the FD parameters, in order (i.e., FD1, FD2, ...). 130 | 131 | :rtype: numpy.ndarray 132 | 133 | .. py:function:: getFDfunc() 134 | 135 | Return a Python function (lambda) that provides the timing delays as a function of observing frequency. The function takes one parameter, the observing frequency (in GHz), and returns timing delays in microseconds. 136 | 137 | :rtype: function 138 | 139 | .. py:function:: getName() 140 | 141 | Return the pulsar name given by either PSR or PSRJ. 142 | 143 | :rtype: str 144 | 145 | .. py:function:: getTspan([years=False]) 146 | 147 | Return the timespan given by the START and FINISH flags in days. 148 | 149 | :param bool years: Divide the timespan by 365.25. 150 | :rtype: float 151 | 152 | 153 | 154 | 155 | Parameter Class 156 | =============== 157 | 158 | The *Parameter* class handles individual pulsar parameters. 159 | 160 | .. py:class:: Parameter(name[,value=None,fit=None,error=None,flag=None,flagvalue=None,numwrap=d.Decimal]) 161 | 162 | Stores the basic values of a Parameter in a par file. 163 | 164 | :param str name: If only the name parameter is specified, then this is the entire parameter string and will be parsed. Otherwise, this is the parameter name (e.g. PSR, P0/F0, etc.) 165 | :param str value: Parameter value. Can be supplied a numeric value that will be wrapped with the type numwrap is set to. 166 | :param str fit: Parameter fit value, i.e. whether or not the parameter is to be fit in the timing model. Can be supplied a numeric value that will be wrapped with an int 167 | :param str error: Parameter error. Can be supplied a numeric value that will be wrapped with the type numwrap is set to. 168 | :param str flag: If there is a flag associated with the parameter 169 | :param str flagvalue: The vale the flag is set to. 170 | :param type numwrap: Type to wrap numeric values by. Decimal is used by default to keep numeric precision but becomes difficult to use with other packages. If precision is unneeded, set to float. 171 | 172 | Methods 173 | ------- 174 | 175 | .. py:function:: getName() 176 | 177 | Return the name of the parameter. 178 | 179 | :rtype: str 180 | 181 | .. py:function:: getValue() 182 | 183 | Return the value of the parameter. 184 | 185 | :rtype: numwrap 186 | 187 | .. py:function:: getError() 188 | 189 | Return the value of the parameter error. 190 | 191 | :rtype: numwrap 192 | 193 | 194 | .. py:function:: getFit() 195 | 196 | Return the value of the fit flag. 197 | 198 | :rtype: int 199 | 200 | .. py:function:: getFlag() 201 | 202 | Return the value of the flag. 203 | 204 | :rtype: str 205 | 206 | .. py:function:: getFlagValue() 207 | 208 | Return the value of the flag value 209 | 210 | :rtype: str 211 | -------------------------------------------------------------------------------- /docs/_sources/par.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | Par Class 11 | ============= 12 | 13 | The *Par* class handles pulsar parameter files. 14 | 15 | .. py:class:: Par(filename[,numwrap=float,usedecimal=False]) 16 | 17 | :param str filename: Path to a .par file 18 | :param type numwrap: Type to wrap numeric values by. Float is used by default for ease but Decimal can be is used to keep numeric precision if needed, e.g., for spin period/frequency. Can set numwrap=DECIMAL or usedecimal=True. 19 | :param bool usedecimal: See above. 20 | 21 | Usage: 22 | 23 | .. code-block:: python 24 | 25 | p = Par(FILENAME) 26 | print p.getPeriod() #prints the period in the par file (does not calculate for a specific MJD for now) 27 | t,dmx,dmxerr = p.getDMseries() #returns the DM parameters in a nice time-series. Note that errors are those given in the par file, which may not be the "correct" ones (more info to be provided later) 28 | print p.get("PX") #prints the parallax 29 | print p.get("PX",error=True) #prints the error on the parallax 30 | 31 | 32 | Methods 33 | ------- 34 | 35 | 36 | .. py:function:: get(tag[,flag=None,error=False]) 37 | 38 | Return the value of a given parameter. 39 | 40 | :param str flag: Return the value of a parameter with a flag provided. For example, noise parameters can be given a backend as a flag, e.g., for parameter "JUMP -fe L-wide 0.0 1 0.0", the flag would be "L-wide". 41 | :param bool error: Return the value of the error associated with a parameter. 42 | :return: value 43 | 44 | .. py:function:: getPeriod() 45 | 46 | Return the pulsar spin period. 47 | 48 | :rtype: float 49 | 50 | .. py:function:: getPeriodDot([shklovskii=False]) 51 | 52 | Return the pulsar spin period derivative. 53 | 54 | :param bool shklovskii: Attempt to correct for the Shklovskii effect if proper motion and parallax information is provided. 55 | :rtype: float 56 | 57 | .. py:function:: getFrequency() 58 | 59 | Return the pulsar spin frequency. 60 | 61 | :rtype: float 62 | 63 | .. py:function:: getFrequencyDot([shklovskii=False]) 64 | 65 | Return the pulsar spin frequency derivative. 66 | 67 | :param bool shklovskii: Attempt to correct for the Shklovskii effect if proper motion and parallax information is provided. 68 | :rtype: float 69 | 70 | 71 | .. py:function:: getPM([error=False]) 72 | 73 | Calculate the proper motion in mas/yr. If only one of the two basis parameters is provided, return that value. 74 | 75 | :param bool error: If true, return the error on the proper motion. 76 | :rtype: float 77 | 78 | .. py:function:: getPX([error=False]) 79 | 80 | Return the parallax in mas. 81 | 82 | :param bool error: If true, return the error on the parallax. 83 | :rtype: float 84 | 85 | .. py:function:: getDIST([error=False]) 86 | 87 | Return the distance in kpc. 88 | 89 | :param bool error: If true, return the error on the distance. 90 | :rtype: float 91 | 92 | .. py:function:: getVpperp() 93 | 94 | Calculate the transverse velocity in km/s. 95 | 96 | :rtype: float 97 | 98 | 99 | 100 | .. py:function:: getDM() 101 | 102 | Return the DM parameter. 103 | 104 | :rtype: float 105 | 106 | .. py:function:: getDMX([full_output=False]) 107 | 108 | Return a tuple of the DMX time series (times, DMXs, DMX errors). 109 | 110 | :param bool full_output: Return a tuple of the times, DMXs, DMX errors, DMXR1s, DMXR2s, DMXF1s, DMXF2s 111 | :return: times (*numpy.ndarray*), DM (*numpy.ndarray*), DM errors (*numpy.ndarray*), unless full_output=True. 112 | 113 | .. py:function:: getXMX() 114 | 115 | Return a tuple of the XMX values. 116 | 117 | :return: xmxs (*numpy.ndarray*), errs (*numpy.ndarray*), R1s (*numpy.ndarray*), R2s (*numpy.ndarray*), EXPs (*numpy.ndarray*), 118 | 119 | .. warning:: This function is under construction. 120 | 121 | .. py:function:: getDMseries() 122 | 123 | Return a tuple of the DM time series (times, DMs, DM errors). DMs are calculated as the DMX model plus the DM parameter (the fiducial value). 124 | 125 | :return: times (*numpy.ndarray*), DM (*numpy.ndarray*), DM errors (*numpy.ndarray*) 126 | 127 | .. py:function:: getFD() 128 | 129 | Return the coefficients associated with the FD parameters, in order (i.e., FD1, FD2, ...). 130 | 131 | :rtype: numpy.ndarray 132 | 133 | .. py:function:: getFDfunc() 134 | 135 | Return a Python function (lambda) that provides the timing delays as a function of observing frequency. The function takes one parameter, the observing frequency (in GHz), and returns timing delays in microseconds. 136 | 137 | :rtype: function 138 | 139 | .. py:function:: getName() 140 | 141 | Return the pulsar name given by either PSR or PSRJ. 142 | 143 | :rtype: str 144 | 145 | .. py:function:: getTspan([years=False]) 146 | 147 | Return the timespan given by the START and FINISH flags in days. 148 | 149 | :param bool years: Divide the timespan by 365.25. 150 | :rtype: float 151 | 152 | 153 | 154 | 155 | Parameter Class 156 | ========= 157 | 158 | The *Parameter* class handles individual pulsar parameters. 159 | 160 | .. py:class:: Parameter(name[,value=None,fit=None,error=None,flag=None,flagvalue=None,numwrap=d.Decimal]) 161 | 162 | Stores the basic values of a Parameter in a par file. 163 | 164 | :param str name: If only the name parameter is specified, then this is the entire parameter string and will be parsed. Otherwise, this is the parameter name (e.g. PSR, P0/F0, etc.) 165 | :param str value: Parameter value. Can be supplied a numeric value that will be wrapped with the type numwrap is set to. 166 | :param str fit: Parameter fit value, i.e. whether or not the parameter is to be fit in the timing model. Can be supplied a numeric value that will be wrapped with an int 167 | :param str error: Parameter error. Can be supplied a numeric value that will be wrapped with the type numwrap is set to. 168 | :param str flag: If there is a flag associated with the parameter 169 | :param str flagvalue: The vale the flag is set to. 170 | :param type numwrap: Type to wrap numeric values by. Decimal is used by default to keep numeric precision but becomes difficult to use with other packages. If precision is unneeded, set to float. 171 | 172 | Methods 173 | ------- 174 | 175 | .. py:function:: getName() 176 | 177 | Return the name of the parameter. 178 | 179 | :rtype: str 180 | 181 | .. py:function:: getValue() 182 | 183 | Return the value of the parameter. 184 | 185 | :rtype: numwrap 186 | 187 | .. py:function:: getError() 188 | 189 | Return the value of the parameter error. 190 | 191 | :rtype: numwrap 192 | 193 | 194 | .. py:function:: getFit() 195 | 196 | Return the value of the fit flag. 197 | 198 | :rtype: int 199 | 200 | .. py:function:: getFlag() 201 | 202 | Return the value of the flag. 203 | 204 | :rtype: str 205 | 206 | .. py:function:: getFlagValue() 207 | 208 | Return the value of the flag value 209 | 210 | :rtype: str 211 | 212 | -------------------------------------------------------------------------------- /docs/_sources/rfimitigator.rst.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | 11 | 12 | RFIMitigator Class 13 | ================== 14 | 15 | The *RFIMitigator* class handles zapping via changing the data weights. 16 | 17 | .. warning:: This class is under heavy construction. 18 | 19 | .. py:class:: RFIMitigator(archive) 20 | 21 | Usage: 22 | 23 | .. code-block:: python 24 | 25 | rm = RFIMitigator(ar) # provide an Archive object 26 | rm.zap_frequency_range(900,1300) # zap between 900 and 1300 MHz 27 | 28 | 29 | 30 | Methods 31 | ------- 32 | 33 | .. py:function:: zap() 34 | 35 | .. py:function:: zap_frequency_range(nulow,nuhigh) 36 | 37 | Mitigate channels within a given frequency range. 38 | 39 | .. py:function:: zap_channels(index) 40 | 41 | Mitigate individual channel(s) 42 | 43 | .. py:function:: zap_minmax([windowsize=20,threshold=4]) 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /docs/_sources/rfimitigator.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | 11 | 12 | RFIMitigator Class 13 | ================== 14 | 15 | The *RFIMitigator* class handles zapping via changing the data weights. 16 | 17 | .. warning:: This class is under heavy construction. 18 | 19 | .. py:class:: RFIMitigator(archive) 20 | 21 | Usage: 22 | 23 | .. code-block:: python 24 | 25 | rm = RFIMitigator(ar) # provide an Archive object 26 | rm.zap_frequency_range(900,1300) # zap between 900 and 1300 MHz 27 | 28 | 29 | 30 | Methods 31 | ------- 32 | 33 | .. py:function:: zap() 34 | 35 | .. py:function:: zap_frequence_range(nulow,nuhigh) 36 | 37 | Mitigate channels within a given frequency range. 38 | 39 | .. py:function:: zap_channels(index) 40 | 41 | Mitigate individual channel(s) 42 | 43 | .. py:function:: zap_minmax([windowsize=20,threshold=4]) 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /docs/_sources/scripts.rst.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | 11 | 12 | Scripts 13 | ===================== 14 | 15 | There are a number of command-line scripts that come with PyPulse for convenience. More to come! 16 | 17 | 18 | 19 | 20 | fitsheader_to_txt 21 | ----------------- 22 | 23 | Prints out the PSRFITS file header information 24 | 25 | fits_to_npy 26 | ----------- 27 | 28 | Converts the data within a PSRFITS file into a .npy file. No metadata are stored with the file. 29 | 30 | 31 | pypav 32 | ----- 33 | 34 | Like PSRCHIVE's `pav` routine, this will provide plots of a PSRFITS file. 35 | 36 | 37 | partytricks 38 | ----------- 39 | 40 | This will take a Par file and calculate the number of pulses from a given time. It can also calculate the eccentricity errors if available 41 | -------------------------------------------------------------------------------- /docs/_sources/scripts.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | 11 | 12 | Scripts 13 | ===================== 14 | 15 | There are a number of command-line scripts that come with PyPulse for convenience. More to come! 16 | 17 | 18 | 19 | 20 | fitsheader_to_txt 21 | ----------------- 22 | 23 | Prints out the PSRFITS file header information 24 | 25 | fits_to_npy 26 | ----------- 27 | 28 | Converts the data within a PSRFITS file into a .npy file. No metadata are stored with the file. 29 | 30 | 31 | pypav 32 | ----- 33 | 34 | Like PSRCHIVE's `pav` routine, this will provide plots of a PSRFITS file. 35 | 36 | 37 | partytricks 38 | ----------- 39 | 40 | This will take a Par file and calculate the number of pulses from a given time. It can also calculate the eccentricity errors if available 41 | -------------------------------------------------------------------------------- /docs/_sources/tim.rst.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | 11 | Tim Class 12 | ========= 13 | 14 | The *Tim* class handles pulsar times-of-arrival (TOAs) files 15 | 16 | .. py:class:: Tim(filename[,numwrap=float,usedecimal=False]) 17 | 18 | :param str filename: Path to a .tim file 19 | :param type numwrap: Type to wrap numeric values by. Float is used by default for ease but Decimal can be is used to keep numeric precision if needed, e.g., for spin period/frequency. Can set numwrap=DECIMAL or usedecimal=True. 20 | :param bool usedecimal: See above. 21 | 22 | Usage: 23 | 24 | .. code-block:: python 25 | 26 | t = Tim(FILENAME) #automatically parses each TOA with the TOA() class 27 | print t.toas[0].getMJD() #prints the MJD of the first TOA as a python Decimal 28 | print t.toas[0].get('snr') #prints the value of the -snr flag of the TOA if it is available 29 | 30 | Methods 31 | ------- 32 | 33 | 34 | .. py:function:: load(filename) 35 | 36 | Loads a .tim file. 37 | 38 | :param str filename: Path to .tim file 39 | 40 | .. py:function:: save(filename) 41 | 42 | Save a .tim file. 43 | 44 | :param str filename: Path to .tim file 45 | 46 | .. py:function:: getFreqs() 47 | 48 | Return the frequencies of each pulse profile the TOAs were generated from. Loops over :func:`getFreq` in :class:`TOA`. 49 | 50 | :rtype: numpy.ndarray 51 | 52 | .. py:function:: getMJDs() 53 | 54 | Return the MJD of each pulse profile the TOAs were generated from. Loops over :func:`getMJD` in :class:`TOA`. 55 | 56 | :rtype: numpy.ndarray 57 | 58 | 59 | .. py:function:: getErrors() 60 | 61 | Return the TOA uncertainties of each pulse profile the TOAs were generated from. Loops over :func:`getError` in :class:`TOA`. 62 | 63 | :rtype: numpy.ndarray 64 | 65 | .. py:function:: get() 66 | 67 | Return the value of a flag in each TOA line. Loops over :func:`get` in :class:`TOA`. 68 | 69 | :rtype: numpy.ndarray 70 | 71 | .. py:function:: getTspan([years=False]) 72 | 73 | Return the total time span covered by the TOAs. 74 | 75 | :param bool years: Divide the total time span in days by 365.25. 76 | :rtype: float 77 | 78 | 79 | TOA Class 80 | ========= 81 | 82 | The *TOA* class handles individual pulsar times-of-arrival (TOAs). 83 | 84 | .. py:class:: TOA(filename[,freq=None,MJD=None,err=None,siteID=None,numwrap=Decimal,**kwargs]) 85 | 86 | Stores the five basic values of a TOA and any additional flags. 87 | 88 | :param str filename: If only the filename parameter is specified, then the parameter is the entire TOA string and will be parsed. 89 | :param str freq: TOA frequency. Can be supplied a numeric value that will be wrapped as a float. 90 | :param str MJD: TOA MJD. Can be supplied a numeric value that will be wrapped with the type numwrap. 91 | :param str err: TOA error in microseconds. Can be supplied a numeric value that will be wrapped as a float. 92 | :param str siteID: TOA observatory site ID. 93 | :param type numwrap: Type to wrap numeric values by. Decimal is used by default to keep numeric precision but becomes difficult to use with other packages. If precision is unneeded, set to float. 94 | :param **kwargs: Additional flags. If the five base parameters are provided, each argument is a tuple of the form (flag, value). Otherwise, this is a string of all of the flags and values that must be parsed. 95 | 96 | Methods 97 | ------- 98 | 99 | .. py:function:: getFilename() 100 | 101 | Return the filename the TOA was generated from. 102 | 103 | :rtype: str 104 | 105 | .. py:function:: getFrequency() 106 | 107 | Return the frequency of the pulse profile the TOA was generated from. 108 | 109 | :rtype: float 110 | 111 | 112 | .. py:function:: getFreq() 113 | 114 | Same as :func:`getFrequency`. 115 | 116 | 117 | .. py:function:: getMJD() 118 | 119 | Return the MJD of the TOA. 120 | 121 | :rtype: float 122 | 123 | .. py:function:: getError() 124 | 125 | Return the TOA error in microseconds. 126 | 127 | :rtype: float 128 | 129 | .. py:function:: getSiteID() 130 | 131 | Return the observatory site ID of the pulse profiles. 132 | 133 | :rtype: str 134 | 135 | .. py:function:: get(flag) 136 | 137 | For any flags stored with the TOA, return the value. 138 | 139 | :param str flag: Name of the flag. 140 | :rtype: str 141 | 142 | .. py:function:: comment() 143 | 144 | Comment out the TOA (the TOA string is appended to "C "). Useful when saving out a .tim file. 145 | 146 | .. py:function:: setFilename(filename) 147 | 148 | Set the filename of the TOA to a value. 149 | 150 | :param str filename: Filename to set in the TOA. 151 | 152 | 153 | .. py:function:: setFrequency(freq) 154 | 155 | Set the frequency of the TOA to a value. 156 | 157 | :param float freq: Frequency to set in the TOA. 158 | 159 | .. py:function:: setFreq(freq) 160 | 161 | Same as :func:`setFrequency`. 162 | 163 | .. py:function:: setMJD(MJD) 164 | 165 | Set the MJD of the TOA to a value. 166 | 167 | :param float MJD: MJD to set in the TOA. 168 | 169 | .. py:function:: setError(err) 170 | 171 | Set the error of the TOA to a value. 172 | 173 | :param float err: Error to set in the TOA. 174 | 175 | .. py:function:: setSiteID(siteID) 176 | 177 | Set the observatory site ID of the TOA to a value. 178 | 179 | :param str siteID: Site ID to set in the TOA. 180 | 181 | .. py:function:: set(flag,value) 182 | 183 | If the flag exists, set the value of an associated flag. 184 | 185 | :param str flag: Name of the flag. 186 | :param str value: Value to set. 187 | 188 | .. py:function:: add(flag,value) 189 | 190 | If the flag does not exist, add the flag with associated value to the TOA. 191 | 192 | :param str flag: Name of the flag. 193 | :param str value: Value to set. 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /docs/_sources/tim.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | 11 | Tim Class 12 | ========= 13 | 14 | The *Tim* class handles pulsar times-of-arrival (TOAs) files 15 | 16 | .. py:class:: Tim(filename[,numwrap=float,usedecimal=False]) 17 | 18 | :param str filename: Path to a .tim file 19 | :param type numwrap: Type to wrap numeric values by. Float is used by default for ease but Decimal can be is used to keep numeric precision if needed, e.g., for spin period/frequency. Can set numwrap=DECIMAL or usedecimal=True. 20 | :param bool usedecimal: See above. 21 | 22 | Usage: 23 | 24 | .. code-block:: python 25 | 26 | t = Tim(FILENAME) #automatically parses each TOA with the TOA() class 27 | print t.toas[0].getMJD() #prints the MJD of the first TOA as a python Decimal 28 | print t.toas[0].get('snr') #prints the value of the -snr flag of the TOA if it is available 29 | 30 | Methods 31 | ------- 32 | 33 | 34 | .. py:function:: load(filename) 35 | 36 | Loads a .tim file. 37 | 38 | :param str filename: Path to .tim file 39 | 40 | .. py:function:: save(filename) 41 | 42 | Save a .tim file. 43 | 44 | :param str filename: Path to .tim file 45 | 46 | .. py:function:: getFreqs() 47 | 48 | Return the frequencies of each pulse profile the TOAs were generated from. Loops over :func:`getFreq` in :class:`TOA`. 49 | 50 | :rtype: numpy.ndarray 51 | 52 | .. py:function:: getMJDs() 53 | 54 | Return the MJD of each pulse profile the TOAs were generated from. Loops over :func:`getMJD` in :class:`TOA`. 55 | 56 | :rtype: numpy.ndarray 57 | 58 | 59 | .. py:function:: getErrors() 60 | 61 | Return the TOA uncertainties of each pulse profile the TOAs were generated from. Loops over :func:`getError` in :class:`TOA`. 62 | 63 | :rtype: numpy.ndarray 64 | 65 | .. py:function:: get() 66 | 67 | Return the value of a flag in each TOA line. Loops over :func:`get` in :class:`TOA`. 68 | 69 | :rtype: numpy.ndarray 70 | 71 | .. py:function:: getTspan([years=False]) 72 | 73 | Return the total time span covered by the TOAs. 74 | 75 | :param bool years: Divide the total time span in days by 365.25. 76 | :rtype: float 77 | 78 | 79 | TOA Class 80 | ========= 81 | 82 | The *TOA* class handles individual pulsar times-of-arrival (TOAs). 83 | 84 | .. py:class:: TOA(filename[,freq=None,MJD=None,err=None,siteID=None,numwrap=Decimal,**kwargs]) 85 | 86 | Stores the five basic values of a TOA and any additional flags. 87 | 88 | :param str filename: If only the filename parameter is specified, then the parameter is the entire TOA string and will be parsed. 89 | :param str freq: TOA frequency. Can be supplied a numeric value that will be wrapped as a float. 90 | :param str MJD: TOA MJD. Can be supplied a numeric value that will be wrapped with the type numwrap. 91 | :param str err: TOA error in microseconds. Can be supplied a numeric value that will be wrapped as a float. 92 | :param str siteID: TOA observatory site ID. 93 | :param type numwrap: Type to wrap numeric values by. Decimal is used by default to keep numeric precision but becomes difficult to use with other packages. If precision is unneeded, set to float. 94 | :param **kwargs: Additional flags. If the five base parameters are provided, each argument is a tuple of the form (flag, value). Otherwise, this is a string of all of the flags and values that must be parsed. 95 | 96 | Methods 97 | ------- 98 | 99 | .. py:function:: getFilename() 100 | 101 | Return the filename the TOA was generated from. 102 | 103 | :rtype: str 104 | 105 | .. py:function:: getFrequency() 106 | 107 | Return the frequency of the pulse profile the TOA was generated from. 108 | 109 | :rtype: float 110 | 111 | 112 | .. py:function:: getFreq() 113 | 114 | Same as :func:`getFrequency`. 115 | 116 | 117 | .. py:function:: getMJD() 118 | 119 | Return the MJD of the TOA. 120 | 121 | :rtype: float 122 | 123 | .. py:function:: getError() 124 | 125 | Return the TOA error in microseconds. 126 | 127 | :rtype: float 128 | 129 | .. py:function:: getSiteID() 130 | 131 | Return the observatory site ID of the pulse profiles. 132 | 133 | :rtype: str 134 | 135 | .. py:function:: get(flag) 136 | 137 | For any flags stored with the TOA, return the value. 138 | 139 | :param str flag: Name of the flag. 140 | :rtype: str 141 | 142 | .. py:function:: comment() 143 | 144 | Comment out the TOA (the TOA string is appended to "C "). Useful when saving out a .tim file. 145 | 146 | .. py:function:: setFilename(filename) 147 | 148 | Set the filename of the TOA to a value. 149 | 150 | :param str filename: Filename to set in the TOA. 151 | 152 | 153 | .. py:function:: setFrequency(freq) 154 | 155 | Set the frequency of the TOA to a value. 156 | 157 | :param float freq: Frequency to set in the TOA. 158 | 159 | .. py:function:: setFreq(freq) 160 | 161 | Same as :func:`setFrequency`. 162 | 163 | .. py:function:: setMJD(MJD) 164 | 165 | Set the MJD of the TOA to a value. 166 | 167 | :param float MJD: MJD to set in the TOA. 168 | 169 | .. py:function:: setError(err) 170 | 171 | Set the error of the TOA to a value. 172 | 173 | :param float err: Error to set in the TOA. 174 | 175 | .. py:function:: setSiteID(siteID) 176 | 177 | Set the observatory site ID of the TOA to a value. 178 | 179 | :param str siteID: Site ID to set in the TOA. 180 | 181 | .. py:function:: set(flag,value) 182 | 183 | If the flag exists, set the value of an associated flag. 184 | 185 | :param str flag: Name of the flag. 186 | :param str value: Value to set. 187 | 188 | .. py:function:: add(flag,value) 189 | 190 | If the flag does not exist, add the flag with associated value to the TOA. 191 | 192 | :param str flag: Name of the flag. 193 | :param str value: Value to set. 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /docs/_sources/utils.rst.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | 11 | 12 | Utils 13 | ===================== 14 | 15 | The utils.py file contains many useful functions called by other classes in PyPulse. 16 | 17 | 18 | 19 | 20 | Functions 21 | --------- 22 | 23 | 24 | .. py:function:: acf(array[,var=False,norm_by_tau=True,lagaxis=False]) 25 | 26 | Uses numpy's correlate function to calculate the autocorrelation function of an array :math:`x`, defined as 27 | 28 | .. math:: \frac{1}{N} \sum_{i\le j} x_i x_j 29 | 30 | where 31 | 32 | :param list/numpy.ndarray array: Data array. 33 | :param bool var: Divide by the variance (using numpy.var) of the time series 34 | :param bool norm_by_tau: Normalize using the number of bins going into each lag bin's computation (thus making each bin an average value). Otherwise just divide by the length of the input array. 35 | :param bool lagaxis: Return the axis of lags and the autocorrelation function rather than just the autocorrelation function. 36 | :return: autocorrelation function, *numpy.ndarray* 37 | 38 | 39 | .. py:function:: imshow(x[,ax=None,origin='lower',interpolation='nearest',aspect='auto',**kwargs]) 40 | 41 | Convenience function for calling matplotlib's imshow(). 42 | 43 | :param list/numpy.ndarray x: 2D data array. 44 | :param axis ax: Uses a matplotlib axis to draw to. If None, then just run open a new figure. 45 | :param str origin: Explicitly pass origin argument to imshow() 46 | :param str interpolation: Explicitly pass interpolation argument to imshow() 47 | :param str aspect: Explicitly pass aspect argument to imshow() 48 | :param **kwargs: Additional arguments to pass to imshow() 49 | :return: im, the return value of either ax.imshow() or plt.imshow() 50 | 51 | .. py:function:: normalize(array[,simple=False,minimum=None]) 52 | 53 | Normalize an array to unit height. 54 | 55 | :param numpy.ndarray array: Data array 56 | :param bool simple: If simple, divide by the maximum of the array. Otherwise, normalize according to :math:`\mathrm{(array-minimum)}/\mathrm{(maximum-minimum)}`, where the minimum is the minimum of the array. 57 | :param float minimum: Provide the minimum value to normalize in the above equation. 58 | :return: array, *numpy.ndarray* 59 | -------------------------------------------------------------------------------- /docs/_sources/utils.txt: -------------------------------------------------------------------------------- 1 | .. PyPulse documentation master file, created by 2 | sphinx-quickstart on Tue Nov 1 19:46:11 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | 10 | 11 | 12 | Utils 13 | ===================== 14 | 15 | The utils.py file contains many useful functions called by other classes in PyPulse. 16 | 17 | 18 | 19 | 20 | Functions 21 | --------- 22 | 23 | 24 | .. py:function:: acf(array[,var=False,norm_by_tau=True,lagaxis=False]) 25 | 26 | Uses numpy's correlate function to calculate the autocorrelation function of an array :math:`x`, defined as 27 | 28 | .. math:: \frac{1}{N} \sum_{i\le j} x_i x_j 29 | 30 | where 31 | 32 | :param list/numpy.ndarray array: Data array. 33 | :param bool var: Divide by the variance (using numpy.var) of the time series 34 | :param bool norm_by_tau: Normalize using the number of bins going into each lag bin's computation (thus making each bin an average value). Otherwise just divide by the length of the input array. 35 | :param bool lagaxis: Return the axis of lags and the autocorrelation function rather than just the autocorrelation function. 36 | :return: autocorrelation function, *numpy.ndarray* 37 | 38 | 39 | .. py:function:: imshow(x[,ax=None,origin='lower',interpolation='nearest',aspect='auto',**kwargs]) 40 | 41 | Convenience function for calling matplotlib's imshow(). 42 | 43 | :param list/numpy.ndarray x: 2D data array. 44 | :param axis ax: Uses a matplotlib axis to draw to. If None, then just run open a new figure. 45 | :param str origin: Explicitly pass origin argument to imshow() 46 | :param str interpolation: Explicitly pass interpolation argument to imshow() 47 | :param str aspect: Explicitly pass aspect argument to imshow() 48 | :param **kwargs: Additional arguments to pass to imshow() 49 | :return: im, the return value of either ax.imshow() or plt.imshow() 50 | 51 | .. py:function:: normalize(array[,simple=False,minimum=None]) 52 | 53 | Normalize an array to unit height. 54 | 55 | :param numpy.ndarray array: Data array 56 | :param bool simple: If simple, divide by the maximum of the array. Otherwise, normalize according to :math:`\mathrm{(array-minimum)}/\mathrm{(maximum-minimum)}`, where the minimum is the minimum of the array. 57 | :param float minimum: Provide the minimum value to normalize in the above equation. 58 | :return: array, *numpy.ndarray* 59 | -------------------------------------------------------------------------------- /docs/_static/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtlam/PyPulse/db9a4c2afbb03f1abb5a8c47aa9f1b28a685170f/docs/_static/ajax-loader.gif -------------------------------------------------------------------------------- /docs/_static/classic.css: -------------------------------------------------------------------------------- 1 | /* 2 | * default.css_t 3 | * ~~~~~~~~~~~~~ 4 | * 5 | * Sphinx stylesheet -- default theme. 6 | * 7 | * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS. 8 | * :license: BSD, see LICENSE for details. 9 | * 10 | */ 11 | 12 | @import url("basic.css"); 13 | 14 | /* -- page layout ----------------------------------------------------------- */ 15 | 16 | body { 17 | font-family: sans-serif; 18 | font-size: 100%; 19 | background-color: #11303d; 20 | color: #000; 21 | margin: 0; 22 | padding: 0; 23 | } 24 | 25 | div.document { 26 | background-color: #1c4e63; 27 | } 28 | 29 | div.documentwrapper { 30 | float: left; 31 | width: 100%; 32 | } 33 | 34 | div.bodywrapper { 35 | margin: 0 0 0 230px; 36 | } 37 | 38 | div.body { 39 | background-color: #ffffff; 40 | color: #000000; 41 | padding: 0 20px 30px 20px; 42 | } 43 | 44 | div.footer { 45 | color: #ffffff; 46 | width: 100%; 47 | padding: 9px 0 9px 0; 48 | text-align: center; 49 | font-size: 75%; 50 | } 51 | 52 | div.footer a { 53 | color: #ffffff; 54 | text-decoration: underline; 55 | } 56 | 57 | div.related { 58 | background-color: #133f52; 59 | line-height: 30px; 60 | color: #ffffff; 61 | } 62 | 63 | div.related a { 64 | color: #ffffff; 65 | } 66 | 67 | div.sphinxsidebar { 68 | } 69 | 70 | div.sphinxsidebar h3 { 71 | font-family: 'Trebuchet MS', sans-serif; 72 | color: #ffffff; 73 | font-size: 1.4em; 74 | font-weight: normal; 75 | margin: 0; 76 | padding: 0; 77 | } 78 | 79 | div.sphinxsidebar h3 a { 80 | color: #ffffff; 81 | } 82 | 83 | div.sphinxsidebar h4 { 84 | font-family: 'Trebuchet MS', sans-serif; 85 | color: #ffffff; 86 | font-size: 1.3em; 87 | font-weight: normal; 88 | margin: 5px 0 0 0; 89 | padding: 0; 90 | } 91 | 92 | div.sphinxsidebar p { 93 | color: #ffffff; 94 | } 95 | 96 | div.sphinxsidebar p.topless { 97 | margin: 5px 10px 10px 10px; 98 | } 99 | 100 | div.sphinxsidebar ul { 101 | margin: 10px; 102 | padding: 0; 103 | color: #ffffff; 104 | } 105 | 106 | div.sphinxsidebar a { 107 | color: #98dbcc; 108 | } 109 | 110 | div.sphinxsidebar input { 111 | border: 1px solid #98dbcc; 112 | font-family: sans-serif; 113 | font-size: 1em; 114 | } 115 | 116 | 117 | 118 | /* -- hyperlink styles ------------------------------------------------------ */ 119 | 120 | a { 121 | color: #355f7c; 122 | text-decoration: none; 123 | } 124 | 125 | a:visited { 126 | color: #355f7c; 127 | text-decoration: none; 128 | } 129 | 130 | a:hover { 131 | text-decoration: underline; 132 | } 133 | 134 | 135 | 136 | /* -- body styles ----------------------------------------------------------- */ 137 | 138 | div.body h1, 139 | div.body h2, 140 | div.body h3, 141 | div.body h4, 142 | div.body h5, 143 | div.body h6 { 144 | font-family: 'Trebuchet MS', sans-serif; 145 | background-color: #f2f2f2; 146 | font-weight: normal; 147 | color: #20435c; 148 | border-bottom: 1px solid #ccc; 149 | margin: 20px -20px 10px -20px; 150 | padding: 3px 0 3px 10px; 151 | } 152 | 153 | div.body h1 { margin-top: 0; font-size: 200%; } 154 | div.body h2 { font-size: 160%; } 155 | div.body h3 { font-size: 140%; } 156 | div.body h4 { font-size: 120%; } 157 | div.body h5 { font-size: 110%; } 158 | div.body h6 { font-size: 100%; } 159 | 160 | a.headerlink { 161 | color: #c60f0f; 162 | font-size: 0.8em; 163 | padding: 0 4px 0 4px; 164 | text-decoration: none; 165 | } 166 | 167 | a.headerlink:hover { 168 | background-color: #c60f0f; 169 | color: white; 170 | } 171 | 172 | div.body p, div.body dd, div.body li, div.body blockquote { 173 | text-align: justify; 174 | line-height: 130%; 175 | } 176 | 177 | div.admonition p.admonition-title + p { 178 | display: inline; 179 | } 180 | 181 | div.admonition p { 182 | margin-bottom: 5px; 183 | } 184 | 185 | div.admonition pre { 186 | margin-bottom: 5px; 187 | } 188 | 189 | div.admonition ul, div.admonition ol { 190 | margin-bottom: 5px; 191 | } 192 | 193 | div.note { 194 | background-color: #eee; 195 | border: 1px solid #ccc; 196 | } 197 | 198 | div.seealso { 199 | background-color: #ffc; 200 | border: 1px solid #ff6; 201 | } 202 | 203 | div.topic { 204 | background-color: #eee; 205 | } 206 | 207 | div.warning { 208 | background-color: #ffe4e4; 209 | border: 1px solid #f66; 210 | } 211 | 212 | p.admonition-title { 213 | display: inline; 214 | } 215 | 216 | p.admonition-title:after { 217 | content: ":"; 218 | } 219 | 220 | pre { 221 | padding: 5px; 222 | background-color: #eeffcc; 223 | color: #333333; 224 | line-height: 120%; 225 | border: 1px solid #ac9; 226 | border-left: none; 227 | border-right: none; 228 | } 229 | 230 | code { 231 | background-color: #ecf0f3; 232 | padding: 0 1px 0 1px; 233 | font-size: 0.95em; 234 | } 235 | 236 | th { 237 | background-color: #ede; 238 | } 239 | 240 | .warning code { 241 | background: #efc2c2; 242 | } 243 | 244 | .note code { 245 | background: #d6d6d6; 246 | } 247 | 248 | .viewcode-back { 249 | font-family: sans-serif; 250 | } 251 | 252 | div.viewcode-block:target { 253 | background-color: #f4debf; 254 | border-top: 1px solid #ac9; 255 | border-bottom: 1px solid #ac9; 256 | } 257 | 258 | div.code-block-caption { 259 | color: #efefef; 260 | background-color: #1c4e63; 261 | } -------------------------------------------------------------------------------- /docs/_static/comment-bright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtlam/PyPulse/db9a4c2afbb03f1abb5a8c47aa9f1b28a685170f/docs/_static/comment-bright.png -------------------------------------------------------------------------------- /docs/_static/comment-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtlam/PyPulse/db9a4c2afbb03f1abb5a8c47aa9f1b28a685170f/docs/_static/comment-close.png -------------------------------------------------------------------------------- /docs/_static/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtlam/PyPulse/db9a4c2afbb03f1abb5a8c47aa9f1b28a685170f/docs/_static/comment.png -------------------------------------------------------------------------------- /docs/_static/contents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtlam/PyPulse/db9a4c2afbb03f1abb5a8c47aa9f1b28a685170f/docs/_static/contents.png -------------------------------------------------------------------------------- /docs/_static/custom.css: -------------------------------------------------------------------------------- 1 | /* This file intentionally left blank. */ 2 | -------------------------------------------------------------------------------- /docs/_static/documentation_options.js: -------------------------------------------------------------------------------- 1 | var DOCUMENTATION_OPTIONS = { 2 | URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), 3 | VERSION: '0.1.1', 4 | LANGUAGE: 'None', 5 | COLLAPSE_INDEX: false, 6 | BUILDER: 'html', 7 | FILE_SUFFIX: '.html', 8 | LINK_SUFFIX: '.html', 9 | HAS_SOURCE: true, 10 | SOURCELINK_SUFFIX: '.txt', 11 | NAVIGATION_WITH_KEYS: false 12 | }; -------------------------------------------------------------------------------- /docs/_static/down-pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtlam/PyPulse/db9a4c2afbb03f1abb5a8c47aa9f1b28a685170f/docs/_static/down-pressed.png -------------------------------------------------------------------------------- /docs/_static/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtlam/PyPulse/db9a4c2afbb03f1abb5a8c47aa9f1b28a685170f/docs/_static/down.png -------------------------------------------------------------------------------- /docs/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtlam/PyPulse/db9a4c2afbb03f1abb5a8c47aa9f1b28a685170f/docs/_static/file.png -------------------------------------------------------------------------------- /docs/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtlam/PyPulse/db9a4c2afbb03f1abb5a8c47aa9f1b28a685170f/docs/_static/minus.png -------------------------------------------------------------------------------- /docs/_static/navigation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtlam/PyPulse/db9a4c2afbb03f1abb5a8c47aa9f1b28a685170f/docs/_static/navigation.png -------------------------------------------------------------------------------- /docs/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtlam/PyPulse/db9a4c2afbb03f1abb5a8c47aa9f1b28a685170f/docs/_static/plus.png -------------------------------------------------------------------------------- /docs/_static/pygments.css: -------------------------------------------------------------------------------- 1 | pre { line-height: 125%; } 2 | td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } 3 | span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } 4 | td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } 5 | span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } 6 | .highlight .hll { background-color: #ffffcc } 7 | .highlight { background: #eeffcc; } 8 | .highlight .c { color: #408090; font-style: italic } /* Comment */ 9 | .highlight .err { border: 1px solid #FF0000 } /* Error */ 10 | .highlight .k { color: #007020; font-weight: bold } /* Keyword */ 11 | .highlight .o { color: #666666 } /* Operator */ 12 | .highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */ 13 | .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ 14 | .highlight .cp { color: #007020 } /* Comment.Preproc */ 15 | .highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */ 16 | .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ 17 | .highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ 18 | .highlight .gd { color: #A00000 } /* Generic.Deleted */ 19 | .highlight .ge { font-style: italic } /* Generic.Emph */ 20 | .highlight .gr { color: #FF0000 } /* Generic.Error */ 21 | .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ 22 | .highlight .gi { color: #00A000 } /* Generic.Inserted */ 23 | .highlight .go { color: #333333 } /* Generic.Output */ 24 | .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ 25 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 26 | .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ 27 | .highlight .gt { color: #0044DD } /* Generic.Traceback */ 28 | .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ 29 | .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ 30 | .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ 31 | .highlight .kp { color: #007020 } /* Keyword.Pseudo */ 32 | .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ 33 | .highlight .kt { color: #902000 } /* Keyword.Type */ 34 | .highlight .m { color: #208050 } /* Literal.Number */ 35 | .highlight .s { color: #4070a0 } /* Literal.String */ 36 | .highlight .na { color: #4070a0 } /* Name.Attribute */ 37 | .highlight .nb { color: #007020 } /* Name.Builtin */ 38 | .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ 39 | .highlight .no { color: #60add5 } /* Name.Constant */ 40 | .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ 41 | .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ 42 | .highlight .ne { color: #007020 } /* Name.Exception */ 43 | .highlight .nf { color: #06287e } /* Name.Function */ 44 | .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ 45 | .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ 46 | .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ 47 | .highlight .nv { color: #bb60d5 } /* Name.Variable */ 48 | .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ 49 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */ 50 | .highlight .mb { color: #208050 } /* Literal.Number.Bin */ 51 | .highlight .mf { color: #208050 } /* Literal.Number.Float */ 52 | .highlight .mh { color: #208050 } /* Literal.Number.Hex */ 53 | .highlight .mi { color: #208050 } /* Literal.Number.Integer */ 54 | .highlight .mo { color: #208050 } /* Literal.Number.Oct */ 55 | .highlight .sa { color: #4070a0 } /* Literal.String.Affix */ 56 | .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ 57 | .highlight .sc { color: #4070a0 } /* Literal.String.Char */ 58 | .highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */ 59 | .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ 60 | .highlight .s2 { color: #4070a0 } /* Literal.String.Double */ 61 | .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ 62 | .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ 63 | .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ 64 | .highlight .sx { color: #c65d09 } /* Literal.String.Other */ 65 | .highlight .sr { color: #235388 } /* Literal.String.Regex */ 66 | .highlight .s1 { color: #4070a0 } /* Literal.String.Single */ 67 | .highlight .ss { color: #517918 } /* Literal.String.Symbol */ 68 | .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ 69 | .highlight .fm { color: #06287e } /* Name.Function.Magic */ 70 | .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ 71 | .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ 72 | .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ 73 | .highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */ 74 | .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ -------------------------------------------------------------------------------- /docs/_static/sidebar.js: -------------------------------------------------------------------------------- 1 | /* 2 | * sidebar.js 3 | * ~~~~~~~~~~ 4 | * 5 | * This script makes the Sphinx sidebar collapsible. 6 | * 7 | * .sphinxsidebar contains .sphinxsidebarwrapper. This script adds 8 | * in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton 9 | * used to collapse and expand the sidebar. 10 | * 11 | * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden 12 | * and the width of the sidebar and the margin-left of the document 13 | * are decreased. When the sidebar is expanded the opposite happens. 14 | * This script saves a per-browser/per-session cookie used to 15 | * remember the position of the sidebar among the pages. 16 | * Once the browser is closed the cookie is deleted and the position 17 | * reset to the default (expanded). 18 | * 19 | * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS. 20 | * :license: BSD, see LICENSE for details. 21 | * 22 | */ 23 | 24 | $(function() { 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | // global elements used by the functions. 34 | // the 'sidebarbutton' element is defined as global after its 35 | // creation, in the add_sidebar_button function 36 | var bodywrapper = $('.bodywrapper'); 37 | var sidebar = $('.sphinxsidebar'); 38 | var sidebarwrapper = $('.sphinxsidebarwrapper'); 39 | 40 | // for some reason, the document has no sidebar; do not run into errors 41 | if (!sidebar.length) return; 42 | 43 | // original margin-left of the bodywrapper and width of the sidebar 44 | // with the sidebar expanded 45 | var bw_margin_expanded = bodywrapper.css('margin-left'); 46 | var ssb_width_expanded = sidebar.width(); 47 | 48 | // margin-left of the bodywrapper and width of the sidebar 49 | // with the sidebar collapsed 50 | var bw_margin_collapsed = '.8em'; 51 | var ssb_width_collapsed = '.8em'; 52 | 53 | // colors used by the current theme 54 | var dark_color = $('.related').css('background-color'); 55 | var light_color = $('.document').css('background-color'); 56 | 57 | function sidebar_is_collapsed() { 58 | return sidebarwrapper.is(':not(:visible)'); 59 | } 60 | 61 | function toggle_sidebar() { 62 | if (sidebar_is_collapsed()) 63 | expand_sidebar(); 64 | else 65 | collapse_sidebar(); 66 | } 67 | 68 | function collapse_sidebar() { 69 | sidebarwrapper.hide(); 70 | sidebar.css('width', ssb_width_collapsed); 71 | bodywrapper.css('margin-left', bw_margin_collapsed); 72 | sidebarbutton.css({ 73 | 'margin-left': '0', 74 | 'height': bodywrapper.height() 75 | }); 76 | sidebarbutton.find('span').text('»'); 77 | sidebarbutton.attr('title', _('Expand sidebar')); 78 | document.cookie = 'sidebar=collapsed'; 79 | } 80 | 81 | function expand_sidebar() { 82 | bodywrapper.css('margin-left', bw_margin_expanded); 83 | sidebar.css('width', ssb_width_expanded); 84 | sidebarwrapper.show(); 85 | sidebarbutton.css({ 86 | 'margin-left': ssb_width_expanded-12, 87 | 'height': bodywrapper.height() 88 | }); 89 | sidebarbutton.find('span').text('«'); 90 | sidebarbutton.attr('title', _('Collapse sidebar')); 91 | document.cookie = 'sidebar=expanded'; 92 | } 93 | 94 | function add_sidebar_button() { 95 | sidebarwrapper.css({ 96 | 'float': 'left', 97 | 'margin-right': '0', 98 | 'width': ssb_width_expanded - 28 99 | }); 100 | // create the button 101 | sidebar.append( 102 | '
«
' 103 | ); 104 | var sidebarbutton = $('#sidebarbutton'); 105 | light_color = sidebarbutton.css('background-color'); 106 | // find the height of the viewport to center the '<<' in the page 107 | var viewport_height; 108 | if (window.innerHeight) 109 | viewport_height = window.innerHeight; 110 | else 111 | viewport_height = $(window).height(); 112 | sidebarbutton.find('span').css({ 113 | 'display': 'block', 114 | 'margin-top': (viewport_height - sidebar.position().top - 20) / 2 115 | }); 116 | 117 | sidebarbutton.click(toggle_sidebar); 118 | sidebarbutton.attr('title', _('Collapse sidebar')); 119 | sidebarbutton.css({ 120 | 'color': '#FFFFFF', 121 | 'border-left': '1px solid ' + dark_color, 122 | 'font-size': '1.2em', 123 | 'cursor': 'pointer', 124 | 'height': bodywrapper.height(), 125 | 'padding-top': '1px', 126 | 'margin-left': ssb_width_expanded - 12 127 | }); 128 | 129 | sidebarbutton.hover( 130 | function () { 131 | $(this).css('background-color', dark_color); 132 | }, 133 | function () { 134 | $(this).css('background-color', light_color); 135 | } 136 | ); 137 | } 138 | 139 | function set_position_from_cookie() { 140 | if (!document.cookie) 141 | return; 142 | var items = document.cookie.split(';'); 143 | for(var k=0; k 3 | 4 | 5 | 6 | 7 | 8 | 9 | PyPulse v0.1.1 — PyPulse 0.1.1 documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 33 | 34 |
35 |
36 |
37 |
38 | 39 |
40 |

PyPulse v0.1.1

41 |

PyPulse is a package used to handle PSRFITS files and perform subsequent analyses on pulse profiles.

42 |

Download:

43 |

Github

44 |

Requirements:

45 | 52 |

Contents:

53 |
54 |
55 | 65 |
66 |
67 |

Misc

68 | 75 |
76 |
77 |

Citations

78 |

See Citations & References for more information, including how to cite PyPulse’s required packages. In using PyPulse, please cite the ASCL via:

79 |

Lam, M. T., 2017, PyPulse, Astrophysics Source Code Library, record ascl:1706.011

80 |
81 |
82 |

Contact

83 |

Please contact michael-dot-lam-at-nanograv-dot-org.

84 |
85 | 86 | 87 |
88 |
89 |
90 |
91 | 123 |
124 |
125 | 138 | 142 | 143 | -------------------------------------------------------------------------------- /docs/license.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | License — PyPulse 0.1.1 documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 33 | 34 |
35 |
36 |
37 |
38 | 39 |
40 |
41 |
42 |

License

43 |

Copyright (c) 2015-2017, Michael T. Lam

44 |

All rights reserved.

45 |

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

46 |
    47 |
  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  2. 48 |
  3. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  4. 49 |
  5. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

  6. 50 |
51 |

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

52 |
53 | 54 | 55 |
56 |
57 |
58 |
59 | 83 |
84 |
85 | 98 | 102 | 103 | -------------------------------------------------------------------------------- /docs/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtlam/PyPulse/db9a4c2afbb03f1abb5a8c47aa9f1b28a685170f/docs/objects.inv -------------------------------------------------------------------------------- /docs/rfimitigator.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | RFIMitigator Class — PyPulse 0.1.1 documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 37 | 38 |
39 |
40 |
41 |
42 | 43 |
44 |
45 |
46 |

RFIMitigator Class

47 |

The RFIMitigator class handles zapping via changing the data weights.

48 |
49 |

Warning

50 |

This class is under heavy construction.

51 |
52 |
53 |
54 | class RFIMitigator(archive)
55 |
56 | 57 |

Usage:

58 |
rm = RFIMitigator(ar) # provide an Archive object
 59 | rm.zap_frequency_range(900,1300) # zap between 900 and 1300 MHz
 60 | 
61 |
62 |
63 |

Methods

64 |
65 |
66 | zap()
67 |
68 | 69 |
70 |
71 | zap_frequency_range(nulow, nuhigh)
72 |

Mitigate channels within a given frequency range.

73 |
74 | 75 |
76 |
77 | zap_channels(index)
78 |

Mitigate individual channel(s)

79 |
80 | 81 |
82 |
83 | zap_minmax([windowsize=20, threshold=4])
84 |
85 | 86 |
87 |
88 | 89 | 90 |
91 |
92 |
93 |
94 | 129 |
130 |
131 | 147 | 151 | 152 | -------------------------------------------------------------------------------- /docs/scripts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Scripts — PyPulse 0.1.1 documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 37 | 38 |
39 |
40 |
41 |
42 | 43 |
44 |
45 |
46 |

Scripts

47 |

There are a number of command-line scripts that come with PyPulse for convenience. More to come!

48 |
49 |

fitsheader_to_txt

50 |

Prints out the PSRFITS file header information

51 |
52 |
53 |

fits_to_npy

54 |

Converts the data within a PSRFITS file into a .npy file. No metadata are stored with the file.

55 |
56 |
57 |

pypav

58 |

Like PSRCHIVE’s pav routine, this will provide plots of a PSRFITS file.

59 |
60 |
61 |

partytricks

62 |

This will take a Par file and calculate the number of pulses from a given time. It can also calculate the eccentricity errors if available

63 |
64 |
65 | 66 | 67 |
68 |
69 |
70 |
71 | 109 |
110 |
111 | 127 | 131 | 132 | -------------------------------------------------------------------------------- /docs/search.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Search — PyPulse 0.1.1 documentation 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 34 | 35 |
36 |
37 |
38 |
39 | 40 |

Search

41 | 42 |
43 | 44 |

45 | Please activate JavaScript to enable the search 46 | functionality. 47 |

48 |
49 | 50 | 51 |

52 | Searching for multiple words only shows matches that contain 53 | all words. 54 |

55 | 56 | 57 |
58 | 59 | 60 | 61 |
62 | 63 | 64 | 65 |
66 | 67 |
68 | 69 | 70 |
71 |
72 |
73 |
74 | 78 |
79 |
80 | 90 | 94 | 95 | -------------------------------------------------------------------------------- /docs/utils.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Utils — PyPulse 0.1.1 documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 38 | 39 |
40 |
41 |
42 |
43 | 44 |
45 |
46 |
47 |

Utils

48 |

The utils.py file contains many useful functions called by other classes in PyPulse.

49 |
50 |

Functions

51 |
52 |
53 | acf(array[, var=False, norm_by_tau=True, lagaxis=False])
54 |

Uses numpy’s correlate function to calculate the autocorrelation function of an array \(x\), defined as

55 |
56 | \[\frac{1}{N} \sum_{i\le j} x_i x_j\]
57 |

where

58 |
59 |
Parameters
60 |
    61 |
  • array (list/numpy.ndarray) – Data array.

  • 62 |
  • var (bool) – Divide by the variance (using numpy.var) of the time series

  • 63 |
  • norm_by_tau (bool) – Normalize using the number of bins going into each lag bin’s computation (thus making each bin an average value). Otherwise just divide by the length of the input array.

  • 64 |
  • lagaxis (bool) – Return the axis of lags and the autocorrelation function rather than just the autocorrelation function.

  • 65 |
66 |
67 |
Returns
68 |

autocorrelation function, numpy.ndarray

69 |
70 |
71 |
72 | 73 |
74 |
75 | imshow(x[, ax=None, origin='lower', interpolation='nearest', aspect='auto', **kwargs])
76 |

Convenience function for calling matplotlib’s imshow().

77 |
78 |
Parameters
79 |
    80 |
  • x (list/numpy.ndarray) – 2D data array.

  • 81 |
  • ax (axis) – Uses a matplotlib axis to draw to. If None, then just run open a new figure.

  • 82 |
  • origin (str) – Explicitly pass origin argument to imshow()

  • 83 |
  • interpolation (str) – Explicitly pass interpolation argument to imshow()

  • 84 |
  • aspect (str) – Explicitly pass aspect argument to imshow()

  • 85 |
  • **kwargs

    Additional arguments to pass to imshow()

    86 |

  • 87 |
88 |
89 |
Returns
90 |

im, the return value of either ax.imshow() or plt.imshow()

91 |
92 |
93 |
94 | 95 |
96 |
97 | normalize(array[, simple=False, minimum=None])
98 |

Normalize an array to unit height.

99 |
100 |
Parameters
101 |
    102 |
  • array (numpy.ndarray) – Data array

  • 103 |
  • simple (bool) – If simple, divide by the maximum of the array. Otherwise, normalize according to \(\mathrm{(array-minimum)}/\mathrm{(maximum-minimum)}\), where the minimum is the minimum of the array.

  • 104 |
  • minimum (float) – Provide the minimum value to normalize in the above equation.

  • 105 |
106 |
107 |
Returns
108 |

array, numpy.ndarray

109 |
110 |
111 |
112 | 113 |
114 |
115 | 116 | 117 |
118 |
119 |
120 |
121 | 156 |
157 |
158 | 174 | 178 | 179 | -------------------------------------------------------------------------------- /pypulse/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["archive", "Archive", "singlepulse", "SinglePulse", 2 | "dynamicspectrum", "DynamicSpectrum", "par", "Par", 3 | "Parameter", "tim", "Tim", "TOA", "utils"] 4 | 5 | __version__ = "0.1.1" 6 | 7 | from pypulse.archive import Archive 8 | from pypulse.singlepulse import SinglePulse 9 | from pypulse.dynamicspectrum import DynamicSpectrum 10 | from pypulse.par import Par 11 | from pypulse.tim import Tim, TOA 12 | from pypulse.dmx import DMX, DM 13 | -------------------------------------------------------------------------------- /pypulse/config/fluxcal.cfg: -------------------------------------------------------------------------------- 1 | # 2 | # Flux calibrator parameters used by fluxcal program 3 | # 4 | # There are two formats: 5 | # 6 | 7 | ########################################################################## 8 | # 9 | # Format 1: 10 | # 11 | # NAME R.Ascension Declination Freq Flux spectral 12 | # (J2000) (J2000) (MHz) (Jy) index 13 | 14 | 0407-658 04:08:20.380 -65:45:09.078 1400.0 14.4 1.189 15 | 16 | 3C353 17:20:28.15 -00:58:46.8 1400.0 57.3 0.76 17 | 18 | 3C274 12:30:49.423 +12:23:28.043 1400.0 200. 0.81 19 | aka Virgo 20 | aka B1228+126 21 | 22 | 3C218 09:18:05.669 -12:05:43.95 1400.0 43.1 0.91 23 | aka Hydra 24 | aka J0918-1205 25 | #aka CAL 26 | 27 | 1413+1509 14:13:41.660 +15:09:39.524 4850.0 0.41 0.20 28 | aka J1413+1509 29 | aka 1413+15 30 | aka J1413on 31 | 32 | ########################################################################## 33 | # 34 | # Format 2: 35 | # 36 | # Flux in Jy for a frequency in GHz is: 37 | # log10(S) = a_0 + a_1*log10(f) + a_2*(log10(f))^2 + ... 38 | # 39 | # See e.g. Baars et al. 1977 for format 2 references 40 | # 41 | # &NAME RAJ DECJ a_0 a_1 a_2 ... 42 | 43 | # fluxes from http://www.vla.nrao.edu/astro/calib/manual/baars.html 44 | 45 | &3C48 01:37:41.30 +33:09:35.13 1.31752 -0.74090 -0.16708 +0.01525 46 | &3C138 05:21:09.90 +16:38:22.12 1.00761 -0.55629 -0.11134 -0.01460 47 | &3C147 05:42:36.127 +49:51:07.23 1.44856 -0.67252 -0.21124 +0.04077 48 | &3C286 13:31:08.284 +30:30:32.94 1.23734 -0.43276 -0.14223 +0.00345 49 | &3C295 14:11:20.647 +52:12:09.04 1.46744 -0.77350 -0.25912 +0.00752 50 | 51 | # 3C190 coeffs derived from flux data compiled on NED - 2008/09 SMR 52 | # - fixed coeff ordering 2009/07 PBD 53 | &3C190 08:01:33.52 +14:14:42.2 0.52853867 -0.93526655 -0.0181853 0.03045624 54 | aka 0801+1414 55 | 56 | # B1442+101 coeffs derived from flux data compiled on NED - 2008/09 PBD 57 | &1445+0958 14:45:16.440 +09:58:35.040 0.389314 -0.0280647 -0.600809 0.0262127 58 | aka J1445+0958 59 | aka J1445+099cal 60 | aka B1442+101 61 | aka 1442+101 62 | aka 1442+10 63 | aka 1442 64 | aka B1442 65 | 66 | # 3C43 coeffs fit to NED data - 2010/02 PBD 67 | &3C43 01:29:59.79 +23:38:19.4 0.55884 -0.732646 0.00253868 0.00141399 68 | aka J0129+2338 69 | aka 0129+2338 70 | aka B0127+23 71 | aka 0127+23 72 | aka B0127 73 | aka 0127 74 | 75 | # 3C394 values fit to NED data - 2011/06 PBD 76 | &3C394 18:59:23.3 +12:59:12 0.585309 -0.843126 -0.1062818 -0.0806427 77 | aka J1859+1259 78 | aka 1859+1259 79 | aka B1857+129 80 | aka 1857+129 81 | 82 | # old values 83 | 84 | # &3C147 05:42:36.137 +49:51:07.234 1.766 0.447 -0.184 85 | # &3C295 14:11:20.647 +52:12:09.04 1.485 0.759 -0.255 86 | 87 | -------------------------------------------------------------------------------- /pypulse/demo/archive_demo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# PyPulse Archive tutorial" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 4, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "from pypulse.archive import Archive" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": null, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [] 29 | } 30 | ], 31 | "metadata": { 32 | "kernelspec": { 33 | "display_name": "Python 2", 34 | "language": "python", 35 | "name": "python2" 36 | }, 37 | "language_info": { 38 | "codemirror_mode": { 39 | "name": "ipython", 40 | "version": 2 41 | }, 42 | "file_extension": ".py", 43 | "mimetype": "text/x-python", 44 | "name": "python", 45 | "nbconvert_exporter": "python", 46 | "pygments_lexer": "ipython2", 47 | "version": "2.7.6" 48 | } 49 | }, 50 | "nbformat": 4, 51 | "nbformat_minor": 1 52 | } 53 | -------------------------------------------------------------------------------- /pypulse/dmx.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Michael Lam 2019 3 | Loads a dmxparse DMX file (tempo output) 4 | ''' 5 | import sys 6 | import numpy as np 7 | import matplotlib.pyplot as plt 8 | import pypulse.utils as u 9 | 10 | if sys.version_info.major == 2: 11 | fmap = map 12 | elif sys.version_info.major == 3: 13 | fmap = lambda x, *args: list(map(x, *args)) 14 | 15 | 16 | class DM(object): 17 | def __init__(self, epoch, value=None, err=None, R1=None, R2=None, 18 | F1=None, F2=None, dmxbin=None): 19 | if (value is not None and err is not None and R1 is not None and 20 | R2 is not None and dmxbin is not None): #F1, F2 not required 21 | self.epoch = epoch 22 | self.value = value 23 | self.err = err 24 | self.R1 = R1 25 | self.R2 = R2 26 | self.F1 = F1 27 | self.F2 = F2 28 | self.dmxbin = dmxbin 29 | else: #parse all arguments 30 | self.dmstring = epoch #stores string 31 | splitstring = self.dmstring.strip().split() 32 | self.epoch = float(splitstring[0]) 33 | self.value = float(splitstring[1]) 34 | self.err = float(splitstring[2]) 35 | self.R1 = float(splitstring[3]) 36 | self.R2 = float(splitstring[4]) 37 | if "DMX" in splitstring[5]: 38 | self.dmxbin = splitstring[5] 39 | else: 40 | self.F1 = float(splitstring[5]) 41 | self.F2 = float(splitstring[6]) 42 | self.dmxbin = splitstring[7] 43 | 44 | def __str__(self): 45 | pass 46 | 47 | def getMJD(self): 48 | return self.getEpoch() 49 | 50 | def getEpoch(self): 51 | return self.epoch 52 | 53 | def getDM(self): 54 | return self.value 55 | 56 | def getValue(self): 57 | return self.value 58 | 59 | def getErr(self): 60 | return self.getError() 61 | 62 | def getError(self): 63 | return self.err 64 | 65 | def getR1(self): 66 | return self.R1 67 | 68 | def getR2(self): 69 | return self.R2 70 | 71 | def getF1(self): 72 | return self.F1 73 | 74 | def getF2(self): 75 | return self.F2 76 | 77 | def getBin(self): 78 | return self.getDMXbin() 79 | 80 | def getDMXbin(self): 81 | return self.dmxbin 82 | 83 | # Use these with extreme caution! 84 | def setMJD(self, epoch): 85 | self.setEpoch(epoch) 86 | 87 | def setEpoch(self, epoch): 88 | self.epoch = epoch 89 | 90 | def setDM(self, value): 91 | self.setValue(value) 92 | 93 | def setValue(self, value): 94 | self.value = value 95 | 96 | def setErr(self, err): 97 | self.setError(err) 98 | 99 | def setError(self, err): 100 | self.err = err 101 | 102 | def setR1(self, R1): 103 | self.R1 = R1 104 | 105 | def setR2(self, R2): 106 | self.R2 = R2 107 | 108 | def setF1(self, F1): 109 | self.F1 = F1 110 | 111 | def setF2(self, F2): 112 | self.F2 = F2 113 | 114 | def setBin(self, dmxbin): 115 | self.setDMXbin(dmxbin) 116 | 117 | def setDMXbin(self, dmxbin): 118 | self.dmxbin = dmxbin 119 | 120 | 121 | class DMX(object): 122 | def __init__(self, filename): 123 | self.filename = filename 124 | 125 | with open(filename, 'r') as FILE: 126 | lines = FILE.readlines() 127 | 128 | self.DMs = [] 129 | self.comment_dict = dict() 130 | 131 | for i, line in enumerate(lines): 132 | if line[0] == "#": 133 | self.comment_dict[i] = line 134 | continue 135 | dm = DM(line) 136 | self.DMs.append(dm) 137 | 138 | def __repr__(self): 139 | return "DMX(%s)"%self.filename 140 | 141 | 142 | def plot(self, filename=None, ax=None, show=True, fmt='k.', **kwargs): 143 | """ Simple plotter """ 144 | if ax is None: 145 | fig = plt.figure() 146 | ax = fig.add_subplot(111) 147 | ax.errorbar(self.getMJDs(), self.getDMs(), yerr=self.getErrs(), fmt=fmt, **kwargs) 148 | 149 | ax.set_xlabel("MJD") 150 | ax.set_ylabel("DMX (pc cm^-3)") 151 | if filename is not None: 152 | plt.savefig(filename) 153 | if show: 154 | plt.show() 155 | return ax 156 | 157 | 158 | def save(self, filename=None): 159 | """ Save DMX file """ 160 | pass 161 | 162 | def getMJDs(self): 163 | """ Return MJDs of all DMs """ 164 | return self.getEpochs() 165 | 166 | def getEpochs(self): 167 | """ Return MJDs of all DMs """ 168 | return self.getter(lambda x: x.getEpoch()) 169 | 170 | def getDMs(self): 171 | """ Return values of all DMs """ 172 | return self.getter(lambda x: x.getValue()) 173 | 174 | def getValues(self): 175 | """ Return values of all DMs """ 176 | return self.getter(lambda x: x.getValue()) 177 | 178 | def getErrs(self): 179 | """ Return errors of all DMs """ 180 | return self.getErrors() 181 | 182 | def getErrors(self): 183 | """ Return errors of all DMs """ 184 | return self.getter(lambda x: x.getError()) 185 | 186 | def getR1s(self): 187 | """ Return R1s of all DMs """ 188 | return self.getter(lambda x: x.getR1()) 189 | 190 | def getR2s(self): 191 | """ Return R2 of all DMs """ 192 | return self.getter(lambda x: x.getR2()) 193 | 194 | def getF1s(self): 195 | """ Return F1s of all DMs """ 196 | return self.getter(lambda x: x.getF1()) 197 | 198 | def getF2s(self): 199 | """ Return F2 of all DMs """ 200 | return self.getter(lambda x: x.getF2()) 201 | 202 | def getBin(self): 203 | """ Return DMX bin of all DMs """ 204 | return self.getDMXbin() 205 | 206 | def getDMXbin(self): 207 | """ Return DMX bin of all DMs """ 208 | return self.getter(lambda x: x.getDMXbin()) 209 | 210 | def getter(self, func): 211 | """ Generic getter. Not written as get() because it requires a function """ 212 | return np.array(fmap(func, self.DMs)) 213 | 214 | def getDMseries(self): 215 | """ get the time series, mirroring Par() """ 216 | ts = self.getMJDs() 217 | dmxs = self.getValues() 218 | errs = self.getErrs() 219 | return ts, dmxs, errs 220 | 221 | def getTspan(self, years=False): 222 | """ Return total timespan of data """ 223 | mjds = self.getMJDs() 224 | if years: 225 | return np.ptp(mjds)/365.25 226 | return np.ptp(mjds) 227 | 228 | def subtractMean(self, save=True): 229 | """ subtract the weighted mean from the timeseries """ 230 | dmxs = self.getValues() 231 | errs = self.getErrs() 232 | wmean, wstd = u.weighted_moments(dmxs, 1.0/errs**2) 233 | 234 | if save: 235 | for dm in self.DMs: 236 | dm.setValue(dm.getValue()-wmean) 237 | return self.getValues() 238 | else: 239 | return dmxs - wmean 240 | -------------------------------------------------------------------------------- /pypulse/functionfit.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import scipy.optimize as optimize 3 | import scipy.special as special 4 | 5 | 6 | def funcgaussian(p, x, baseline=False): 7 | if baseline: 8 | return p[0] * np.exp(-((x-p[1])/(np.sqrt(2)*p[2]))**2) + p[3] 9 | return p[0] * np.exp(-((x-p[1])/(np.sqrt(2)*p[2]))**2) 10 | 11 | def errgaussian(p, x, y, baseline=False): 12 | return funcgaussian(p, x, baseline=baseline) - y 13 | 14 | def gaussianfit(x, y, baseline=False): 15 | x = np.array(x) 16 | y = np.array(y) 17 | height = max(y) 18 | mu = np.sum(x*y)/np.sum(y) 19 | sigma = np.sqrt(np.abs(np.sum((x-mu)**2*y)/np.sum(y))) 20 | if baseline: 21 | p0 = [height, mu, sigma, 0.0] 22 | else: 23 | p0 = [height, mu, sigma] 24 | out = optimize.leastsq(errgaussian, p0[:], args=(x, y, baseline), full_output=1) 25 | p1 = out[0] # output parameters 26 | p1[2] = np.abs(p1[2]) #enforces positive sigma 27 | 28 | s_sq = (errgaussian(p1, x, y, baseline)**2).sum() / (len(x) - 4) 29 | perrs = np.zeros_like(p1) 30 | for i in range(len(perrs)): 31 | perrs[i] = np.sqrt(out[1][i, i]*s_sq) 32 | 33 | #Return values are the coefficients and the errors 34 | return p1, perrs 35 | 36 | #area = np.sum(binwidths*hist) 37 | def funcsimpleDISSpdf(p, x, area=None): 38 | if area is None: 39 | area = 1 40 | S0 = p[0] 41 | niss = p[1] 42 | #scale = p[2] 43 | g = x/S0 44 | return area*((g*niss)**niss / (g * special.gamma(niss))) * np.exp(-g*niss) /S0 45 | #return area*((g*niss)**niss / (g * special.gamma(niss))) * np.exp(-g*niss) /S0 46 | #return scale*((g*niss)**niss / (g * special.gamma(niss))) * np.exp(-g*niss) /S0 47 | 48 | def errsimpleDISSpdf(p, x, y, area=None): 49 | return funcsimpleDISSpdf(p, x, area=area) - y 50 | 51 | def simpleDISSpdffit(x, y): 52 | x = np.array(x) 53 | y = np.array(y) 54 | p0 = [x[np.argmax(y)], 1.0]#, np.max(y)] 55 | p1, success = optimize.leastsq(errsimpleDISSpdf, p0[:], args=(x, y)) 56 | #Return values are the coefficients, the residuals 57 | return p1, errsimpleDISSpdf(p1, x, y) 58 | 59 | #2d Gaussian fitting 60 | #Modification of scipy cookbook to include rotation http://wiki.scipy.org/Cookbook/FittingData 61 | #Note! arr[r, c] convention versus (x, y) 62 | def gaussian2d(amplitude, center_x, center_y, width_x, width_y, rotation, baseline): 63 | center_x_rot = center_x * np.cos(rotation) - center_y * np.sin(rotation) 64 | center_y_rot = center_x * np.sin(rotation) + center_y * np.cos(rotation) 65 | def rotgauss(x, y): 66 | xrot = x * np.cos(rotation) - y * np.sin(rotation) 67 | yrot = x * np.sin(rotation) + y * np.cos(rotation) 68 | return amplitude*np.exp(-0.5*(((center_x_rot-xrot)/width_x)**2+((center_y_rot-yrot)/width_y)**2)) + baseline #Baseline leads to underestimated scintillation parameters and is unnecessary if a baseline value is removed prior? 69 | return rotgauss 70 | 71 | def moments(data): 72 | """Returns (height, x, y, width_x, width_y, rotation, baseline) 73 | the gaussian parameters of a 2D distribution by calculating its 74 | moments """ 75 | total = np.sum(data) 76 | X, Y = np.indices(data.shape) 77 | x = np.sum(X*data)/total 78 | y = np.sum(Y*data)/total 79 | col = data[:, int(y)] 80 | width_x = np.sqrt(np.abs((np.arange(col.size)-x)**2*col).sum()/col.sum()) 81 | row = data[int(x), :] 82 | width_y = np.sqrt(np.abs((np.arange(row.size)-y)**2*row).sum()/row.sum()) 83 | height = np.max(data) 84 | baseline = np.min(data) 85 | return height-baseline, x, y, width_x, width_y, 0.0, baseline 86 | 87 | def fitgaussian2d(data): 88 | """Returns (height, x, y, width_x, width_y) 89 | the gaussian parameters of a 2D distribution found by a fit""" 90 | params = moments(data) 91 | errorfunction = lambda p: np.ravel(gaussian2d(*p)(*np.indices(data.shape)) - data) 92 | p, cov, infodict, mesg, ier = optimize.leastsq(errorfunction, params, full_output=True) 93 | #Must multiply by reduced chi-squared first 94 | #http://stackoverflow.com/questions/14581358/getting-standard-errors-on-fitted-parameters-using-the-optimize-leastsq-method-i 95 | s_sq = (errorfunction(p)**2).sum()/(data.size - len(p)) 96 | if cov is not None: 97 | cov *= s_sq 98 | return p, cov 99 | 100 | 101 | -------------------------------------------------------------------------------- /pypulse/rfimitigator.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | if sys.version_info.major == 2: 4 | fmap = map 5 | elif sys.version_info.major == 3: 6 | fmap = lambda x, *args: list(map(x, *args)) 7 | xrange = range 8 | 9 | class RFIMitigator(object): 10 | def __init__(self, archive): 11 | self.archive = archive 12 | 13 | def can_mitigate(self, flag='F'): 14 | ''' 15 | Check if the shape of the data array is conducive to mitigation 16 | ''' 17 | if flag == 'F': 18 | if self.archive.getNchan() == 1: 19 | return False 20 | return True 21 | if flag == 'T': 22 | if self.archive.getNsubint() == 1: 23 | return False 24 | return True 25 | 26 | def zap(self, val=0.0, t=None, f=None): 27 | ''' 28 | Passes straight to archive's setWeights() 29 | ''' 30 | self.archive.setWeights(val=val, t=t, f=f) 31 | 32 | def unzap(self): 33 | ''' 34 | Gets rid of all weighting 35 | ''' 36 | MAX = np.max(self.archive.getWeights()) 37 | self.archive.setWeights(MAX) 38 | 39 | def zap_frequency_range(self, nulow, nuhigh): 40 | ''' 41 | Mitigate channels within a given frequency range 42 | ''' 43 | if not self.can_mitigate(): 44 | return 45 | 46 | Faxis = self.archive.getAxis('F') 47 | inds = np.where((nulow <= Faxis)&(Faxis <= nuhigh))[0] 48 | for ind in inds: 49 | self.zap(f=ind) 50 | 51 | def zap_channels(self, index): 52 | ''' 53 | Mitigate an individual channel 54 | ''' 55 | if not self.can_mitigate(): 56 | return 57 | if isinstance(index, int): 58 | self.archive.setWeights(0.0, f=index) 59 | elif isinstance(index, (list, tuple, np.ndarray)): 60 | for elem in index: 61 | self.zap(f=elem) 62 | 63 | def zap_minmax(self, windowsize=20, threshold=4): 64 | ''' 65 | Run NANOGrav algorithm, median zapping. Run per subintegration 66 | windowsize = 20 frequency bins long 67 | threshold = 4 sigma 68 | ''' 69 | if not self.can_mitigate(): 70 | return 71 | 72 | nsubint = self.archive.getNsubint() 73 | nchan = self.archive.getNchan() 74 | 75 | # Prepare data 76 | data = self.archive.getData(squeeze=False) 77 | #SinglePulse average profile, no need to invoke creating more SinglePulse instances 78 | spavg = self.archive.spavg 79 | opw = spavg.opw 80 | 81 | if nchan <= windowsize: 82 | for i in xrange(nsubint): 83 | for j in xrange(nchan): 84 | subdata = data[i, 0, :, opw] 85 | compptp = np.ptp(data[i, 0, j, opw]) 86 | ptps = np.zeros(windowsize) 87 | for k in xrange(windowsize): 88 | ptps[k] = np.ptp(subdata[k, :]) 89 | 90 | med = np.median(ptps) 91 | if compptp > threshold*med: 92 | self.zap(f=j) 93 | return 94 | 95 | for i in xrange(nsubint): 96 | for j in xrange(nchan): 97 | low = j - windowsize//2 98 | high = j + windowsize//2 99 | 100 | if low < 0: 101 | high = abs(low) 102 | low = 0 103 | elif high > nchan: 104 | diff = high - nchan 105 | high -= diff 106 | low -= diff 107 | 108 | subdata = data[i, 0, low:high, opw] 109 | compptp = np.ptp(data[i, 0, j, opw]) 110 | ptps = np.zeros(windowsize) 111 | for k in xrange(windowsize): 112 | ptps[k] = np.ptp(subdata[k, :]) 113 | 114 | #ptps = np.array(map(lambda subdata: np.ptp(subdata),data[i,0,low:high,opw])) 115 | 116 | med = np.median(ptps) 117 | if compptp > threshold*med: 118 | self.zap(f=j) 119 | 120 | return 121 | -------------------------------------------------------------------------------- /pypulse/scripts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtlam/PyPulse/db9a4c2afbb03f1abb5a8c47aa9f1b28a685170f/pypulse/scripts/__init__.py -------------------------------------------------------------------------------- /pypulse/scripts/fits_to_npy: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | ''' 4 | Michael Lam 5 | Last Updated: 9/12/2014 6 | 7 | Converts PSRFITS data arrays to npy arrays 8 | ''' 9 | 10 | from pypulse.archive import Archive 11 | from optparse import OptionParser 12 | import sys 13 | import subprocess 14 | import gc 15 | 16 | 17 | cmdline = OptionParser(usage="usage: %prog [options] file1 (file2 ...)") 18 | #cmdline.add_option("-m", dest="overwrite", 19 | # help="Overwrite input files", action="store_true", default=False) 20 | 21 | cmdline.add_option("-T",dest="tscrunch", 22 | help="Sum/scrunch over all times",action="store_true",default=False) 23 | #default=None) #add in factor here? 24 | 25 | cmdline.add_option("-F",dest="fscrunch", 26 | help="Sum/scrunch over all frequencies",action="store_true",default=False) 27 | #default=None) #add in factor here? 28 | 29 | cmdline.add_option("-p",dest="pscrunch", 30 | help="Sum/scrunch over all polarizations",action="store_true",default=False) 31 | #default=None) #add in factor here? 32 | 33 | cmdline.add_option("-v",dest="verbose", 34 | help="Verbose",action="store_true",default=False) 35 | #default=None) #add in factor here? 36 | 37 | 38 | cmdline.add_option("--header",dest="writeheader", 39 | help="Write out header in format filename.header.txt",action="store_true",default=False) 40 | #default=None) #add in factor here? 41 | 42 | cmdline.add_option("--ascii",dest="ascii", 43 | help="Write out to ascii txt file instead of npy",action="store_true",default=False) 44 | 45 | 46 | cmdline.add_option("-e", dest="ext", 47 | help="Extension to append to filename (default=npy or txt)", action="store", 48 | type="string", default="default") 49 | 50 | cmdline.add_option("-o", dest="outdir", 51 | help="Output directory (default=initial directory)",action="store", 52 | type="string", default=".") # default to the directory you are in 53 | 54 | 55 | #cmdline.add_option("-n", "--nchan", dest="nchan", 56 | # help="Original number of PFB channels in file (default=4)", 57 | # action="store", type="int", default=4) 58 | 59 | (opt,args) = cmdline.parse_args() 60 | 61 | 62 | if (len(args)==0): 63 | cmdline.print_help() 64 | sys.exit() 65 | 66 | 67 | 68 | 69 | 70 | 71 | for fname in args: 72 | if opt.writeheader: 73 | p = subprocess.call("python fitsheader_to_txt %s"%fname,shell=True) 74 | 75 | 76 | ar = Archive(fname,prepare=False,verbose=opt.verbose) 77 | ar.dedisperse() 78 | 79 | 80 | if opt.tscrunch: 81 | if opt.verbose: 82 | print("tscrunching") 83 | ar.tscrunch() 84 | if opt.pscrunch: 85 | if opt.verbose: 86 | print("pscrunching") 87 | ar.pscrunch() 88 | if opt.fscrunch: 89 | if opt.verbose: 90 | print("fscrunching") 91 | ar.fscrunch() 92 | 93 | if opt.ext == "default": 94 | if opt.ascii: 95 | ext = "txt" 96 | else: 97 | ext = "npy" 98 | else: 99 | ext = opt.ext 100 | 101 | if opt.outdir == "default": 102 | outdir = None 103 | else: 104 | outdir = opt.outdir 105 | 106 | 107 | ar.saveData(ext=ext,ascii=opt.ascii,outdir=outdir) 108 | #ar.gc() 109 | del ar 110 | 111 | 112 | # Error: if already pscrunched and do not select pscrunch, saveData will fail 113 | -------------------------------------------------------------------------------- /pypulse/scripts/fitsheader_to_txt: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | ''' 4 | Michael Lam 5 | Last Updated: 9/12/2014 6 | 7 | Converts PSRFITS header to txt 8 | ''' 9 | 10 | from optparse import OptionParser 11 | import pyfits 12 | import sys 13 | 14 | 15 | cmdline = OptionParser(usage="usage: %prog [options] file1 (file2 ...)") 16 | #cmdline.add_option("-m", dest="overwrite", 17 | # help="Overwrite input files", action="store_true", default=False) 18 | 19 | 20 | cmdline.add_option("-e", dest="ext", 21 | help="Extension to append to filename (default=header.txt)", action="store", 22 | type="string", default="header.txt") 23 | #cmdline.add_option("-n", "--nchan", dest="nchan", 24 | # help="Original number of PFB channels in file (default=4)", 25 | # action="store", type="int", default=4) 26 | 27 | (opt,args) = cmdline.parse_args() 28 | 29 | 30 | if (len(args)==0): 31 | cmdline.print_help() 32 | sys.exit() 33 | 34 | 35 | 36 | 37 | 38 | for fname in args: 39 | 40 | hdulist = pyfits.open(fname) 41 | header = hdulist[0].header 42 | #print hdulist.info() 43 | 44 | hdunames = map(lambda x: x.name,hdulist) 45 | basename = "".join(fname.split('.')[:-1]) 46 | 47 | 48 | outfilename = basename + "." + opt.ext 49 | 50 | 51 | 52 | #Write out header to file 53 | header.toTxtFile(outfilename,clobber=True) 54 | FILE = open(outfilename,"a") 55 | 56 | output = "" 57 | 58 | #for key in header: 59 | # print "%s\t%s"%(key,header[key]) 60 | 61 | if 'HISTORY' in hdunames: 62 | output += "==============================\n" 63 | output += "==========HISTORY=============\n" 64 | output += "==============================\n" 65 | 66 | historyheader = map(lambda x: x.name,hdulist['HISTORY'].columns) 67 | output += ",".join(historyheader) + "\n" 68 | for d in hdulist['HISTORY'].data: 69 | output += ",".join(map(lambda x: str(x),d)) + "\n" 70 | 71 | if "PSRPARAM" in hdunames: 72 | output += "==============================\n" 73 | output += "=========PARAMETERS===========\n" 74 | output += "==============================\n" 75 | 76 | for d in hdulist['PSRPARAM'].data: 77 | output += d[0] + "\n" 78 | 79 | if "POLYCO" in hdunames: 80 | output += "==============================\n" 81 | output += "==========POLYCO==============\n" 82 | output += "==============================\n" 83 | 84 | polycoheader = map(lambda x: x.name,hdulist['POLYCO'].columns) 85 | output += ",".join(polycoheader) + "\n" 86 | for d in hdulist['POLYCO'].data: 87 | output += ",".join(map(lambda x: str(x),d)) + "\n" 88 | 89 | # Do not include any info from hdulist['SUBINT'] 90 | 91 | FILE.write(output) 92 | FILE.close() 93 | hdulist.close() 94 | -------------------------------------------------------------------------------- /pypulse/scripts/partytricks: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | ''' 4 | Michael Lam 5 | Last Updated: 9/24/2018 6 | 7 | Takes a Par file and calculates the number of pulses from a given time. 8 | Can also calculate the eccentricity errors if available 9 | ''' 10 | 11 | from pypulse.par import Par 12 | from optparse import OptionParser 13 | import numpy as np 14 | from decimal import * 15 | getcontext().prec = 32 16 | from astropy.time import Time 17 | import datetime 18 | 19 | one = Decimal(1) 20 | half = Decimal(0.5) 21 | ltsec = Decimal(299792458) #meters 22 | def fix(num): 23 | return "0"+str(num+one)[1:] 24 | 25 | 26 | cmdline = OptionParser(usage="usage: %prog [options] parfile") 27 | 28 | cmdline.add_option("-t", dest="now", 29 | help="Provide the UTC time in iso format \"YYYY-MM-DD HH:MM:SS\", otherwise use the current system time", action="store", 30 | type="string", default="default") 31 | 32 | 33 | (opt,args) = cmdline.parse_args() 34 | 35 | 36 | if (len(args)==0): 37 | cmdline.print_help() 38 | raise SystemExit 39 | 40 | 41 | 42 | 43 | for fname in args: 44 | print(opt.now) 45 | if opt.now == 'default': 46 | now = Time(datetime.datetime.utcnow()) 47 | else: 48 | try: 49 | now = Time(opt.now,format='iso') 50 | except ValueError: 51 | print("Exiting: Provided UTC time must be in format \"YYYY-MM-DD HH:MM:SS\"") 52 | raise SystemExit 53 | 54 | 55 | print("Using time: %s"%str(now)) 56 | print 57 | 58 | p = Par(fname,numwrap=Decimal) 59 | pepoch = Time(float(p.get('PEPOCH')),format='mjd') 60 | 61 | f = p.getFrequency() 62 | ferr = p.get('F0',error=True) 63 | fdot = p.getFrequencyDot() 64 | fdoterr = p.get('F1',error=True) 65 | 66 | 67 | P = one/f 68 | Perr = P*ferr/f 69 | print("PEPOCH: %s"%str(pepoch.iso)) 70 | print("P = %s"%P) 71 | print("+/- %s s"%fix(Perr)) 72 | Pdot = -one*fdot/f**2 73 | Pdoterr = Pdot*((fdoterr/fdot)**2 + 2*(ferr/f)**2).sqrt() 74 | print("Pdot = %s"%fix(Pdot)) 75 | print(" +/- %s s/s"%fix(Pdoterr)) 76 | print 77 | 78 | # P = [dP/dt]T -> T = P/[dP/dt] 79 | # the last digit in P is 10^-18 s. 80 | # Pdot = 1.402548e-20 s/s 81 | print("The last digit in P changes every %s s"%str(Decimal(1e-18)/Pdot)) #that digit is 10^-18 s 82 | print("The 1e-16 digit in P changes every %s hr"%str(Decimal(1e-16)/Pdot/Decimal(60*60))) #that digit is 10^-18 s 83 | print("The 1e-10 digit in P changes every %s yr"%str(Decimal(1e-10)/Pdot/Decimal(86400*365.25))) #that digit is 10^-18 s 84 | print 85 | 86 | 87 | # Need other binary models 88 | if p.get('BINARY') == 'ELL1': 89 | x = p.get('A1') 90 | xerr = p.get('A1',error=True) 91 | pb = p.get('PB') 92 | pberr = p.get('PB',error=True) 93 | eps1 = p.get('EPS1') 94 | eps2 = p.get('EPS2') 95 | eps1err = p.get('EPS1',error=True) 96 | eps2err = p.get('EPS2',error=True) 97 | 98 | q = (eps1**2 + eps2**2) 99 | ecc = q.sqrt() 100 | 101 | qerr = ((2*eps1*eps1err)**2 + (2*eps2*eps2err)**2).sqrt() 102 | eccerr = half*q**(Decimal(-0.5)) * qerr 103 | 104 | sini = p.get('SINI') 105 | sinierr = p.get('SINI',error=True) 106 | 107 | 108 | 109 | 110 | a = (x/sini)*ltsec 111 | aerr = a*((xerr/x)**2 + (sinierr/sini)**2).sqrt() 112 | 113 | 114 | print("Eccentricity calculations:") 115 | print("e = %s"%str(ecc)) 116 | print(" +/- %s "%str(eccerr)) 117 | print("a = %s"%str(a)) 118 | print(" +/- %s m"%str(aerr)) 119 | 120 | 121 | # Eccentricity e = sqrt(1-(b/a)^2) 122 | # Therefore, b = a*sqrt(1-e^2) 123 | # difference between both is a-b = a-a*sqrt(1-e^2) = a*(1-sqrt(1-e^2)) 124 | 125 | 126 | 127 | eccsq = ecc**2 128 | eccsqerr = eccsq*(2*eccerr/ecc) 129 | q = 1-eccsq #1-e^2 130 | qerr = eccsqerr 131 | r = q.sqrt() #sqrt(1-e^2) 132 | rerr = r*(half*qerr/q) 133 | s = 1-r #1-sqrt(1-e^2) 134 | serr = rerr 135 | fac = a*s 136 | facerr = fac*((aerr/a)**2 + (serr/s)**2).sqrt() 137 | print("a-b = %s"%str(fac)) 138 | print(" +/- %s m"%str(fix(facerr))) 139 | print() 140 | 141 | 142 | 143 | 144 | print("Number of rotations:") 145 | pepoch = Time(float(p.get('PEPOCH')),format='mjd') 146 | print("PEPOCH: %s"%str(pepoch.iso)) 147 | dt = Decimal((now.mjd-pepoch.mjd)*86400) #seconds 148 | # phi = phi0 + f*(t-t0) + (1/2)*fdot*(t-t0)^2 149 | # where t0 = 0, phi0 = 0 150 | phi = f*dt + half*fdot*dt**2 151 | print("N = %s"%str(phi)) 152 | 153 | fprime = f + fdot*dt 154 | print("Spin Period = %s s"%str(one/fprime)) 155 | 156 | 157 | # Need other binary models 158 | if p.get('BINARY') == 'ELL1': 159 | print("Number of orbits:") 160 | Norb = phi*P/86400/pb 161 | print("N_orb = %s"%str(Norb)) 162 | -------------------------------------------------------------------------------- /pypulse/scripts/pypav: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import argparse 3 | import sys 4 | from pypulse.archive import Archive 5 | 6 | 7 | 8 | parser = argparse.ArgumentParser(description='View data in a PSRCHIVE-like pav plot') 9 | 10 | parser.add_argument('-D',action='store_true', 11 | help='Plot a single profile (chan 0, poln 0, subint 0 by default)') 12 | parser.add_argument('-G',action='store_true', 13 | help='Plot an image of amplitude against frequency & phase') 14 | parser.add_argument('-Y',action='store_true', 15 | help='Plot colour map of sub-integrations against pulse phase') 16 | parser.add_argument('--waterfall',action='store_true', 17 | help='Plot waterfall map') 18 | 19 | parser.add_argument('-d',action='store_true', 20 | help='Dedisperse all channels') 21 | parser.add_argument('-F',action='store_true', 22 | help='Fscrunch all frequency channels') 23 | parser.add_argument('-T',action='store_true', 24 | help='Tscrunch all integrations') 25 | parser.add_argument('-p',action='store_true', 26 | help='Add all polarizations together') 27 | 28 | parser.add_argument('-C',action='store_true', 29 | help='Center the pulse at a phase of 0.5') 30 | 31 | parser.add_argument("filename", 32 | help='Filename required') 33 | 34 | 35 | args = parser.parse_args() 36 | print(args) 37 | 38 | ar = Archive(args.filename,prepare=False) 39 | # Pre-processing 40 | if args.p: 41 | ar.pscrunch() 42 | if args.D or args.d: 43 | ar.dedisperse() 44 | if args.T: 45 | ar.tscrunch() 46 | if args.F: 47 | ar.fscrunch() 48 | 49 | if args.C: 50 | ar.center() 51 | 52 | # Plotting 53 | if args.D: 54 | ar.plot() 55 | elif args.G: 56 | ar.pavplot() #need to set mode 'GTpd' or otherwise? 57 | elif args.Y: 58 | ar.pavplot() 59 | elif args.waterfall: 60 | ar.waterfall() 61 | -------------------------------------------------------------------------------- /pypulse/tim.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Michel Lam 2015 3 | Loads a tim file 4 | ''' 5 | import sys 6 | import decimal 7 | import warnings 8 | import numpy as np 9 | #import re 10 | if sys.version_info.major == 2: 11 | fmap = map 12 | elif sys.version_info.major == 3: 13 | fmap = lambda x, *args: list(map(x, *args)) 14 | 15 | #numre = re.compile('(\d+[.]\d+D[+]\d+)|(-?\d+[.]\d+)') 16 | #flagre = re.compile('-[a-zA-Z]') 17 | 18 | #www.atnf.csiro.au/research/pulsar/tempo2/index.php?n=Documentation.ObservationFiles 19 | COMMANDS = ["EFAC", "EQUAD", "T2EFAC", "T2EQUAD", "GLOBAL_EFAC", "EMAX", "EMIN", "EFLOOR", "END", "FMAX", "FMIN", "INCLUDE", "INFO", "MODE", "NOSKIP", "PHASE", "SIGMA", "SKIP", "TIME", "TRACK"] 20 | 21 | 22 | ''' 23 | if all five primary arguments are given, run as normal 24 | else filename is a string and must be parsed 25 | 26 | kwargs are flags 27 | ''' 28 | 29 | DECIMAL = decimal.Decimal 30 | 31 | class TOA(object): 32 | def __init__(self, filename, freq=None, MJD=None, err=None, 33 | siteID=None, numwrap=float, **kwargs): 34 | self.flags = [] 35 | #behave using all arguments regularly 36 | if freq is not None and MJD is not None and err is not None and siteID is not None: 37 | self.filename = filename 38 | self.freq = float(freq) #numwrap? 39 | self.MJD = numwrap(MJD) 40 | self.err = float(err) #numwrap? 41 | self.siteID = siteID 42 | for flag, value in kwargs.items(): 43 | setattr(self, flag, value) 44 | self.flags.append(flag) 45 | else: #parse all arguments 46 | self.toastring = filename #stores toa string 47 | splitstring = self.toastring.strip().split() 48 | self.filename = splitstring[0] 49 | self.freq = float(splitstring[1]) 50 | self.MJD = numwrap(splitstring[2]) 51 | self.err = float(splitstring[3]) 52 | self.siteID = splitstring[4] 53 | for i in range(5, len(splitstring), 2): 54 | flag = splitstring[i][1:] 55 | setattr(self, flag, splitstring[i+1]) 56 | self.flags.append(flag) 57 | 58 | #def __repr__(self): 59 | # return 60 | def __str__(self): 61 | if isinstance(self.MJD, DECIMAL): 62 | retval = "%s %0.6f %s % 7.3f %+4s "%(self.filename, self.freq, self.MJD, self.err, str(self.siteID)) 63 | else: 64 | retval = "%s %0.6f %0.15f % 7.3f %+4s "%(self.filename, self.freq, self.MJD, self.err, str(self.siteID)) 65 | for flag in self.flags: 66 | retval += "-%s %s "%(flag, getattr(self, flag)) 67 | retval = retval[:-1] 68 | return retval 69 | 70 | def getFilename(self): 71 | return self.filename 72 | 73 | def getFreq(self): 74 | return self.getFrequency() 75 | 76 | def getFrequency(self): 77 | return self.freq 78 | 79 | def getMJD(self): 80 | return self.MJD 81 | 82 | def getErr(self): 83 | return self.getError() 84 | 85 | def getError(self): 86 | return self.err 87 | 88 | def getSiteID(self): 89 | return self.siteID 90 | 91 | def get(self, flag): 92 | value = None 93 | try: 94 | value = getattr(self, flag) 95 | except AttributeError: 96 | return None 97 | return value 98 | 99 | # Use these with extreme caution! 100 | def comment(self, cut=None): 101 | self.filename = "C "+self.filename 102 | if cut is not None: 103 | self.add("cut", cut) 104 | 105 | def setFilename(self, filename): 106 | self.filename = filename 107 | 108 | def setFreq(self, freq): 109 | self.setFrequency(freq) 110 | 111 | def setFrequency(self, freq): 112 | self.freq = freq 113 | 114 | def setMJD(self, MJD): 115 | self.MJD = MJD 116 | 117 | def setErr(self, err): 118 | self.setError(err) 119 | 120 | def setError(self, err): 121 | self.err = err 122 | 123 | def setSiteID(self, siteID): 124 | self.siteID = siteID 125 | 126 | def set(self, flag, value): 127 | if hasattr(self, flag): 128 | setattr(self, flag, value) 129 | else: 130 | raise AttributeError("TOA does not contain flag: %s"%flag) 131 | 132 | def add(self, flag, value): 133 | if hasattr(self, flag): 134 | raise AttributeError("Flag already exists: %s"%flag) 135 | else: 136 | self.flags.append(flag) 137 | setattr(self, flag, value) 138 | 139 | 140 | class Tim(object): 141 | def __init__(self, filename, numwrap=float, usedecimal=False): 142 | self.usedecimal = usedecimal 143 | if self.usedecimal: 144 | self.numwrap = DECIMAL 145 | else: 146 | self.numwrap = numwrap 147 | self.load(filename) 148 | 149 | def load(self, filename): 150 | self.filename = filename 151 | 152 | if isinstance(filename, (list, np.ndarray)): 153 | lines = filename 154 | elif isinstance(filename, (str, np.str_)): 155 | with open(filename, 'r') as FILE:#this assumes the file exists 156 | lines = FILE.readlines() 157 | else: 158 | return None 159 | 160 | self.comment_dict = dict() #store these for saving later 161 | self.command_dict = dict() 162 | self.numlines = len(lines) 163 | 164 | self.toas = list() 165 | for i, line in enumerate(lines): 166 | line = line.strip() #for non-IPTA-compliant TOAs 167 | if len(line) == 0 or line[:2] == "C " or line[:2] == "CC" or line[0] == "#": #CC might be bad, but otherwise there are too many variants 168 | self.comment_dict[i] = line 169 | continue 170 | stripline = line.strip() 171 | count = stripline.count(" ") 172 | splitline = stripline.split() 173 | if len(splitline) == 0 or splitline[0] in COMMANDS or count < 4: #is a command 174 | self.command_dict[i] = tuple(splitline) #primitive handling 175 | else: 176 | toa = TOA(line, numwrap=self.numwrap) 177 | self.toas.append(toa) 178 | 179 | def __repr__(self): 180 | numwrapstr = repr(self.numwrap).split("'")[1] 181 | return "Tim(%r, numwrap=%s, usedecimal=%r)" % (self.filename, numwrapstr, self.usedecimal) 182 | 183 | def comment(self, func, cut=None): 184 | """ Apply boolean function to comment TOAs """ 185 | for index, toa in enumerate(self.toas): 186 | if func(toa): 187 | self.comment_line(index, cut=cut) 188 | 189 | def comment_line(self, index, cut=None): 190 | """ Comment out a single TOA, syntactic sugar """ 191 | self.toas[index].comment(cut=cut) 192 | 193 | def any(self, func): 194 | """ Apply boolean function and see if any TOA meets said condition """ 195 | for toa in self.toas: 196 | if func(toa): 197 | return True 198 | return False 199 | 200 | def all(self, func): 201 | """ Apply boolean function and see if all TOAs meet said condition """ 202 | for toa in self.toas: 203 | if not func(toa): 204 | return False 205 | return True 206 | 207 | def where(self, func): 208 | """ Apply boolean function and see which indices are True for when TOAs meet said condition """ 209 | return np.where(np.array(fmap(func, self.toas))) 210 | 211 | 212 | def save(self, filename=None): 213 | """ Save tim file """ 214 | if self.numwrap != DECIMAL: 215 | warnings.warn("Numbers are not wrapped in the Decimal() class. Output MJDs may be improperly truncated!") 216 | 217 | output = "" 218 | 219 | ntoa = 0 220 | for i in range(self.numlines): 221 | if i in self.comment_dict.keys(): 222 | output += (self.comment_dict[i]+"\n") 223 | elif i in self.command_dict.keys(): 224 | output += (" ".join(self.command_dict[i])+"\n") 225 | else: 226 | output += (str(self.toas[ntoa])+"\n") 227 | ntoa += 1 228 | if filename is None: 229 | filename = self.filename 230 | with open(filename, 'w') as FILE: 231 | FILE.write(output) 232 | 233 | def getFilenames(self): 234 | """ Return filenames of all TOAs """ 235 | return np.array([toa.getFilename() for toa in self.toas]) 236 | 237 | def getFreqs(self): 238 | """ Return frequencies of all TOAs """ 239 | return np.array([toa.getFreq() for toa in self.toas]) 240 | getFrequencies = getFreqs 241 | 242 | def getMJDs(self): 243 | """ Return MJDs of all TOAs """ 244 | return np.array([toa.getMJD() for toa in self.toas]) 245 | 246 | def getErrs(self): 247 | """ Return uncertainties of all TOAs """ 248 | return np.array([toa.getErr() for toa in self.toas]) 249 | getErrors = getErrs 250 | 251 | def getSiteIDs(self): 252 | """ Return Site IDs of all TOAs """ 253 | return np.array([toa.getSiteID() for toa in self.toas]) 254 | 255 | def get(self, value, numwrap=None): 256 | """ Return value of flag """ 257 | if numwrap is None: 258 | retval = np.array([toa.get(value) for toa in self.toas]) 259 | else: 260 | retval = np.array([numwrap(toa.get(value)) for toa in self.toas]) 261 | return retval 262 | 263 | def getTspan(self, years=False): 264 | """ Return total timespan of data """ 265 | mjds = self.getMJDs() 266 | if years: 267 | return np.ptp(mjds)/self.numwrap("365.25") 268 | return np.ptp(mjds) 269 | 270 | def set(self, flag, value): 271 | """ Set value of flag for all TOAs """ 272 | for toa in self.toas: 273 | toa.set(flag, value) 274 | return 275 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy>=1.0 2 | scipy>=0.17 3 | matplotlib>=1.3 4 | astropy>=1.0 5 | multiprocessing==0.70a1 6 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.md -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import sys 5 | 6 | from setuptools import setup 7 | 8 | import pypulse 9 | 10 | if sys.argv[-1] == 'publish': 11 | os.system('python setup.py sdist upload') 12 | sys.exit() 13 | 14 | 15 | # read the contents of your README file 16 | this_directory = os.path.abspath(os.path.dirname(__file__)) 17 | with open(os.path.join(this_directory, 'README.md')) as f: 18 | long_description = f.read() 19 | 20 | 21 | setup( 22 | name='PyPulse', 23 | version=pypulse.__version__, 24 | author='Michael Lam', 25 | author_email='michael.lam@nanograv.org', 26 | url='https://github.com/mtlam/PyPulse', 27 | download_url = 'https://github.com/mtlam/PyPulse/archive/v0.1.1.tar.gz', 28 | packages=['pypulse'], 29 | package_dir = {'pypulse': 'pypulse'}, 30 | zip_safe=False, 31 | license='BSD-3', 32 | description='A python package for handling and analyzing PSRFITS files.', 33 | long_description=long_description, 34 | long_description_content_type='text/markdown', 35 | install_requires=['numpy', 'scipy', 'matplotlib', 'astropy'], 36 | classifiers=[ 37 | 'Development Status :: 3 - Alpha', 38 | 'Intended Audience :: Developers', 39 | 'Intended Audience :: Science/Research', 40 | 'License :: OSI Approved :: BSD License', 41 | 'Operating System :: OS Independent', 42 | 'Programming Language :: Python', 43 | ] 44 | ) 45 | -------------------------------------------------------------------------------- /tests/test_par.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Michael Lam 2020 3 | Unit tests for par.py 4 | ''' 5 | 6 | import unittest 7 | import pypulse.par as par 8 | 9 | class TestParameter(unittest.TestCase): 10 | """ Paramaeter testing class """ 11 | 12 | @classmethod 13 | def setUpClass(cls): 14 | cls.filename = "data/J1909-3744_NANOGrav_11yv1.gls.par" 15 | cls.par = par.Par(cls.filename) 16 | cls.param = cls.par.paramlist[5] # PX 17 | cls.ecorr = cls.par.paramlist[-5] 18 | 19 | def test_getName(self): 20 | """ Test getName() """ 21 | self.assertEqual(self.param.getName(), "PX") 22 | 23 | def test_getValue(self): 24 | """ Test getValue() """ 25 | self.assertEqual(self.param.getValue(), 0.9177) 26 | 27 | def test_getFit(self): 28 | """ Test getFit() """ 29 | self.assertEqual(self.param.getFit(), 1) 30 | 31 | def test_getError(self): 32 | """ Test getError() """ 33 | self.assertEqual(self.param.getError(), 0.0295) 34 | 35 | def test_getFlag(self): 36 | """ Test getFlag() """ 37 | self.assertEqual(self.ecorr.getFlag(), "-f") 38 | 39 | def test_getFlagValue(self): 40 | """ Test getFlagValue() """ 41 | self.assertEqual(self.ecorr.getFlagValue(), "Rcvr_800_GUPPI") 42 | 43 | def test_hasFlag(self): 44 | """ Test hasFlag() """ 45 | self.assertTrue(self.ecorr.hasFlag()) 46 | 47 | 48 | class TestPar(unittest.TestCase): 49 | """ Par testing class """ 50 | 51 | @classmethod 52 | def setUpClass(cls): 53 | cls.filename = "data/J1909-3744_NANOGrav_11yv1.gls.par" 54 | cls.par = par.Par(cls.filename) 55 | 56 | def test_get(self): 57 | """ Test get() """ 58 | values = [0.00370, 0.07670, 0.00590, 0.06000] 59 | for i, val in enumerate(self.par.get("ECORR")): 60 | self.assertEqual(values[i], val) 61 | 62 | 63 | #def test_getParameterFlags(self): 64 | # """ Test getFlags() """ 65 | # print(self.par.getParameterFlags("ECORR")) 66 | 67 | def test_getName(self): 68 | """ Test getName() """ 69 | self.assertEqual(self.par.getName(), "J1909-3744") 70 | 71 | def test_getPX(self): 72 | """ Test getPX() and getPX(error=True) """ 73 | self.assertEqual(self.par.getPX(), 0.9177) 74 | self.assertEqual(self.par.getPX(error=True), 0.0295) 75 | 76 | def test_getDM(self): 77 | """ Test getDM() """ 78 | self.assertEqual(self.par.getDM(), 10.391362) 79 | 80 | 81 | def test_getTspan(self): 82 | """ Test getTspan() """ 83 | self.assertAlmostEqual(self.par.getTspan(), 4094.783) 84 | self.assertAlmostEqual(self.par.getTspan(years=True), 11.2109, 85 | places=4) 86 | 87 | 88 | if __name__ == '__main__': 89 | unittest.main() 90 | -------------------------------------------------------------------------------- /tests/test_tim.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Michael Lam 2020 3 | Unit tests for tim.py 4 | ''' 5 | 6 | import unittest 7 | import decimal 8 | import pypulse.tim as tim 9 | 10 | 11 | class TestTOA(unittest.TestCase): 12 | """ TOA testing class """ 13 | 14 | @classmethod 15 | def setUpClass(cls): 16 | cls.filename = "data/J1909-3744_NANOGrav_11yv1.tim" 17 | cls.tim = tim.Tim(cls.filename, usedecimal=True) #numwrap only applies to MJD 18 | cls.toas = cls.tim.toas 19 | 20 | def test_getFilename(self): 21 | """ Test getFilename() """ 22 | self.assertEqual(self.toas[-1].getFilename(), "guppi_57386_J1909-3744_0008.11y.x.ff") 23 | 24 | 25 | def test_getFreq(self): 26 | """ Test getFreq() """ 27 | self.assertEqual(self.toas[-1].getFreq(), 1157.031006) 28 | 29 | def test_getMJD(self): 30 | """ Test getMJD() """ 31 | self.assertEqual(self.toas[-1].getMJD(), decimal.Decimal("57386.798000084492063")) 32 | 33 | 34 | def test_getErr(self): 35 | """ Test getErr() """ 36 | self.assertEqual(self.toas[-1].getErr(), 0.381) 37 | 38 | 39 | def test_get(self): 40 | """ Test get() """ 41 | self.assertEqual(self.toas[-1].get("f"), "Rcvr1_2_GUPPI") 42 | self.assertEqual(float(self.toas[-1].get("bw")), 12.5) 43 | 44 | 45 | class TestTim(unittest.TestCase): 46 | """ Tim testing class """ 47 | 48 | @classmethod 49 | def setUpClass(cls): 50 | cls.filename = "data/J1909-3744_NANOGrav_11yv1.tim" 51 | cls.tim = tim.Tim(cls.filename, usedecimal=True) 52 | 53 | def test_getFilenames(self): 54 | """ Test getFilenames() """ 55 | values = self.tim.getFilenames() 56 | self.assertEqual(values[-1], "guppi_57386_J1909-3744_0008.11y.x.ff") 57 | 58 | def test_getFreqs(self): 59 | """ Test getFreqs() """ 60 | values = self.tim.getFreqs() 61 | self.assertEqual(float(values[-1]), 1157.031006) 62 | 63 | def test_getMJDs(self): 64 | """ Test getMJDs() """ 65 | values = self.tim.getMJDs() 66 | self.assertEqual(values[-1], decimal.Decimal("57386.798000084492063")) 67 | 68 | def test_getErrs(self): 69 | """ Test getErrs() """ 70 | values = self.tim.getErrs() 71 | self.assertEqual(float(values[-1]), 0.381) 72 | 73 | def test_get(self): 74 | """ Test get() """ 75 | f = self.tim.get("f") 76 | bw = self.tim.get("bw", numwrap=float) #forced to be a float 77 | self.assertEqual(f[-1], "Rcvr1_2_GUPPI") 78 | self.assertEqual(bw[-1], 12.5) 79 | 80 | def test_getTspan(self): 81 | """ Test getTspan() """ 82 | self.assertAlmostEqual(float(self.tim.getTspan()), 4094.78146, places=4) 83 | self.assertAlmostEqual(float(self.tim.getTspan(years=True)), 11.2109, 84 | places=4) 85 | 86 | if __name__ == '__main__': 87 | unittest.main() 88 | --------------------------------------------------------------------------------