def test_bad_l0_invalid(tmpdir, caplog): # Test no valid values testfile = os.path.join(str(tmpdir), 'sparta.fits') create_sparta_table(outfile=testfile, L0=1000) compute_psf_from_sparta(testfile) assert caplog.records[ 1].message == '1/1 : No valid values, skipping this row' assert caplog.records[2].message == 'No valid values'
def test_reconstruction2(tmpdir): tbl = create_sparta_table() # Modify values for the first LGS tbl.data[0]['LGS1_L0'] = 20 tbl.data[0]['LGS1_SEEING'] = 0.8 tbl.data[0]['LGS1_TUR_GND'] = 0.5 # and give a bad value to the 3rd LGS tbl.data[0]['LGS3_L0'] = 100 hdul = fits.HDUList([tbl]) # Note: the case when npsflin=1 is tested below with test_script res = compute_psf_from_sparta(hdul, npsflin=3, lmin=500, lmax=700, nl=3, mean_of_lgs=False) assert len(res) == 5 # check that meta are correctly saved fit = Table.read(res['FIT_ROWS']) assert_allclose(fit[fit['lgs_idx'] == 1]['L0'], 20) assert_allclose(fit[fit['lgs_idx'] != 1]['L0'], 25) # check fit result assert_allclose(fit['center'], 20) assert_allclose(fit[fit['lbda'] == 500]['fwhm'][:, 0], [0.79, 0.86, 0.86], atol=1e-2)
def test_plot(tmpdir): import matplotlib matplotlib.use('agg', force=True) testfile = os.path.join(str(tmpdir), 'sparta.fits') create_sparta_table(outfile=testfile, nlines=2) res = compute_psf_from_sparta(testfile) outfile = os.path.join(str(tmpdir), 'fitres.fits') res.writeto(outfile, overwrite=True) fig = plot_psf(res) fig.savefig(str(tmpdir.join('fig.png'))) fig = plot_psf(outfile) fig.savefig(str(tmpdir.join('fig.png')))
def test_bad_l0(tmpdir, caplog): testfile = os.path.join(str(tmpdir), 'sparta.fits') create_sparta_table(outfile=testfile, bad_l0=True) # Note: the case when npsflin=1 is tested below with test_script res = compute_psf_from_sparta(testfile, lmin=490, lmax=541.76, nl=5) assert (caplog.records[1].message == '1/1 : Using only 3 values out of 4 after outliers rejection') assert caplog.records[3].message == 'Using three lasers mode' assert len(res) == 5 # check that meta are correctly saved fit = Table.read(res['FIT_ROWS']) assert_allclose(fit['L0'], 25) # check fit result assert_allclose(fit['center'], 20) assert_allclose(fit[1]['lbda'], 502.9, atol=1e-1) assert_allclose(fit[1]['fwhm'], 0.86, atol=1e-2)
def test_script_with_file(tmpdir): testfile = os.path.join(str(tmpdir), 'sparta.fits') create_sparta_table(outfile=testfile) logfile = os.path.join(str(tmpdir), 'muse_psfr.log') outfile = os.path.join(str(tmpdir), 'out.fits') main([testfile, '--no-color', '--logfile', logfile, '--outfile', outfile]) with fits.open(outfile) as hdul: assert [hdu.name for hdu in hdul] == [ 'PRIMARY', 'SPARTA_ATM_DATA', 'FIT_ROWS', 'FIT_MEAN', 'PSF_MEAN' ] with open(logfile) as f: lines = f.read().splitlines() assert lines[2:] == [ 'OB None None Airmass 0.00-0.00', '--------------------------------------------------------------------', 'LBDA 5000 7000 9000', 'FWHM 0.85 0.73 0.62', 'BETA 2.73 2.55 2.23', '--------------------------------------------------------------------' ]
def test_reconstruction(tmpdir): tbl = create_sparta_table() hdul = fits.HDUList([tbl]) # Note: the case when npsflin=1 is tested below with test_script res = compute_psf_from_sparta(hdul, npsflin=3, lmin=490, lmax=541.76, nl=5) assert len(res) == 5 # check that meta are correctly saved fit = Table.read(res['FIT_ROWS']) assert_allclose(fit['L0'], 25) # check fit result assert_allclose(fit['center'], 20) assert_allclose(fit[1]['lbda'], 502.9, atol=1e-1) assert_allclose(fit[1]['fwhm'], 0.85, atol=1e-2)
def test_fit_poly(tmpdir): tbl = create_sparta_table() hdul = fits.HDUList([tbl]) res = compute_psf_from_sparta(hdul, lmin=500, lmax=900, nl=9) fit = Table.read(res['FIT_ROWS']) res = fit_psf_with_polynom(fit['lbda'], fit['fwhm'][:, 0], fit['n'], deg=(5, 5), output=1) assert_allclose(res['fwhm_pol'][0], 0.65, atol=1e-2) assert_allclose(res['beta_pol'][0], 0.78, atol=1e-2) # fit[1] at 550nm matches roughly res[8] (550.1) assert_allclose(res['beta_fit'][8], fit[1]['n'], atol=1e-2) assert_allclose(res['fwhm_fit'][8], fit[1]['fwhm'], atol=1e-2)
def main(args=None): parser = argparse.ArgumentParser( description=f'MUSE-PSFR version {__version__}') addarg = parser.add_argument addarg('raw', help='observation raw file name', nargs='?') addarg('--values', help='values of seeing, GL, L0, to use instead of the ' 'raw file, comma-separated') addarg('--logfile', default='muse_psfr.log', help='name of log file') addarg('-o', '--outfile', help='name of a FITS file in which the results ' 'are saved: table with individual and mean Moffat fits, and mean ' 'reconstructed PSF') addarg('--njobs', default=-1, type=int, help='number of parallel jobs ' '(by default use all CPUs)') addarg('--verbose', '-v', action='store_true', help='verbose flag') addarg('--no-color', action='store_true', help='no color in output') addarg('--plot', action='store_true', help='plot reconstructed psf') addarg('--version', action='version', version='%(prog)s ' + __version__) args = parser.parse_args(args) logger.info('MUSE-PSFR version %s', __version__) if args.values: values = [float(x) for x in args.values.split(',')] if len(values) != 3: sys.exit('--values must contain a list of 3 comma-separated ' 'values for seeing, GL, and L0') header_line = None rawf = io.BytesIO() create_sparta_table(outfile=rawf, seeing=values[0], GL=values[1], L0=values[2]) rawf.seek(0) else: if args.raw is None: sys.exit('no input file provided') rawf = args.raw hdr = fits.getheader(rawf) header_line = ('OB %s %s Airmass %.2f-%.2f' % (hdr.get('HIERARCH ESO OBS NAME'), hdr.get('DATE'), hdr.get('HIERARCH ESO TEL AIRM START', 0), hdr.get('HIERARCH ESO TEL AIRM END', 0))) logger.info(header_line) logger.info('Computing PSF Reconstruction from Sparta data') if args.verbose: _logger = logging.getLogger('muse_psfr') _logger.setLevel("DEBUG") _logger.handlers[0].setLevel("DEBUG") res = compute_psf_from_sparta(rawf, lmin=500, lmax=900, nl=3, n_jobs=args.njobs, plot=args.plot) if res: data = res['FIT_MEAN'].data lbda, fwhm, beta = data['lbda'], data['fwhm'][:, 0], data['n'] else: sys.exit('No results') f = io.StringIO() if header_line: f.write(header_line + '\n') f.write('-' * 68 + '\n') try: import colorama # noqa except ImportError: args.no_color = True lbda *= 10 if args.no_color: f.write('LBDA %.0f %.0f %.0f\n' % tuple(lbda)) f.write('FWHM %.2f %.2f %.2f\n' % tuple(fwhm)) f.write('BETA %.2f %.2f %.2f\n' % tuple(beta)) else: from colorama import Fore, Back, Style RED, GREEN, BLUE = Fore.RED, Fore.GREEN, Fore.BLUE begin_style = Back.BLACK + Style.BRIGHT + Fore.WHITE end_style = Fore.RESET + Style.NORMAL + Back.RESET f.write( f'{begin_style}' f'LBDA {BLUE}{lbda[0]:.0f} {GREEN}{lbda[1]:.0f} {RED}{lbda[2]:.0f}' f'{end_style}\n' f'{begin_style}' f'FWHM {BLUE}{fwhm[0]:.2f} {GREEN}{fwhm[1]:.2f} {RED}{fwhm[2]:.2f}' f'{end_style}\n' f'{begin_style}' f'BETA {BLUE}{beta[0]:.2f} {GREEN}{beta[1]:.2f} {RED}{beta[2]:.2f}' f'{end_style}\n') f.write(Style.RESET_ALL) f.write('-' * 68 + '\n') f.seek(0) for line in f: logger.info(line.rstrip('\n')) if args.logfile is not None: f.seek(0) with open(args.logfile, 'a') as fd: fd.write('\nFile: {}\n'.format(args.raw)) fd.write(f.read()) logger.info('Results saved to %s' % args.logfile) if args.outfile is not None: res.writeto(args.outfile, overwrite=True) logger.info('FITS file saved to %s' % args.outfile)