Skip to content
fits.py 4.13 KiB
Newer Older
Wei Shoulin's avatar
Wei Shoulin committed

import logging
Xie Zhou's avatar
Xie Zhou committed
import os
import shutil
from glob import glob

from astropy.io import fits

Wei Shoulin's avatar
Wei Shoulin committed
from ..common.db import DBClient
Xie Zhou's avatar
Xie Zhou committed
from ..common.utils import get_parameter
Wei Shoulin's avatar
Wei Shoulin committed

log = logging.getLogger('csst')

Xie Zhou's avatar
Xie Zhou committed

Wei Shoulin's avatar
Wei Shoulin committed
class FitsApi(object):
    def __init__(self):
        self.root_dir = os.getenv("CSST_LOCAL_FILE_ROOT", "/opt/temp/csst")
        self.check_dir()
        self.db = DBClient()

    def check_dir(self):
        if not os.path.exists(self.root_dir):
            os.mkdir(self.root_dir)
            log.info("using [%s] as root directory", self.root_dir)
        if not os.path.exists(os.path.join(self.root_dir, "fits")):
            os.mkdir(os.path.join(self.root_dir, "fits"))
        if not os.path.exists(os.path.join(self.root_dir, "refs")):
            os.mkdir(os.path.join(self.root_dir, "refs"))
        if not os.path.exists(os.path.join(self.root_dir, "results")):
            os.mkdir(os.path.join(self.root_dir, "results"))

    def find(self, **kwargs):
        '''
        parameter kwargs:
Xie Zhou's avatar
Xie Zhou committed
        obs_time = [int]
        type = [str]
        fits_id = [str]
Wei Shoulin's avatar
Wei Shoulin committed

Xie Zhou's avatar
Xie Zhou committed
        return list of paths
Wei Shoulin's avatar
Wei Shoulin committed
        '''
Xie Zhou's avatar
Xie Zhou committed
        paths = []
        obs_time = get_parameter(kwargs, "obs_time")
        type = get_parameter(kwargs, "type")
        fits_id = get_parameter(kwargs, "fits_id")

        if (obs_time is None or type is None) and fits_id is None:
            raise Exception('obs_time and type need to be defind')

        if fits_id is None:
            c, r = self.db.select_many(
                'select * from t_rawfits where obs_time=? and type=?',
                (obs_time, type)
            )
            if len(r) < 1:
                raise Exception('not found')
            for items in r:
                paths.append(items[4])
Wei Shoulin's avatar
Wei Shoulin committed
        return paths

    def read(self, **kwargs):
        '''
        parameter kwargs:
        fits_id = [str] 
        file_path = [str] 
Xie Zhou's avatar
Xie Zhou committed
        chunk_size = [int]

Wei Shoulin's avatar
Wei Shoulin committed
        yield bytes of fits file
        '''
        fits_id = get_parameter(kwargs, "fits_id")
        file_path = get_parameter(kwargs, "file_path")

        if fits_id is None and file_path is None:
            raise Exception("fits_id or file_path need to be defined")

        if fits_id is not None:
Xie Zhou's avatar
Xie Zhou committed
            c, r = self.db.select_one(
                "select * from t_rawfits where id=?", (fits_id))
Wei Shoulin's avatar
Wei Shoulin committed
            if c == 1:
                file_path = r["path"]

        if file_path is not None:
            chunk_size = get_parameter(kwargs, "chunk_size", 1024)
Xie Zhou's avatar
Xie Zhou committed
            with open(file_path, 'r') as f:
Wei Shoulin's avatar
Wei Shoulin committed
                while True:
                    data = f.read(chunk_size)
                    if not data:
                        break
                    yield data

    def update_status(self, **kwargs):
        pass

Xie Zhou's avatar
Xie Zhou committed
    def upload(self, **kwargs):
        '''
        parameter kwargs:
        file_path = [str]

        upload to database and copy to csstpath
        '''
        file_path = get_parameter(kwargs, "file_path")

        if file_path is None:
            raise Exception("file_path need to be defined")

        basename = os.path.basename(file_path)
        name = basename.split('.fits')[0]
        c, r = self.db.select_many(
            "select * from t_rawfits where id=?",
            (name,)
        )
        if len(r) >= 1:
            print('already upload', name)
            return

        hu = fits.getheader(file_path)
        obs_time = hu['obst']
        ccd_num = hu['ccd_num']
        # print(obs_time, ccd_num)
        type = 'obs'
        save_path = os.path.join(self.root_dir, 'fits')
        save_path = os.path.join(save_path, basename)

        self.db.execute(
            'INSERT INTO t_rawfits VALUES(?,?,?,?,?)',
            (name, obs_time, ccd_num, type, save_path)
        )
        self.db._conn.commit()
        if file_path != save_path:
            shutil.copyfile(file_path, save_path)
        log.info("%s imported.", save_path)

Wei Shoulin's avatar
Wei Shoulin committed
    def scan2db(self):
        paths = {}
Xie Zhou's avatar
Xie Zhou committed

Wei Shoulin's avatar
Wei Shoulin committed
        for (path, _, file_names) in os.walk(os.path.join(self.root_dir, "fits")):
            for filename in file_names:
                if filename.find(".fits") > 0:
Xie Zhou's avatar
Xie Zhou committed
                    self.upload(file_path=os.path.join(path, filename))
        return paths