Source code for marvin.tools.mixins.dapall

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
# @Author: José Sánchez-Gallego (gallegoj@uw.edu)
# @Date: 2018-07-13
# @Filename: dapall.py
# @License: BSD 3-clause (http://www.opensource.org/licenses/BSD-3-Clause)
#
# @Last modified by: José Sánchez-Gallego (gallegoj@uw.edu)
# @Last modified time: 2018-11-14 12:03:58

import distutils
import os

import astropy.io.fits

import marvin
from marvin.core.exceptions import MarvinError
from marvin.utils.general import get_dapall_path, map_dapall


__all__ = ['DAPallMixIn']


[docs]class DAPallMixIn(object): """A mixin that provides access to DAPall paremeters. Must be used in combination with `.MarvinToolsClass` and initialised before `~.DAPallMixIn.dapall` can be called. `DAPallMixIn` uses the `.MarvinToolsClass.data_origin` of the object to determine how to obtain the DAPall information. However, if the object contains a ``dapall`` attribute with the path to a DAPall file, that file will be used. """ __min_dapall_version__ = distutils.version.StrictVersion('2.1.0') @property def dapall(self): """Returns the contents of the DAPall data for this target.""" if (not self._dapver or distutils.version.StrictVersion(self._dapver) < self.__min_dapall_version__): raise MarvinError('DAPall is not available for versions before MPL-6.') if hasattr(self, '_dapall') and self._dapall is not None: return self._dapall if self.data_origin == 'file': try: dapall_data = self._get_dapall_from_file() except IOError: marvin.log.debug('cannot find DAPall file. Trying remote request.') dapall_data = self._get_from_api() elif self.data_origin == 'db': dapall_data = self._get_dapall_from_db() else: dapall_data = self._get_dapall_from_api() self._dapall = dapall_data return self._dapall def _get_dapall_from_file(self): """Uses DAPAll file to retrieve information.""" daptype = self.bintype.name + '-' + self.template.name dapall_path = get_dapall_path(self._drpver, self._dapver) assert dapall_path is not None, 'cannot build DAPall file.' if not os.path.exists(dapall_path): raise MarvinError('cannot find DAPall file in the system.') dapall_hdu = astropy.io.fits.open(dapall_path) header = dapall_hdu[0].header dapall_table = dapall_hdu[-1].data dapall_row = dapall_table[(dapall_table['PLATEIFU'] == self.plateifu) & (dapall_table['DAPTYPE'] == daptype)] assert len(dapall_row) == 1, 'cannot find matching row in DAPall.' return map_dapall(header, dapall_row[0]) def _get_dapall_from_db(self): """Uses the DB to retrieve the DAPAll data.""" dapall_data = {} daptype = self.bintype.name + '-' + self.template.name mdb = marvin.marvindb if not mdb.isdbconnected: raise MarvinError('No DB connected') datadb = mdb.datadb dapdb = mdb.dapdb dapall_row = mdb.session.query(dapdb.DapAll).join( dapdb.File, datadb.PipelineInfo, datadb.PipelineVersion).filter( mdb.datadb.PipelineVersion.version == self._dapver, dapdb.DapAll.plateifu == self.plateifu, dapdb.DapAll.daptype == daptype).use_cache().first() if dapall_row is None: raise MarvinError('cannot find a DAPall match for this target in the DB.') for col in dapall_row.__table__.columns.keys(): if col != 'pk' and '_pk' not in col: dapall_data[col] = getattr(dapall_row, col) return dapall_data def _get_dapall_from_api(self): """Uses the API to retrieve the DAPall data.""" url = marvin.config.urlmap['api']['dapall']['url'] url_full = url.format(name=self.plateifu, bintype=self.bintype.name, template=self.template.name) try: response = self._toolInteraction(url_full) except Exception as ee: raise MarvinError('found a problem while getting DAPall: {0}'.format(str(ee))) if response.results['error'] is not None: raise MarvinError('found a problem while getting DAPall: {}' .format(str(response.results['error']))) data = response.getData() return data['dapall_data']