class Spaxel(Base, ArrayOps): __tablename__ = 'spaxel' __table_args__ = { 'autoload': True, 'schema': 'mangadatadb', 'extend_existing': True } flux = deferred(Column(ARRAY_D(Float, zero_indexes=True))) ivar = deferred(Column(ARRAY_D(Float, zero_indexes=True))) mask = deferred(Column(ARRAY_D(Integer, zero_indexes=True))) disp = deferred(Column(ARRAY_D(Float, zero_indexes=True))) predisp = deferred(Column(ARRAY_D(Float, zero_indexes=True))) def __repr__(self): return '<Spaxel (pk={0}, x={1}, y={2})'.format(self.pk, self.x, self.y) @hybrid_method def sum(self, name=None): total = sum(self.flux) return total @sum.expression def sum(cls): # return select(func.sum(func.unnest(cls.flux))).select_from(func.unnest(cls.flux)).label('totalflux') return select([func.sum(column('totalflux'))]).select_from( func.unnest(cls.flux).alias('totalflux'))
class RssFiber(Base, ArrayOps): __tablename__ = 'rssfiber' __table_args__ = {'autoload': True, 'schema': 'mangadatadb', 'extend_existing': True} flux = deferred(Column(ARRAY_D(Float, zero_indexes=True))) ivar = deferred(Column(ARRAY_D(Float, zero_indexes=True))) mask = deferred(Column(ARRAY_D(Integer, zero_indexes=True))) xpos = deferred(Column(ARRAY_D(Float, zero_indexes=True))) ypos = deferred(Column(ARRAY_D(Float, zero_indexes=True))) def __repr__(self): return '<RssFiber (pk={0})>'.format(self.pk)
class Wavelength(Base, ArrayOps): __tablename__ = 'wavelength' __table_args__ = {'autoload': True, 'schema': 'mangadatadb', 'extend_existing': True} wavelength = deferred(Column(ARRAY_D(Float, zero_indexes=True))) def __repr__(self): return '<Wavelength (pk={0})>'.format(self.pk)
class RssFiber(Base, ArrayOps): __tablename__ = 'rssfiber' __table_args__ = { 'autoload': True, 'schema': 'mangadatadb', 'extend_existing': True } flux = deferred(Column(ARRAY_D(Float, zero_indexes=True))) ivar = deferred(Column(ARRAY_D(Float, zero_indexes=True))) mask = deferred(Column(ARRAY_D(Integer, zero_indexes=True))) xpos = deferred(Column(ARRAY_D(Float, zero_indexes=True))) ypos = deferred(Column(ARRAY_D(Float, zero_indexes=True))) disp = deferred(Column(ARRAY_D(Float, zero_indexes=True))) predisp = deferred(Column(ARRAY_D(Float, zero_indexes=True))) def __repr__(self): return '<RssFiber (pk={0}, expnum={1}, mjd={2}, fiber={3})>'.format( self.pk, self.exposure_no, self.mjd, self.fiber.fiberid)
class Cube(Base, ArrayOps): __tablename__ = 'cube' __table_args__ = { 'autoload': True, 'schema': 'mangadatadb', 'extend_existing': True } specres = deferred(Column(ARRAY_D(Float, zero_indexes=True))) specresd = deferred(Column(ARRAY_D(Float, zero_indexes=True))) prespecres = deferred(Column(ARRAY_D(Float, zero_indexes=True))) prespecresd = deferred(Column(ARRAY_D(Float, zero_indexes=True))) def __repr__(self): return '<Cube (pk={0}, plate={1}, ifudesign={2}, tag={3})>'.format( self.pk, self.plate, self.ifu.name, self.pipelineInfo.version.version) @property def header(self): '''Returns an astropy header''' session = Session.object_session(self) data = session.query( FitsHeaderKeyword.label, FitsHeaderValue.value, FitsHeaderValue.comment).join(FitsHeaderValue).filter( FitsHeaderValue.cube == self).all() hdr = fits.Header(data) return hdr @property def name(self): return 'manga-{0}-{1}-LOGCUBE.fits.gz'.format(self.plate, self.ifu.name) @property def default_mapsname(self): return 'mangadap-{0}-{1}-default.fits.gz'.format( self.plate, self.ifu.name) def getPath(self): sasurl = os.getenv('SAS_URL') if sasurl: sasredux = os.path.join(sasurl, 'sas/mangawork/manga/spectro/redux') path = sasredux else: redux = os.getenv('MANGA_SPECTRO_REDUX') path = redux version = self.pipelineInfo.version.version cubepath = os.path.join(path, version, str(self.plate), 'stack') return cubepath @property def location(self): name = self.name path = self.getPath() loc = os.path.join(path, name) return loc @property def image(self): ifu = '{0}.png'.format(self.ifu.name) path = self.getPath() imageloc = os.path.join(path, 'images', ifu) return imageloc def header_to_dict(self): '''Returns a simple python dictionary header''' values = self.headervals hdrdict = {str(val.keyword.label): val.value for val in values} return hdrdict @property def plateclass(self): '''Returns a plate class''' plate = Plate(self) return plate def testhead(self, key): ''' Test existence of header keyword''' try: if self.header_to_dict()[key]: return True except: return False def getFlags(self, bits, name): session = Session.object_session(self) # if bits not a digit, return None if not str(bits).isdigit(): return 'NULL' else: bits = int(bits) # Convert the integer value to list of bits bitlist = [int(i) for i in '{0:08b}'.format(bits)] bitlist.reverse() indices = [i for i, bit in enumerate(bitlist) if bit] labels = [] for i in indices: maskbit = session.query(MaskBit).filter_by(flag=name, bit=i).one() labels.append(maskbit.label) return labels def getQualFlags(self, stage='3d'): ''' get quality flags ''' name = 'MANGA_DRP2QUAL' if stage == '2d' else 'MANGA_DRP3QUAL' col = 'DRP2QUAL' if stage == '2d' else 'DRP3QUAL' try: bits = self.header_to_dict()[col] except: bits = None if bits: labels = self.getFlags(bits, name) return labels else: return None def getTargFlags(self, type=1): ''' get target flags ''' name = 'MANGA_TARGET1' if type == 1 else 'MANGA_TARGET2' if type == 2 else 'MANGA_TARGET3' hdr = self.header_to_dict() istarg = 'MNGTARG1' in hdr.keys() if istarg: col = 'MNGTARG1' if type == 1 else 'MNGTARG2' if type == 2 else 'MNGTARG3' else: col = 'MNGTRG1' if type == 1 else 'MNGTRG2' if type == 2 else 'MNGTRG3' try: bits = hdr[col] except: bits = None if bits: labels = self.getFlags(bits, name) return labels else: return None def get3DCube(self, extension='flux'): """Returns a 3D array of ``extension`` from the cube spaxels. For example, ``cube.get3DCube('flux')`` will return the original flux cube with the same ordering as the FITS data cube. Note that this method seems to be really slow retrieving arrays (this is especially serious for large IFUs). """ session = Session.object_session(self) spaxels = session.query(getattr(Spaxel, extension)).filter( Spaxel.cube_pk == self.pk).order_by(Spaxel.x, Spaxel.y).all() # Assumes cubes are always square (!) nx = ny = int(np.sqrt(len(spaxels))) nwave = len(spaxels[0][0]) spArray = np.array(spaxels) return spArray.transpose().reshape((nwave, ny, nx)).transpose(0, 2, 1) @hybrid_property def plateifu(self): '''Returns parameter plate-ifu''' return '{0}-{1}'.format(self.plate, self.ifu.name) @plateifu.expression def plateifu(cls): return func.concat(Cube.plate, '-', IFUDesign.name) @hybrid_property def restwave(self): if self.target: redshift = self.target.NSA_objects[0].z wave = np.array(self.wavelength.wavelength) restwave = wave / (1 + redshift) return restwave else: return None @restwave.expression def restwave(cls): restw = (func.rest_wavelength(sampledb.NSA.z)) return restw def has_modelspaxels(self, name=None): if not name: name = '(SPX|HYB)' has_ms = False model_cubes = [ f.modelcube for f in self.dapfiles if re.search('LOGCUBE-{0}'.format(name), f.filename) ] if model_cubes: mc = sum(model_cubes, []) if mc: from marvin.db.models.DapModelClasses import ModelSpaxel session = Session.object_session(mc[0]) ms = session.query(ModelSpaxel).filter_by( modelcube_pk=mc[0].pk).first() has_ms = True if ms else False return has_ms def has_spaxels(self): if len(self.spaxels) > 0: return True else: return False def has_fibers(self): if len(self.fibers) > 0: return True else: return False