Source code for lcc.stars_processing.systematic_search.stars_searcher

import collections
import os
from warnings import warn
import warnings
import pandas as pd

from lcc.data_manager.status_resolver import StatusResolver
from lcc.db_tier.stars_provider import StarsProvider
from lcc.entities.exceptions import QueryInputError, InvalidFilesPath
from lcc.utils.helpers import progressbar
from lcc.utils.stars import saveStars


[docs]class StarsSearcher(): ''' The class manages systematic searching in databases. It also can be used as base class for other star searchers. Attributes ---------- stars_filter : FilteringManager object Filter which is prepared filter star objects save_path : str Path from "run" module to the folder where found light curves will be saved stat_file_path : str Status file name save_lim : int Number of searched objects after which status file is saved obth_method : str Name of connector class save_coords : bool Save params space coordinates of inspected stars status : pandas.DataFrame Status table about results of queries ''' DEF_save_lim = 50 DEF_unfound_lim = 150 def __init__(self, stars_filters, save_path=".", stat_file_path=None, save_lim=None, unfound_lim=None, obth_method=None, save_coords=None): ''' Parameters ---------- stars_filters : lists Stars filters save_path : str Path from "run" module to the folder where found light curves will be saved stat_file_path : str Status file name save_lim : int Number of searched objects after which status file is saved obth_method : str Name of connector class save_coords : bool Save params space coordinates of inspected stars ''' if not save_lim: save_lim = self.DEF_save_lim if not unfound_lim: unfound_lim = self.DEF_unfound_lim if not obth_method: raise QueryInputError( "Database for searching need to be specified.") self.save_path = save_path self.stat_file_path = stat_file_path self.obth_method = obth_method self.save_lim = save_lim self.unfound_lim = unfound_lim self.stars_filters = stars_filters self.not_uploaded = [] self.passed_stars = [] if save_coords: self.que_coords = None self.save_coords = save_coords self.status = pd.DataFrame()
[docs] def filterStar(self, star, *args, **kwargs): ''' This method filter given star. In case of match method "matchOccured" will be performed Parameters ---------- stars : `Star` instance Star to filter Returns ------- bool If star passed thru filtering ''' for star_filt in self.stars_filters: result = star_filt.filterStars([star]) if not result: break if not self.stars_filters or len(result) == 1: self.matchOccured(star) return True else: return False
[docs] def matchOccured(self, star, *args, **kwargs): ''' What to do with star which passed thru filtering Parameters ---------- star : `Star` instance Star object which will be saved as fits Returns ------- None ''' saveStars([star], self.save_path)[0] self.passed_stars.append(star)
[docs] def failProcedure(self, query, err=""): ''' What to do if a fail occurs Parameters ---------- query : optional Query informations err : str Error message Returns ------- None ''' warnings.warn("Error occurred during filtering: %s" % err)
[docs] def statusFile(self, query, status, delimiter="\t"): ''' This method generates status file for overall query in certain db. Every queried star will be noted. Parameters ---------- query : dict Query informations status : dict Information whether queried star was found, filtered and passed thru filtering Returns ------- None ''' data = [query.pop("name")] + query.values() + status.values() columns = ["name"] + query.keys() + status.keys() this_status = pd.DataFrame( [data], columns=columns, index=[len(self.status)]) self.status = self.status.append(this_status) if self.stat_file_path: self.status.to_csv(self.stat_file_path, index=False)
[docs] def queryStars(self, queries): ''' Query db according to list of queries. Stars passed thru filter are managed by `matchOccured` method. Parameters ---------- queries : list, iterable List of dictionaries of queries for certain db Returns ------- None ''' stars_num = 0 passed_num = 0 all_unfound = 0 unfound_counter = 0 for query in progressbar(queries, "Query: "): status = collections.OrderedDict( (("found", False), ("lc", False), ("passed", False))) try: stars = StarsProvider().getProvider( self.obth_method, query).getStarsWithCurves() except QueryInputError: raise except (KeyboardInterrupt, SystemExit): raise except: warn("Couldn't download any light curve") stars = [] # Check if the searched star was found result_len = len(stars) if result_len == 0: unfound_counter += 1 all_unfound += 1 if unfound_counter > self.unfound_lim: warn("Max number of unsatisfied queries reached: %i" % self.unfound_lim) unfound_counter = 0 for one_star in stars: status["found"] = True contain_lc = True try: one_star.lightCurve.time except AttributeError: contain_lc = False if contain_lc: # TODO if self.save_coords and self.stars_filters: spc = self.stars_filters[ 0].getSpaceCoordinates([one_star]).values if len(spc): self._saveCoords([one_star.name] + spc[0].tolist()) # Try to apply filters to the star try: passed = self.filterStar(one_star, query) status["lc"] = True status["passed"] = passed stars_num += 1 if passed: passed_num += 1 except (KeyboardInterrupt, SystemExit): raise except IOError as err: raise InvalidFilesPath(err) except Exception as err: self.failProcedure(query, err) warn( "Something went wrong during filtering:\n\t%s" % err) else: status["lc"] = False status["passed"] = False query["name"] = one_star.name self.statusFile(query, status) if not stars: query["name"] = "" self.statusFile(query, status) print "\n************\t\tQuery is done\t\t************" print "Query results:\nThere are %i stars passed thru filtering from %s." % (passed_num, stars_num) if all_unfound: print "There are %i unsatisfied queries" % all_unfound if self.not_uploaded: print "\t%i stars have not been uploaded into local db, because they are already there." % len(self.not_uploaded)
def _saveCoords(self, query): if self.stars_filters: star_filter = self.stars_filters[0] labels = [] for desc in star_filter.descriptors: if hasattr(desc.LABEL, "__iter__"): labels += desc.LABEL else: labels.append(desc.LABEL) header = ["star_name"] + labels this_df = pd.DataFrame([query], columns=header) if not isinstance(self.que_coords, pd.DataFrame): self.que_coords = this_df self.que_coords = self.que_coords.append(this_df) self.que_coords.to_csv( os.path.join(self.save_path, "..", "space_coordinates.csv"), index=False, delimiter=";") else: warnings.warn( "There are no filters, so space coordinates cannot be obtained.\n")