panoptes.utils package

Submodules

panoptes.utils.error module

exception panoptes.utils.error.ArduinoDataError(msg=None, exit=False)[source]

Bases: panoptes.utils.error.PanError

PanError raised when there is something very wrong with Arduino information.

exception panoptes.utils.error.BadConnection(msg=None, exit=False)[source]

Bases: panoptes.utils.error.PanError

PanError raised when a connection is bad

exception panoptes.utils.error.BadSerialConnection(msg=None, exit=False)[source]

Bases: panoptes.utils.error.PanError

PanError raised when serial command is bad

exception panoptes.utils.error.CameraNotFound(msg=None, exit=False)[source]

Bases: panoptes.utils.error.NotFound

Camera cannot be imported

exception panoptes.utils.error.DomeNotFound(msg=None, exit=False)[source]

Bases: panoptes.utils.error.NotFound

Dome device not found.

exception panoptes.utils.error.GoogleCloudError(msg=None, exit=False)[source]

Bases: panoptes.utils.error.PanError

Errors related to google cloud

exception panoptes.utils.error.IllegalValue(msg=None, exit=False)[source]

Bases: panoptes.utils.error.PanError, ValueError

Errors from trying to hardware parameters to values not supported by a particular model

exception panoptes.utils.error.InvalidCommand(msg=None, exit=False)[source]

Bases: panoptes.utils.error.PanError

PanError raised if a system command does not run

exception panoptes.utils.error.InvalidConfig(msg=None, exit=False)[source]

Bases: panoptes.utils.error.PanError

PanError raised if config file is invalid

exception panoptes.utils.error.InvalidDeserialization(msg='Problem deserializing', **kwargs)[source]

Bases: panoptes.utils.error.PanError

Error for serialization errors

exception panoptes.utils.error.InvalidMountCommand(msg=None, exit=False)[source]

Bases: panoptes.utils.error.PanError

PanError raised if attempting to send command that doesn’t exist

exception panoptes.utils.error.InvalidObservation(msg=None, exit=False)[source]

Bases: panoptes.utils.error.NotFound

PanError raised if a field is invalid.

exception panoptes.utils.error.InvalidSerialization(msg='Problem Serializing', **kwargs)[source]

Bases: panoptes.utils.error.PanError

Error for serialization errors

exception panoptes.utils.error.InvalidSystemCommand(msg='Problem running system command', **kwargs)[source]

Bases: panoptes.utils.error.PanError

Error for a system level command malfunction

exception panoptes.utils.error.MountNotFound(msg='Mount Not Found', **kwargs)[source]

Bases: panoptes.utils.error.NotFound

Mount cannot be import

exception panoptes.utils.error.NoObservation(msg='No valid observations found.', **kwargs)[source]

Bases: panoptes.utils.error.PanError

Generic no Observation

exception panoptes.utils.error.NotFound(msg=None, exit=False)[source]

Bases: panoptes.utils.error.PanError

Generic not found class

exception panoptes.utils.error.NotSupported(msg=None, exit=False)[source]

Bases: panoptes.utils.error.PanError, NotImplementedError

Errors from trying to use hardware features not supported by a particular model

exception panoptes.utils.error.PanError(msg=None, exit=False)[source]

Bases: Exception

Base class for Panoptes errors

exit_program(msg=None)[source]

Kills running program

exception panoptes.utils.error.SolveError(msg=None, exit=False)[source]

Bases: panoptes.utils.error.NotFound

Camera cannot be imported

exception panoptes.utils.error.TheSkyXError(msg=None, exit=False)[source]

Bases: panoptes.utils.error.PanError

Errors from TheSkyX

exception panoptes.utils.error.TheSkyXKeyError(msg=None, exit=False)[source]

Bases: panoptes.utils.error.TheSkyXError

Errors from TheSkyX because bad key passed

exception panoptes.utils.error.TheSkyXTimeout(msg=None, exit=False)[source]

Bases: panoptes.utils.error.TheSkyXError

Errors from TheSkyX because bad key passed

exception panoptes.utils.error.Timeout(msg='Timeout waiting for event', **kwargs)[source]

Bases: panoptes.utils.error.PanError

Error called when an event times out

panoptes.utils.horizon module

class panoptes.utils.horizon.Horizon(obstructions=[], default_horizon=30)[source]

Bases: object

A simple class to define some coordinate points.

