Skip to content

Commit

Permalink
Merge remote-tracking branch 'AOtools/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
ojdf committed May 23, 2017
2 parents aeb0be7 + f3c70bf commit 8f35acc
Show file tree
Hide file tree
Showing 18 changed files with 299 additions and 31 deletions.
31 changes: 21 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,39 @@
AOtools
=========
# AOtools

Useful tools for Adaptive Optics analysis for the Python Programming Language

[![Build Status](https://travis-ci.org/AOtools/aotools.svg?branch=master)](https://travis-ci.org/AOtools/aotools)[![Build status](https://ci.appveyor.com/api/projects/status/hru9gl4jekcwtm6l/branch/master?svg=true)](https://ci.appveyor.com/project/Soapy/aotools/branch/master)
[![Build Status](https://travis-ci.org/AOtools/aotools.svg?branch=master)](https://travis-ci.org/AOtools/aotools)
[![Build status](https://ci.appveyor.com/api/projects/status/hru9gl4jekcwtm6l/branch/master?svg=true)](https://ci.appveyor.com/project/Soapy/aotools/branch/master)
[![codecov](https://codecov.io/gh/AOtools/aotools/branch/master/graph/badge.svg)](https://codecov.io/gh/AOtools/aotools)
[![Documentation Status](http://readthedocs.org/projects/aotools/badge/?version=latest)](http://aotools.readthedocs.org/en/latest/?badge=latest)

Required libraries
------------------
## Required libraries

```python
SciPy
NumPy
matplotlib
```


Installation
------------
## Installation
As everything is just pure python, you don't really need to "install" at all. To be able to use the tools from anywhere on your system,
add the `aotools` directory to your `PYTHONTPATH`.
Alternatively you can use one of the methods below.

As everything is just pure python, you don't really need to "install" at all. To be able to use the tools from anywhere on your system, add the `aotools` directory to your `PYTHONTPATH`. Alternatively, to install the tools to your system python distribution, run:
### Pip
AOtools can be installed using pip:

pip install aotools

(which may require admin or root privileges)

### From Source
Alternatively, to install the tools to your system python distribution from source, run:

python setup.py install

(which may need admin or root privileges) from the `aotools` directory.
(which may require admin or root privileges) from the `aotools` directory.

This package includes contributions from [Urban Bitenc](https://www.dur.ac.uk/physics/staff/profiles/?id=11418) at the CfAI, Durham University
This package includes contributions from [Urban Bitenc](https://www.dur.ac.uk/physics/staff/profiles/?id=11418) and
[James Osborn](https://www.dur.ac.uk/physics/staff/profiles/?id=11091)at the CfAI, Durham University.
1 change: 1 addition & 0 deletions aotools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from .fouriertransform import *
from .interpolation import *
from .turbulence import *
from .image_processing import *

from ._version import get_versions
__version__ = get_versions()['version']
Expand Down
2 changes: 1 addition & 1 deletion aotools/astronomy/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from ._astronomy import *
from ._astronomy import *
100 changes: 89 additions & 11 deletions aotools/astronomy/_astronomy.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,106 @@
def photonsPerMag(mag, mask, pxlScale, wvlBand, expTime):
'''
import numpy

# Dictionary of flux values at the top of the atmosphere
# band, lamda, dLamda, m=0 flux (Jy)
FLUX_DICTIONARY = {'U': [0.36, 0.15, 1810],
'B': [0.44, 0.22, 4260],
'V': [0.55, 0.16, 3640],
'R': [0.64, 0.23, 3080],
'I': [1.0, 0.19, 2550],
'J': [1.26, 0.16, 1600],
'H': [1.60, 0.23, 1080],
'K': [2.22, 0.23, 670],
'g': [0.52, 0.14, 3730],
'r': [0.67, 0.14, 4490],
'i': [0.79, 0.16, 4760],
'z': [0.91, 0.13, 4810]}


def photons_per_mag(mag, mask, pixel_scale, wvlBand, exposure_time):
"""
Calculates the photon flux for a given aperture, star magnitude and wavelength band
Parameters:
mag (float): Star apparent magnitude
mask (ndarray): 2-d pupil mask array, 1 is transparent, 0 opaque
pxlScale (float): size in metres of each pixel in mask
pixel_scale (float): size in metres of each pixel in mask
wvlBand (float): length of wavelength band in nanometres
expTime (float): Exposure time in seconds
exposure_time (float): Exposure time in seconds
Returns:
float: number of photons
'''

#Area defined in cm, so turn m to cm
area = mask.sum() * pxlScale**2 * 100**2
"""
# Area defined in cm, so turn m to cm
area = mask.sum() * pixel_scale ** 2 * 100 ** 2

photonPerSecPerAreaPerWvl = 1000 * (10**(-float(mag)/2.5))

#Wvl defined in Angstroms
# Wavelength defined in Angstroms
photonPerSecPerArea = photonPerSecPerAreaPerWvl * wvlBand*10

photonPerSec = photonPerSecPerArea * area

photons = photonPerSec * expTime
photons = float(photonPerSec * exposure_time)

return photons

def photons_per_band(mag, mask, pxlScale, expTime, waveband='V'):
'''
Calculates the photon flux for a given aperture, star magnitude and wavelength band
Parameters:
mag (float): Star apparent magnitude
mask (ndarray): 2-d pupil mask array, 1 is transparent, 0 opaque
pxlScale (float): size in metres of each pixel in mask
expTime (float): Exposure time in seconds
waveband (string): Waveband
Returns:
float: number of photons
'''

#Area defined m
area = mask.sum() * pxlScale**2

# Flux density photons s^-1 m^-2
flux_photons = magnitude_to_flux(mag,waveband)

# Total photons
photons = flux_photons * expTime * area

return photons


def magnitude_to_flux(magnitude, waveband='V'):
"""
Converts apparent magnitude to a flux of photons
Parameters:
magnitude (float): Star apparent magnitude
waveband (string): Waveband of the stellar magnitude, can be U, B, V, R, I, J, H, K, g, r, i, z
Returns:
float: Number of photons emitted by the object per second per meter squared
"""

flux_Jy = FLUX_DICTIONARY[waveband][2] * 10 ** (-0.4 * magnitude)
flux_photons = flux_Jy * 1.51E7 * FLUX_DICTIONARY[waveband][1] # photons sec^-1 m^-2
return flux_photons


def flux_to_magnitude(flux, waveband='V'):
"""
Converts incident flux of photons to the apparent magnitude
Parameters:
flux (float): Number of photons received from an object per second per meter squared
waveband (string): Waveband of the measured flux, can be U, B, V, R, I, J, H, K, g, r, i, z
Returns:
float: Apparent magnitude
"""

return photons
flux_Jy = flux / (1.51E7 * FLUX_DICTIONARY[waveband][1])
magnitude = float(-2.5 * numpy.log10(flux_Jy / FLUX_DICTIONARY[waveband][2]))
return magnitude
2 changes: 1 addition & 1 deletion aotools/image_processing/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from .centroiders import *
from .image_processing import *
from ._image_processing import *
3 changes: 2 additions & 1 deletion aotools/turbulence/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
from .infinitephasescreen import *
from .temporal_ps import *
from .slopecovariance import *
from .turb import *
from .turb import *
from .atmos_conversions import *
75 changes: 75 additions & 0 deletions aotools/turbulence/atmos_conversions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import numpy

def cn2_to_seeing(cn2,lamda=500.E-9):
"""
Calculates the seeing angle from the integrated Cn2 value
Parameters:
cn2 (float): integrated Cn2 value in m^2/3
lamda : wavelength
Returns:
seeing angle in arcseconds
"""
r0 = cn2_to_r0(cn2,lamda)
seeing = r0_to_seeing(r0,lamda)
return seeing

def cn2_to_r0(cn2,lamda=500.E-9):
"""
Calculates r0 from the integrated Cn2 value
Parameters:
cn2 (float): integrated Cn2 value in m^2/3
lamda : wavelength
Returns:
r0 in cm
"""
r0=(0.423*(2*numpy.pi/lamda)**2*cn2)**(-3./5.)
return r0

def r0_to_seeing(r0,lamda=500.E-9):
"""
Calculates the seeing angle from r0
Parameters:
r0 (float): Freid's parameter in cm
lamda : wavelength
Returns:
seeing angle in arcseconds
"""
return (0.98*lamda/r0)*180.*3600./numpy.pi

def coherenceTime(cn2,v,lamda=500.E-9):
"""
Calculates the coherence time from profiles of the Cn2 and wind velocity
Parameters:
cn2 (array): Cn2 profile in m^2/3
v (array): profile of wind velocity, same altitude scale as cn2
lamda : wavelength
Returns:
coherence time in seconds
"""
Jv = (cn2*(v**(5./3.))).sum()
tau0=(Jv**(-3./5.))*0.057*lamda**(6./5.)
return tau0

def isoplanaticAngle(cn2,h,lamda=500.E-9):
"""
Calculates the isoplanatic angle from the Cn2 profile
Parameters:
cn2 (array): Cn2 profile in m^2/3
h (Array): Altitude levels of cn2 profile in m
lamda : wavelength
Returns:
isoplanatic angle in arcseconds
"""
Jh = (cn2*(h**(5./3.))).sum()
iso = 0.057*lamda**(6./5.)*Jh**(-3./5.) *180.*3600./numpy.pi
return iso
4 changes: 2 additions & 2 deletions aotools/turbulence/temporal_ps.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def calc_slope_temporalps(slope_data):
n_frames = slope_data.shape[-2]

# Only take half result, as FFT mirrors
tps = abs(numpy.fft.fft(slope_data, axis=-2)[..., :n_frames/2, :])**2
tps = abs(numpy.fft.fft(slope_data, axis=-2)[..., :int(n_frames/2), :])**2

# Find mean across all sub-aps
tps = (abs(tps)**2)
Expand All @@ -52,7 +52,7 @@ def get_tps_time_axis(frame_rate, n_frames):
ndarray: Time values for temporal power spectra plots
"""

t_vals = numpy.fft.fftfreq(n_frames, 1./frame_rate)[:n_frames/2.]
t_vals = numpy.fft.fftfreq(n_frames, 1./frame_rate)[:int(n_frames/2)]

return t_vals

Expand Down
6 changes: 3 additions & 3 deletions aotools/wfs/wfslib.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@


def findActiveSubaps(subaps, mask, threshold, returnFill=False):
'''
"""
Finds the subapertures which are "seen" be through the
pupil function. Returns the coords of those subaps
pupil function. Returns the coords of those subapertures
Parameters:
subaps (int): The number of subaps in x (assumes square)
Expand All @@ -24,7 +24,7 @@ def findActiveSubaps(subaps, mask, threshold, returnFill=False):
Returns:
ndarray: An array of active subap coords
'''
"""

subapCoords = []
xSpacing = mask.shape[0]/float(subaps)
Expand Down
12 changes: 12 additions & 0 deletions doc/source/astronomy.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Astronomical Functions
======================

Magnitude and Flux Calculations
-------------------------------

.. automodule:: aotools.astronomy
:members:
:imported-members:
:undoc-members:
:exclude-members: numpy
:show-inheritance:
2 changes: 1 addition & 1 deletion doc/source/centroiders.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Centroiders


Centroider module
--------------------------
-----------------

.. automodule:: aotools.image_processing.centroiders
:members:
Expand Down
2 changes: 1 addition & 1 deletion doc/source/fft.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Normalised Fourier Transforms
=============================

aotools.fouriertransform module
------------------
-------------------------------

.. automodule:: aotools.fouriertransform
:members:
Expand Down
1 change: 1 addition & 0 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Contents:
wfs
zernike
opticalpropagation
astronomy

Indices and tables
==================
Expand Down
5 changes: 5 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
'aotools.wfs',
],

install_requires=['numpy',
'scipy',
'matplotlib',
],

description='A set of useful functions for Adaptive Optics in Python',
long_description=open('README.md').read(),
version=versioneer.get_version(),
Expand Down
23 changes: 23 additions & 0 deletions test/test_astronomy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from aotools import astronomy, circle


def test_photons_per_mag():
mask = circle(2, 5)
photons = astronomy.photons_per_mag(5.56, mask, 0.5, 0.3, 10)
assert type(photons) == float


def test_flux_to_magnitude():
magnitude = astronomy.flux_to_magnitude(52504716., 'V')
assert type(magnitude) == float


def test_magnitude_to_flux():
flux = astronomy.magnitude_to_flux(5.56, 'V')
assert type(flux) == float


def test_magnitude_to_flux_and_flux_to_magnitude():
flux = astronomy.magnitude_to_flux(5.56, 'V')
magnitude = astronomy.flux_to_magnitude(flux, 'V')
assert magnitude == 5.56
Loading

0 comments on commit 8f35acc

Please sign in to comment.