def test_else(): f = ConditionalDispatch() # Multiply even numbers by two. f.add(lambda x: 2 * x, lambda x: x % 2 == 0) f.add(lambda x: 3 * x) assert f(2) == 4 assert f(3) == 9
class Parent(object): _create = ConditionalDispatch() @classmethod def read(cls, filename): raise NotImplementedError @classmethod def read_many(cls, filenames): return list(map(cls.read, filenames)) @classmethod def from_glob(cls, pattern): """ Read out files using glob (e.g., ~/BIR_2011*) pattern. Returns list of objects made from all matched files. """ return cls.read_many(glob.glob(pattern)) @classmethod def from_single_glob(cls, singlepattern): """ Read out a single file using glob (e.g., ~/BIR_2011*) pattern. If more than one file matches the pattern, raise ValueError. """ matches = glob.glob(os.path.expanduser(singlepattern)) if len(matches) != 1: raise ValueError("Invalid number of matches: {0:d}".format(len(matches))) return cls.read(matches[0]) @classmethod def from_files(cls, filenames): """ Return list of object read from given list of filenames. """ filenames = list(map(os.path.expanduser, filenames)) return cls.read_many(filenames) @classmethod def from_file(cls, filename): """ Return object from file. """ filename = os.path.expanduser(filename) return cls.read(filename) @classmethod def from_dir(cls, directory): """ Return list that contains all files in the directory read in. """ directory = os.path.expanduser(directory) return cls.read_many( (os.path.join(directory, elem) for elem in os.listdir(directory)) ) @classmethod def from_url(cls, url): """ Return object read from URL. Parameters ---------- url : str URL to retrieve the data from """ path = download_file(url, get_and_create_download_dir()) return cls.read(path)
def oddeven(request): f = ConditionalDispatch() # Multiply even numbers by two. f.add(lambda x: 2 * x, lambda x: x % 2 == 0) # Multiply odd numbers by three. f.add(lambda x: 3 * x, lambda x: x % 2 == 1) return f
def test_nocond(): f = ConditionalDispatch() # Multiply even numbers by two. f.add(lambda x: 2 * x, lambda x: x % 2 == 0) with pytest.raises(TypeError) as exc_info: f(3) assert "Your input did not fulfill the condition for any function." in str(exc_info.value)
def test_else2(): # This verifies else branches do not catch cases that are covered # by cases added later. f = ConditionalDispatch() # Because gcd(2, 3) == 1, 2 | x and 3 | x are mutually exclusive. f.add(lambda x: 2 * x, lambda x: x % 2 == 0) f.add(lambda x: 3 * x) f.add(lambda x: 4 * x, lambda x: x % 3 == 0) assert f(2) == 4 assert f(3) == 12 assert f(5) == 15
class LightCurve(object): """ LightCurve(filepath) A generic light curve object. Parameters ---------- args : filepath, url, or start and end dates The input for a LightCurve object should either be a filepath, a URL, or a date range to be queried for the particular instrument. Attributes ---------- meta : string, dict The comment string or header associated with the light curve input data : pandas.DataFrame An pandas DataFrame prepresenting one or more fields as they vary with respect to time. Examples -------- >>> import sunpy >>> import datetime >>> import numpy as np >>> base = datetime.datetime.today() >>> dates = [base - datetime.timedelta(minutes=x) for x in range(0, 24 * 60)] >>> intensity = np.sin(np.arange(0, 12 * np.pi, step=(12 * np.pi) / 24 * 60)) >>> light_curve = sunpy.lightcurve.LightCurve.create( ... {"param1": intensity}, index=dates ... ) >>> light_curve.peek() References ---------- | http://pandas.pydata.org/pandas-docs/dev/dsintro.html """ _cond_dispatch = ConditionalDispatch() create = classmethod(_cond_dispatch.wrapper()) def __init__(self, data, meta=None): self.data = pandas.DataFrame(data) if meta == '' or meta is None: self.meta = OrderedDict() else: self.meta = OrderedDict(meta) @property def header(self): """ Return the lightcurves metadata .. deprecated:: 0.4.0 Use .meta instead """ warnings.warn( """lightcurve.header has been renamed to lightcurve.meta for compatability with map, please use meta instead""", Warning) return self.meta @classmethod def from_time(cls, time, **kwargs): '''Called by Conditional Dispatch object when valid time is passed as input to create method.''' date = parse_time(time) url = cls._get_url_for_date(date, **kwargs) filepath = cls._download( url, kwargs, err="Unable to download data for specified date") return cls.from_file(filepath) @classmethod def from_range(cls, start, end, **kwargs): '''Called by Conditional Dispatch object when start and end time are passed as input to create method.''' url = cls._get_url_for_date_range(parse_time(start), parse_time(end)) filepath = cls._download( url, kwargs, err="Unable to download data for specified date range") result = cls.from_file(filepath) result.data = result.data.truncate(start, end) return result @classmethod def from_timerange(cls, timerange, **kwargs): '''Called by Conditional Dispatch object when time range is passed as input to create method.''' url = cls._get_url_for_date_range(timerange) filepath = cls._download( url, kwargs, err="Unable to download data for specified date range") result = cls.from_file(filepath) result.data = result.data.truncate(timerange.start(), timerange.end()) return result @classmethod def from_file(cls, filename): '''Used to return Light Curve object by reading the given filename Parameters: filename: Path of the file to be read. ''' filename = os.path.expanduser(filename) meta, data = cls._parse_filepath(filename) if data.empty: raise ValueError("No data found!") else: return cls(data, meta) @classmethod def from_url(cls, url, **kwargs): ''' Downloads a file from the given url, reads and returns a Light Curve object. Parameters: url : string Uniform Resource Locator pointing to the file. kwargs :Dict Dict object containing other related parameters to assist in download. ''' try: filepath = cls._download(url, kwargs) except (urllib2.HTTPError, urllib2.URLError, ValueError): err = ("Unable to read location %s.") % url raise ValueError(err) return cls.from_file(filepath) @classmethod def from_data(cls, data, index=None, meta=None): ''' Called by Conditional Dispatch object to create Light Curve object when corresponding data is passed to create method. ''' return cls(pandas.DataFrame(data, index=index), meta) @classmethod def from_yesterday(cls): return cls.from_url(cls._get_default_uri()) @classmethod def from_dataframe(cls, dataframe, meta=None): ''' Called by Conditional Dispatch object to create Light Curve object when Pandas DataFrame is passed to create method. ''' return cls(dataframe, meta) def plot(self, axes=None, **plot_args): """Plot a plot of the light curve Parameters ---------- axes: matplotlib.axes object or None If provided the image will be plotted on the given axes. Else the current matplotlib axes will be used. **plot_args : dict Any additional plot arguments that should be used when plotting the image. """ #Get current axes if axes is None: axes = plt.gca() axes = self.data.plot(ax=axes, **plot_args) return axes def peek(self, **kwargs): """Displays the light curve in a new figure""" figure = plt.figure() self.plot(**kwargs) figure.show() return figure @staticmethod def _download(uri, kwargs, err='Unable to download data at specified URL'): """Attempts to download data at the specified URI""" _filename = os.path.basename(uri).split("?")[0] # user specifies a download directory if "directory" in kwargs: download_dir = os.path.expanduser(kwargs["directory"]) else: download_dir = sunpy.config.get("downloads", "download_dir") # overwrite the existing file if the keyword is present if "overwrite" in kwargs: overwrite = kwargs["overwrite"] else: overwrite = False # If the file is not already there, download it filepath = os.path.join(download_dir, _filename) if not (os.path.isfile(filepath)) or (overwrite and os.path.isfile(filepath)): try: response = urllib2.urlopen(uri) except (urllib2.HTTPError, urllib2.URLError): raise urllib2.URLError(err) with open(filepath, 'wb') as fp: shutil.copyfileobj(response, fp) else: warnings.warn( "Using existing file rather than downloading, use overwrite=True to override.", RuntimeWarning) return filepath @classmethod def _get_default_uri(cls): """Default data to load when none is specified""" msg = "No default action set for %s" raise NotImplementedError(msg % cls.__name__) @classmethod def _get_url_for_date(cls, date, **kwargs): """Returns a URL to the data for the specified date""" msg = "Date-based downloads not supported for for %s" raise NotImplementedError(msg % cls.__name__) @classmethod def _get_url_for_date_range(cls, *args, **kwargs): """Returns a URL to the data for the specified date range""" msg = "Date-range based downloads not supported for for %s" raise NotImplementedError(msg % cls.__name__) @staticmethod def _parse_csv(filepath): """Place holder method to parse CSV files.""" msg = "Generic CSV parsing not yet implemented for LightCurve" raise NotImplementedError(msg) @staticmethod def _parse_fits(filepath): """Place holder method to parse FITS files.""" msg = "Generic FITS parsing not yet implemented for LightCurve" raise NotImplementedError(msg) @classmethod def _parse_filepath(cls, filepath): """Check the file extension to see how to parse the file""" filename, extension = os.path.splitext(filepath) if extension.lower() in (".csv", ".txt"): return cls._parse_csv(filepath) else: return cls._parse_fits(filepath) def truncate(self, a, b=None): """Returns a truncated version of the timeseries object""" if isinstance(a, TimeRange): time_range = a else: time_range = TimeRange(a, b) truncated = self.data.truncate(time_range.start(), time_range.end()) return self.__class__.create(truncated, self.meta.copy()) def extract(self, a): """Extract a set of particular columns from the DataFrame""" # TODO allow the extract function to pick more than one column if isinstance(self, pandas.Series): return self else: return LightCurve(self.data[a], self.meta.copy()) def time_range(self): """Returns the start and end times of the LightCurve as a TimeRange object""" return TimeRange(self.data.index[0], self.data.index[-1])
class LightCurve(object): """ LightCurve(filepath) A generic light curve object. Parameters ---------- args : filepath, url, or start and end dates The input for a LightCurve object should either be a filepath, a URL, or a date range to be queried for the particular instrument. Attributes ---------- data : pandas.DataFrame An pandas DataFrame prepresenting one or more fields as they vary with respect to time. header : string, dict The comment string or header associated with the light curve input Examples -------- import sunpy import datetime base = datetime.datetime.today() dates = [base - datetime.timedelta(minutes=x) for x in range(0, 24 * 60)] light_curve = sunpy.lightcurve.LightCurve.create( {"param1": range(24 * 60)}, index=dates) light_curve.show() References ---------- | http://pandas.pydata.org/pandas-docs/dev/dsintro.html """ _cond_dispatch = ConditionalDispatch() create = classmethod(_cond_dispatch.wrapper()) def __init__(self, data, header=None): self.data = data self.header = header @classmethod def from_time(cls, time, **kwargs): date = parse_time(time) url = cls._get_url_for_date(date) filepath = cls._download( url, kwargs, err="Unable to download data for specified date") return cls.from_file(filepath) @classmethod def from_range(cls, from_, to, **kwargs): url = cls._get_url_for_date_range(from_, to) filepath = cls._download( url, kwargs, err="Unable to download data for specified date range") return cls.from_file(filepath) @classmethod def from_timerange(cls, timerange, **kwargs): url = cls._get_url_for_date_range(timerange) filepath = cls._download( url, kwargs, err="Unable to download data for specified date range") return cls.from_file(filepath) @classmethod def from_file(cls, filename): filename = os.path.expanduser(filename) header, data = cls._parse_filepath(filename) return cls(data, header) @classmethod def from_url(cls, url, **kwargs): try: filepath = cls._download(url, kwargs) except (urllib2.HTTPError, urllib2.URLError, ValueError): err = ("Unable to read location. Did you " "specify a valid filepath or URL?") raise ValueError(err) return cls.from_file(filepath) @classmethod def from_data(cls, data, index=None, header=None): return cls(pandas.DataFrame(data, index=index), header) @classmethod def from_yesterday(cls): return cls.from_url(cls._get_default_uri()) @classmethod def from_dataframe(cls, dataframe, header=None): return cls(dataframe, header) def plot(self, axes=None, **plot_args): """Plot a plot of the light curve Parameters ---------- axes: matplotlib.axes object or None If provided the image will be plotted on the given axes. Else the current matplotlib axes will be used. **plot_args : dict Any additional plot arguments that should be used when plotting the image. """ #Get current axes if axes is None: axes = plt.gca() axes = self.data.plot(ax=axes, **plot_args) return axes def peek(self, **kwargs): """Displays the light curve in a new figure""" figure = plt.figure() self.plot(**kwargs) figure.show() return figure @staticmethod def _download(uri, kwargs, err='Unable to download data at specified URL'): """Attempts to download data at the specified URI""" _filename = os.path.basename(uri).split("?")[0] # user specifies a download directory if "directory" in kwargs: download_dir = os.path.expanduser(kwargs["directory"]) else: download_dir = sunpy.config.get("downloads", "download_dir") # overwrite the existing file if the keyword is present if "overwrite" in kwargs: overwrite = kwargs["overwrite"] else: overwrite = False # If the file is not already there, download it filepath = os.path.join(download_dir, _filename) if not (os.path.isfile(filepath)) or (overwrite and os.path.isfile(filepath)): try: response = urllib2.urlopen(uri) except (urllib2.HTTPError, urllib2.URLError): raise urllib2.URLError(err) with open(filepath, 'wb') as fp: shutil.copyfileobj(response, fp) return filepath @classmethod def _get_default_uri(cls): """Default data to load when none is specified""" msg = "No default action set for %s" raise NotImplementedError(msg % cls.__name__) @classmethod def _get_url_for_date(cls, date): """Returns a URL to the data for the specified date""" msg = "Date-based downloads not supported for for %s" raise NotImplementedError(msg % cls.__name__) @classmethod def _get_url_for_date_range(cls, *args, **kwargs): """Returns a URL to the data for the specified date range""" msg = "Date-range based downloads not supported for for %s" raise NotImplementedError(msg % cls.__name__) @staticmethod def _parse_csv(filepath): """Place holder method to parse CSV files.""" msg = "Generic CSV parsing not yet implemented for LightCurve" raise NotImplementedError(msg) @staticmethod def _parse_fits(filepath): """Place holder method to parse FITS files.""" msg = "Generic FITS parsing not yet implemented for LightCurve" raise NotImplementedError(msg) @classmethod def _parse_filepath(cls, filepath): filename, extension = os.path.splitext(filepath) if extension.lower() in (".csv", ".txt"): return cls._parse_csv(filepath) else: return cls._parse_fits(filepath) def truncate(self, a, b=None): """Returns a truncated version of the timeseries object""" if isinstance(a, TimeRange): time_range = a else: time_range = TimeRange(a, b) truncated = self.data.truncate(time_range.start(), time_range.end()) return LightCurve(truncated, self.header.copy()) def extract(self, a): """Extract a set of particular columns from the DataFrame""" # TODO allow the extract function to pick more than one column if isinstance(self, pandas.Series): return self else: return LightCurve(self.data[a], self.header.copy()) def time_range(self): """Returns the start and end times of the LightCurve as a TimeRange object""" return TimeRange(self.data.index[0], self.data.index[-1])
class LightCurve(object): """ LightCurve(filepath) A generic light curve object. Attributes ---------- meta : `str` or `dict` The comment string or header associated with the data. data : `~pandas.DataFrame` An pandas DataFrame prepresenting one or more fields as a function of time. Examples -------- >>> import sunpy >>> import datetime >>> import numpy as np >>> base = datetime.datetime.today() >>> dates = [base - datetime.timedelta(minutes=x) for x in range(0, 24 * 60)] >>> intensity = np.sin(np.arange(0, 12 * np.pi, step=(12 * np.pi) / 24 * 60)) >>> light_curve = sunpy.lightcurve.LightCurve.create({"param1": intensity}, index=dates) >>> light_curve.peek() # doctest: +SKIP References ---------- * `Pandas Documentation <http://pandas.pydata.org/pandas-docs/dev/dsintro.html>`_ """ _cond_dispatch = ConditionalDispatch() create = classmethod(_cond_dispatch.wrapper()) def __init__(self, data, meta=None): self.data = pandas.DataFrame(data) if meta == '' or meta is None: self.meta = OrderedDict() else: self.meta = OrderedDict(meta) @property def header(self): """ Return the lightcurves metadata .. deprecated:: 0.4.0 Use .meta instead """ warnings.warn( """lightcurve.header has been renamed to lightcurve.meta for compatibility with map, please use meta instead""", Warning) return self.meta @classmethod def from_time(cls, time, **kwargs): """ Called by Conditional Dispatch object when valid time is passed as input to create method. """ date = parse_time(time) url = cls._get_url_for_date(date, **kwargs) filepath = cls._download( url, kwargs, err="Unable to download data for specified date") return cls.from_file(filepath) @classmethod def from_range(cls, start, end, **kwargs): """Called by Conditional Dispatch object when start and end time are passed as input to create method. :param start: :param end: :param kwargs: :return: """ url = cls._get_url_for_date_range(parse_time(start), parse_time(end), **kwargs) filepath = cls._download( url, kwargs, err="Unable to download data for specified date range") result = cls.from_file(filepath) result.data = result.data.truncate(start, end) return result @classmethod def from_timerange(cls, timerange, **kwargs): """ Called by Conditional Dispatch object when time range is passed as input to create method. """ url = cls._get_url_for_date_range(timerange, **kwargs) filepath = cls._download( url, kwargs, err="Unable to download data for specified date range") result = cls.from_file(filepath) result.data = result.data.truncate(timerange.start, timerange.end) return result @classmethod def from_file(cls, filename): """Used to return Light Curve object by reading the given filename. Parameters ---------- filename: `str` Path of the file to be read. Returns ------- Lightcurve object. """ filename = os.path.expanduser(filename) meta, data = cls._parse_filepath(filename) if data.empty: raise ValueError("No data found!") else: return cls(data, meta) @classmethod def from_url(cls, url, **kwargs): """ Called by Conditional Dispatch object to create Light Curve object when given a url. Downloads a file from the given url, attemps to read it and returns a Light Curve object. Parameters ---------- url : str A url given as a string. """ try: filepath = cls._download(url, kwargs) except (urllib.error.HTTPError, urllib.error.URLError, ValueError): err = "Unable to read location {!s}.".format(url) raise ValueError(err) return cls.from_file(filepath) @classmethod def from_data(cls, data, index=None, meta=None): """ Called by Conditional Dispatch object to create Light Curve object when corresponding data is passed to create method. Parameters ---------- data : `~numpy.ndarray` The data array index : `~datetime.datetime` array The time values """ return cls(pandas.DataFrame(data, index=index), meta) @classmethod def from_yesterday(cls): """ Called by Conditional Dispatch object if no input if given """ return cls.from_url(cls._get_default_uri()) @classmethod def from_dataframe(cls, dataframe, meta=None): """ Called by Conditional Dispatch object to create Light Curve object when Pandas DataFrame is passed to create method. Parameters ---------- dataframe : `~pandas.DataFrame` The data. meta : `str` or `dict` The metadata. """ return cls(dataframe, meta) def plot(self, axes=None, **plot_args): """Plot a plot of the light curve Parameters ---------- axes : `~matplotlib.axes.Axes` or None If provided the image will be plotted on the given axes. Otherwise the current axes will be used. **plot_args : `dict` Any additional plot arguments that should be used when plotting. Returns ------- axes : `~matplotlib.axes.Axes` The plot axes. """ # Get current axes if axes is None: axes = plt.gca() axes = self.data.plot(ax=axes, **plot_args) return axes def peek(self, **kwargs): """Displays the light curve in a new figure. Parameters ---------- **kwargs : `dict` Any additional plot arguments that should be used when plotting. Returns ------- fig : `~matplotlib.Figure` A plot figure. """ figure = plt.figure() self.plot(**kwargs) figure.show() return figure @staticmethod def _download(uri, kwargs, err='Unable to download data at specified URL'): """Attempts to download data at the specified URI. Parameters ---------- **kwargs : uri A url """ _filename = os.path.basename(uri).split("?")[0] # user specifies a download directory if "directory" in kwargs: download_dir = os.path.expanduser(kwargs["directory"]) else: download_dir = config.get("downloads", "download_dir") # overwrite the existing file if the keyword is present if "overwrite" in kwargs: overwrite = kwargs["overwrite"] else: overwrite = False # If the file is not already there, download it filepath = os.path.join(download_dir, _filename) if not (os.path.isfile(filepath)) or (overwrite and os.path.isfile(filepath)): try: response = urllib.request.urlopen(uri) except (urllib.error.HTTPError, urllib.error.URLError): raise urllib.error.URLError(err) with open(filepath, 'wb') as fp: shutil.copyfileobj(response, fp) else: warnings.warn( "Using existing file rather than downloading, use " "overwrite=True to override.", RuntimeWarning) return filepath @classmethod def _get_default_uri(cls): """Default data to load when none is specified.""" msg = "No default action set for {}" raise NotImplementedError(msg.format(cls.__name__)) @classmethod def _get_url_for_date(cls, date, **kwargs): """Returns a URL to the data for the specified date.""" msg = "Date-based downloads not supported for for {}" raise NotImplementedError(msg.format(cls.__name__)) @classmethod def _get_url_for_date_range(cls, *args, **kwargs): """Returns a URL to the data for the specified date range.""" msg = "Date-range based downloads not supported for for {}" raise NotImplementedError(msg.format(cls.__name__)) @staticmethod def _parse_csv(filepath): """Place holder method to parse CSV files.""" msg = "Generic CSV parsing not yet implemented for LightCurve" raise NotImplementedError(msg) @staticmethod def _parse_fits(filepath): """Place holder method to parse FITS files.""" msg = "Generic FITS parsing not yet implemented for LightCurve" raise NotImplementedError(msg) @classmethod def _parse_filepath(cls, filepath): """Check the file extension to see how to parse the file.""" filename, extension = os.path.splitext(filepath) if extension.lower() in (".csv", ".txt"): return cls._parse_csv(filepath) else: return cls._parse_fits(filepath) def truncate(self, a, b=None): """Returns a truncated version of the timeseries object. Parameters ---------- a : `sunpy.time.TimeRange` A time range to truncate to. Returns ------- newlc : `~sunpy.lightcurve.LightCurve` A new lightcurve with only the selected times. """ if isinstance(a, TimeRange): time_range = a else: time_range = TimeRange(a, b) truncated = self.data.truncate(time_range.start, time_range.end) return self.__class__.create(truncated, self.meta.copy()) def extract(self, column_name): """Returns a new lightcurve with the chosen column. Parameters ---------- column_name : `str` A valid column name Returns ------- newlc : `~sunpy.lightcurve.LightCurve` A new lightcurve with only the selected column. """ # TODO allow the extract function to pick more than one column if isinstance(self, pandas.Series): return self else: return LightCurve(self.data[column_name], self.meta.copy()) def time_range(self): """Returns the start and end times of the LightCurve as a `~sunpy.time.TimeRange` object""" return TimeRange(self.data.index[0], self.data.index[-1])
def test_types(): f = ConditionalDispatch() f.add(lambda x: 2 * x, lambda x: x % 2 == 0, [int]) with pytest.raises(TypeError): f(2.0)
class LightCurve(object): """ LightCurve(filepath) A generic light curve object. Parameters ---------- args : filepath, url, or start and end dates The input for a LightCurve object should either be a filepath, a URL, or a date range to be queried for the particular instrument. Attributes ---------- data : pandas.DataFrame An pandas DataFrame prepresenting one or more fields as they vary with respect to time. header : string, dict The comment string or header associated with the light curve input Examples -------- >>> import sunpy >>> import datetime >>> base = datetime.datetime.today() >>> dates = [base - datetime.timedelta(minutes=x) for x in range(0, 24 * 60)] >>> light_curve = sunpy.lightcurve.LightCurve({"param1": range(24 * 60)}, index=dates) >>> light_curve.show() References ---------- | http://pandas.pydata.org/pandas-docs/dev/dsintro.html """ _cond_dispatch = ConditionalDispatch() create = classmethod(_cond_dispatch.wrapper()) def __init__(self, data, header=None): self.data = data self.header = header @classmethod def from_time(cls, time, **kwargs): date = sunpy.time.parse_time(time) url = cls._get_url_for_date(date) filepath = cls._download( url, kwargs, err="Unable to download data for specified date") return cls.from_file(filepath) @classmethod def from_range(cls, from_, to, **kwargs): url = cls._get_url_for_date_range(from_, to) filepath = self._download( url, kwargs, err="Unable to download data for specified date range") return cls.from_file(filepath) @classmethod def from_timerange(cls, timerange, **kwargs): url = cls._get_url_for_date_range(timerange) err = "Unable to download data for specified date range" filepath = self._download(url, err, kwargs) return cls.from_file(filepath) @classmethod def from_file(cls, filename): filename = os.path.expanduser(filename) header, data = cls._parse_filepath(filename) return cls(data, header) @classmethod def from_url(cls, url, **kwargs): try: filepath = cls._download(url, kwargs) except (urllib2.HTTPError, urllib2.URLError, ValueError): err = ("Unable to read location. Did you " "specify a valid filepath or URL?") raise ValueError(err) return cls.from_file(filepath) @classmethod def from_data(cls, data, index=None, header=None): return cls(pandas.DataFrame(data, index=index), header) @classmethod def from_yesterday(cls): return cls.from_url(cls._get_default_uri()) @classmethod def from_dataframe(cls, dataframe, header=None): return cls(dataframe, header) def plot(self, **kwargs): """Plot a plot of the light curve""" axes = self.data.plot(**kwargs) return axes.get_figure() def show(self, **kwargs): """Shows a plot of the light curve""" fig = self.plot(**kwargs) fig.show() return fig @staticmethod def _download(uri, kwargs, err='Unable to download data at specified URL'): """Attempts to download data at the specified URI""" _filename = os.path.basename(uri).split("?")[0] # user specifies a download directory if "directory" in kwargs: download_dir = os.path.expanduser(kwargs["directory"]) else: download_dir = sunpy.config.get("downloads", "download_dir") # overwrite the existing file if the keyword is present if "overwrite" in kwargs: overwrite = kwargs["overwrite"] else: overwrite = False # If the file is not already there, download it filepath = os.path.join(download_dir, _filename) if not (os.path.isfile(filepath)) or (overwrite and os.path.isfile(filepath)): try: response = urllib2.urlopen(uri) except (urllib2.HTTPError, urllib2.URLError): raise urllib2.URLError(err) with open(filepath, 'wb') as fp: shutil.copyfileobj(response, fp) return filepath @classmethod def _get_default_uri(cls): """Default data to load when none is specified""" msg = "No default action set for %s" raise NotImplementedError(msg % cls.__name__) @classmethod def _get_url_for_date(cls, date): """Returns a URL to the data for the specified date""" msg = "Date-based downloads not supported for for %s" raise NotImplementedError(msg % cls.__name__) @classmethod def _get_url_for_date_range(cls, *args, **kwargs): """Returns a URL to the data for the specified date range""" msg = "Date-range based downloads not supported for for %s" raise NotImplementedError(msg % cls.__name__) @staticmethod def _parse_csv(filepath): """Place holder method to parse CSV files.""" msg = "Generic CSV parsing not yet implemented for LightCurve" raise NotImplementedError(msg) @staticmethod def _parse_fits(filepath): """Place holder method to parse FITS files.""" msg = "Generic FITS parsing not yet implemented for LightCurve" raise NotImplementedError(msg) @classmethod def _parse_filepath(cls, filepath): filename, extension = os.path.splitext(filepath) if extension.lower() in (".csv", ".txt"): return cls._parse_csv(filepath) else: return cls._parse_fits(filepath) def discrete_boxcar_average(self, seconds=1): """Computes a discrete boxcar average for the DataFrame""" date_range = pandas.DateRange(self.data.index[0], self.data.index[-1], offset=pandas.datetools.Second(seconds)) grouped = self.data.groupby(date_range.asof) subsampled = grouped.mean() return LightCurve(subsampled, self.header.copy()) def truncate(self, start=None, end=None): """Returns a truncated version of the Lyra object""" if start is None: start = self.data.index[0] if end is None: end = self.data.index[-1] truncated = self.data.truncate(sunpy.time.parse_time(start), sunpy.time.parse_time(end)) return LightCurve(truncated, self.header.copy())