Accepts a list of lists where each list consists of two points corresponding to an altitude (0-90) and an azimuth (0-360). If azimuth is a negative number (but greater than -360) then 360 will be added to put it in the correct range.

The list are points that are obstruction points beyond the default horizon.

__init__(obstructions=[], default_horizon=30)[source]

Create a list of horizon obstruction points.

Each item in the obstructions list should be two or more points, where each point is an [Alt, Az] coordinate.

Example

An example obstruction_point list:

[
[[40, 30], [40, 75]],   # From azimuth 30° to 75° there is an
                        # obstruction that is at 40° altitude
[[50, 180], [40, 200]], # From azimuth 180° to 200° there is
                        # an obstruction that slopes from 50°
                        # to 40° altitude
]
Parameters:
  • obstructions (list(list(list)), optional) – A list of obstructions where each obstruction consists of a set of lists. The individual lists are alt/az pairs. Defaults to empty list in which case the default_horizon defines a flat horizon.
  • default_horizon (float, optional) – A default horizon to be used whenever there is no obstruction.

panoptes.utils.library module

panoptes.utils.library.load_c_library(name, path=None, mode=0, **kwargs)[source]

Utility function to load a shared/dynamically linked library (.so/.dylib/.dll).

The name and location of the shared library can be manually specified with the library_path argument, otherwise the ctypes.util.find_library function will be used to try to locate based on library_name.

Parameters:
  • name (str) – name of the library (without ‘lib’ prefix or any suffixes, e.g. ‘fli’).
  • path (str, optional) – path to the library e.g. ‘/usr/local/lib/libfli.so’.
  • mode (int, optional) – mode in which to load the library, see dlopen(3) man page for details. Should be one of ctypes.RTLD_GLOBAL, ctypes.RTLD_LOCAL, or ctypes.DEFAULT_MODE. Default is ctypes.DEFAULT_MODE.
Returns:

ctypes.CDLL

Raises:
  • pocs.utils.error.NotFound – raised if library_path not given & find_library fails to locate the library.
  • OSError – raises if the ctypes.CDLL loader cannot load the library.
panoptes.utils.library.load_module(module_name)[source]

Dynamically load a module.

>>> from panoptes.utils.library import load_module
>>> error = load_module('panoptes.utils.error')
>>> error.__name__
'panoptes.utils.error'
>>> error.__package__
'panoptes.utils'
Parameters:module_name (str) – Name of module to import.
Returns:an imported module name
Return type:module
Raises:error.NotFound – If module cannot be imported.

panoptes.utils.logging module

panoptes.utils.rs232 module

Provides SerialData, a PySerial wrapper.

class panoptes.utils.rs232.SerialData(port=None, baudrate=115200, name=None, timeout=2.0, open_delay=0.0, retry_limit=5, retry_delay=0.5, **kwargs)[source]

Bases: object

SerialData wraps a PySerial instance for reading from and writing to a serial device.

Because POCS is intended to be very long running, and hardware may be turned off when unused or to force a reset, this wrapper may or may not have an open connection to the underlying serial device. Note that for most devices, is_connected will return true if the device is turned off/unplugged after a connection is opened; the code will only discover there is a problem when we attempt to interact with the device.

>>> import serial

# Register our serial simulators
>>> serial.protocol_handler_packages.append('panoptes.utils.serial_handlers')
>>> from panoptes.utils.serial_handlers import protocol_buffers as pb

# Import our serial utils
>>> from panoptes.utils.rs232 import SerialData

# Connect to our fake buffered device
>>> device_listener = SerialData(port='buffers://')

# Note: A manual reset is currently required because implementation is not complete.
# See https://github.com/panoptes/POCS/issues/758 for details.
>>> pb.ResetBuffers()
>>> device_listener.is_connected
True

>>> device_listener.port
'buffers://'

# Device sends event
>>> pb.SetRBufferValue(b'emit event')

# Listen for event
>>> device_listener.read()
'emit event'

>>> device_listener.write('ack event')
9
>>> pb.GetWBufferValue()
b'ack event'

# Remove custom handlers
>>> serial.protocol_handler_packages.remove('panoptes.utils.serial_handlers')
__init__(port=None, baudrate=115200, name=None, timeout=2.0, open_delay=0.0, retry_limit=5, retry_delay=0.5, **kwargs)[source]

Create a SerialData instance and attempt to open a connection.

The device need not exist at the time this is called, in which case is_connected will be false.

