diff --git a/.travis.yml b/.travis.yml index 0042f6c..de52e40 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,29 +1,24 @@ language: python python: - - '3.6' - +- '3.6' branches: only: - - master - + - master install: - - sudo apt-get update - - wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh; - - - - bash miniconda.sh -b -p $HOME/miniconda - - export PATH="$HOME/miniconda/bin:$PATH" - - hash -r - - conda config --set always_yes yes --set changeps1 no - - conda env create -q python=$TRAVIS_PYTHON_VERSION -f environment.yml - - source activate goodman_focus - - - - python setup.py test - - python setup.py install - +- sudo apt-get update +- wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh; +- bash miniconda.sh -b -p $HOME/miniconda +- export PATH="$HOME/miniconda/bin:$PATH" +- hash -r +- conda config --set always_yes yes --set changeps1 no +- conda env create -q python=$TRAVIS_PYTHON_VERSION -f environment.yml +- source activate goodman_focus +- python setup.py test +- python setup.py install script: - - coverage run --branch --source= setup.py test - +- coverage run --branch --source= setup.py test after_success: - - coveralls \ No newline at end of file +- coveralls +notifications: + slack: + secure: nJCEgN2ou41cgpRZ89GVBkNbKsxaMaIYVClJcOoU/hTFI3/XLLxsWSe1x+Shp6relrdS/P+T1gwSwvGqKrZWBZ/TDRSAwCyLxZ4l49sfNV7JoHmEgyg4qulXKkPwLpCK7R3PJwE0MAIaZAaklNcxTKV63KjjAXiFuyF3ldK2sjQMwjUeqlomRG+3EZQJUxkQTKAnrupq5gPO+iZlI2jevTYm1qwmT6KhUeg0wQMT49PkA1AZbDK9ch2NysIYAQgEW6nyot7k30rytU3rFetCcrmuzuT7i33LCsjQd/ltyOnnqujVMNE5nFRJLA0k16IV6zZbpIIKhfUb2k3ObtJW8A2lhULF+s4N8ayPl5hZJPZ6c9riLDm96iqLIfi79s09UL3Ws4vN3oTWOgbd/28fNgwl4yqZecuYFT9EUPidTkgYg2P1Pi0r0InsAP+KbELTeQoN+XltBS0sJnoCKkIK/fe1ZZHVXEVkUMt5AqPcv6+UMSS49OjU0+bIkqXlqamlFHWIstcWPVdshNHu9aWqxMtWrYQdhkZDjBbfM9BG9Bv0K8zfNi5n4UyJslmUY6vZl7x+gx5xU7tgZYVmZSckBu1n14PZC8lGQHuuuP4poLlQ954Q+TB7Jwv177apR20Vx6DKw/od7i6Zy2MwxbUhFtn8V7oa8wLSQYInnUXlL4I= diff --git a/CHANGES.rst b/CHANGES.rst index 140a003..c7f20cd 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -3,6 +3,9 @@ - Created dedicated documentation for rtd - Fixed bug where return was missing +- GoodmanFocus need to be instantiated only once [#19] +- Argument --file-pattern is now actually used in file selection [#18] +- Eliminated some warnings 0.2.0 ===== diff --git a/goodman_focus/goodman_focus.py b/goodman_focus/goodman_focus.py index cd73917..736ec25 100644 --- a/goodman_focus/goodman_focus.py +++ b/goodman_focus/goodman_focus.py @@ -7,6 +7,7 @@ import re import sys +from astropy.io import fits from astropy.stats import sigma_clip from astropy.modeling import models, fitting, Model from ccdproc import CCDData @@ -112,7 +113,7 @@ def get_peaks(ccd, file_name='', plots=False): raw_profile = np.median(ccd.data[low_limit:high_limit, :], axis=0) x_axis = np.array(range(len(raw_profile))) - clipped_profile = sigma_clip(raw_profile, sigma=1, iters=5) + clipped_profile = sigma_clip(raw_profile, sigma=1, maxiters=5) _mean = np.mean(clipped_profile) @@ -122,7 +123,7 @@ def get_peaks(ccd, file_name='', plots=False): background_model = models.Linear1D(slope=0, intercept=np.mean(clipped_profile)) - fitter = fitting.SimplexLSQFitter() + fitter = fitting.LinearLSQFitter() fitted_background = fitter(background_model, clipped_x_axis, @@ -227,7 +228,7 @@ def get_fwhm(peaks, values, x_axis, profile, model): else: log.info("Applying sigma clipping to collected FWHM values." " SIGMA: 3, ITERATIONS: 1") - clipped_fwhm = sigma_clip(all_fwhm, sigma=3, iters=1) + clipped_fwhm = sigma_clip(all_fwhm, sigma=3, maxiters=1) if np.ma.is_masked(clipped_fwhm): cleaned_fwhm = clipped_fwhm[~clipped_fwhm.mask] @@ -319,59 +320,80 @@ def __init__(self, self.log.critical("No such directory") sys.exit(0) - _ifc = ImageFileCollection(self.full_path, keywords=self.keywords) - - self.ifc = _ifc.summary.to_pandas() - self.log.debug("Found {} FITS files".format(self.ifc.shape[0])) - self.ifc = self.ifc[(self.ifc['OBSTYPE'] == self.obstype)] - if self.ifc.shape[0] != 0: - self.log.debug("Found {} FITS files with OBSTYPE = FOCUS".format( - self.ifc.shape[0])) - - self.focus_groups = [] - configs = self.ifc.groupby(['CAM_TARG', - 'GRT_TARG', - 'FILTER', - 'FILTER2', - 'GRATING', - 'SLIT', - 'WAVMODE', - 'RDNOISE', - 'GAIN', - 'ROI']).size().reset_index().rename( - columns={0: 'count'}) - # print(configs.to_string()) - for i in configs.index: - focus_group = self.ifc[((self.ifc['CAM_TARG'] == configs.iloc[i]['CAM_TARG']) & - (self.ifc['GRT_TARG'] == configs.iloc[i]['GRT_TARG']) & - (self.ifc['FILTER'] == configs.iloc[i]['FILTER']) & - (self.ifc['FILTER2'] == configs.iloc[i]['FILTER2']) & - (self.ifc['GRATING'] == configs.iloc[i]['GRATING']) & - (self.ifc['SLIT'] == configs.iloc[i]['SLIT']) & - (self.ifc['WAVMODE'] == configs.iloc[i]['WAVMODE']) & - (self.ifc['RDNOISE'] == configs.iloc[i]['RDNOISE']) & - (self.ifc['GAIN'] == configs.iloc[i]['GAIN']) & - (self.ifc['ROI'] == configs.iloc[i]['ROI']))] - self.focus_groups.append(focus_group) + def __call__(self, files=None): + if files is None: + + _ifc = ImageFileCollection(location=self.full_path, + keywords=self.keywords, + glob_include=self.file_pattern) + + self.ifc = _ifc.summary.to_pandas() + self.log.debug("Found {} FITS files".format(self.ifc.shape[0])) + self.ifc = self.ifc[(self.ifc['OBSTYPE'] == self.obstype)] + if self.ifc.shape[0] != 0: + self.log.debug("Found {} FITS files with OBSTYPE = FOCUS".format( + self.ifc.shape[0])) + + self.focus_groups = [] + configs = self.ifc.groupby(['CAM_TARG', + 'GRT_TARG', + 'FILTER', + 'FILTER2', + 'GRATING', + 'SLIT', + 'WAVMODE', + 'RDNOISE', + 'GAIN', + 'ROI']).size().reset_index().rename( + columns={0: 'count'}) + # print(configs.to_string()) + for i in configs.index: + focus_group = self.ifc[ + ((self.ifc['CAM_TARG'] == configs.iloc[i]['CAM_TARG']) & + (self.ifc['GRT_TARG'] == configs.iloc[i]['GRT_TARG']) & + (self.ifc['FILTER'] == configs.iloc[i]['FILTER']) & + (self.ifc['FILTER2'] == configs.iloc[i]['FILTER2']) & + (self.ifc['GRATING'] == configs.iloc[i]['GRATING']) & + (self.ifc['SLIT'] == configs.iloc[i]['SLIT']) & + (self.ifc['WAVMODE'] == configs.iloc[i]['WAVMODE']) & + (self.ifc['RDNOISE'] == configs.iloc[i]['RDNOISE']) & + (self.ifc['GAIN'] == configs.iloc[i]['GAIN']) & + (self.ifc['ROI'] == configs.iloc[i]['ROI']))] + self.focus_groups.append(focus_group) + else: + self.log.critical('Focus files must have OBSTYPE keyword equal to ' + '"FOCUS", none found.') + self.log.info('Please use "--obstype" to change the value though ' + 'it is not recommended to use neither "OBJECT" nor ' + '"FLAT" because it may contaminate the sample with ' + 'non focus images.') + sys.exit(0) else: - self.log.critical('Focus files must have OBSTYPE keyword equal to ' - '"FOCUS", none found.') - self.log.info('Please use "--obstype" to change the value though ' - 'it is not recommended to use neither "OBJECT" nor ' - '"FLAT" because it may contaminate the sample with ' - 'non focus images.') - sys.exit(0) + if isinstance(files, list): + full_path_content = os.listdir(self.full_path) - @property - def fwhm(self): - return self._fwhm + if not all([_file in full_path_content for _file in files]): + files_dont_exist = [_file for _file in files if _file not in full_path_content] + for _file in files_dont_exist: + self.log.critical("File {} does not exist in {}" + "".format(_file, self.full_path)) + sys.exit(0) + else: + data = {'file': files} + + for key in ['INSTCONF', 'FILTER', 'FILTER2', 'WAVMODE']: + key_data = [fits.getval(os.path.join(self.full_path, + _file), key) for _file in files] + + data[key] = key_data + + self.focus_groups = [pandas.DataFrame(data)] + + else: + self.log.critical('"files" argument must be a list') + sys.exit(0) - @fwhm.setter - def fwhm(self, value): - if value is not None: - self._fwhm = value - def __call__(self, *args, **kwargs): results = {} for focus_group in self.focus_groups: mode_name = self._get_mode_name(focus_group) @@ -399,6 +421,15 @@ def __call__(self, *args, **kwargs): return results + @property + def fwhm(self): + return self._fwhm + + @fwhm.setter + def fwhm(self, value): + if value is not None: + self._fwhm = value + def _fit(self, df): focus = df['focus'].tolist() fwhm = df['fwhm'].tolist() @@ -504,7 +535,43 @@ def run_goodman_focus(args=None): # pragma: no cover features_model=args.features_model, plot_results=args.plot_results, debug=args.debug) - goodman_focus() + result = goodman_focus() + log.info("Summary") + for key in result.keys(): + log.info("Mode: {} Best Focus: {}".format(key, result[key])) + + +# def run_goodman_focus_list(args=None): # pragma: no cover +# """Entrypoint +# +# Args: +# args (list): (optional) a list of arguments and respective values. +# +# """ +# args = get_args(arguments=args) +# goodman_focus = GoodmanFocus(data_path=args.data_path, +# file_pattern=args.file_pattern, +# obstype=args.obstype, +# features_model=args.features_model, +# plot_results=args.plot_results, +# debug=args.debug) +# +# file_list = ['0016_foc_400m2.fits', +# '0018_foc_400m2.fits', +# '0020_foc_400m2.fits', +# '0022_foc_400m2.fits', +# '0024_foc_400m2.fits', +# '0026_foc_400m2.fits', +# '0028_foc_400m2.fits', +# '0017_foc_400m2.fits', +# '0019_foc_400m2.fits', +# '0021_foc_400m2.fits', +# '0023_foc_400m2.fits', +# '0025_foc_400m2.fits', +# '0027_foc_400m2.fits'] +# +# result = goodman_focus(files=file_list) +# print(result) if __name__ == '__main__': # pragma: no cover diff --git a/goodman_focus/tests/test_goodman_focus.py b/goodman_focus/tests/test_goodman_focus.py index a611a7a..accca5b 100644 --- a/goodman_focus/tests/test_goodman_focus.py +++ b/goodman_focus/tests/test_goodman_focus.py @@ -130,6 +130,7 @@ def setUp(self): ccd = CCDData(data=np.ones((100, 1000)), meta=fits.Header(), unit='adu') + ccd.header['instconf'] = 'Red' ccd.header['obstype'] = 'FOCUS' ccd.header['cam_foc'] = self.focus_values[i] ccd.header['cam_targ'] = 0 @@ -190,6 +191,19 @@ def test__call__Moffat1D(self): self.goodman_focus() self.assertIsNotNone(self.goodman_focus.fwhm) + def test__call__with_list(self): + self.assertIsNone(self.goodman_focus.fwhm) + result = self.goodman_focus(files=self.file_list) + self.assertIsNotNone(self.goodman_focus.fwhm) + + def test__call__list_file_no_exist(self): + file_list = ["no_file_{}.fits".format(i) for i in range(10, 20)] + self.assertRaises(SystemExit, self.goodman_focus, file_list) + + def test__call__not_a_list(self): + _string = 'not a list' + self.assertRaises(SystemExit, self.goodman_focus, _string) + def tearDown(self): for _file in self.file_list: os.unlink(_file) @@ -269,7 +283,8 @@ def test_directory_not_empty_and_no_matching_files(self): def test_no_focus_files(self): path_no_focus_files = os.path.join(os.getcwd(), 'test_dir_no_focus') - self.assertRaises(SystemExit, GoodmanFocus, path_no_focus_files) + goodman_focus = GoodmanFocus(data_path=path_no_focus_files) + self.assertRaises(SystemExit, goodman_focus) def tearDown(self):