Parameters:
  • port – The port (e.g. /dev/tty123 or socket://host:port) to which to open a connection.
  • baudrate – For true serial lines (e.g. RS-232), sets the baud rate of the device.
  • name – Name of this object. Defaults to the name of the port.
  • timeout (float, optional) – Timeout in seconds for both read and write. Defaults to 2.0.
  • open_delay – Seconds to wait after opening the port.
  • retry_limit – Number of times to try readline() calls in read().
  • retry_delay – Delay between readline() calls in read().
Raises:

ValueError – If the serial parameters are invalid (e.g. a negative baudrate).

connect()[source]

If disconnected, then connect to the serial port.

Raises:error.BadSerialConnection if unable to open the connection.
disconnect()[source]

Closes the serial connection.

Raises:error.BadSerialConnection if unable to close the connection.
get_and_parse_reading(retry_limit=5)[source]

Reads a line of JSON text and returns the decoded value, along with the current time.

Parameters:retry_limit – Number of lines to read in an attempt to get one that parses as JSON.
Returns:A pair (tuple) of (timestamp, decoded JSON line). The timestamp is the time of completion of the readline operation.
get_reading()[source]

Reads and returns a line, along with the timestamp of the read.

Returns:A pair (tuple) of (timestamp, line). The timestamp is the time of completion of the readline operation.
is_connected

True if serial port is open, False otherwise.

port

Name of the port.

read(retry_limit=None, retry_delay=None)[source]

Reads next line of input using readline.

If no response is given, delay for retry_delay and then try to read again. Fail after retry_limit attempts.

read_bytes(size=1)[source]

Reads size bytes from the serial port.

If a read timeout is set on self.ser, this may return less characters than requested. With no timeout it will block until the requested number of bytes is read.

Parameters:size – Number of bytes to read.
Returns:Bytes read from the port.
reset_input_buffer()[source]

Clear buffered data from connected port/device.

Note that Wilfred reports that the input from an Arduino can seriously lag behind realtime (e.g. 10 seconds), and that clear_buffer may exist for that reason (i.e. toss out any buffered input from a device, and then read the next full line, which likely requires tossing out a fragment of a line).

write(value)[source]

Write value (a string) after encoding as bytes.

write_bytes(data)[source]

Write data of type bytes.

panoptes.utils.rs232.get_serial_port_info()[source]

Returns the serial ports defined on the system.

Returns: a list of PySerial’s ListPortInfo objects. See:
https://github.com/pyserial/pyserial/blob/master/serial/tools/list_ports_common.py

panoptes.utils.serializers module

class panoptes.utils.serializers.StringYAML(_kw=<object object>, typ=None, pure=False, output=None, plug_ins=None)[source]

Bases: ruamel.yaml.main.YAML

dump(data, stream=None, **kwargs)[source]

YAML class that can dump to a string.

By default the YAML parser doesn’t serialize directly to a string. This class is a small wrapper to output StreamIO as a string if no stream is provided.

See https://yaml.readthedocs.io/en/latest/example.html#output-of-dump-as-a-string.

Note

This class should not be used directly but instead is instantiated as part of the yaml convenience methods below.

Parameters:
  • data (object) – An object, usually dict-like.
  • stream (None | stream, optional) – A stream object to write the YAML. If default None, return value as string.
  • **kwargs – Keywords passed to the dump function.
Returns:

The serialized object string.

Return type:

str

panoptes.utils.serializers.deserialize_all_objects(obj)[source]

Recursively parse the incoming object for various data types.

This will currently attempt to parse and return, in the following order:

If obj is a dict with exactly two keys named unit and value, then attempt to parse into a valid astropy.unit.Quantity.

A boolean.

A datetime.datetime object as parsed by dateutil.parser.parse.

If a string ending with any of ['m', 'deg', 's'], an astropy.unit.Quantity

Note

See the to/from_json/yaml methods, which use this function.

Parameters:obj (dict or str or object) – Object to check for quantities.
Returns:Same as obj but with objects converted to quantities.
Return type:dict
panoptes.utils.serializers.from_json(msg)[source]

Convert a JSON string into a Python object.

Astropy quanitites will be converted from a {"value": val, "unit": unit} format. Additionally, the following units will be converted if the value ends with the exact string:

  • deg
  • m
  • s

Time-like values are not parsed, however see example below.

Examples:

>>> from panoptes.utils.serializers import from_json
>>> config_str = '{"name":"Mauna Loa","elevation":{"value":3397.0,"unit":"m"}}'
>>> from_json(config_str)
{'name': 'Mauna Loa', 'elevation': <Quantity 3397. m>}

# Invalid values will be returned as is.
>>> from_json('{"horizon":{"value":42.0,"unit":"degr"}}')
{'horizon': {'value': 42.0, 'unit': 'degr'}}

# The following will convert if final string:
>>> from_json('{"horizon": "42.0 deg"}')
{'horizon': <Quantity 42. deg>}

>>> from_json('{"elevation": "1000 m"}')
{'elevation': <Quantity 1000. m>}

>>> from_json('{"readout_time": "10 s"}')
{'readout_time': <Quantity 10. s>}

# Be careful with short unit names in extended format!
>>> horizon = from_json('{"horizon":{"value":42.0,"unit":"d"}}')
>>> horizon['horizon']
<Quantity 42. d>
>>> horizon['horizon'].decompose()
<Quantity 3628800. s>

>>> from panoptes.utils import current_time
>>> time_str = to_json({"current_time": current_time().datetime})
>>> from_json(time_str)['current_time']         
2019-04-08T06:43:28.232406

>>> from astropy.time import Time
>>> Time(from_json(time_str)['current_time'])   
<Time object: scale='utc' format='isot' value=2019-04-08T06:43:28.232>
Parameters:msg (str) – The JSON string representation of the object.
Returns:The loaded object.
Return type:dict
panoptes.utils.serializers.from_yaml(msg, parse=True)[source]

Convert a YAML string into a Python object.

This is a thin-wrapper around ruamel.YAML.load that also parses the results looking for astropy.units.Quantity objects.

Comments are preserved as long as the object remains YAML (lost on conversion to JSON, for example).

See from_json for examples of astropy unit parsing.

Examples

Note how comments in the YAML are preserved.

>>> config_str = '''name: Testing PANOPTES Unit
... pan_id: PAN000
...
... location:
...   latitude: 19.54 deg
...   longitude: -155.58 deg
...   name: Mauna Loa Observatory  # Can be anything
... '''

>>> config = from_yaml(config_str)
>>> config['location']['latitude']
<Quantity 19.54 deg>

>>> yaml_config = to_yaml(config)
>>> yaml_config                  
''' name: Testing PANOPTES Unit
... pan_id: PAN000  # CHANGE NAME
...
... location:
...   latitude: 19.54 deg
...   longitude: value: -155.58 deg
...   name: Mauna Loa Observatory  # Can be anything
... '''
>>> yaml_config == config_str
True
Parameters:
  • msg (str) – The YAML string representation of the object.
  • parse (bool) – If objects should be parsed via _parse_all_objects, default True.
Returns:

The ordered dict representing the YAML string, with appropriate

object deserialization.

Return type:

collections.OrderedDict

panoptes.utils.serializers.serialize_all_objects(obj)[source]

Iterate the obj items and serialize each value.

Note

See the to/from_json/yaml methods, which use this function.

Parameters:obj (dict) – The dictionary object to be iterated.
Returns:The same as obj but with the values serialized.
Return type:dict
panoptes.utils.serializers.serialize_object(obj)[source]

Serialize the given object.

This is a custom serializer function used by to_json to serialize individual objects. Also called in a loop by serialize_all_objects.

>>> from panoptes.utils.serializers import serialize_object
>>> from dateutil.parser import parse as date_parse
>>> from astropy import units as u
>>> serialize_object(42 * u.meter)
'42.0 m'
>>> party_time = date_parse('1999-12-31 11:59:59')
>>> type(party_time)
 <class 'datetime.datetime'>
>>> serialize_object(party_time)
'1999-12-31T11:59:59.000'

Note

See the to/from_json/yaml methods, which use this function.

Parameters:obj (any) – The object to be serialized.

Returns:

panoptes.utils.serializers.to_json(obj, filename=None, append=True, **kwargs)[source]

Convert a Python object to a JSON string.

Will handle datetime objects as well as astropy.unit.Quantity objects. Astropy quantities will be converted to a dict: {“value”: val, “unit”: unit}.

Examples:

>>> from panoptes.utils.serializers import to_json
>>> from astropy import units as u
>>> config = { "name": "Mauna Loa", "elevation": 3397 * u.meter }
>>> to_json(config)
'{"name": "Mauna Loa", "elevation": "3397.0 m"}'

>>> to_json({"numpy_array": np.arange(10)})
'{"numpy_array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}'

>>> from panoptes.utils import current_time
>>> to_json({"current_time": current_time()})       
'{"current_time": "2019-04-08 22:19:28.402198"}'
Parameters:
  • obj (object) – The object to be converted to JSON, usually a dict.
  • filename (str, optional) – Path to file for saving.
  • append (bool, optional) – Append to filename, default True. Setting False will clobber the file.
  • **kwargs – Keyword arguments passed to json.dumps.
Returns:

The JSON string representation of the object.

Return type:

str

panoptes.utils.serializers.to_yaml(obj, **kwargs)[source]

Serialize a Python object to a YAML string.

This will properly serialize the following:

  • datetime.datetime
  • astropy.time.Time
  • astropy.units.Quantity

Examples

Also see the examples from_yaml.

>>> import os
>>> os.environ['POCSTIME'] = '1999-12-31 23:49:49'
>>> from panoptes.utils import current_time
>>> t0 = current_time()
>>> t0
<Time object: scale='utc' format='iso' value=1999-12-31 23:49:49.000>

>>> to_yaml({'astropy time -> astropy time': t0})
"astropy time -> astropy time: '1999-12-31T23:49:49.000'\n"

>>> to_yaml({'datetime -> astropy time': t0.datetime})
"datetime -> astropy time: '1999-12-31T23:49:49.000'\n"

>>> # Can pass a `stream` parameter to save to file
>>> with open('temp.yaml', 'w') as f:           
...     to_yaml({'my_object': 42}, stream=f)
Parameters:
  • obj (dict) – The object to be converted to be serialized.
  • **kwargs – Arguments passed to ruamel.yaml.dump. See Examples.
Returns:

The YAML string representation of the object.

Return type:

str

panoptes.utils.theskyx module

class panoptes.utils.theskyx.TheSkyX(host='localhost', port=3040, connect=True, *args, **kwargs)[source]

Bases: object

A socket connection for communicating with TheSkyX

connect()[source]

Sets up serial connection

is_connected
read(timeout=5)[source]
write(value)[source]

panoptes.utils.time module

class panoptes.utils.time.CountdownTimer(duration)[source]

Bases: object

Simple timer object for tracking whether a time duration has elapsed.

Parameters:duration (int or float or astropy.units.Quantity) – Amount of time to before time expires. May be numeric seconds or an Astropy time duration (e.g. 1 * u.minute).
expired()[source]

Return a boolean, telling if the timeout has expired.

Returns:If timer has expired.
Return type:bool
restart()[source]

Restart the timed duration.

sleep(max_sleep=None)[source]

Sleep until the timer expires, or for max_sleep, whichever is sooner.

Parameters:max_sleep – Number of seconds to wait for, or None.
Returns:True if slept for less than time_left(), False otherwise.
time_left()[source]

Return how many seconds are left until the timeout expires.

Returns:Number of seconds remaining in timer, zero if is_non_blocking=True.
Return type:int
panoptes.utils.time.current_time(flatten=False, datetime=False, pretty=False)[source]

Convenience method to return the “current” time according to the system.

Note

If the $POCSTIME environment variable is set then this will return the time given in the variable. This is used for setting specific times during testing. After checking the value of POCSTIME the environment variable will also be incremented by one second so that subsequent calls to this function will generate monotonically increasing times.

Operation of POCS from $POCS/bin/pocs_shell will clear the POCSTIME variable.

>>> os.environ['POCSTIME'] = '1999-12-31 23:59:59'
>>> party_time = current_time(pretty=True)
>>> party_time
'1999-12-31 23:59:59'

# Next call is one second later when using $POCSTIME.
>>> y2k = current_time(pretty=True)
>>> y2k
'2000-01-01 00:00:00'

Note

The time returned from this function is not timezone aware. All times are UTC.

>>> from panoptes.utils import current_time
>>> current_time()                
<Time object: scale='utc' format='datetime' value=2018-10-07 22:29:03.009873>

>>> current_time(datetime=True)   
datetime.datetime(2018, 10, 7, 22, 29, 26, 594368)

>>> current_time(pretty=True)     
'2018-10-07 22:29:51'
Returns:Object representing now.
Return type:astropy.time.Time
panoptes.utils.time.flatten_time(t)[source]

Given an astropy time, flatten to have no extra chars besides integers.

>>> from astropy.time import Time
>>> from panoptes.utils import flatten_time
>>> t0 = Time('1999-12-31 23:59:59')
>>> t0.isot
'1999-12-31T23:59:59.000'

>>> flatten_time(t0)
'19991231T235959'
Parameters:t (astropy.time.Time) – The time to be flattened.
Returns:The flattened string representation of the time.
Return type:str
panoptes.utils.time.wait_for_events(events, timeout=600, sleep_delay=<Quantity 5. s>, callback=None)[source]

Wait for event(s) to be set.

This method will wait for a maximum of timeout seconds for all of the events to complete.

Checks every sleep_delay seconds for the events to be set.

If provided, the callback will be called every sleep_delay seconds. The callback should return True to continue waiting otherwise False to interrupt the loop and return from the function.

>>> import time
>>> import threading
>>> from panoptes.utils.time import wait_for_events
>>> # Create some events, normally something like taking an image.
>>> event0 = threading.Event()
>>> event1 = threading.Event()

>>> # Wait for 30 seconds but interrupt after 1 second by returning False from callback.
>>> def interrupt_cb(): time.sleep(1); return False
>>> # The function will return False if events are not set.
>>> wait_for_events([event0, event1], timeout=30, callback=interrupt_cb)
False

>>> # Timeout will raise an exception.
>>> wait_for_events([event0, event1], timeout=1)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File ".../panoptes-utils/src/panoptes/utils/time.py", line 254, in wait_for_events
panoptes.utils.error.Timeout: Timeout: Timeout waiting for generic event

>>> # Set the events in another thread for normal usage.
>>> def set_events(): time.sleep(1); event0.set(); event1.set()
>>> threading.Thread(target=set_events).start()
>>> wait_for_events([event0, event1], timeout=30)
True
Parameters:
  • events (list(threading.Event)) – An Event or list of Events to wait on.
  • timeout (float|`astropy.units.Quantity`) – Timeout in seconds to wait for events, default 600 seconds.
  • sleep_delay (float, optional) – Time in seconds between event checks.
  • callback (callable) – A periodic callback that should return True to continue waiting or False to interrupt the loop. Can also be used for e.g. custom logging.
Returns:

True if events were set, False otherwise.

Return type:

bool

Raises:

error.Timeout – Raised if events have not all been set before timeout seconds.

panoptes.utils.utils module

class panoptes.utils.utils.DelaySigTerm[source]

Bases: contextlib.ContextDecorator

Supports delaying SIGTERM during a critical section.

This allows one to avoid having SIGTERM interrupt a critical block of code, such as saving to a database.

Example

with DelaySigTerm():
db.WriteCurrentRecord(record)
panoptes.utils.utils.altaz_to_radec(alt=None, az=None, location=None, obstime=None, **kwargs)[source]

Convert alt/az degrees to RA/Dec SkyCoord.

>>> from panoptes.utils import altaz_to_radec
>>> from astropy.coordinates import EarthLocation
>>> from astropy import units as u
>>> keck = EarthLocation.of_site('Keck Observatory')
...
>>> altaz_to_radec(alt=75, az=180, location=keck, obstime='2020-02-02T20:20:02.02')
<SkyCoord (ICRS): (ra, dec) in deg
    (281.78..., 4.807...)>
>>> # Can use quantities or not.
>>> alt = 4500 * u.arcmin
>>> az = 180 * u.degree
>>> altaz_to_radec(alt=alt, az=az, location=keck, obstime='2020-02-02T20:20:02.02')
<SkyCoord (ICRS): (ra, dec) in deg
    (281.78..., 4.807...)>
>>> # Will use current time if none given.
>>> altaz_to_radec(alt=35, az=90, location=keck)
<SkyCoord (ICRS): (ra, dec) in deg
    (..., ...)>
>>> # Must pass a `location` instance.
>>> altaz_to_radec()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  ...
    assert location is not None
AssertionError
Parameters:
Returns:

Coordinates corresponding to the AltAz.

Return type:

astropy.coordinates.SkyCoord

panoptes.utils.utils.get_free_space(directory=None)[source]

Return the amoung of freespace in gigabytes for given directory.

>>> from panoptes.utils import get_free_space
>>> get_free_space()
<Quantity ... Gbyte>
>>> get_free_space(directory='/')
<Quantity ... Gbyte>
Parameters:directory (str, optional) – Path to directory. If None defaults to $PANDIR.
Returns:The number of gigabytes avialable in folder.
Return type:astropy.units.Quantity
panoptes.utils.utils.get_quantity_value(quantity, unit=None)[source]

Thin-wrapper around the astropy.units.Quantity.to_value method.

If passed something other than a Quantity will simply return the original object.

>>> from astropy import units as u
>>> from panoptes.utils import get_quantity_value
>>> get_quantity_value(60 * u.second)
60.0
>>> # Can convert between units.
>>> get_quantity_value(60 * u.minute, unit='second')
3600.0
>>> get_quantity_value(60 * u.minute, unit=u.second)
3600.0
>>> get_quantity_value(60)
60
Parameters:
Returns:

numerical value of the Quantity after conversion to the specified unit.

Return type:

float

panoptes.utils.utils.image_id_from_path(path)[source]

Return the image_id from the given path or uri.

>>> from panoptes.utils import image_id_from_path
>>> path = 'gs://panoptes-raw-images/PAN012/ee04d1/20190820T111638/20190820T122447.fits'
>>> image_id_from_path(path)
'PAN012_ee04d1_20190820T122447'
>>> path = 'nothing/to/match'
>>> image_id_from_path(path)
Parameters:path (str) – A path or uri for a file.
Returns:The image id in the form “<unit_id>_<camera_id>_<image_id>”
Return type:str
panoptes.utils.utils.listify(obj)[source]

Given an object, return a list.

Always returns a list. If obj is None, returns empty list, if obj is list, just returns obj, otherwise returns list with obj as single member.

If a dict object is passed then this function will return a list of only the values.

>>> listify(42)
[42]
>>> listify('foo')
['foo']
>>> listify(None)
[]
>>> listify(['a'])
['a']

>>> my_dict = dict(a=42, b='foo')
>>> listify(my_dict)
[42, 'foo']
>>> listify(my_dict.values())
[42, 'foo']
>>> listify(my_dict.keys())
['a', 'b']
Returns:You guessed it.
Return type:list
panoptes.utils.utils.moving_average(data_set, periods=3)[source]

Moving average.

Parameters:
  • data_set (numpy.array) – An array of values over which to perform the moving average.
  • periods (int, optional) – Number of periods.
Returns:

An array of the computed averages.

Return type:

numpy.array

panoptes.utils.utils.sequence_id_from_path(path)[source]

Return the sequence_id from the given path or uri.

>>> from panoptes.utils import sequence_id_from_path
>>> path = 'gs://panoptes-raw-images/PAN012/ee04d1/20190820T111638/20190820T122447.fits'
>>> sequence_id_from_path(path)
'PAN012_ee04d1_20190820T111638'
>>> path = 'nothing/to/match'
>>> sequence_id_from_path(path)
Parameters:path (str) – A path or uri for a file.
Returns:The image id in the form “<unit_id>_<camera_id>_<sequence_id>”
Return type:str
panoptes.utils.utils.string_to_params(opts)[source]

Parses a single string into parameters that can be passed to a function.

A user of the peas_shell can supply positional and keyword arguments to the command being called, however the Cmd module that is used for the shell does not parse these options but instead passes this as a single string. This utility method does some simple parsing of that string and returns a list of positional parameters and a dictionary of keyword arguments. A keyword argument is considered anything that contains an equal sign (e.g. exptime=30). Any leading to a keyword argument will be stripped during parsing.

A list of items can be passed by specifying the keyword argument multiple times.

Note

This function will attempt to parse keyword values as floats if possible. If a string is required include a single quote around the value, e.g. param=‘42’ will keep the value as the string ‘42’.

>>> from panoptes.utils import string_to_params
>>> args, kwargs = string_to_params("parg1 parg2 key1=a_str key2=2 key2='2' key3=03")
>>> args
['parg1', 'parg2']
>>> kwargs
{'key1': 'a_str', 'key2': [2.0, '2'], 'key3': 3.0}
>>> isinstance(kwargs['key2'][0], float)
True
>>> isinstance(kwargs['key2'][1], str)
True
>>> kwargs['key2'][1] == '2'
True
>>> args, kwargs = string_to_params('--key1=val1 --key1-2=val1-2')
>>> kwargs
{'key1': 'val1', 'key1-2': 'val1-2'}
Parameters:opts (str) – A single string containing everything beyond the actual command that is called.
Returns:Returns a list of positional parameters and a dictionary of keyword arguments. These correspond to the *args and **kwargs that a typical function would receive.
Return type:tuple(list, dict)

Module contents