diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index c61133373..bc87c0a88 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -26,7 +26,7 @@ jobs: # Might be quicker to install rubin-env plus any necessary additions. shell: bash -l {0} run: | - mamba install -y "numpy>1.15" scipy "matplotlib>3.1" pandas llvmlite numba "astropy>=3.2" "photutils>=1.7" astroquery coloredlogs scikit-image>=0.20 h5py emcee tqdm mpi4py schwimmbad "iminuit>=2" "coverage>=3.6" configparser coveralls deprecated pyyaml pytest pytest-cov rubin-libradtran "getCalspec>=2.0.0" + mamba install -y "numpy>1.15" scipy "matplotlib>3.1" pandas llvmlite numba "astropy>=3.2" "photutils>=1.7" astroquery coloredlogs scikit-image>=0.20 h5py emcee tqdm mpi4py schwimmbad "iminuit>=2" "coverage>=3.6" configparser coveralls deprecated pyyaml "pytest==8.0.0" pytest-cov rubin-libradtran "getCalspec>=2.0.0" # python -c "from getCalspec.rebuild import rebuild_tables; rebuild_tables()" pip install lsst.utils pip install git+https://github.com/LSSTDESC/getObsAtmo.git@main diff --git a/config/auxtel.ini b/config/auxtel.ini index ea488c2f4..fd51aae13 100644 --- a/config/auxtel.ini +++ b/config/auxtel.ini @@ -20,7 +20,9 @@ SPECTRACTOR_FIT_TIMEOUT_PER_ITER = 1200 # maximum time per gradient descent before TimeoutError in seconds SPECTRACTOR_FIT_TIMEOUT = 7200 # library to compute atmospheric transmission: none, libradtran, getobsatmo -SPECTRACTOR_ATMOSPHERE_SIM = getobstamo +SPECTRACTOR_ATMOSPHERE_SIM = getobsatmo +# simulate star field with Gaia catalog: False, True +SPECTRACTOR_SIMULATE_STARFIELD = False [instrument] # instrument name @@ -55,7 +57,7 @@ CCD_PIXEL2ARCSEC = 0.0952 # approximate maximum ADU output of the CCD CCD_MAXADU = 170000 # electronic gain : elec/ADU -CCD_GAIN = 1.1 +CCD_GAIN = 1.3 # rebinning of the image in pixel CCD_REBIN = 2 @@ -107,7 +109,7 @@ PIXWIDTH_BACKGROUND = 40 PIXWIDTH_BOXSIZE = 20 [PSF] -# the PSF model: Gauss, Moffat or MoffatGauss +# the PSF model: Gauss, Moffat, DoubleMoffat or MoffatGauss PSF_TYPE = Moffat # the order of the polynomials to model wavelength dependence of the PSF shape parameters PSF_POLY_ORDER = 2 diff --git a/config/ctio.ini b/config/ctio.ini index 46aa69201..35a285446 100644 --- a/config/ctio.ini +++ b/config/ctio.ini @@ -17,6 +17,8 @@ SPECTRACTOR_DECONVOLUTION_PSF2D = True SPECTRACTOR_DECONVOLUTION_FFM = True # library to compute atmospheric transmission: none, libradtran, getobsatmo SPECTRACTOR_ATMOSPHERE_SIM = none +# simulate star field with Gaia catalog: False, True +SPECTRACTOR_SIMULATE_STARFIELD = True [instrument] # instrument name @@ -99,10 +101,10 @@ PIXWIDTH_BACKGROUND = 100 PIXWIDTH_BOXSIZE = 40 [PSF] -# the PSF model: Gauss, Moffat or MoffatGauss +# the PSF model: Gauss, Moffat, DoubleMoffat, or MoffatGauss PSF_TYPE = Moffat # the order of the polynomials to model wavelength dependence of the PSF shape parameters -PSF_POLY_ORDER = 4 +PSF_POLY_ORDER = 2 # regularisation parameter for the chisq minimisation to extract the spectrum PSF_FIT_REG_PARAM = 0.04 # step size in pixels for the first transverse PSF1D fit diff --git a/config/default.ini b/config/default.ini index b79e9bb23..714e74dc6 100644 --- a/config/default.ini +++ b/config/default.ini @@ -21,6 +21,8 @@ SPECTRACTOR_FIT_TIMEOUT_PER_ITER = 600 SPECTRACTOR_FIT_TIMEOUT = 3600 # library to compute atmospheric transmission: none, libradtran, getobsatmo SPECTRACTOR_ATMOSPHERE_SIM = none +# simulate star field with Gaia catalog: False, True +SPECTRACTOR_SIMULATE_STARFIELD = False [instrument] # instrument name @@ -113,12 +115,14 @@ PIXWIDTH_BACKGROUND = 40 PIXWIDTH_BOXSIZE = 20 [PSF] -# the PSF model: Gauss, Moffat or MoffatGauss +# the PSF model: Gauss, Moffat, DoubleMoffat or MoffatGauss PSF_TYPE = Moffat # the order of the polynomials to model wavelength dependence of the PSF shape parameters PSF_POLY_ORDER = 2 # regularisation parameter for the chisq minimisation to extract the spectrum PSF_FIT_REG_PARAM = 0.01 +# polynomial type: must be polynomial or legendre +PSF_POLY_TYPE = polynomial [detection line algorithm parameters] # order of the background polynome to fit diff --git a/config/stardice.ini b/config/stardice.ini index d3864c1b6..179b2d4f3 100644 --- a/config/stardice.ini +++ b/config/stardice.ini @@ -6,7 +6,7 @@ THROUGHPUT_DIR = simulation/StarDiceThroughput/ [pipeline] # method to get target centroid, choose among: guess, fit, WCS -SPECTRACTOR_FIT_TARGET_CENTROID = WCS +SPECTRACTOR_FIT_TARGET_CENTROID = fit # method to get image rotation angle: False, disperser, hessian SPECTRACTOR_COMPUTE_ROTATION_ANGLE = disperser # parameter to prevent from background subtraction @@ -19,6 +19,8 @@ SPECTRACTOR_DECONVOLUTION_FFM = True SPECTRACTOR_DECONVOLUTION_SIGMA_CLIP = 100 # library to compute atmospheric transmission: none, libradtran, getobsatmo SPECTRACTOR_ATMOSPHERE_SIM = getobsatmo +# simulate star field with Gaia catalog: False, True +SPECTRACTOR_SIMULATE_STARFIELD = False [instrument] # instrument name @@ -59,9 +61,9 @@ CCD_REBIN = 1 [spectrograph] # distance between hologram and CCD in mm -DISTANCE2CCD = 33.3 +DISTANCE2CCD = 33.5 # uncertainty on distance between hologram and CCD in mm -DISTANCE2CCD_ERR = 0.1 +DISTANCE2CCD_ERR = 0.06 # default value for order 2 over order 1 transmission ratio GRATING_ORDER_2OVER1 = 0.1 @@ -75,7 +77,7 @@ XWINDOW_ROT = 30 # window y size to search for the targeted object YWINDOW_ROT = 30 # prior on the reliability of the centroid estimate in pixels -PIXSHIFT_PRIOR = 0.5 +PIXSHIFT_PRIOR = 0.2 [rotation parameters] # must be set to true, otherwise create residuals and correlated noise @@ -96,21 +98,21 @@ SPEC_ORDER = 1 [background subtraction parameters] # half transverse width of the signal rectangular window in pixels -PIXWIDTH_SIGNAL = 10 +PIXWIDTH_SIGNAL = 30 # distance from dispersion axis to analyse the background in pixels -PIXDIST_BACKGROUND = 20 +PIXDIST_BACKGROUND = 30 # transverse width of the background rectangular window in pixels PIXWIDTH_BACKGROUND = 80 # box size for sextractor evaluation of the background -PIXWIDTH_BOXSIZE = 40 +PIXWIDTH_BOXSIZE = 80 [PSF] # the PSF model: Gauss, Moffat or MoffatGauss PSF_TYPE = Moffat # the order of the polynomials to model wavelength dependence of the PSF shape parameters -PSF_POLY_ORDER = 4 +PSF_POLY_ORDER = 2 # regularisation parameter for the chisq minimisation to extract the spectrum -PSF_FIT_REG_PARAM = 0.1 +PSF_FIT_REG_PARAM = 1 # step size in pixels for the first transverse PSF1D fit PSF_PIXEL_STEP_TRANSVERSE_FIT = 1 # PSF is not evaluated outside a region larger than max(PIXWIDTH_SIGNAL, PSF_FWHM_CLIP*fwhm) pixels @@ -120,9 +122,9 @@ PSF_FWHM_CLIP = 2 # order of the background polynome to fit CALIB_BGD_ORDER = 3 # half range to look for local extrema in pixels around tabulated line values -CALIB_PEAK_WIDTH = 7 +CALIB_PEAK_WIDTH = 3 # size of the peak sides to use to fit spectrum base line -CALIB_BGD_WIDTH = 15 +CALIB_BGD_WIDTH = 5 # window size for the savgol filter in pixels CALIB_SAVGOL_WINDOW = 5 # polynom order for the savgol filter diff --git a/runAstrometry.py b/runAstrometry.py index b0255433b..e40110211 100644 --- a/runAstrometry.py +++ b/runAstrometry.py @@ -2,6 +2,7 @@ from spectractor.astrometry import Astrometry from spectractor.logbook import LogBook from spectractor.config import load_config, apply_rebinning_to_parameters +from spectractor.extractor.images import Image if __name__ == "__main__": @@ -50,7 +51,6 @@ logbook = LogBook(logbook=args.logbook) for file_name in file_names: - disperser_label = args.disperser_label if parameters.OBS_NAME == "CTIO": tag = file_name.split('/')[-1] tag = tag.replace('sim_', 'reduc_') @@ -66,8 +66,8 @@ ypos = float(ypos) guess = [xpos, ypos] target_label = args.target_label - a = Astrometry(file_name, target_label=target_label, disperser_label=disperser_label, - output_directory=args.output_directory) + image = Image(file_name, config=args.config) + a = Astrometry(image, output_directory=args.output_directory) extent = ((int(max(0, xpos - radius)), int(min(xpos + radius, parameters.CCD_IMSIZE))), (int(max(0, ypos - radius)), int(min(ypos + radius, parameters.CCD_IMSIZE)))) gaia_min_residuals = a.run_full_astrometry(extent=extent, maxiter=int(args.maxiter)) diff --git a/runImageSim.py b/runImageSim.py index 141211765..b69d65e96 100644 --- a/runImageSim.py +++ b/runImageSim.py @@ -49,4 +49,4 @@ continue image = ImageSim(file_name, spectrum_file_name, args.output_directory, A2=1, - psf_poly_params=psf_poly_params, with_stars=False) + psf_poly_params=psf_poly_params, with_starfield=False) diff --git a/runSimulator.py b/runSimulator.py index e5e7e9ca4..7fc4f204f 100644 --- a/runSimulator.py +++ b/runSimulator.py @@ -43,6 +43,6 @@ atmgrid = AtmosphereGrid(file_name) image = ImageSim(file_name, spectrum_file_name, args.output_directory, A1=1, A2=1, pwv=5, ozone=300, aerosols=0.03, - psf_poly_params=None, with_stars=True) + psf_poly_params=None, with_starfield=True) sim_file_name = args.output_directory + tag.replace('reduc_', 'sim_') Spectractor(sim_file_name, args.output_directory, target, [xpos, ypos], disperser_label, args.config) diff --git a/setup.cfg b/setup.cfg index 532062ace..e115e8d7b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [tool:pytest] -exclude=test_(extractor_ctio_planetary_nebula|astrometry|mcmc|multispectra) +addopts = --ignore=tests/test_astrometry.py --ignore=tests/test_mcmc.py --ignore=tests/test_extractor_ctio_planetary_nebula.py [coverage:run] omit=spectractor/fit/mcmc.py diff --git a/setup.py b/setup.py index cc9386411..7b7c891bf 100644 --- a/setup.py +++ b/setup.py @@ -30,8 +30,6 @@ version=current_version, packages=['spectractor', 'spectractor.extractor', 'spectractor.simulation', 'spectractor.fit'], install_requires=reqs, - test_suite='nose.collector', - tests_require=['nose'], package_dir={'spectractor': './spectractor'}, package_data={'spectractor': ['../config/*.ini'], 'spectractor.extractor': ['dispersers/HoloPhAg/*.txt', 'dispersers/HoloPhP/*.txt', diff --git a/spectractor/_version.py b/spectractor/_version.py index dd4fc07ae..2ccb07c61 100644 --- a/spectractor/_version.py +++ b/spectractor/_version.py @@ -28,5 +28,5 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -__version__ = '3.0.3' +__version__ = '3.1.0' __version_info__ = tuple(map(int, __version__.split('.'))) diff --git a/spectractor/astrometry.py b/spectractor/astrometry.py index 812502b1a..e5fe8b86e 100644 --- a/spectractor/astrometry.py +++ b/spectractor/astrometry.py @@ -323,7 +323,7 @@ def __init__(self, image, wcs_file_name="", gaia_file_name="", output_directory= self.gaia_radec_positions_after_pm = None if os.path.isfile(self.gaia_file_name): self.my_logger.info(f"\n\tLoad Gaia catalog from {self.gaia_file_name}.") - self.gaia_catalog = ascii.read(self.gaia_file_name, format="ecsv") + self.gaia_catalog = Table(ascii.read(self.gaia_file_name, format="ecsv"), masked=True) self.gaia_radec_positions_after_pm = get_gaia_coords_after_proper_motion(self.gaia_catalog, self.image.date_obs) self.sources = None self.sources_radec_positions = None diff --git a/spectractor/config.py b/spectractor/config.py index 4cba851da..e25984b7a 100644 --- a/spectractor/config.py +++ b/spectractor/config.py @@ -116,6 +116,10 @@ def load_config(config_filename, rebin=True): if parameters.PIXWIDTH_BOXSIZE > parameters.PIXWIDTH_BACKGROUND: raise ValueError(f'parameters.PIXWIDTH_BOXSIZE must be smaller than parameters.PIXWIDTH_BACKGROUND (or equal).') + # check consistency + if parameters.PSF_POLY_TYPE not in ["polynomial", "legendre"]: + raise ValueError(f'parameters.PSF_POLY_TYPE must be either "polynomial" or "legendre". Got {parameters.PSF_POLY_TYPE=}') + # check presence of atmospheric simulation packages if parameters.SPECTRACTOR_ATMOSPHERE_SIM.lower() not in ["none", "libradtran", "getobsatmo"]: raise ValueError(f'parameters.SPECTRACTOR_ATMOSPHERE_SIM must be either ["none", "libradtran", "getobsatmo"]. ' diff --git a/spectractor/extractor/background.py b/spectractor/extractor/background.py index 3647433fa..0317040f1 100644 --- a/spectractor/extractor/background.py +++ b/spectractor/extractor/background.py @@ -54,7 +54,7 @@ def make_source_mask(data, nsigma, npixels, mask=None, sigclip_sigma=3.0, Parameters ---------- - data : 2D `~numpy.ndarray` + data : np.ndarray The 2D array of the image. nsigma : float The number of standard deviations per pixel above the ``background`` @@ -236,7 +236,7 @@ def extract_spectrogram_background_sextractor(data, err, ws=(20, 30), mask_signa >>> from spectractor import parameters >>> parameters.DEBUG = True >>> psf = MoffatGauss() - >>> s0 = ChromaticPSF(psf, Nx=100, Ny=200, saturation=1000) + >>> s0 = ChromaticPSF(psf, Nx=100, Ny=300, saturation=1000) >>> params = s0.generate_test_poly_params() >>> saturation = params[-1] >>> data = s0.evaluate(s0.set_pixels(mode="1D"), poly_params=params) @@ -275,7 +275,7 @@ def extract_spectrogram_background_sextractor(data, err, ws=(20, 30), mask_signa bkg = Background2D(data, (parameters.PIXWIDTH_BOXSIZE, parameters.PIXWIDTH_BOXSIZE), filter_size=(filter_size, filter_size), sigma_clip=sigma_clip, bkg_estimator=bkg_estimator, - mask=mask) + mask=mask, exclude_percentile=80) # reset at zero the edges bkg.background[data == 0] = 0 bgd_model_func_interp = RegularGridInterpolator((np.arange(Nx), np.arange(Ny)), bkg.background.T, method='linear', diff --git a/spectractor/extractor/chromaticpsf.py b/spectractor/extractor/chromaticpsf.py index 8aea658c2..2c9caa114 100644 --- a/spectractor/extractor/chromaticpsf.py +++ b/spectractor/extractor/chromaticpsf.py @@ -224,7 +224,7 @@ def generate_test_poly_params(self): .. doctest:: :hide: - >>> assert(np.all(np.isclose(params,[10, 50, 100, 150, 200, 0, 0, 0, 0, 5, 0, 2, 0, -0.4, -0.4,1,0,20000]))) + >>> assert(np.all(np.isclose(params,[10, 50, 100, 150, 200, 0, 0, 0, 0, 5, 0, 2, 0, -0.4, 0, 1, 0, 20000]))) """ if not isinstance(self.psf, MoffatGauss) and not isinstance(self.psf, Moffat): @@ -241,7 +241,7 @@ def generate_test_poly_params(self): params += [0.] * (self.degrees['gamma'] - 1) + [0, 5] # gamma params += [0.] * (self.degrees['alpha'] - 1) + [0, 2] # alpha if isinstance(self.psf, MoffatGauss): - params += [0.] * (self.degrees['eta_gauss'] - 1) + [-0.4, -0.4] # eta_gauss + params += [0.] * (self.degrees['eta_gauss'] - 1) + [0, -0.4] # eta_gauss params += [0.] * (self.degrees['stddev'] - 1) + [0, 1] # stddev params += [self.saturation] # saturation poly_params = np.zeros_like(params) @@ -252,7 +252,12 @@ def generate_test_poly_params(self): continue else: shift = self.degrees[name] + 1 - c = np.polynomial.legendre.poly2leg(params[index + shift:index:-1]) + if parameters.PSF_POLY_TYPE == "legendre": + c = np.polynomial.legendre.poly2leg(params[index + shift:index:-1]) + elif parameters.PSF_POLY_TYPE == "polynomial": + c = np.asarray(params[index + shift:index:-1]) + else: + raise ValueError(f"Unknown polynomial type {parameters.PSF_POLY_TYPE=}.") coeffs = np.zeros(shift) coeffs[:c.size] = c poly_params[index + 1:index + shift + 1] = coeffs @@ -613,7 +618,7 @@ def convolve_psf_cube_masked(psf_cube_masked): return psf_cube_masked @staticmethod - def get_boundaries(psf_cube_masked): + def set_rectangular_boundaries(psf_cube_masked): """Compute the ChromaticPSF computation boundaries, as a dictionnary of integers giving the `"xmin"`, `"xmax"`, `"ymin"` and `"ymax"` edges where to compute the PSF for each wavelength. True regions are rectangular after this operation. The `psf_cube_masked` cube is updated accordingly and returned. @@ -639,7 +644,7 @@ def get_boundaries(psf_cube_masked): >>> profile_params[:, 1] = np.arange(s.Nx) >>> psf_cube_masked = s.build_psf_cube_masked(s.set_pixels(mode="2D"), profile_params) >>> psf_cube_masked = s.convolve_psf_cube_masked(psf_cube_masked) - >>> boundaries, psf_cube_masked = s.get_boundaries(psf_cube_masked) + >>> boundaries, psf_cube_masked = s.set_rectangular_boundaries(psf_cube_masked) >>> boundaries["xmin"].shape (100,) >>> psf_cube_masked.shape @@ -678,14 +683,13 @@ def get_boundaries(psf_cube_masked): psf_cube_masked[k, ymin:ymax, xmin:xmax] = True return boundaries, psf_cube_masked - @staticmethod - def get_sparse_indices(psf_cube_masked): - """Methods that returns the indices to build sparse matrices from `psf_cube_masked`. + def get_sparse_indices(self, boundaries): + """Methods that returns the indices to build sparse matrices from rectangular `boundaries`. Parameters ---------- - psf_cube_masked: np.ndarray - Cube of boolean values where `psf_cube` cube is positive, eventually convolved. + boundaries: dict + The dictionnary of PSF edges per wavelength. Returns ------- @@ -702,14 +706,20 @@ def get_sparse_indices(psf_cube_masked): >>> profile_params[:, 1] = np.arange(s.Nx) >>> psf_cube_masked = s.build_psf_cube_masked(s.set_pixels(mode="2D"), profile_params) >>> psf_cube_masked = s.convolve_psf_cube_masked(psf_cube_masked) - >>> psf_cube_sparse_indices, M_sparse_indices = s.get_sparse_indices(psf_cube_masked) - >>> M_sparse_indices.shape - (72000,) - >>> len(psf_cube_sparse_indices) - 100 + >>> boundaries, psf_cube_masked = s.set_rectangular_boundaries(psf_cube_masked) + >>> psf_cube_sparse_indices, M_sparse_indices = s.get_sparse_indices(boundaries) + >>> assert M_sparse_indices.shape == np.sum(psf_cube_masked) + >>> assert len(psf_cube_sparse_indices) == s.Nx """ - wl_size = psf_cube_masked.shape[0] - psf_cube_sparse_indices = [np.where(psf_cube_masked[k].ravel() > 0)[0] for k in range(wl_size)] + wl_size = self.Nx # assuming that the number of cube layers is the number of pixel columns + psf_cube_sparse_indices = [] + for k in range(wl_size): + xmin, xmax = boundaries["xmin"][k], boundaries["xmax"][k] + if xmin == -1: + psf_cube_sparse_indices.append([]) + else: + ymin, ymax = boundaries["ymin"][k], boundaries["ymax"][k] + psf_cube_sparse_indices.append(np.concatenate([np.arange(xmin,xmax) + k * wl_size for k in range(ymin, ymax)])) M_sparse_indices = np.concatenate(psf_cube_sparse_indices) return psf_cube_sparse_indices, M_sparse_indices @@ -751,8 +761,8 @@ def build_sparse_M(self, pixels, profile_params, M_sparse_indices, boundaries, d >>> psf_cube_masked = s.build_psf_cube_masked(s.set_pixels(mode="2D"), profile_params) >>> psf_cube_masked = s.convolve_psf_cube_masked(psf_cube_masked) - >>> boundaries, psf_cube_masked = s.get_boundaries(psf_cube_masked) - >>> psf_cube_sparse_indices, M_sparse_indices = s.get_sparse_indices(psf_cube_masked) + >>> boundaries, psf_cube_masked = s.set_rectangular_boundaries(psf_cube_masked) + >>> psf_cube_sparse_indices, M_sparse_indices = s.get_sparse_indices(boundaries) >>> M = s.build_sparse_M(s.set_pixels(mode="2D"), profile_params, M_sparse_indices, boundaries, dtype="float32") >>> M.shape (2000, 100) @@ -770,8 +780,8 @@ def build_sparse_M(self, pixels, profile_params, M_sparse_indices, boundaries, d >>> psf_cube_masked = s.build_psf_cube_masked(s.set_pixels(mode="1D"), profile_params) >>> psf_cube_masked = s.convolve_psf_cube_masked(psf_cube_masked) - >>> boundaries, psf_cube_masked = s.get_boundaries(psf_cube_masked) - >>> psf_cube_sparse_indices, M_sparse_indices = s.get_sparse_indices(psf_cube_masked) + >>> boundaries, psf_cube_masked = s.set_rectangular_boundaries(psf_cube_masked) + >>> psf_cube_sparse_indices, M_sparse_indices = s.get_sparse_indices(boundaries) >>> M = s.build_sparse_M(s.set_pixels(mode="1D"), profile_params, M_sparse_indices, boundaries, dtype="float32") >>> M.shape (2000, 100) @@ -849,8 +859,8 @@ def build_psf_jacobian(self, pixels, profile_params, psf_cube_sparse_indices, bo >>> profile_params[:, 1] = np.arange(s.Nx) # PSF x_c positions >>> psf_cube_masked = s.build_psf_cube_masked(s.set_pixels(mode="2D"), profile_params) >>> psf_cube_masked = s.convolve_psf_cube_masked(psf_cube_masked) - >>> boundaries, psf_cube_masked = s.get_boundaries(psf_cube_masked) - >>> psf_cube_sparse_indices, M_sparse_indices = s.get_sparse_indices(psf_cube_masked) + >>> boundaries, psf_cube_masked = s.set_rectangular_boundaries(psf_cube_masked) + >>> psf_cube_sparse_indices, M_sparse_indices = s.get_sparse_indices(boundaries) >>> s.params.fixed[s.Nx:s.Nx+s.deg+1] = [True] * (s.deg+1) # fix all x_c parameters >>> J = s.build_psf_jacobian(s.set_pixels(mode="2D"), profile_params, psf_cube_sparse_indices, boundaries, dtype="float32") >>> J.shape @@ -879,8 +889,8 @@ def build_psf_jacobian(self, pixels, profile_params, psf_cube_sparse_indices, bo if Nx != profile_params.shape[0]: raise ValueError(f"Number of pixels along x axis must be same as profile_params table length. " f"Got {Nx=} and {profile_params.shape}.") - leg_pixels = np.linspace(-1, 1, Nx) - legs = np.zeros((self.n_poly_params-Nx, Nx), dtype=dtype) + poly_x = np.linspace(-1, 1, Nx) + polys = np.zeros((self.n_poly_params-Nx, Nx), dtype=dtype) ip = 0 repeats = [] for ipsf, label in enumerate(self.psf.params.labels): @@ -889,7 +899,10 @@ def build_psf_jacobian(self, pixels, profile_params, psf_cube_sparse_indices, bo repeats.append(nparams) for k in range(nparams): coeffs = np.eye(1, nparams, k)[0] - legs[ip] = np.polynomial.legendre.legval(leg_pixels, coeffs).astype(dtype) + if parameters.PSF_POLY_TYPE == "legendre": + polys[ip] = np.polynomial.legendre.legval(poly_x, coeffs).astype(dtype) + elif parameters.PSF_POLY_TYPE == "polynomial": + polys[ip] = np.polynomial.polynomial.polyval(poly_x, coeffs).astype(dtype) ip += 1 for ip, label in enumerate(self.psf.params.labels): if "amplitude" in label: # skip computation of ChromaticPSF jacobian for amplitude parameters @@ -905,7 +918,7 @@ def build_psf_jacobian(self, pixels, profile_params, psf_cube_sparse_indices, bo else: Jpsf = self.psf.jacobian(pixels[boundaries["ymin"][x]:boundaries["ymax"][x]], profile_params[x, :], analytical=True) - J[:, psf_cube_sparse_indices[x]] += np.repeat(Jpsf[1:], repeats, axis=0) * legs[:, x, None] # Jpsf[1:] excludes amplitude + J[:, psf_cube_sparse_indices[x]] += np.repeat(Jpsf[1:], repeats, axis=0) * polys[:, x, None] # Jpsf[1:] excludes amplitude return J def build_sparse_dM(self, pixels, profile_params, M_sparse_indices, boundaries, dtype="float32"): @@ -940,8 +953,8 @@ def build_sparse_dM(self, pixels, profile_params, M_sparse_indices, boundaries, >>> profile_params[:, 1] = np.arange(s.Nx) # PSF x_c positions >>> psf_cube_masked = s.build_psf_cube_masked(s.set_pixels(mode="2D"), profile_params) >>> psf_cube_masked = s.convolve_psf_cube_masked(psf_cube_masked) - >>> boundaries, psf_cube_masked = s.get_boundaries(psf_cube_masked) - >>> psf_cube_sparse_indices, M_sparse_indices = s.get_sparse_indices(psf_cube_masked) + >>> boundaries, psf_cube_masked = s.set_rectangular_boundaries(psf_cube_masked) + >>> psf_cube_sparse_indices, M_sparse_indices = s.get_sparse_indices(boundaries) >>> s.params.fixed[s.Nx:s.Nx+s.deg+1] = [True] * (s.deg+1) # fix all x_c parameters >>> dM = s.build_sparse_dM(s.set_pixels(mode="2D"), profile_params, M_sparse_indices, boundaries, dtype="float32") >>> len(dM), dM[0].shape @@ -971,8 +984,8 @@ def build_sparse_dM(self, pixels, profile_params, M_sparse_indices, boundaries, if Nx != profile_params.shape[0]: raise ValueError(f"Number of pixels along x axis must be same as profile_params table length. " f"Got {Nx=} and {profile_params.shape}.") - leg_pixels = np.linspace(-1, 1, Nx) - legs = np.zeros((self.n_poly_params-Nx, Nx), dtype=dtype) + poly_x = np.linspace(-1, 1, Nx) + polys = np.zeros((self.n_poly_params-Nx, Nx), dtype=dtype) ip = 0 repeats = [] for ipsf, label in enumerate(self.psf.params.labels): @@ -982,7 +995,10 @@ def build_sparse_dM(self, pixels, profile_params, M_sparse_indices, boundaries, for k in range(nparams): # psf_index.append(ipsf) coeffs = np.eye(1, nparams, k)[0] - legs[ip] = np.polynomial.legendre.legval(leg_pixels, coeffs).astype(dtype) + if parameters.PSF_POLY_TYPE == "legendre": + polys[ip] = np.polynomial.legendre.legval(poly_x, coeffs).astype(dtype) + elif parameters.PSF_POLY_TYPE == "polynomial": + polys[ip] = np.polynomial.polynomial.polyval(poly_x, coeffs).astype(dtype) ip += 1 sparse_J = np.zeros((self.n_poly_params - self.Nx, M_sparse_indices.size), dtype=dtype) indptr = np.zeros(Nx+1, dtype=int) @@ -996,7 +1012,7 @@ def build_sparse_dM(self, pixels, profile_params, M_sparse_indices, boundaries, indptr[x+1] = (boundaries["xmax"][x]-boundaries["xmin"][x])*(boundaries["ymax"][x]-boundaries["ymin"][x]) + indptr[x] if boundaries["xmin"][x] < 0: continue - sparse_J[:, indptr[x]:indptr[x+1]] += np.repeat(Jpsf[1:], repeats, axis=0) * legs[:, x, None] + sparse_J[:, indptr[x]:indptr[x + 1]] += np.repeat(Jpsf[1:], repeats, axis=0) * polys[:, x, None] dM = [sparse.csr_matrix((sparse_J[ip], M_sparse_indices, indptr), shape=(len(profile_params), pixels[0].size), dtype=dtype).T for ip in range(sparse_J.shape[0])] return dM @@ -1065,7 +1081,8 @@ def rotate_table(self, angle_degree): def from_profile_params_to_poly_params(self, profile_params, indices=None): """ Transform the profile_params array into a set of parameters for the chromatic PSF parameterisation. - Fit Legendre polynomial functions across the pixels for each PSF parameters. + Fit polynomial functions across the pixels for each PSF parameters. + Type of the polynomial function is set by parameters.PSF_POLY_TYPE. The order of the polynomial functions is given by the self.degrees array. Parameters @@ -1099,8 +1116,7 @@ def from_profile_params_to_poly_params(self, profile_params, indices=None): .. doctest:: :hide: - - >>> assert(np.all(np.isclose(profile_params[0], [10, 0, 50, 5, 2, 0, 1, 8e3]))) + >>> assert(np.all(np.isclose(profile_params[0], [10, 0, 50, 5, 2, -0.4, 1, 8e3]))) From the profile parameters to the polynomial parameters: @@ -1122,8 +1138,7 @@ def from_profile_params_to_poly_params(self, profile_params, indices=None): if amplitude is None: self.my_logger.warning('\n\tAmplitude array not initialized. ' 'Polynomial fit for shape parameters will be unweighted.') - - pixels = np.linspace(-1, 1, len(self.table))[indices] + poly_x = np.linspace(-1, 1, len(self.table))[indices] for k, name in enumerate(self.psf.params.labels): delta = 0 if name != 'amplitude': @@ -1132,8 +1147,12 @@ def from_profile_params_to_poly_params(self, profile_params, indices=None): delta = self.x0 if name == 'y_c': delta = self.y0 - fit = np.polynomial.legendre.legfit(pixels, profile_params[indices, k] - delta, - deg=self.degrees[name], w=weights) + if parameters.PSF_POLY_TYPE == "legendre": + fit = np.polynomial.legendre.legfit(poly_x, profile_params[indices, k] - delta, + deg=self.degrees[name], w=weights) + elif parameters.PSF_POLY_TYPE == "polynomial": + fit = np.polynomial.polynomial.polyfit(poly_x, profile_params[indices, k] - delta, + deg=self.degrees[name], w=weights) poly_params = np.concatenate([poly_params, fit]) return poly_params @@ -1236,8 +1255,7 @@ def from_poly_params_to_profile_params(self, poly_params, apply_bounds=False): .. doctest:: :hide: - - >>> assert np.allclose(profile_params[0], [10, 0, 50, 5, 2, -5e-3, 1, 8e3], rtol=1e-3, atol=1e-3) + >>> assert np.allclose(profile_params[0], [10, 0, 50, 5, 2, -0.4, 1, 8e3], rtol=1e-3, atol=1e-3) From the profile parameters to the polynomial parameters: @@ -1254,12 +1272,11 @@ def from_poly_params_to_profile_params(self, poly_params, apply_bounds=False): .. doctest:: :hide: - - >>> assert np.allclose(profile_params[0], [1, 0, 50, 5, 2, 0, 1, 8e3]) + >>> assert np.allclose(profile_params[0], [1, 0, 50, 5, 2, -0.4, 1, 8e3]) """ length = len(self.table) - pixels = np.linspace(-1, 1, length) + poly_x = np.linspace(-1, 1, length) profile_params = np.zeros((length, len(self.psf.params.labels))) shift = 0 for k, name in enumerate(self.psf.params.labels): @@ -1270,14 +1287,17 @@ def from_poly_params_to_profile_params(self, poly_params, apply_bounds=False): profile_params[:, k] = np.ones(length) else: if len(poly_params) > length: - profile_params[:, k] = \ - np.polynomial.legendre.legval(pixels, - poly_params[ - length + shift:length + shift + self.degrees[name] + 1]) + if parameters.PSF_POLY_TYPE == "legendre": + profile_params[:, k] = np.polynomial.legendre.legval(poly_x, poly_params[length + shift:length + shift + self.degrees[name] + 1]) + elif parameters.PSF_POLY_TYPE == "polynomial": + profile_params[:, k] = np.polynomial.polynomial.polyval(poly_x, poly_params[length + shift:length + shift + self.degrees[name] + 1]) else: p = poly_params[shift:shift + self.degrees[name] + 1] if len(p) > 0: # to avoid saturation parameters in case not set - profile_params[:, k] = np.polynomial.legendre.legval(pixels, p) + if parameters.PSF_POLY_TYPE == "legendre": + profile_params[:, k] = np.polynomial.legendre.legval(poly_x, p) + elif parameters.PSF_POLY_TYPE == "polynomial": + profile_params[:, k] = np.polynomial.polynomial.polyval(poly_x, p) shift += self.degrees[name] + 1 if name == 'x_c': profile_params[:, k] += self.x0 @@ -1337,17 +1357,31 @@ def from_profile_params_to_shape_params(self, profile_params): def set_bounds(self): """ This function returns an array of bounds for PSF polynomial parameters (no amplitude ones). - It is very touchy, change the values with caution ! Returns ------- bounds: list 2D array containing the pair of bounds for each polynomial parameters. + Examples + ________ + >>> psf = MoffatGauss() + >>> s = ChromaticPSF(psf, Nx=100, Ny=100, deg=4, saturation=8000) + >>> s.set_bounds() # doctest: +ELLIPSIS + [array([-inf, inf]), array([-inf, inf]), ... + """ bounds = [[], []] for k, name in enumerate(self.psf.params.labels): - tmp_bounds = [[-np.inf] * (1 + self.degrees[name]), [np.inf] * (1 + self.degrees[name])] + if parameters.PSF_POLY_TYPE == "legendre": + tmp_bounds = [[-np.inf] * (1 + self.degrees[name]), [np.inf] * (1 + self.degrees[name])] + elif parameters.PSF_POLY_TYPE == "polynomial": + tmp_bounds = [[self.psf.params.bounds[k][0]] + [-np.inf] * (self.degrees[name]), + [self.psf.params.bounds[k][1]] + [np.inf] * (self.degrees[name])] + # tmp_bounds = [[self.psf.params.bounds[k][0]] + [-0.5 * 2 * (self.psf.params.bounds[k][1] - self.psf.params.bounds[k][0]) for deg in range(1, self.degrees[name] + 1)], + # [self.psf.params.bounds[k][1]] + [0.5 * 2 * (self.psf.params.bounds[k][1] - self.psf.params.bounds[k][0]) for deg in range(1, self.degrees[name] + 1)]] + else: + raise ValueError(f"Unknown polynomial type {parameters.PSF_POLY_TYPE=}.") if name == "saturation": tmp_bounds = [[0], [2 * self.saturation]] elif name == "amplitude": @@ -1417,14 +1451,16 @@ def plot_summary(self, truth=None): PSF_truth[:, 1] = np.arange(self.Nx) # replace x_c all_pixels = np.arange(self.profile_params.shape[0]) for i, name in enumerate(self.psf.params.labels): - legs = [self.params.values[k] for k in range(self.params.ndim) if name in self.params.labels[k]] - pval = np.polynomial.legendre.leg2poly(legs)[::-1] + coeffs = [self.params.values[k] for k in range(self.params.ndim) if name in self.params.labels[k]] delta = 0 if name == 'x_c': delta = self.x0 if name == 'y_c': delta = self.y0 - PSF_models.append(np.polyval(pval, rescale_x_to_legendre(all_pixels)) + delta) + if parameters.PSF_POLY_TYPE == "legendre": + PSF_models.append(np.polynomial.polynomial.legval(rescale_x_to_legendre(all_pixels), coeffs) + delta) + elif parameters.PSF_POLY_TYPE == "polynomial": + PSF_models.append(np.polynomial.polynomial.polyval(rescale_x_to_legendre(all_pixels), coeffs) + delta) for i, name in enumerate(self.psf.params.labels): p = ax.plot(all_pixels, self.profile_params[:, i], marker='+', linestyle='none') ax.plot(all_pixels[self.fitted_pixels], self.profile_params[self.fitted_pixels, i], label=name, @@ -1444,7 +1480,7 @@ def plot_summary(self, truth=None): plt.show() def fit_transverse_PSF1D_profile(self, data, err, w, ws, pixel_step=1, bgd_model_func=None, saturation=None, - live_fit=False, sigma_clip=5): + live_fit=False, sigma_clip=5, mask=None): """ Fit the transverse profile of a 2D data image with a PSF profile. Loop is done on the x-axis direction. @@ -1489,6 +1525,7 @@ def fit_transverse_PSF1D_profile(self, data, err, w, ws, pixel_step=1, bgd_model >>> bgd += 1000*np.exp(-((xx-20)**2+(yy-10)**2)/(2*2)) >>> data += bgd >>> data_errors = np.sqrt(data+1) + >>> mask = bgd > np.median(bgd) Extract the background: @@ -1497,8 +1534,8 @@ def fit_transverse_PSF1D_profile(self, data, err, w, ws, pixel_step=1, bgd_model Fit the transverse profile: >>> s = ChromaticPSF(psf, Nx=100, Ny=100, deg=4, saturation=saturation) - >>> s.fit_transverse_PSF1D_profile(data, data_errors, w=20, ws=[30,50], pixel_step=5, - ... bgd_model_func=bgd_model_func, saturation=saturation, live_fit=False, sigma_clip=5) + >>> s.fit_transverse_PSF1D_profile(data, data_errors, w=20, ws=[30,50], pixel_step=5, mask=mask, + ... bgd_model_func=bgd_model_func, saturation=saturation, live_fit=False, sigma_clip=5,) >>> s.plot_summary(truth=s0) .. doctest:: @@ -1609,6 +1646,8 @@ def fit_transverse_PSF1D_profile(self, data, err, w, ws, pixel_step=1, bgd_model psf.params.bounds = bounds w = PSFFitWorkspace(psf, signal, data_errors=err[:, x], bgd_model_func=None, live_fit=False, verbose=False, jacobian_analytical=True) + if mask is not None: + w.mask = list(np.where(mask[:, x])[0]) try: run_minimisation_sigma_clipping(w, method="newton", sigma_clip=sigma_clip, niter_clip=1, verbose=False) except: @@ -1648,21 +1687,24 @@ def fit_transverse_PSF1D_profile(self, data, err, w, ws, pixel_step=1, bgd_model # keep only brightest transverse profiles selected_pixels = self.profile_params[:, 0] > 0.1 * np.max(self.profile_params[:, 0]) # then keep only profiles with first shape parameter (index=3) are not too deviant from its median value - selected_pixels = selected_pixels & (np.abs(self.profile_params[:, 3]) < 5 * np.median(self.profile_params[:, 3])) + for k in range(3, self.profile_params.shape[1]): + selected_pixels = selected_pixels & (np.abs(self.profile_params[:, k]) < 5 * np.median(self.profile_params[:, k])) self.params.values = self.from_profile_params_to_poly_params(self.profile_params, indices=selected_pixels) self.from_profile_params_to_shape_params(self.profile_params) self.cov_matrix = np.diag(1 / np.array(self.table['flux_err']) ** 2) psf.params.bounds = initial_bounds - def fit_chromatic_psf(self, data, bgd_model_func=None, data_errors=None, mode="1D", analytical=True, + def fit_chromatic_psf(self, data, mask=None, bgd_model_func=None, data_errors=None, mode="1D", analytical=True, amplitude_priors_method="noprior", verbose=False, live_fit=False): """ Fit a chromatic PSF model on 2D data. Parameters ---------- - data: array_like + data: np.array 2D array containing the image data. + mask: np.array, optional + 2D array containing the masked pixels. bgd_model_func: callable, optional A 2D function to model the extracted background (default: None -> null background) data_errors: np.array @@ -1702,6 +1744,8 @@ def fit_chromatic_psf(self, data, bgd_model_func=None, data_errors=None, mode="1 >>> data += bgd >>> data = np.random.poisson(data) >>> data_errors = np.sqrt(np.abs(data+1)) + >>> mask = np.zeros_like(data).astype(bool) + >>> mask[10:30,20:22] = True Extract the background: @@ -1723,7 +1767,7 @@ def fit_chromatic_psf(self, data, bgd_model_func=None, data_errors=None, mode="1 Fit the data using the transverse 1D PSF model only: >>> w = s.fit_chromatic_psf(data, mode="1D", data_errors=data_errors, bgd_model_func=bgd_model_func, - ... amplitude_priors_method="noprior", verbose=True) + ... amplitude_priors_method="noprior", verbose=True, mask=mask) >>> s.plot_summary(truth=s0) >>> amplitude_residuals.append([s0.params.values[:s0.Nx], w.amplitude_params-s0.params.values[:s0.Nx], ... w.amplitude_params_err]) @@ -1740,7 +1784,7 @@ def fit_chromatic_psf(self, data, bgd_model_func=None, data_errors=None, mode="1 >>> parameters.PSF_FIT_REG_PARAM = 0.002 >>> w = s.fit_chromatic_psf(data, mode="2D", data_errors=data_errors, bgd_model_func=bgd_model_func, - ... amplitude_priors_method="psf1d", verbose=True, analytical=True) + ... amplitude_priors_method="psf1d", verbose=True, analytical=True, mask=mask) >>> s.plot_summary(truth=s0) >>> amplitude_residuals.append([s0.params.values[:s0.Nx], w.amplitude_params-s0.params.values[:s0.Nx], ... w.amplitude_params_err]) @@ -1765,13 +1809,13 @@ def fit_chromatic_psf(self, data, bgd_model_func=None, data_errors=None, mode="1 """ if mode == "1D": - w = ChromaticPSFFitWorkspace(self, data, data_errors=data_errors, mode=mode, bgd_model_func=bgd_model_func, + w = ChromaticPSFFitWorkspace(self, data, mask=mask, data_errors=data_errors, mode=mode, bgd_model_func=bgd_model_func, amplitude_priors_method=amplitude_priors_method, verbose=verbose, live_fit=live_fit, analytical=analytical) run_minimisation(w, method="newton", ftol=1 / (w.Nx * w.Ny), xtol=1e-6, niter=50, with_line_search=True) elif mode == "2D": # first shot to set the mask - w = ChromaticPSFFitWorkspace(self, data, data_errors=data_errors, mode=mode, bgd_model_func=bgd_model_func, + w = ChromaticPSFFitWorkspace(self, data, mask=mask, data_errors=data_errors, mode=mode, bgd_model_func=bgd_model_func, amplitude_priors_method=amplitude_priors_method, verbose=verbose, live_fit=live_fit, analytical=analytical) # first, fit the transverse position @@ -1840,7 +1884,7 @@ def fit_chromatic_psf(self, data, bgd_model_func=None, data_errors=None, mode="1 class ChromaticPSFFitWorkspace(FitWorkspace): - def __init__(self, chromatic_psf, data, data_errors, mode, bgd_model_func=None, file_name="", analytical=True, + def __init__(self, chromatic_psf, data, data_errors, mode, bgd_model_func=None, mask=None, file_name="", analytical=True, amplitude_priors_method="noprior", verbose=False, plot=False, live_fit=False, truth=None): if mode not in ["1D", "2D"]: raise ValueError(f"mode argument must be '1D' or '2D'. Got {mode=}.") @@ -1890,6 +1934,10 @@ def __init__(self, chromatic_psf, data, data_errors, mode, bgd_model_func=None, self.data = self.data.astype("float32").ravel() self.err = self.err.astype("float32").ravel() self.pixels = np.arange(self.data.shape[0]) + if mask is not None: + self.mask = list(np.where(mask[self.bgd_width:-self.bgd_width, :].astype(bool).ravel())[0]) + else: + self.mask = [] if mode == "1D": self.pixels = np.arange(self.Ny) @@ -1901,6 +1949,7 @@ def __init__(self, chromatic_psf, data, data_errors, mode, bgd_model_func=None, self.poly_params[self.Nx + self.y_c_0_index] -= self.bgd_width self.profile_params = self.chromatic_psf.from_poly_params_to_profile_params(self.poly_params) self.data_before_mask = np.copy(self.data) + self.mask_before_mask = list(np.copy(self.mask)) self.boundaries = None self.psf_cube_sparse_indices = None self.psf_cube_masked = None @@ -1915,8 +1964,6 @@ def __init__(self, chromatic_psf, data, data_errors, mode, bgd_model_func=None, # (which is not exactly true in rotated images) self.data_cov = sparse.diags(self.err * self.err, dtype="float32", format="dia") self.W = sparse.diags(1 / (self.err * self.err), dtype="float32", format="dia") - self.sqrtW = self.W.sqrt() - # create a mask self.W_before_mask = self.W.copy() # design matrix @@ -1933,7 +1980,7 @@ def __init__(self, chromatic_psf, data, data_errors, mode, bgd_model_func=None, self.amplitude_priors_method = amplitude_priors_method self.fwhm_priors = np.copy(self.chromatic_psf.table['fwhm']) self.reg = parameters.PSF_FIT_REG_PARAM - self.trace_r = self.Nx / np.min(self.fwhm_priors) # spectrophotometric uncertainty principle + self.trace_r = self.Nx / np.median(self.fwhm_priors) # spectrophotometric uncertainty principle self.Q = np.zeros((self.Nx, self.Nx)) self.Q_dot_A0 = np.zeros(self.Nx) if amplitude_priors_method not in self.amplitude_priors_list: @@ -2035,14 +2082,23 @@ def set_mask(self, poly_params=None): fwhmx_clip=3 * parameters.PSF_FWHM_CLIP, fwhmy_clip=parameters.PSF_FWHM_CLIP) self.psf_cube_masked = self.chromatic_psf.convolve_psf_cube_masked(psf_cube_masked) - self.boundaries, self.psf_cube_masked = self.chromatic_psf.get_boundaries(self.psf_cube_masked) - self.psf_cube_sparse_indices, self.M_sparse_indices = self.chromatic_psf.get_sparse_indices(self.psf_cube_masked) - mask = np.sum(self.psf_cube_masked.reshape(psf_cube_masked.shape[0], psf_cube_masked[0].size), axis=0) == 0 + self.boundaries, self.psf_cube_masked = self.chromatic_psf.set_rectangular_boundaries(self.psf_cube_masked) + self.psf_cube_sparse_indices, self.M_sparse_indices = self.chromatic_psf.get_sparse_indices(self.boundaries) + # mask = np.sum(self.psf_cube_masked.reshape(psf_cube_masked.shape[0], psf_cube_masked[0].size), axis=0) == 0 + # cumulate the boolean values as int + weight_mask = np.sum(self.psf_cube_masked, axis=0) + # look for indices with maximum weight per column (all sheets of the psf cube have contributed) + res = np.max(weight_mask, axis=0)[np.newaxis,:] * np.ones((weight_mask.shape[0],1)) + # keep only the pixels where all psf_cube sheets have contributed per column + mask = (weight_mask != res).ravel() + self.mask = list(self.mask_before_mask) + list(np.where(mask)[0]) + self.mask = list(set(self.mask)) W = np.copy(self.W_before_mask.data.ravel()) - W[mask] = 0 + self.mask = list(np.copy(self.mask_before_mask)) + self.mask += list(np.where(mask)[0]) + self.mask = list(set(self.mask)) + W[self.mask] = 0 self.W = sparse.diags(W, dtype="float32", format="dia") - self.sqrtW = self.W.sqrt() - self.mask = list(np.where(mask)[0]) def simulate(self, *shape_params): r""" @@ -2237,7 +2293,7 @@ def simulate(self, *shape_params): M = self.chromatic_psf.build_sparse_M(self.pixels, profile_params, dtype="float32", M_sparse_indices=self.M_sparse_indices, boundaries=self.boundaries) - M_dot_W = M.T @ self.sqrtW + M_dot_W = M.T @ self.W.sqrt() W_dot_data = self.W @ self.data # Compute the minimizing amplitudes if sparse_dot_mkl is None: diff --git a/spectractor/extractor/dispersers/holo4_003/NOTES b/spectractor/extractor/dispersers/holo4_003/NOTES index 9d8fb6eeb..0a041036b 100644 --- a/spectractor/extractor/dispersers/holo4_003/NOTES +++ b/spectractor/extractor/dispersers/holo4_003/NOTES @@ -1,3 +1,5 @@ - transmission.txt : prediction from the chimera built with LPNHE optical test bench measurements between 430 and 1000nm, then extrapolating with an hologram efficiency model fitted on data -- ratio_order_2over1.txt : computed using separated extraction of spectrum order 1 and 2 from BG40 exposures, nights 20220608, 20220628, 20220629 and 20220630 with ratio 3/2 model, CCD_REBIN=2 with Savitsky Golay filter -- ratio_order_3over2.txt : prediction from the chimera built with LPNHE optical test bench measurements between 430 and 1000nm, then extrapolating with an hologram efficiency model fitted on data +- ratio_order_2over1.txt : computed using separated extraction of spectrum order 1 and 2 from BG40 exposures, nights 20220608, 20220628, 20220629 and 20220630 with ratio 3/2 model, CCD_REBIN=2 with Savitsky Golay filter, extrapolated fitting an hologram transmission model with BG40 data rescaled by a factor 1.09 (see ratio_order_2over1_from_fit_bg401.09.txt) +- ratio_order_3over2.txt : prediction from the chimera built with LPNHE optical test bench measurements between 430 and 1000nm, rescaled with the estimate using SDSSg filter ratio of orders, extrapolated fitting an hologram transmission model (see ratio_order_2over1_from_fit.txt) +#- ratio_order_2over1.txt : computed using separated extraction of spectrum order 1 and 2 from BG40 exposures, nights 20220608, 20220628, 20220629 and 20220630 with ratio 3/2 model, CCD_REBIN=2 with Savitsky Golay filter +#- ratio_order_3over2.txt : prediction from the chimera built with LPNHE optical test bench measurements between 430 and 1000nm, rescaled with the estimate using SDSSg filter ratio of orders diff --git a/spectractor/extractor/dispersers/holo4_003/ratio_order_2over1.txt b/spectractor/extractor/dispersers/holo4_003/ratio_order_2over1.txt index 6f27e0c43..b6563b307 100644 --- a/spectractor/extractor/dispersers/holo4_003/ratio_order_2over1.txt +++ b/spectractor/extractor/dispersers/holo4_003/ratio_order_2over1.txt @@ -1,800 +1,800 @@ -3.000000000000000000e+02 -7.090213097062541436e+00 -3.010000000000000000e+02 -7.090213097062542325e+00 -3.020000000000000000e+02 -7.090213097062542325e+00 -3.030000000000000000e+02 -7.090213097062543213e+00 -3.040000000000000000e+02 -7.090213097062544989e+00 -3.050000000000000000e+02 -7.090213097062544989e+00 -3.060000000000000000e+02 -7.090213097062544989e+00 -3.070000000000000000e+02 -7.090213097062544989e+00 -3.080000000000000000e+02 -7.090213097062544989e+00 -3.090000000000000000e+02 -7.090213097062544989e+00 -3.100000000000000000e+02 -7.090213097062544989e+00 -3.110000000000000000e+02 -7.090213097062544989e+00 -3.120000000000000000e+02 -7.090213097062544989e+00 -3.130000000000000000e+02 -7.090213097062544989e+00 -3.140000000000000000e+02 -7.090213097062544989e+00 -3.150000000000000000e+02 -7.090213097062544989e+00 -3.160000000000000000e+02 -7.090213097062544989e+00 -3.170000000000000000e+02 -7.090213097062544989e+00 -3.180000000000000000e+02 -7.090213097062544989e+00 -3.190000000000000000e+02 -7.090213097062544989e+00 -3.200000000000000000e+02 -7.090213097062544989e+00 -3.210000000000000000e+02 -7.090213097062544989e+00 -3.220000000000000000e+02 -7.090213097062544989e+00 -3.230000000000000000e+02 -7.090213097062544989e+00 -3.240000000000000000e+02 -7.090213097062544989e+00 -3.250000000000000000e+02 -7.090213097062544989e+00 -3.260000000000000000e+02 -7.090213097062544989e+00 -3.270000000000000000e+02 -7.090213097062544989e+00 -3.280000000000000000e+02 -7.090213097062544989e+00 -3.290000000000000000e+02 -7.090213097062544989e+00 -3.300000000000000000e+02 -7.090213097062544989e+00 -3.310000000000000000e+02 -7.090213097062544989e+00 -3.320000000000000000e+02 -7.090213097062544989e+00 -3.330000000000000000e+02 -7.090213097062544989e+00 -3.340000000000000000e+02 -7.090213097062544989e+00 -3.350000000000000000e+02 -6.328803424402677180e+00 -3.360000000000000000e+02 -5.527802037939696156e+00 -3.370000000000000000e+02 -4.613243163438663252e+00 -3.380000000000000000e+02 -3.812382915170114295e+00 -3.390000000000000000e+02 -2.991109607661365910e+00 -3.400000000000000000e+02 -1.822843895112854273e+00 -3.410000000000000000e+02 -6.926260049797368090e-01 -3.420000000000000000e+02 3.870096902209335665e-01 -3.430000000000000000e+02 1.747384374344775892e+00 -3.440000000000000000e+02 2.303928005602863482e+00 -3.450000000000000000e+02 2.783002638712051446e+00 -3.460000000000000000e+02 3.136856115706376791e+00 -3.470000000000000000e+02 3.573486275341247520e+00 -3.480000000000000000e+02 3.998683400877324878e+00 -3.490000000000000000e+02 4.040869007395492929e+00 -3.500000000000000000e+02 4.153621186251155173e+00 -3.510000000000000000e+02 4.307819339879337406e+00 -3.520000000000000000e+02 4.122505813925746665e+00 -3.530000000000000000e+02 3.909383886504167016e+00 -3.540000000000000000e+02 3.698665671948257128e+00 -3.550000000000000000e+02 3.516173380005064519e+00 -3.560000000000000000e+02 3.356477995828850425e+00 -3.570000000000000000e+02 3.160081580233749854e+00 -3.580000000000000000e+02 2.984200165885861011e+00 -3.590000000000000000e+02 2.770167735908844353e+00 -3.600000000000000000e+02 2.544125745463342803e+00 -3.610000000000000000e+02 2.390559827962756234e+00 -3.620000000000000000e+02 2.312684631433588933e+00 -3.630000000000000000e+02 2.249351988051884632e+00 -3.640000000000000000e+02 2.160481333197594722e+00 -3.650000000000000000e+02 2.080340203487198281e+00 -3.660000000000000000e+02 2.036984480629119965e+00 -3.670000000000000000e+02 1.994087600564666829e+00 -3.680000000000000000e+02 1.940603736211912844e+00 -3.690000000000000000e+02 1.888583656013298029e+00 -3.700000000000000000e+02 1.790755255006616364e+00 -3.710000000000000000e+02 1.692465345587529812e+00 -3.720000000000000000e+02 1.617378317791101860e+00 -3.730000000000000000e+02 1.559343907277888075e+00 -3.740000000000000000e+02 1.511663235743319511e+00 -3.750000000000000000e+02 1.442967817317731161e+00 -3.760000000000000000e+02 1.392010166481182143e+00 -3.770000000000000000e+02 1.356970819697515651e+00 -3.780000000000000000e+02 1.315672992097228322e+00 -3.790000000000000000e+02 1.280728020654762433e+00 -3.800000000000000000e+02 1.250648336598931154e+00 -3.810000000000000000e+02 1.233236446903313910e+00 -3.820000000000000000e+02 1.201881619672994672e+00 -3.830000000000000000e+02 1.146703838483096760e+00 -3.840000000000000000e+02 1.097896025484838445e+00 -3.850000000000000000e+02 1.048476150035318355e+00 -3.860000000000000000e+02 1.017637220687949817e+00 -3.870000000000000000e+02 1.028435253921600401e+00 -3.880000000000000000e+02 1.039485602203704451e+00 -3.890000000000000000e+02 1.007069572347964126e+00 -3.900000000000000000e+02 9.727890037215338737e-01 -3.910000000000000000e+02 9.663333174638393253e-01 -3.920000000000000000e+02 9.478789831251134279e-01 -3.930000000000000000e+02 9.146401266440861155e-01 -3.940000000000000000e+02 8.964838841883382425e-01 -3.950000000000000000e+02 8.709237174070031395e-01 -3.960000000000000000e+02 8.265883653201128167e-01 -3.970000000000000000e+02 8.033407222810033943e-01 -3.980000000000000000e+02 8.118924754640002295e-01 -3.990000000000000000e+02 8.044148519649951812e-01 -4.000000000000000000e+02 7.726953097894549982e-01 -4.010000000000000000e+02 7.646660821341034753e-01 -4.020000000000000000e+02 7.743080343406182342e-01 -4.030000000000000000e+02 7.657572992398562484e-01 -4.040000000000000000e+02 7.496357501429595782e-01 -4.050000000000000000e+02 7.334880799993769296e-01 -4.060000000000000000e+02 7.164893091571650219e-01 -4.070000000000000000e+02 7.012917685380222199e-01 -4.080000000000000000e+02 6.911186014599846050e-01 -4.090000000000000000e+02 6.814727432371219251e-01 -4.100000000000000000e+02 6.712368360203043727e-01 -4.110000000000000000e+02 6.631628188627718412e-01 -4.120000000000000000e+02 6.557240173062228727e-01 -4.130000000000000000e+02 6.426077737163423675e-01 -4.140000000000000000e+02 6.306938107431300233e-01 -4.150000000000000000e+02 6.231470464372395046e-01 -4.160000000000000000e+02 6.155417585989471085e-01 -4.170000000000000000e+02 6.065583524274558158e-01 -4.180000000000000000e+02 5.973653276235721954e-01 -4.190000000000000000e+02 5.880300677074770110e-01 -4.200000000000000000e+02 5.794847797288136260e-01 -4.210000000000000000e+02 5.710896937506615423e-01 -4.220000000000000000e+02 5.649269475079771174e-01 -4.230000000000000000e+02 5.611600528314897307e-01 -4.240000000000000000e+02 5.590998265874644879e-01 -4.250000000000000000e+02 5.521542515421713482e-01 -4.260000000000000000e+02 5.347576224958094926e-01 -4.270000000000000000e+02 5.209377065831362064e-01 -4.280000000000000000e+02 5.173853413716962280e-01 -4.290000000000000000e+02 5.133642763288562838e-01 -4.300000000000000000e+02 5.031284167181094835e-01 -4.310000000000000000e+02 4.935211140689056419e-01 -4.320000000000000000e+02 4.880868077467254151e-01 -4.330000000000000000e+02 4.801128385743494986e-01 -4.340000000000000000e+02 4.717682983576887423e-01 -4.350000000000000000e+02 4.710363751507173347e-01 -4.360000000000000000e+02 4.702276890457245395e-01 -4.370000000000000000e+02 4.622921815338318918e-01 -4.380000000000000000e+02 4.547698834270983981e-01 -4.390000000000000000e+02 4.531389015741070225e-01 -4.400000000000000000e+02 4.503861585087456931e-01 -4.410000000000000000e+02 4.414805861234325501e-01 -4.420000000000000000e+02 4.325248711655828027e-01 -4.430000000000000000e+02 4.286142196459217235e-01 -4.440000000000000000e+02 4.275428105567987691e-01 -4.450000000000000000e+02 4.247827786684365003e-01 -4.460000000000000000e+02 4.209600553455061789e-01 -4.470000000000000000e+02 4.177210706210515712e-01 -4.480000000000000000e+02 4.127250600023361637e-01 -4.490000000000000000e+02 4.061739185334488078e-01 -4.500000000000000000e+02 4.011949896430181406e-01 -4.510000000000000000e+02 3.984389066119622957e-01 -4.520000000000000000e+02 3.960398812874672547e-01 -4.530000000000000000e+02 3.929348478948982426e-01 -4.540000000000000000e+02 3.886898482747888073e-01 -4.550000000000000000e+02 3.830207331471457977e-01 -4.560000000000000000e+02 3.761158173254862125e-01 -4.570000000000000000e+02 3.723824576145031151e-01 -4.580000000000000000e+02 3.715717745057048882e-01 -4.590000000000000000e+02 3.697182244393833472e-01 -4.600000000000000000e+02 3.658589993526584205e-01 -4.610000000000000000e+02 3.616719520199900839e-01 -4.620000000000000000e+02 3.576812568545735815e-01 -4.630000000000000000e+02 3.543864690911576742e-01 -4.640000000000000000e+02 3.522280955521581158e-01 -4.650000000000000000e+02 3.504491996285457045e-01 -4.660000000000000000e+02 3.462631876000078490e-01 -4.670000000000000000e+02 3.415205514492465344e-01 -4.680000000000000000e+02 3.384089465309362277e-01 -4.690000000000000000e+02 3.361808400752953618e-01 -4.700000000000000000e+02 3.338449166956842240e-01 -4.710000000000000000e+02 3.311657795290107731e-01 -4.720000000000000000e+02 3.275213049028709023e-01 -4.730000000000000000e+02 3.239354617756656785e-01 -4.740000000000000000e+02 3.208363739629827571e-01 -4.750000000000000000e+02 3.186696177888769799e-01 -4.760000000000000000e+02 3.161602865869745371e-01 -4.770000000000000000e+02 3.128410256276050738e-01 -4.780000000000000000e+02 3.104662875566143176e-01 -4.790000000000000000e+02 3.090143600831314896e-01 -4.800000000000000000e+02 3.081707598125788539e-01 -4.810000000000000000e+02 3.069198629731377248e-01 -4.820000000000000000e+02 3.019714098310701811e-01 -4.830000000000000000e+02 2.973032450354184952e-01 -4.840000000000000000e+02 2.956908062068524523e-01 -4.850000000000000000e+02 2.947100948529325914e-01 -4.860000000000000000e+02 2.939056685952170511e-01 -4.870000000000000000e+02 2.916286543564557410e-01 -4.880000000000000000e+02 2.870339431469631775e-01 -4.890000000000000000e+02 2.816971438289136986e-01 -4.900000000000000000e+02 2.791004008932900793e-01 -4.910000000000000000e+02 2.802878119207415364e-01 -4.920000000000000000e+02 2.805368097427271001e-01 -4.930000000000000000e+02 2.784182570727317119e-01 -4.940000000000000000e+02 2.753849010497286254e-01 -4.950000000000000000e+02 2.719841364541146778e-01 -4.960000000000000000e+02 2.695455429084538945e-01 -4.970000000000000000e+02 2.678427239474470145e-01 -4.980000000000000000e+02 2.665017100198022737e-01 -4.990000000000000000e+02 2.649065167667907228e-01 -5.000000000000000000e+02 2.625448971300224366e-01 -5.010000000000000000e+02 2.605327268643842786e-01 -5.020000000000000000e+02 2.588775133516937887e-01 -5.030000000000000000e+02 2.567718978178080147e-01 -5.040000000000000000e+02 2.543575805589111116e-01 -5.050000000000000000e+02 2.522306554662914202e-01 -5.060000000000000000e+02 2.508842499016156191e-01 -5.070000000000000000e+02 2.496783842260557051e-01 -5.080000000000000000e+02 2.480466856910102935e-01 -5.090000000000000000e+02 2.465207081940127831e-01 -5.100000000000000000e+02 2.449208617331634363e-01 -5.110000000000000000e+02 2.434411448417727886e-01 -5.120000000000000000e+02 2.420025343302613652e-01 -5.130000000000000000e+02 2.394674880313324705e-01 -5.140000000000000000e+02 2.367835379825995457e-01 -5.150000000000000000e+02 2.353722058444396859e-01 -5.160000000000000000e+02 2.336618640339418185e-01 -5.170000000000000000e+02 2.321268605904972526e-01 -5.180000000000000000e+02 2.304314592746790624e-01 -5.190000000000000000e+02 2.283464729493796530e-01 -5.200000000000000000e+02 2.265780891294194022e-01 -5.210000000000000000e+02 2.256899832125863758e-01 -5.220000000000000000e+02 2.250991244949594738e-01 -5.230000000000000000e+02 2.233560615211991895e-01 -5.240000000000000000e+02 2.215911662546430905e-01 -5.250000000000000000e+02 2.209070846613355177e-01 -5.260000000000000000e+02 2.197276445663630118e-01 -5.270000000000000000e+02 2.190231828766119881e-01 -5.280000000000000000e+02 2.178701800624724405e-01 -5.290000000000000000e+02 2.150125104164173628e-01 -5.300000000000000000e+02 2.125333736501849868e-01 -5.310000000000000000e+02 2.120636993767610057e-01 -5.320000000000000000e+02 2.124650126834856378e-01 -5.330000000000000000e+02 2.114997118427921485e-01 -5.340000000000000000e+02 2.094850735750174442e-01 -5.350000000000000000e+02 2.076346526871917231e-01 -5.360000000000000000e+02 2.052689544373455521e-01 -5.370000000000000000e+02 2.035871992438794964e-01 -5.380000000000000000e+02 2.030179648328740427e-01 -5.390000000000000000e+02 2.017867402520298059e-01 -5.400000000000000000e+02 1.998175876055161004e-01 -5.410000000000000000e+02 1.982126679078189679e-01 -5.420000000000000000e+02 1.968221777258057359e-01 -5.430000000000000000e+02 1.951206513723492408e-01 -5.440000000000000000e+02 1.933572413120855371e-01 -5.450000000000000000e+02 1.924033739507697016e-01 -5.460000000000000000e+02 1.912292451448932284e-01 -5.470000000000000000e+02 1.897415695859978324e-01 -5.480000000000000000e+02 1.884175909126065140e-01 -5.490000000000000000e+02 1.869666203081614686e-01 -5.500000000000000000e+02 1.855619361337265405e-01 -5.510000000000000000e+02 1.845441303939724942e-01 -5.520000000000000000e+02 1.835914214664698674e-01 -5.530000000000000000e+02 1.826191053899133276e-01 -5.540000000000000000e+02 1.814372241223501658e-01 -5.550000000000000000e+02 1.802821089549231093e-01 -5.560000000000000000e+02 1.789652630866330196e-01 -5.570000000000000000e+02 1.778285904912150217e-01 -5.580000000000000000e+02 1.768766064530321314e-01 -5.590000000000000000e+02 1.757726218800563789e-01 -5.600000000000000000e+02 1.741378226592481815e-01 -5.610000000000000000e+02 1.723288261162471136e-01 -5.620000000000000000e+02 1.707501802187501305e-01 -5.630000000000000000e+02 1.696560826079121231e-01 -5.640000000000000000e+02 1.688866431451916950e-01 -5.650000000000000000e+02 1.676131424568440831e-01 -5.660000000000000000e+02 1.660828506312333475e-01 -5.670000000000000000e+02 1.646337159350181323e-01 -5.680000000000000000e+02 1.632198378269752725e-01 -5.690000000000000000e+02 1.623592743612009281e-01 -5.700000000000000000e+02 1.617382098917645727e-01 -5.710000000000000000e+02 1.607528905989208667e-01 -5.720000000000000000e+02 1.594418388929920716e-01 -5.730000000000000000e+02 1.581722095854678212e-01 -5.740000000000000000e+02 1.569735905444122337e-01 -5.750000000000000000e+02 1.559091853012824491e-01 -5.760000000000000000e+02 1.549316713274414004e-01 -5.770000000000000000e+02 1.535227930799748230e-01 -5.780000000000000000e+02 1.519361704420207348e-01 -5.790000000000000000e+02 1.506882691193676127e-01 -5.800000000000000000e+02 1.491550228204485962e-01 -5.810000000000000000e+02 1.472755598602591975e-01 -5.820000000000000000e+02 1.458910722211179678e-01 -5.830000000000000000e+02 1.445061541950944106e-01 -5.840000000000000000e+02 1.432251686690005632e-01 -5.850000000000000000e+02 1.417824358351622016e-01 -5.860000000000000000e+02 1.407177299135873028e-01 -5.870000000000000000e+02 1.395365186160640036e-01 -5.880000000000000000e+02 1.386613500714227454e-01 -5.890000000000000000e+02 1.376856108123127864e-01 -5.900000000000000000e+02 1.371074581111847712e-01 -5.910000000000000000e+02 1.358785692803984035e-01 -5.920000000000000000e+02 1.347587844386158584e-01 -5.930000000000000000e+02 1.339446389066242249e-01 -5.940000000000000000e+02 1.328714086248795612e-01 -5.950000000000000000e+02 1.303082016745845950e-01 -5.960000000000000000e+02 1.280845601150825963e-01 -5.970000000000000000e+02 1.257039358822217012e-01 -5.980000000000000000e+02 1.232436776011627821e-01 -5.990000000000000000e+02 1.205046803707603698e-01 -6.000000000000000000e+02 1.182720193486171689e-01 -6.010000000000000000e+02 1.160052597216233439e-01 -6.020000000000000000e+02 1.129659906267471703e-01 -6.030000000000000000e+02 1.106328400783497257e-01 -6.040000000000000000e+02 1.097242059362349836e-01 -6.050000000000000000e+02 1.081873105499707999e-01 -6.060000000000000000e+02 1.057636530345747450e-01 -6.070000000000000000e+02 1.053256949202308473e-01 -6.080000000000000000e+02 1.042384655554098039e-01 -6.090000000000000000e+02 1.014123589208693055e-01 -6.100000000000000000e+02 1.002267225271305517e-01 -6.110000000000000000e+02 9.796249555250345631e-02 -6.120000000000000000e+02 9.572763560385537385e-02 -6.130000000000000000e+02 9.376457849802230515e-02 -6.140000000000000000e+02 9.194063446381861571e-02 -6.150000000000000000e+02 9.018079583129121057e-02 -6.160000000000000000e+02 8.684672437258034172e-02 -6.170000000000000000e+02 8.513035175552598199e-02 -6.180000000000000000e+02 8.457769811552133532e-02 -6.190000000000000000e+02 8.124867691737501507e-02 -6.200000000000000000e+02 8.083303141529971092e-02 -6.210000000000000000e+02 7.969580623993287316e-02 -6.220000000000000000e+02 7.807788370960067059e-02 -6.230000000000000000e+02 7.588536004885376718e-02 -6.240000000000000000e+02 7.465648723171451617e-02 -6.250000000000000000e+02 7.293219633282768677e-02 -6.260000000000000000e+02 7.102910568592249452e-02 -6.270000000000000000e+02 6.823992446657642374e-02 -6.280000000000000000e+02 6.729404339639416532e-02 -6.290000000000000000e+02 6.570446276328731350e-02 -6.300000000000000000e+02 6.389084977333474302e-02 -6.310000000000000000e+02 6.167264304752995835e-02 -6.320000000000000000e+02 6.168744106786816506e-02 -6.330000000000000000e+02 6.149270221404462555e-02 -6.340000000000000000e+02 6.018832858602345126e-02 -6.350000000000000000e+02 5.800737047095026050e-02 -6.360000000000000000e+02 5.912179117724896543e-02 -6.370000000000000000e+02 5.654270805248425708e-02 -6.380000000000000000e+02 5.412364314191689396e-02 -6.390000000000000000e+02 5.066405966988099530e-02 -6.400000000000000000e+02 4.870174645719493878e-02 -6.410000000000000000e+02 4.809799948468499592e-02 -6.420000000000000000e+02 4.775645758073446961e-02 -6.430000000000000000e+02 5.032795678436362968e-02 -6.440000000000000000e+02 5.380941097176278332e-02 -6.450000000000000000e+02 5.003574563882724757e-02 -6.460000000000000000e+02 4.687504817622907549e-02 -6.470000000000000000e+02 4.278333113019516104e-02 -6.480000000000000000e+02 4.038501734549286570e-02 -6.490000000000000000e+02 3.734994413927558016e-02 -6.500000000000000000e+02 3.159026823157892738e-02 -6.510000000000000000e+02 2.552501180555797472e-02 -6.520000000000000000e+02 1.840569895823435803e-02 -6.530000000000000000e+02 1.095708058464484394e-02 -6.540000000000000000e+02 8.546557230822095577e-03 -6.550000000000000000e+02 8.958049086387047735e-03 -6.560000000000000000e+02 9.449554893691874610e-03 -6.570000000000000000e+02 9.882699255074307160e-03 -6.580000000000000000e+02 1.053704001307656860e-02 -6.590000000000000000e+02 1.126777823618900325e-02 -6.600000000000000000e+02 1.222589539075055742e-02 -6.610000000000000000e+02 1.334616941659527885e-02 -6.620000000000000000e+02 1.414199728570622941e-02 -6.630000000000000000e+02 1.523066274219376376e-02 -6.640000000000000000e+02 1.656803737484623118e-02 -6.650000000000000000e+02 1.791816523222217183e-02 -6.660000000000000000e+02 1.946047719303312801e-02 -6.670000000000000000e+02 2.016747267923760939e-02 -6.680000000000000000e+02 2.075530070851973330e-02 -6.690000000000000000e+02 2.207424218040054606e-02 -6.700000000000000000e+02 2.347914200244569094e-02 -6.710000000000000000e+02 2.611735269247505986e-02 -6.720000000000000000e+02 3.115979221791311329e-02 -6.730000000000000000e+02 3.542261050738817335e-02 -6.740000000000000000e+02 3.838780755210113166e-02 -6.750000000000000000e+02 4.342362526503897036e-02 -6.760000000000000000e+02 4.939630041023400364e-02 -6.770000000000000000e+02 5.373615578630489692e-02 -6.780000000000000000e+02 5.592804575849290305e-02 -6.790000000000000000e+02 5.499742458285750840e-02 -6.800000000000000000e+02 6.175563369688819026e-02 -6.810000000000000000e+02 6.054550042609304489e-02 -6.820000000000000000e+02 5.932669376852171828e-02 -6.830000000000000000e+02 6.079455649472691181e-02 -6.840000000000000000e+02 1.053535976490686116e-02 -6.850000000000000000e+02 -3.669168823655337419e-02 -6.860000000000000000e+02 -8.564000370867089207e-02 -6.870000000000000000e+02 -1.335350554003449097e-01 -6.880000000000000000e+02 -1.784736175504070266e-01 -6.890000000000000000e+02 -2.322038120760240298e-01 -6.900000000000000000e+02 -2.806830911676423401e-01 -6.910000000000000000e+02 -3.284996786866697938e-01 -6.920000000000000000e+02 -3.778162718497888317e-01 -6.930000000000000000e+02 -3.776943659534208186e-01 -6.940000000000000000e+02 -3.809622962482322461e-01 -6.950000000000000000e+02 -3.809622962482322461e-01 -6.960000000000000000e+02 -3.809622962482322461e-01 -6.970000000000000000e+02 -3.809622962482322461e-01 -6.980000000000000000e+02 -3.809622962482322461e-01 -6.990000000000000000e+02 -3.809622962482322461e-01 -7.000000000000000000e+02 -3.809622962482322461e-01 -7.010000000000000000e+02 -3.809622962482322461e-01 -7.020000000000000000e+02 -3.809622962482322461e-01 -7.030000000000000000e+02 -3.809622962482322461e-01 -7.040000000000000000e+02 -3.809622962482322461e-01 -7.050000000000000000e+02 -3.809622962482322461e-01 -7.060000000000000000e+02 -3.809622962482322461e-01 -7.070000000000000000e+02 -3.809622962482322461e-01 -7.080000000000000000e+02 -3.809622962482322461e-01 -7.090000000000000000e+02 -3.809622962482322461e-01 -7.100000000000000000e+02 -3.809622962482322461e-01 -7.110000000000000000e+02 -3.809622962482322461e-01 -7.120000000000000000e+02 -3.809622962482322461e-01 -7.130000000000000000e+02 -3.809622962482322461e-01 -7.140000000000000000e+02 -3.809622962482322461e-01 -7.150000000000000000e+02 -3.809622962482322461e-01 -7.160000000000000000e+02 -3.809622962482322461e-01 -7.170000000000000000e+02 -3.809622962482322461e-01 -7.180000000000000000e+02 -3.809622962482322461e-01 -7.190000000000000000e+02 -3.809622962482322461e-01 -7.200000000000000000e+02 -3.809622962482322461e-01 -7.210000000000000000e+02 -3.809622962482322461e-01 -7.220000000000000000e+02 -3.809622962482322461e-01 -7.230000000000000000e+02 -3.809622962482322461e-01 -7.240000000000000000e+02 -3.809622962482322461e-01 -7.250000000000000000e+02 -3.809622962482322461e-01 -7.260000000000000000e+02 -3.809622962482322461e-01 -7.270000000000000000e+02 -3.809622962482322461e-01 -7.280000000000000000e+02 -3.809622962482322461e-01 -7.290000000000000000e+02 -3.809622962482322461e-01 -7.300000000000000000e+02 -3.809622962482322461e-01 -7.310000000000000000e+02 -3.809622962482322461e-01 -7.320000000000000000e+02 -3.809622962482322461e-01 -7.330000000000000000e+02 -3.809622962482322461e-01 -7.340000000000000000e+02 -3.809622962482322461e-01 -7.350000000000000000e+02 -3.809622962482322461e-01 -7.360000000000000000e+02 -3.809622962482322461e-01 -7.370000000000000000e+02 -3.809622962482322461e-01 -7.380000000000000000e+02 -3.809622962482322461e-01 -7.390000000000000000e+02 -3.809622962482322461e-01 -7.400000000000000000e+02 -3.809622962482322461e-01 -7.410000000000000000e+02 -3.809622962482322461e-01 -7.420000000000000000e+02 -3.809622962482322461e-01 -7.430000000000000000e+02 -3.809622962482322461e-01 -7.440000000000000000e+02 -3.809622962482322461e-01 -7.450000000000000000e+02 -3.809622962482322461e-01 -7.460000000000000000e+02 -3.809622962482322461e-01 -7.470000000000000000e+02 -3.809622962482322461e-01 -7.480000000000000000e+02 -3.809622962482322461e-01 -7.490000000000000000e+02 -3.809622962482322461e-01 -7.500000000000000000e+02 -3.809622962482322461e-01 -7.510000000000000000e+02 -3.809622962482322461e-01 -7.520000000000000000e+02 -3.809622962482322461e-01 -7.530000000000000000e+02 -3.809622962482322461e-01 -7.540000000000000000e+02 -3.809622962482322461e-01 -7.550000000000000000e+02 -3.809622962482322461e-01 -7.560000000000000000e+02 -3.809622962482322461e-01 -7.570000000000000000e+02 -3.809622962482322461e-01 -7.580000000000000000e+02 -3.809622962482322461e-01 -7.590000000000000000e+02 -3.809622962482322461e-01 -7.600000000000000000e+02 -3.809622962482322461e-01 -7.610000000000000000e+02 -3.809622962482322461e-01 -7.620000000000000000e+02 -3.809622962482322461e-01 -7.630000000000000000e+02 -3.809622962482322461e-01 -7.640000000000000000e+02 -3.809622962482322461e-01 -7.650000000000000000e+02 -3.809622962482322461e-01 -7.660000000000000000e+02 -3.809622962482322461e-01 -7.670000000000000000e+02 -3.809622962482322461e-01 -7.680000000000000000e+02 -3.809622962482322461e-01 -7.690000000000000000e+02 -3.809622962482322461e-01 -7.700000000000000000e+02 -3.809622962482322461e-01 -7.710000000000000000e+02 -3.809622962482322461e-01 -7.720000000000000000e+02 -3.809622962482322461e-01 -7.730000000000000000e+02 -3.809622962482322461e-01 -7.740000000000000000e+02 -3.809622962482322461e-01 -7.750000000000000000e+02 -3.809622962482322461e-01 -7.760000000000000000e+02 -3.809622962482322461e-01 -7.770000000000000000e+02 -3.809622962482322461e-01 -7.780000000000000000e+02 -3.809622962482322461e-01 -7.790000000000000000e+02 -3.809622962482322461e-01 -7.800000000000000000e+02 -3.809622962482322461e-01 -7.810000000000000000e+02 -3.809622962482322461e-01 -7.820000000000000000e+02 -3.809622962482322461e-01 -7.830000000000000000e+02 -3.809622962482322461e-01 -7.840000000000000000e+02 -3.809622962482322461e-01 -7.850000000000000000e+02 -3.809622962482322461e-01 -7.860000000000000000e+02 -3.809622962482322461e-01 -7.870000000000000000e+02 -3.809622962482322461e-01 -7.880000000000000000e+02 -3.809622962482322461e-01 -7.890000000000000000e+02 -3.809622962482322461e-01 -7.900000000000000000e+02 -3.809622962482322461e-01 -7.910000000000000000e+02 -3.809622962482322461e-01 -7.920000000000000000e+02 -3.809622962482322461e-01 -7.930000000000000000e+02 -3.809622962482322461e-01 -7.940000000000000000e+02 -3.809622962482322461e-01 -7.950000000000000000e+02 -3.809622962482322461e-01 -7.960000000000000000e+02 -3.809622962482322461e-01 -7.970000000000000000e+02 -3.809622962482322461e-01 -7.980000000000000000e+02 -3.809622962482322461e-01 -7.990000000000000000e+02 -3.809622962482322461e-01 -8.000000000000000000e+02 -3.809622962482322461e-01 -8.010000000000000000e+02 -3.809622962482322461e-01 -8.020000000000000000e+02 -3.809622962482322461e-01 -8.030000000000000000e+02 -3.809622962482322461e-01 -8.040000000000000000e+02 -3.809622962482322461e-01 -8.050000000000000000e+02 -3.809622962482322461e-01 -8.060000000000000000e+02 -3.809622962482322461e-01 -8.070000000000000000e+02 -3.809622962482322461e-01 -8.080000000000000000e+02 -3.809622962482322461e-01 -8.090000000000000000e+02 -3.809622962482322461e-01 -8.100000000000000000e+02 -3.809622962482322461e-01 -8.110000000000000000e+02 -3.809622962482322461e-01 -8.120000000000000000e+02 -3.809622962482322461e-01 -8.130000000000000000e+02 -3.809622962482322461e-01 -8.140000000000000000e+02 -3.809622962482322461e-01 -8.150000000000000000e+02 -3.809622962482322461e-01 -8.160000000000000000e+02 -3.809622962482322461e-01 -8.170000000000000000e+02 -3.809622962482322461e-01 -8.180000000000000000e+02 -3.809622962482322461e-01 -8.190000000000000000e+02 -3.809622962482322461e-01 -8.200000000000000000e+02 -3.809622962482322461e-01 -8.210000000000000000e+02 -3.809622962482322461e-01 -8.220000000000000000e+02 -3.809622962482322461e-01 -8.230000000000000000e+02 -3.809622962482322461e-01 -8.240000000000000000e+02 -3.809622962482322461e-01 -8.250000000000000000e+02 -3.809622962482322461e-01 -8.260000000000000000e+02 -3.809622962482322461e-01 -8.270000000000000000e+02 -3.809622962482322461e-01 -8.280000000000000000e+02 -3.809622962482322461e-01 -8.290000000000000000e+02 -3.809622962482322461e-01 -8.300000000000000000e+02 -3.809622962482322461e-01 -8.310000000000000000e+02 -3.809622962482322461e-01 -8.320000000000000000e+02 -3.809622962482322461e-01 -8.330000000000000000e+02 -3.809622962482322461e-01 -8.340000000000000000e+02 -3.809622962482322461e-01 -8.350000000000000000e+02 -3.809622962482322461e-01 -8.360000000000000000e+02 -3.809622962482322461e-01 -8.370000000000000000e+02 -3.809622962482322461e-01 -8.380000000000000000e+02 -3.809622962482322461e-01 -8.390000000000000000e+02 -3.809622962482322461e-01 -8.400000000000000000e+02 -3.809622962482322461e-01 -8.410000000000000000e+02 -3.809622962482322461e-01 -8.420000000000000000e+02 -3.809622962482322461e-01 -8.430000000000000000e+02 -3.809622962482322461e-01 -8.440000000000000000e+02 -3.809622962482322461e-01 -8.450000000000000000e+02 -3.809622962482322461e-01 -8.460000000000000000e+02 -3.809622962482322461e-01 -8.470000000000000000e+02 -3.809622962482322461e-01 -8.480000000000000000e+02 -3.809622962482322461e-01 -8.490000000000000000e+02 -3.809622962482322461e-01 -8.500000000000000000e+02 -3.809622962482322461e-01 -8.510000000000000000e+02 -3.809622962482322461e-01 -8.520000000000000000e+02 -3.809622962482322461e-01 -8.530000000000000000e+02 -3.809622962482322461e-01 -8.540000000000000000e+02 -3.809622962482322461e-01 -8.550000000000000000e+02 -3.809622962482322461e-01 -8.560000000000000000e+02 -3.809622962482322461e-01 -8.570000000000000000e+02 -3.809622962482322461e-01 -8.580000000000000000e+02 -3.809622962482322461e-01 -8.590000000000000000e+02 -3.809622962482322461e-01 -8.600000000000000000e+02 -3.809622962482322461e-01 -8.610000000000000000e+02 -3.809622962482322461e-01 -8.620000000000000000e+02 -3.809622962482322461e-01 -8.630000000000000000e+02 -3.809622962482322461e-01 -8.640000000000000000e+02 -3.809622962482322461e-01 -8.650000000000000000e+02 -3.809622962482322461e-01 -8.660000000000000000e+02 -3.809622962482322461e-01 -8.670000000000000000e+02 -3.809622962482322461e-01 -8.680000000000000000e+02 -3.809622962482322461e-01 -8.690000000000000000e+02 -3.809622962482322461e-01 -8.700000000000000000e+02 -3.809622962482322461e-01 -8.710000000000000000e+02 -3.809622962482322461e-01 -8.720000000000000000e+02 -3.809622962482322461e-01 -8.730000000000000000e+02 -3.809622962482322461e-01 -8.740000000000000000e+02 -3.809622962482322461e-01 -8.750000000000000000e+02 -3.809622962482322461e-01 -8.760000000000000000e+02 -3.809622962482322461e-01 -8.770000000000000000e+02 -3.809622962482322461e-01 -8.780000000000000000e+02 -3.809622962482322461e-01 -8.790000000000000000e+02 -3.809622962482322461e-01 -8.800000000000000000e+02 -3.809622962482322461e-01 -8.810000000000000000e+02 -3.809622962482322461e-01 -8.820000000000000000e+02 -3.809622962482322461e-01 -8.830000000000000000e+02 -3.809622962482322461e-01 -8.840000000000000000e+02 -3.809622962482322461e-01 -8.850000000000000000e+02 -3.809622962482322461e-01 -8.860000000000000000e+02 -3.809622962482322461e-01 -8.870000000000000000e+02 -3.809622962482322461e-01 -8.880000000000000000e+02 -3.809622962482322461e-01 -8.890000000000000000e+02 -3.809622962482322461e-01 -8.900000000000000000e+02 -3.809622962482322461e-01 -8.910000000000000000e+02 -3.809622962482322461e-01 -8.920000000000000000e+02 -3.809622962482322461e-01 -8.930000000000000000e+02 -3.809622962482322461e-01 -8.940000000000000000e+02 -3.809622962482322461e-01 -8.950000000000000000e+02 -3.809622962482322461e-01 -8.960000000000000000e+02 -3.809622962482322461e-01 -8.970000000000000000e+02 -3.809622962482322461e-01 -8.980000000000000000e+02 -3.809622962482322461e-01 -8.990000000000000000e+02 -3.809622962482322461e-01 -9.000000000000000000e+02 -3.809622962482322461e-01 -9.010000000000000000e+02 -3.809622962482322461e-01 -9.020000000000000000e+02 -3.809622962482322461e-01 -9.030000000000000000e+02 -3.809622962482322461e-01 -9.040000000000000000e+02 -3.809622962482322461e-01 -9.050000000000000000e+02 -3.809622962482322461e-01 -9.060000000000000000e+02 -3.809622962482322461e-01 -9.070000000000000000e+02 -3.809622962482322461e-01 -9.080000000000000000e+02 -3.809622962482322461e-01 -9.090000000000000000e+02 -3.809622962482322461e-01 -9.100000000000000000e+02 -3.809622962482322461e-01 -9.110000000000000000e+02 -3.809622962482322461e-01 -9.120000000000000000e+02 -3.809622962482322461e-01 -9.130000000000000000e+02 -3.809622962482322461e-01 -9.140000000000000000e+02 -3.809622962482322461e-01 -9.150000000000000000e+02 -3.809622962482322461e-01 -9.160000000000000000e+02 -3.809622962482322461e-01 -9.170000000000000000e+02 -3.809622962482322461e-01 -9.180000000000000000e+02 -3.809622962482322461e-01 -9.190000000000000000e+02 -3.809622962482322461e-01 -9.200000000000000000e+02 -3.809622962482322461e-01 -9.210000000000000000e+02 -3.809622962482322461e-01 -9.220000000000000000e+02 -3.809622962482322461e-01 -9.230000000000000000e+02 -3.809622962482322461e-01 -9.240000000000000000e+02 -3.809622962482322461e-01 -9.250000000000000000e+02 -3.809622962482322461e-01 -9.260000000000000000e+02 -3.809622962482322461e-01 -9.270000000000000000e+02 -3.809622962482322461e-01 -9.280000000000000000e+02 -3.809622962482322461e-01 -9.290000000000000000e+02 -3.809622962482322461e-01 -9.300000000000000000e+02 -3.809622962482322461e-01 -9.310000000000000000e+02 -3.809622962482322461e-01 -9.320000000000000000e+02 -3.809622962482322461e-01 -9.330000000000000000e+02 -3.809622962482322461e-01 -9.340000000000000000e+02 -3.809622962482322461e-01 -9.350000000000000000e+02 -3.809622962482322461e-01 -9.360000000000000000e+02 -3.809622962482322461e-01 -9.370000000000000000e+02 -3.809622962482322461e-01 -9.380000000000000000e+02 -3.809622962482322461e-01 -9.390000000000000000e+02 -3.809622962482322461e-01 -9.400000000000000000e+02 -3.809622962482322461e-01 -9.410000000000000000e+02 -3.809622962482322461e-01 -9.420000000000000000e+02 -3.809622962482322461e-01 -9.430000000000000000e+02 -3.809622962482322461e-01 -9.440000000000000000e+02 -3.809622962482322461e-01 -9.450000000000000000e+02 -3.809622962482322461e-01 -9.460000000000000000e+02 -3.809622962482322461e-01 -9.470000000000000000e+02 -3.809622962482322461e-01 -9.480000000000000000e+02 -3.809622962482322461e-01 -9.490000000000000000e+02 -3.809622962482322461e-01 -9.500000000000000000e+02 -3.809622962482322461e-01 -9.510000000000000000e+02 -3.809622962482322461e-01 -9.520000000000000000e+02 -3.809622962482322461e-01 -9.530000000000000000e+02 -3.809622962482322461e-01 -9.540000000000000000e+02 -3.809622962482322461e-01 -9.550000000000000000e+02 -3.809622962482322461e-01 -9.560000000000000000e+02 -3.809622962482322461e-01 -9.570000000000000000e+02 -3.809622962482322461e-01 -9.580000000000000000e+02 -3.809622962482322461e-01 -9.590000000000000000e+02 -3.809622962482322461e-01 -9.600000000000000000e+02 -3.809622962482322461e-01 -9.610000000000000000e+02 -3.809622962482322461e-01 -9.620000000000000000e+02 -3.809622962482322461e-01 -9.630000000000000000e+02 -3.809622962482322461e-01 -9.640000000000000000e+02 -3.809622962482322461e-01 -9.650000000000000000e+02 -3.809622962482322461e-01 -9.660000000000000000e+02 -3.809622962482322461e-01 -9.670000000000000000e+02 -3.809622962482322461e-01 -9.680000000000000000e+02 -3.809622962482322461e-01 -9.690000000000000000e+02 -3.809622962482322461e-01 -9.700000000000000000e+02 -3.809622962482322461e-01 -9.710000000000000000e+02 -3.809622962482322461e-01 -9.720000000000000000e+02 -3.809622962482322461e-01 -9.730000000000000000e+02 -3.809622962482322461e-01 -9.740000000000000000e+02 -3.809622962482322461e-01 -9.750000000000000000e+02 -3.809622962482322461e-01 -9.760000000000000000e+02 -3.809622962482322461e-01 -9.770000000000000000e+02 -3.809622962482322461e-01 -9.780000000000000000e+02 -3.809622962482322461e-01 -9.790000000000000000e+02 -3.809622962482322461e-01 -9.800000000000000000e+02 -3.809622962482322461e-01 -9.810000000000000000e+02 -3.809622962482322461e-01 -9.820000000000000000e+02 -3.809622962482322461e-01 -9.830000000000000000e+02 -3.809622962482322461e-01 -9.840000000000000000e+02 -3.809622962482322461e-01 -9.850000000000000000e+02 -3.809622962482322461e-01 -9.860000000000000000e+02 -3.809622962482322461e-01 -9.870000000000000000e+02 -3.809622962482322461e-01 -9.880000000000000000e+02 -3.809622962482322461e-01 -9.890000000000000000e+02 -3.809622962482322461e-01 -9.900000000000000000e+02 -3.809622962482322461e-01 -9.910000000000000000e+02 -3.809622962482322461e-01 -9.920000000000000000e+02 -3.809622962482322461e-01 -9.930000000000000000e+02 -3.809622962482322461e-01 -9.940000000000000000e+02 -3.809622962482322461e-01 -9.950000000000000000e+02 -3.809622962482322461e-01 -9.960000000000000000e+02 -3.809622962482322461e-01 -9.970000000000000000e+02 -3.809622962482322461e-01 -9.980000000000000000e+02 -3.809622962482322461e-01 -9.990000000000000000e+02 -3.809622962482322461e-01 -1.000000000000000000e+03 -3.809622962482322461e-01 -1.001000000000000000e+03 -3.809622962482322461e-01 -1.002000000000000000e+03 -3.809622962482322461e-01 -1.003000000000000000e+03 -3.809622962482322461e-01 -1.004000000000000000e+03 -3.809622962482322461e-01 -1.005000000000000000e+03 -3.809622962482322461e-01 -1.006000000000000000e+03 -3.809622962482322461e-01 -1.007000000000000000e+03 -3.809622962482322461e-01 -1.008000000000000000e+03 -3.809622962482322461e-01 -1.009000000000000000e+03 -3.809622962482322461e-01 -1.010000000000000000e+03 -3.809622962482322461e-01 -1.011000000000000000e+03 -3.809622962482322461e-01 -1.012000000000000000e+03 -3.809622962482322461e-01 -1.013000000000000000e+03 -3.809622962482322461e-01 -1.014000000000000000e+03 -3.809622962482322461e-01 -1.015000000000000000e+03 -3.809622962482322461e-01 -1.016000000000000000e+03 -3.809622962482322461e-01 -1.017000000000000000e+03 -3.809622962482322461e-01 -1.018000000000000000e+03 -3.809622962482322461e-01 -1.019000000000000000e+03 -3.809622962482322461e-01 -1.020000000000000000e+03 -3.809622962482322461e-01 -1.021000000000000000e+03 -3.809622962482322461e-01 -1.022000000000000000e+03 -3.809622962482322461e-01 -1.023000000000000000e+03 -3.809622962482322461e-01 -1.024000000000000000e+03 -3.809622962482322461e-01 -1.025000000000000000e+03 -3.809622962482322461e-01 -1.026000000000000000e+03 -3.809622962482322461e-01 -1.027000000000000000e+03 -3.809622962482322461e-01 -1.028000000000000000e+03 -3.809622962482322461e-01 -1.029000000000000000e+03 -3.809622962482322461e-01 -1.030000000000000000e+03 -3.809622962482322461e-01 -1.031000000000000000e+03 -3.809622962482322461e-01 -1.032000000000000000e+03 -3.809622962482322461e-01 -1.033000000000000000e+03 -3.809622962482322461e-01 -1.034000000000000000e+03 -3.809622962482322461e-01 -1.035000000000000000e+03 -3.809622962482322461e-01 -1.036000000000000000e+03 -3.809622962482322461e-01 -1.037000000000000000e+03 -3.809622962482322461e-01 -1.038000000000000000e+03 -3.809622962482322461e-01 -1.039000000000000000e+03 -3.809622962482322461e-01 -1.040000000000000000e+03 -3.809622962482322461e-01 -1.041000000000000000e+03 -3.809622962482322461e-01 -1.042000000000000000e+03 -3.809622962482322461e-01 -1.043000000000000000e+03 -3.809622962482322461e-01 -1.044000000000000000e+03 -3.809622962482322461e-01 -1.045000000000000000e+03 -3.809622962482322461e-01 -1.046000000000000000e+03 -3.809622962482322461e-01 -1.047000000000000000e+03 -3.809622962482322461e-01 -1.048000000000000000e+03 -3.809622962482322461e-01 -1.049000000000000000e+03 -3.809622962482322461e-01 -1.050000000000000000e+03 -3.809622962482322461e-01 -1.051000000000000000e+03 -3.809622962482322461e-01 -1.052000000000000000e+03 -3.809622962482322461e-01 -1.053000000000000000e+03 -3.809622962482322461e-01 -1.054000000000000000e+03 -3.809622962482322461e-01 -1.055000000000000000e+03 -3.809622962482322461e-01 -1.056000000000000000e+03 -3.809622962482322461e-01 -1.057000000000000000e+03 -3.809622962482322461e-01 -1.058000000000000000e+03 -3.809622962482322461e-01 -1.059000000000000000e+03 -3.809622962482322461e-01 -1.060000000000000000e+03 -3.809622962482322461e-01 -1.061000000000000000e+03 -3.809622962482322461e-01 -1.062000000000000000e+03 -3.809622962482322461e-01 -1.063000000000000000e+03 -3.809622962482322461e-01 -1.064000000000000000e+03 -3.809622962482322461e-01 -1.065000000000000000e+03 -3.809622962482322461e-01 -1.066000000000000000e+03 -3.809622962482322461e-01 -1.067000000000000000e+03 -3.809622962482322461e-01 -1.068000000000000000e+03 -3.809622962482322461e-01 -1.069000000000000000e+03 -3.809622962482322461e-01 -1.070000000000000000e+03 -3.809622962482322461e-01 -1.071000000000000000e+03 -3.809622962482322461e-01 -1.072000000000000000e+03 -3.809622962482322461e-01 -1.073000000000000000e+03 -3.809622962482322461e-01 -1.074000000000000000e+03 -3.809622962482322461e-01 -1.075000000000000000e+03 -3.809622962482322461e-01 -1.076000000000000000e+03 -3.809622962482322461e-01 -1.077000000000000000e+03 -3.809622962482322461e-01 -1.078000000000000000e+03 -3.809622962482322461e-01 -1.079000000000000000e+03 -3.809622962482322461e-01 -1.080000000000000000e+03 -3.809622962482322461e-01 -1.081000000000000000e+03 -3.809622962482322461e-01 -1.082000000000000000e+03 -3.809622962482322461e-01 -1.083000000000000000e+03 -3.809622962482322461e-01 -1.084000000000000000e+03 -3.809622962482322461e-01 -1.085000000000000000e+03 -3.809622962482322461e-01 -1.086000000000000000e+03 -3.809622962482322461e-01 -1.087000000000000000e+03 -3.809622962482322461e-01 -1.088000000000000000e+03 -3.809622962482322461e-01 -1.089000000000000000e+03 -3.809622962482322461e-01 -1.090000000000000000e+03 -3.809622962482322461e-01 -1.091000000000000000e+03 -3.809622962482322461e-01 -1.092000000000000000e+03 -3.809622962482322461e-01 -1.093000000000000000e+03 -3.809622962482322461e-01 -1.094000000000000000e+03 -3.809622962482322461e-01 -1.095000000000000000e+03 -3.809622962482322461e-01 -1.096000000000000000e+03 -3.809622962482319686e-01 -1.097000000000000000e+03 -3.809622962482319686e-01 -1.098000000000000000e+03 -3.809622962482319686e-01 -1.099000000000000000e+03 -3.809622962482319686e-01 +3.000000000000000000e+02 1.519544011494232405e-01 +3.010000000000000000e+02 1.272278051479444061e-01 +3.020000000000000000e+02 1.055417219638186549e-01 +3.030000000000000000e+02 8.661960635797485986e-02 +3.040000000000000000e+02 7.024835257570144487e-02 +3.050000000000000000e+02 5.626854495393492084e-02 +3.060000000000000000e+02 4.456723540542639056e-02 +3.070000000000000000e+02 3.507270016451729394e-02 +3.080000000000000000e+02 2.775078098537234195e-02 +3.090000000000000000e+02 2.260252762754767081e-02 +3.100000000000000000e+02 1.966294101990322118e-02 +3.110000000000000000e+02 1.900067827641053683e-02 +3.120000000000000000e+02 2.071862741732687432e-02 +3.130000000000000000e+02 2.495529499046067815e-02 +3.140000000000000000e+02 3.188697610621633177e-02 +3.150000000000000000e+02 4.173069482421434828e-02 +3.160000000000000000e+02 5.474791339295302650e-02 +3.170000000000000000e+02 7.124901044473196110e-02 +3.180000000000000000e+02 9.159851846801202180e-02 +3.190000000000000000e+02 1.162210856672341586e-01 +3.200000000000000000e+02 1.456080805253935351e-01 +3.210000000000000000e+02 1.803246801433725510e-01 +3.220000000000000000e+02 2.210171634332580015e-01 +3.230000000000000000e+02 2.684199509778198989e-01 +3.240000000000000000e+02 3.233616735687566690e-01 +3.250000000000000000e+02 3.867691852056251434e-01 +3.260000000000000000e+02 4.596679348412270327e-01 +3.270000000000000000e+02 5.431764474380907926e-01 +3.280000000000000000e+02 6.384918242740029726e-01 +3.290000000000000000e+02 7.468621721548418524e-01 +3.300000000000000000e+02 8.695407938360413258e-01 +3.310000000000000000e+02 1.007716016581050811e+00 +3.320000000000000000e+02 1.162410086440075707e+00 +3.330000000000000000e+02 1.334341254381509412e+00 +3.340000000000000000e+02 1.523745964418995902e+00 +3.350000000000000000e+02 1.730164077723588489e+00 +3.360000000000000000e+02 1.952200375863182513e+00 +3.370000000000000000e+02 2.187290404108467534e+00 +3.380000000000000000e+02 2.431516319395185199e+00 +3.390000000000000000e+02 2.679533928869020087e+00 +3.400000000000000000e+02 2.924677193028491828e+00 +3.410000000000000000e+02 3.159291235229362282e+00 +3.420000000000000000e+02 3.375303085889779453e+00 +3.430000000000000000e+02 3.564975378757617275e+00 +3.440000000000000000e+02 3.721721147326182422e+00 +3.450000000000000000e+02 3.840816879511077975e+00 +3.460000000000000000e+02 3.919860418653115630e+00 +3.470000000000000000e+02 3.958883060569799550e+00 +3.480000000000000000e+02 3.960117598236263081e+00 +3.490000000000000000e+02 3.927508255051261443e+00 +3.500000000000000000e+02 3.866093971272740681e+00 +3.510000000000000000e+02 3.781395022041457832e+00 +3.520000000000000000e+02 3.678897281578411338e+00 +3.530000000000000000e+02 3.563680497628093580e+00 +3.540000000000000000e+02 3.440195092886218831e+00 +3.550000000000000000e+02 3.312165229556018886e+00 +3.560000000000000000e+02 3.182584538669757990e+00 +3.570000000000000000e+02 3.053770772840744385e+00 +3.580000000000000000e+02 2.927451497272737235e+00 +3.590000000000000000e+02 2.804860708142703274e+00 +3.600000000000000000e+02 2.686833535928860428e+00 +3.610000000000000000e+02 2.573891911136587662e+00 +3.620000000000000000e+02 2.466318065667425508e+00 +3.630000000000000000e+02 2.364215259951348180e+00 +3.640000000000000000e+02 2.267556540547907673e+00 +3.650000000000000000e+02 2.176223004121589977e+00 +3.660000000000000000e+02 2.090033255519735178e+00 +3.670000000000000000e+02 2.008765701383618651e+00 +3.680000000000000000e+02 1.932175147632497980e+00 +3.690000000000000000e+02 1.860004948874272257e+00 +3.700000000000000000e+02 1.791995734828703446e+00 +3.710000000000000000e+02 1.727891535437269921e+00 +3.720000000000000000e+02 1.667443951461035301e+00 +3.730000000000000000e+02 1.610414872645969275e+00 +3.740000000000000000e+02 1.556578128854717580e+00 +3.750000000000000000e+02 1.505720367247634028e+00 +3.760000000000000000e+02 1.457641376572070158e+00 +3.770000000000000000e+02 1.412154024030392474e+00 +3.780000000000000000e+02 1.369083927656423727e+00 +3.790000000000000000e+02 1.328268954803502488e+00 +3.800000000000000000e+02 1.289558612928151993e+00 +3.810000000000000000e+02 1.252813380505723329e+00 +3.820000000000000000e+02 1.217904012201442843e+00 +3.830000000000000000e+02 1.184710842221927685e+00 +3.840000000000000000e+02 1.153123102233183817e+00 +3.850000000000000000e+02 1.123038264690024768e+00 +3.860000000000000000e+02 1.094361418384153462e+00 +3.870000000000000000e+02 1.067004680099121305e+00 +3.880000000000000000e+02 1.040886644179084497e+00 +3.890000000000000000e+02 1.015931870356303834e+00 +3.900000000000000000e+02 9.920704091761332055e-01 +3.910000000000000000e+02 9.692373636911130186e-01 +3.920000000000000000e+02 9.473724856708093389e-01 +3.930000000000000000e+02 9.264198043279028294e-01 +3.940000000000000000e+02 9.063272854407132817e-01 +3.950000000000000000e+02 8.870465187213678604e-01 +3.960000000000000000e+02 8.685324313088639281e-01 +3.970000000000000000e+02 8.507430253383891916e-01 +3.980000000000000000e+02 8.336391376347006554e-01 +3.990000000000000000e+02 8.171842196915386491e-01 +4.000000000000000000e+02 8.013441362193630679e-01 +4.010000000000000000e+02 7.860869806666920256e-01 +4.020000000000000000e+02 7.713829062427700611e-01 +4.030000000000000000e+02 7.572039710862791262e-01 +4.040000000000000000e+02 7.435239963380961825e-01 +4.050000000000000000e+02 7.303184359809510307e-01 +4.060000000000000000e+02 7.175642574086015246e-01 +4.070000000000000000e+02 7.052398317779527970e-01 +4.080000000000000000e+02 6.933248332827602889e-01 +4.090000000000000000e+02 6.818001465649761172e-01 +4.100000000000000000e+02 6.706477815507677631e-01 +4.110000000000000000e+02 6.598507950635820185e-01 +4.120000000000000000e+02 6.493932186255126915e-01 +4.130000000000000000e+02 6.392599919120716123e-01 +4.140000000000000000e+02 6.294369013744934849e-01 +4.150000000000000000e+02 6.199105235880709719e-01 +4.160000000000000000e+02 6.106681729251528523e-01 +4.170000000000000000e+02 6.016978531880048386e-01 +4.180000000000000000e+02 5.929882128696635224e-01 +4.190000000000000000e+02 5.845285037412005780e-01 +4.200000000000000000e+02 5.763085424903187093e-01 +4.210000000000000000e+02 5.683186751613055199e-01 +4.220000000000000000e+02 5.605497441684816895e-01 +4.230000000000000000e+02 5.529930576750755611e-01 +4.240000000000000000e+02 5.456403611483284788e-01 +4.250000000000000000e+02 5.384838109176316445e-01 +4.260000000000000000e+02 5.315159495778901677e-01 +4.270000000000000000e+02 5.247296830936811762e-01 +4.280000000000000000e+02 5.181182594723434676e-01 +4.290000000000000000e+02 5.116752488851749048e-01 +4.300000000000000000e+02 5.053945251262489391e-01 +4.310000000000000000e+02 4.992702483075807107e-01 +4.320000000000000000e+02 4.932968486978412948e-01 +4.330000000000000000e+02 4.874690116193976519e-01 +4.340000000000000000e+02 4.817816633255768699e-01 +4.350000000000000000e+02 4.762299577864015365e-01 +4.360000000000000000e+02 4.708092643166593705e-01 +4.370000000000000000e+02 4.655151559858394239e-01 +4.380000000000000000e+02 4.603433987538123606e-01 +4.390000000000000000e+02 4.552899412811343693e-01 +4.400000000000000000e+02 4.503509053662769768e-01 +4.410000000000000000e+02 4.455225769662541913e-01 +4.420000000000000000e+02 4.408013977603070233e-01 +4.430000000000000000e+02 4.361839572192996450e-01 +4.440000000000000000e+02 4.316669851465750329e-01 +4.450000000000000000e+02 4.272473446583576195e-01 +4.460000000000000000e+02 4.229220255743326717e-01 +4.470000000000000000e+02 4.186881381911624622e-01 +4.480000000000000000e+02 4.145429074137498282e-01 +4.490000000000000000e+02 4.104836672208575510e-01 +4.500000000000000000e+02 4.065078554434086167e-01 +4.510000000000000000e+02 4.026130088353485625e-01 +4.520000000000000000e+02 3.987967584185051484e-01 +4.530000000000000000e+02 3.950568250839721074e-01 +4.540000000000000000e+02 3.913910154340087821e-01 +4.550000000000000000e+02 3.877972178494073496e-01 +4.560000000000000000e+02 3.842733987684536778e-01 +4.570000000000000000e+02 3.808175991644199287e-01 +4.580000000000000000e+02 3.774279312095868977e-01 +4.590000000000000000e+02 3.741025751144873568e-01 +4.600000000000000000e+02 3.708397761318226182e-01 +4.610000000000000000e+02 3.676378417153406963e-01 +4.620000000000000000e+02 3.644951388244805912e-01 +4.630000000000000000e+02 3.614100913662351977e-01 +4.640000000000000000e+02 3.583811777662213038e-01 +4.650000000000000000e+02 3.554069286615802459e-01 +4.660000000000000000e+02 3.524859247086465364e-01 +4.670000000000000000e+02 3.496167944988867182e-01 +4.680000000000000000e+02 3.467982125769764057e-01 +4.690000000000000000e+02 3.440288975553217332e-01 +4.700000000000000000e+02 3.413076103195986089e-01 +4.710000000000000000e+02 3.386331523203358618e-01 +4.720000000000000000e+02 3.360043639457865883e-01 +4.730000000000000000e+02 3.334201229716566295e-01 +4.740000000000000000e+02 3.308793430835478833e-01 +4.750000000000000000e+02 3.283809724682056896e-01 +4.760000000000000000e+02 3.259239924698854041e-01 +4.770000000000000000e+02 3.235074163083958010e-01 +4.780000000000000000e+02 3.211302878555616913e-01 +4.790000000000000000e+02 3.187916804671113713e-01 +4.800000000000000000e+02 3.164906958669987946e-01 +4.810000000000000000e+02 3.142264630815674864e-01 +4.820000000000000000e+02 3.119981374209456204e-01 +4.830000000000000000e+02 3.098048995052826715e-01 +4.840000000000000000e+02 3.076459543335683389e-01 +4.850000000000000000e+02 3.055205303928711924e-01 +4.860000000000000000e+02 3.034278788060326137e-01 +4.870000000000000000e+02 3.013672725158438870e-01 +4.880000000000000000e+02 2.993380055039797094e-01 +4.890000000000000000e+02 2.973393920429255877e-01 +4.900000000000000000e+02 2.953707659793530227e-01 +4.910000000000000000e+02 2.934314800473701856e-01 +4.920000000000000000e+02 2.915209052102739062e-01 +4.930000000000000000e+02 2.896384300293861624e-01 +4.940000000000000000e+02 2.877834600587380609e-01 +4.950000000000000000e+02 2.859554172643604120e-01 +4.960000000000000000e+02 2.841537394670408667e-01 +4.970000000000000000e+02 2.823778798074393914e-01 +4.980000000000000000e+02 2.806273062325760348e-01 +4.990000000000000000e+02 2.789015010026386632e-01 +5.000000000000000000e+02 2.771999602172549038e-01 +5.010000000000000000e+02 2.755221933602918227e-01 +5.020000000000000000e+02 2.738677228623813131e-01 +5.030000000000000000e+02 2.722360836803672246e-01 +5.040000000000000000e+02 2.706268228929116226e-01 +5.050000000000000000e+02 2.690394993115591271e-01 +5.060000000000000000e+02 2.674736831065768761e-01 +5.070000000000000000e+02 2.659289554469145833e-01 +5.080000000000000000e+02 2.644049081536687940e-01 +5.090000000000000000e+02 2.629011433664922293e-01 +5.100000000000000000e+02 2.614172732223645212e-01 +5.110000000000000000e+02 2.599529195462153552e-01 +5.120000000000000000e+02 2.585077135528728864e-01 +5.130000000000000000e+02 2.570812955598743010e-01 +5.140000000000000000e+02 2.556733147107192461e-01 +5.150000000000000000e+02 2.542834287080265043e-01 +5.160000000000000000e+02 2.529113035563207434e-01 +5.170000000000000000e+02 2.515566133139139904e-01 +5.180000000000000000e+02 2.502190398536344174e-01 +5.190000000000000000e+02 2.488982726319293182e-01 +5.200000000000000000e+02 2.475940084660907536e-01 +5.210000000000000000e+02 2.463059513192199512e-01 +5.220000000000000000e+02 2.450338120926504326e-01 +5.230000000000000000e+02 2.437773084254953870e-01 +5.240000000000000000e+02 2.425361645011122891e-01 +5.250000000000000000e+02 2.413101108600975986e-01 +5.260000000000000000e+02 2.400988842196609130e-01 +5.270000000000000000e+02 2.389022272990763696e-01 +5.280000000000000000e+02 2.377198886509710729e-01 +5.290000000000000000e+02 2.365516224982603388e-01 +5.300000000000000000e+02 2.353971885764653271e-01 +5.310000000000000000e+02 2.342563519812536632e-01 +5.320000000000000000e+02 2.331288830209747587e-01 +5.330000000000000000e+02 2.320145570740007324e-01 +5.340000000000000000e+02 2.309131544507126987e-01 +5.350000000000000000e+02 2.298244602599377739e-01 +5.360000000000000000e+02 2.287482642796767607e-01 +5.370000000000000000e+02 2.276843608319671364e-01 +5.380000000000000000e+02 2.266325486617387641e-01 +5.390000000000000000e+02 2.255926308194716734e-01 +5.400000000000000000e+02 2.245644145475843012e-01 +5.410000000000000000e+02 2.235477111703565445e-01 +5.420000000000000000e+02 2.225423359872971130e-01 +5.430000000000000000e+02 2.215481081698050247e-01 +5.440000000000000000e+02 2.205648506610304593e-01 +5.450000000000000000e+02 2.195923900788210870e-01 +5.460000000000000000e+02 2.186305566215963059e-01 +5.470000000000000000e+02 2.176791839771309856e-01 +5.480000000000000000e+02 2.167381092340651683e-01 +5.490000000000000000e+02 2.158071727960883812e-01 +5.500000000000000000e+02 2.148862182987025804e-01 +5.510000000000000000e+02 2.139750925284588934e-01 +5.520000000000000000e+02 2.130736453445966627e-01 +5.530000000000000000e+02 2.121817296029893107e-01 +5.540000000000000000e+02 2.112992010823303290e-01 +5.550000000000000000e+02 2.104259184124893378e-01 +5.560000000000000000e+02 2.095617430049387386e-01 +5.570000000000000000e+02 2.087065389851995578e-01 +5.580000000000000000e+02 2.078601731272430586e-01 +5.590000000000000000e+02 2.070225147897792883e-01 +5.600000000000000000e+02 2.061934358543501267e-01 +5.610000000000000000e+02 2.053728106651965257e-01 +5.620000000000000000e+02 2.045605159708350496e-01 +5.630000000000000000e+02 2.037564308672568936e-01 +5.640000000000000000e+02 2.029604367427501888e-01 +5.650000000000000000e+02 2.021724172242450324e-01 +5.660000000000000000e+02 2.013922581251551547e-01 +5.670000000000000000e+02 2.006198473946657068e-01 +5.680000000000000000e+02 1.998550750684219834e-01 +5.690000000000000000e+02 1.990978332205584067e-01 +5.700000000000000000e+02 1.983480159170575297e-01 +5.710000000000000000e+02 1.976055191703548763e-01 +5.720000000000000000e+02 1.968702408951988336e-01 +5.730000000000000000e+02 1.961420808656780257e-01 +5.740000000000000000e+02 1.954209406734079835e-01 +5.750000000000000000e+02 1.947067236868569029e-01 +5.760000000000000000e+02 1.939993350117119320e-01 +5.770000000000000000e+02 1.932986814523377783e-01 +5.780000000000000000e+02 1.926046714742234711e-01 +5.790000000000000000e+02 1.919172151674372051e-01 +5.800000000000000000e+02 1.912362242110131616e-01 +5.810000000000000000e+02 1.905616118382887636e-01 +5.820000000000000000e+02 1.898932928031310807e-01 +5.830000000000000000e+02 1.892311833470363136e-01 +5.840000000000000000e+02 1.885752011670716044e-01 +5.850000000000000000e+02 1.879252653846457122e-01 +5.860000000000000000e+02 1.872812965150760511e-01 +5.870000000000000000e+02 1.866432164379183967e-01 +5.880000000000000000e+02 1.860109483680665587e-01 +5.890000000000000000e+02 1.853844168275569360e-01 +5.900000000000000000e+02 1.847635476180971847e-01 +5.910000000000000000e+02 1.841482677942816726e-01 +5.920000000000000000e+02 1.835385056374631840e-01 +5.930000000000000000e+02 1.829341906302785481e-01 +5.940000000000000000e+02 1.823352534318061768e-01 +5.950000000000000000e+02 1.817416258533297857e-01 +5.960000000000000000e+02 1.811532408346978318e-01 +5.970000000000000000e+02 1.805700324212591579e-01 +5.980000000000000000e+02 1.799919357413592436e-01 +5.990000000000000000e+02 1.794188869843861001e-01 +6.000000000000000000e+02 1.788508233793334734e-01 +6.010000000000000000e+02 1.782876831738952061e-01 +6.020000000000000000e+02 1.777294056140400202e-01 +6.030000000000000000e+02 1.771759309240992508e-01 +6.040000000000000000e+02 1.766272002873004454e-01 +6.050000000000000000e+02 1.760831558267779151e-01 +6.060000000000000000e+02 1.755437405870247658e-01 +6.070000000000000000e+02 1.750088985157867705e-01 +6.080000000000000000e+02 1.744785744463652200e-01 +6.090000000000000000e+02 1.739527140803479033e-01 +6.100000000000000000e+02 1.734312639707359660e-01 +6.110000000000000000e+02 1.729141715054524908e-01 +6.120000000000000000e+02 1.724013848912429314e-01 +6.130000000000000000e+02 1.718928531379365077e-01 +6.140000000000000000e+02 1.713885260430728641e-01 +6.150000000000000000e+02 1.708883541768713155e-01 +6.160000000000000000e+02 1.703922888675559466e-01 +6.170000000000000000e+02 1.699002821869912694e-01 +6.180000000000000000e+02 1.694122869327407965e-01 +6.190000000000000000e+02 1.689282566300690513e-01 +6.200000000000000000e+02 1.684481454948997536e-01 +6.210000000000000000e+02 1.679719084364943438e-01 +6.220000000000000000e+02 1.674995010406903351e-01 +6.230000000000000000e+02 1.670308795573495486e-01 +6.240000000000000000e+02 1.665660008881131304e-01 +6.250000000000000000e+02 1.661048225780647480e-01 +6.260000000000000000e+02 1.656473027893393124e-01 +6.270000000000000000e+02 1.651934003117023764e-01 +6.280000000000000000e+02 1.647430745365915661e-01 +6.290000000000000000e+02 1.642962854498361824e-01 +6.300000000000000000e+02 1.638529936209065230e-01 +6.310000000000000000e+02 1.634131601924124211e-01 +6.320000000000000000e+02 1.629767468698088140e-01 +6.330000000000000000e+02 1.625437159113371777e-01 +6.340000000000000000e+02 1.621140301181689392e-01 +6.350000000000000000e+02 1.616876528247640776e-01 +6.360000000000000000e+02 1.612645478894360052e-01 +6.370000000000000000e+02 1.608446796851005223e-01 +6.380000000000000000e+02 1.604280130902416557e-01 +6.390000000000000000e+02 1.600145134800477209e-01 +6.400000000000000000e+02 1.596041467177388706e-01 +6.410000000000000000e+02 1.591968791460780797e-01 +6.420000000000000000e+02 1.587926775790517164e-01 +6.430000000000000000e+02 1.583915092937226710e-01 +6.440000000000000000e+02 1.579933420222590090e-01 +6.450000000000000000e+02 1.575981439441165310e-01 +6.460000000000000000e+02 1.572058836783820635e-01 +6.470000000000000000e+02 1.568165302762816182e-01 +6.480000000000000000e+02 1.564300532138251931e-01 +6.490000000000000000e+02 1.560464223846183274e-01 +6.500000000000000000e+02 1.556656080928031649e-01 +6.510000000000000000e+02 1.552875810461513129e-01 +6.520000000000000000e+02 1.549123123492880394e-01 +6.530000000000000000e+02 1.545397734970589687e-01 +6.540000000000000000e+02 1.541699363680217316e-01 +6.550000000000000000e+02 1.538027732180725360e-01 +6.560000000000000000e+02 1.534382566741944176e-01 +6.570000000000000000e+02 1.530763597283312238e-01 +6.580000000000000000e+02 1.527170557313814181e-01 +6.590000000000000000e+02 1.523603183873068756e-01 +6.600000000000000000e+02 1.520061217473642479e-01 +6.610000000000000000e+02 1.516544402044379403e-01 +6.620000000000000000e+02 1.513052484874901904e-01 +6.630000000000000000e+02 1.509585216561210863e-01 +6.640000000000000000e+02 1.506142350952191233e-01 +6.650000000000000000e+02 1.502723645097387428e-01 +6.660000000000000000e+02 1.499328859195498964e-01 +6.670000000000000000e+02 1.495957756544075978e-01 +6.680000000000000000e+02 1.492610103490070728e-01 +6.690000000000000000e+02 1.489285669381387178e-01 +6.700000000000000000e+02 1.485984226519232176e-01 +6.710000000000000000e+02 1.482705550111535764e-01 +6.720000000000000000e+02 1.479449418227091750e-01 +6.730000000000000000e+02 1.476215611750666401e-01 +6.740000000000000000e+02 1.473003914338844866e-01 +6.750000000000000000e+02 1.469814112376836013e-01 +6.760000000000000000e+02 1.466645994935932562e-01 +6.770000000000000000e+02 1.463499353731858577e-01 +6.780000000000000000e+02 1.460373983083859128e-01 +6.790000000000000000e+02 1.457269679874542700e-01 +6.800000000000000000e+02 1.454186243510426635e-01 +6.810000000000000000e+02 1.451123475883279446e-01 +6.820000000000000000e+02 1.448081181332075973e-01 +6.830000000000000000e+02 1.445059166605739132e-01 +6.840000000000000000e+02 1.442057240826498110e-01 +6.850000000000000000e+02 1.439075215453885781e-01 +6.860000000000000000e+02 1.436112904249498001e-01 +6.870000000000000000e+02 1.433170123242230032e-01 +6.880000000000000000e+02 1.430246690694271516e-01 +6.890000000000000000e+02 1.427342427067628816e-01 +6.900000000000000000e+02 1.424457154991290164e-01 +6.910000000000000000e+02 1.421590699228942323e-01 +6.920000000000000000e+02 1.418742886647256507e-01 +6.930000000000000000e+02 1.415913546184777716e-01 +6.940000000000000000e+02 1.413102508821314218e-01 +6.950000000000000000e+02 1.410309607547904909e-01 +6.960000000000000000e+02 1.407534677337269335e-01 +6.970000000000000000e+02 1.404777555114792575e-01 +6.980000000000000000e+02 1.402038079730074938e-01 +6.990000000000000000e+02 1.399316091928840544e-01 +7.000000000000000000e+02 1.396611434325464030e-01 +7.010000000000000000e+02 1.393923951375929393e-01 +7.020000000000000000e+02 1.391253489351197969e-01 +7.030000000000000000e+02 1.388599896311129567e-01 +7.040000000000000000e+02 1.385963022078772755e-01 +7.050000000000000000e+02 1.383342718215153366e-01 +7.060000000000000000e+02 1.380738837994411883e-01 +7.070000000000000000e+02 1.378151236379476507e-01 +7.080000000000000000e+02 1.375579769998042379e-01 +7.090000000000000000e+02 1.373024297119013193e-01 +7.100000000000000000e+02 1.370484677629346948e-01 +7.110000000000000000e+02 1.367960773011219489e-01 +7.120000000000000000e+02 1.365452446319690427e-01 +7.130000000000000000e+02 1.362959562160615534e-01 +7.140000000000000000e+02 1.360481986669017929e-01 +7.150000000000000000e+02 1.358019587487767910e-01 +7.160000000000000000e+02 1.355572233746649147e-01 +7.170000000000000000e+02 1.353139796041763487e-01 +7.180000000000000000e+02 1.350722146415223590e-01 +7.190000000000000000e+02 1.348319158335284096e-01 +7.200000000000000000e+02 1.345930706676689015e-01 +7.210000000000000000e+02 1.343556667701437390e-01 +7.220000000000000000e+02 1.341196919039760183e-01 +7.230000000000000000e+02 1.338851339671501273e-01 +7.240000000000000000e+02 1.336519809907758538e-01 +7.250000000000000000e+02 1.334202211372801095e-01 +7.260000000000000000e+02 1.331898426986330708e-01 +7.270000000000000000e+02 1.329608340945988842e-01 +7.280000000000000000e+02 1.327331838710129885e-01 +7.290000000000000000e+02 1.325068806980934932e-01 +7.300000000000000000e+02 1.322819133687746507e-01 +7.310000000000000000e+02 1.320582707970656966e-01 +7.320000000000000000e+02 1.318359420164408602e-01 +7.330000000000000000e+02 1.316149161782498300e-01 +7.340000000000000000e+02 1.313951825501568083e-01 +7.350000000000000000e+02 1.311767305146015750e-01 +7.360000000000000000e+02 1.309595495672881138e-01 +7.370000000000000000e+02 1.307436293156920282e-01 +7.380000000000000000e+02 1.305289594775963513e-01 +7.390000000000000000e+02 1.303155298796469241e-01 +7.400000000000000000e+02 1.301033304559337800e-01 +7.410000000000000000e+02 1.298923512465875452e-01 +7.420000000000000000e+02 1.296825823964058988e-01 +7.430000000000000000e+02 1.294740141534961309e-01 +7.440000000000000000e+02 1.292666368679408484e-01 +7.450000000000000000e+02 1.290604409904832495e-01 +7.460000000000000000e+02 1.288554170712293556e-01 +7.470000000000000000e+02 1.286515557583814418e-01 +7.480000000000000000e+02 1.284488477969719933e-01 +7.490000000000000000e+02 1.282472840276382975e-01 +7.500000000000000000e+02 1.280468553853977565e-01 +7.510000000000000000e+02 1.278475528984504006e-01 +7.520000000000000000e+02 1.276493676870031346e-01 +7.530000000000000000e+02 1.274522909620988409e-01 +7.540000000000000000e+02 1.272563140244766244e-01 +7.550000000000000000e+02 1.270614282634428271e-01 +7.560000000000000000e+02 1.268676251557571411e-01 +7.570000000000000000e+02 1.266748962645403709e-01 +7.580000000000000000e+02 1.264832332381947422e-01 +7.590000000000000000e+02 1.262926278093404187e-01 +7.600000000000000000e+02 1.261030717937726697e-01 +7.610000000000000000e+02 1.259145570894250887e-01 +7.620000000000000000e+02 1.257270756753579577e-01 +7.630000000000000000e+02 1.255406196107561601e-01 +7.640000000000000000e+02 1.253551810339402772e-01 +7.650000000000000000e+02 1.251707521613982521e-01 +7.660000000000000000e+02 1.249873252868249629e-01 +7.670000000000000000e+02 1.248048927801794217e-01 +7.680000000000000000e+02 1.246234470867560867e-01 +7.690000000000000000e+02 1.244429807262655008e-01 +7.700000000000000000e+02 1.242634862919330951e-01 +7.710000000000000000e+02 1.240849564496079721e-01 +7.720000000000000000e+02 1.239073839368848573e-01 +7.730000000000000000e+02 1.237307615622426638e-01 +7.740000000000000000e+02 1.235550822041861507e-01 +7.750000000000000000e+02 1.233803388104123683e-01 +7.760000000000000000e+02 1.232065243969757695e-01 +7.770000000000000000e+02 1.230336320474778866e-01 +7.780000000000000000e+02 1.228616549122588664e-01 +7.790000000000000000e+02 1.226905862076028975e-01 +7.800000000000000000e+02 1.225204192149613597e-01 +7.810000000000000000e+02 1.223511472801756955e-01 +7.820000000000000000e+02 1.221827638127192250e-01 +7.830000000000000000e+02 1.220152622849496882e-01 +7.840000000000000000e+02 1.218486362313675742e-01 +7.850000000000000000e+02 1.216828792478871629e-01 +7.860000000000000000e+02 1.215179849911195015e-01 +7.870000000000000000e+02 1.213539471776616668e-01 +7.880000000000000000e+02 1.211907595834011836e-01 +7.890000000000000000e+02 1.210284160428230921e-01 +7.900000000000000000e+02 1.208669104483324902e-01 +7.910000000000000000e+02 1.207062367495855132e-01 +7.920000000000000000e+02 1.205463889528254201e-01 +7.930000000000000000e+02 1.203873611202309762e-01 +7.940000000000000000e+02 1.202291473692762708e-01 +7.950000000000000000e+02 1.200717418720945312e-01 +7.960000000000000000e+02 1.199151388548524572e-01 +7.970000000000000000e+02 1.197593325971329642e-01 +7.980000000000000000e+02 1.196043174313280305e-01 +7.990000000000000000e+02 1.194500877420371365e-01 +8.000000000000000000e+02 1.192966379654748221e-01 +8.010000000000000000e+02 1.191439625888867371e-01 +8.020000000000000000e+02 1.189920561499727136e-01 +8.030000000000000000e+02 1.188409132363200532e-01 +8.040000000000000000e+02 1.186905284848396303e-01 +8.050000000000000000e+02 1.185408965812142501e-01 +8.060000000000000000e+02 1.183920122593514201e-01 +8.070000000000000000e+02 1.182438703008451275e-01 +8.080000000000000000e+02 1.180964655344443059e-01 +8.090000000000000000e+02 1.179497928355271036e-01 +8.100000000000000000e+02 1.178038471255836162e-01 +8.110000000000000000e+02 1.176586233717062807e-01 +8.120000000000000000e+02 1.175141165860831421e-01 +8.130000000000000000e+02 1.173703218255024439e-01 +8.140000000000000000e+02 1.172272341908599247e-01 +8.150000000000000000e+02 1.170848488266762882e-01 +8.160000000000000000e+02 1.169431609206177669e-01 +8.170000000000000000e+02 1.168021657030236943e-01 +8.180000000000000000e+02 1.166618584464397534e-01 +8.190000000000000000e+02 1.165222344651619391e-01 +8.200000000000000000e+02 1.163832891147775356e-01 +8.210000000000000000e+02 1.162450177917229571e-01 +8.220000000000000000e+02 1.161074159328347594e-01 +8.230000000000000000e+02 1.159704790149192755e-01 +8.240000000000000000e+02 1.158342025543170895e-01 +8.250000000000000000e+02 1.156985821064803882e-01 +8.260000000000000000e+02 1.155636132655523951e-01 +8.270000000000000000e+02 1.154292916639526184e-01 +8.280000000000000000e+02 1.152956129719673040e-01 +8.290000000000000000e+02 1.151625728973443563e-01 +8.300000000000000000e+02 1.150301671848964896e-01 +8.310000000000000000e+02 1.148983916161063629e-01 +8.320000000000000000e+02 1.147672420087372941e-01 +8.330000000000000000e+02 1.146367142164489289e-01 +8.340000000000000000e+02 1.145068041284184601e-01 +8.350000000000000000e+02 1.143775076689678982e-01 +8.360000000000000000e+02 1.142488207971897735e-01 +8.370000000000000000e+02 1.141207395065878955e-01 +8.380000000000000000e+02 1.139932598247112433e-01 +8.390000000000000000e+02 1.138663778128013032e-01 +8.400000000000000000e+02 1.137400895654404193e-01 +8.410000000000000000e+02 1.136143912102010739e-01 +8.420000000000000000e+02 1.134892789073073532e-01 +8.430000000000000000e+02 1.133647488492936922e-01 +8.440000000000000000e+02 1.132407972606710028e-01 +8.450000000000000000e+02 1.131174203975956472e-01 +8.460000000000000000e+02 1.129946145475434344e-01 +8.470000000000000000e+02 1.128723760289872952e-01 +8.480000000000000000e+02 1.127507011910781759e-01 +8.490000000000000000e+02 1.126295864133319974e-01 +8.500000000000000000e+02 1.125090281053176683e-01 +8.510000000000000000e+02 1.123890227063491370e-01 +8.520000000000000000e+02 1.122695666851858121e-01 +8.530000000000000000e+02 1.121506565397278748e-01 +8.540000000000000000e+02 1.120322887967258041e-01 +8.550000000000000000e+02 1.119144600114834187e-01 +8.560000000000000000e+02 1.117971667675718705e-01 +8.570000000000000000e+02 1.116804056765431374e-01 +8.580000000000000000e+02 1.115641733776486511e-01 +8.590000000000000000e+02 1.114484665375603395e-01 +8.600000000000000000e+02 1.113332818500942789e-01 +8.610000000000000000e+02 1.112186160359419224e-01 +8.620000000000000000e+02 1.111044658423985948e-01 +8.630000000000000000e+02 1.109908280430981359e-01 +8.640000000000000000e+02 1.108776994377525110e-01 +8.650000000000000000e+02 1.107650768518904927e-01 +8.660000000000000000e+02 1.106529571366018511e-01 +8.670000000000000000e+02 1.105413371682854723e-01 +8.680000000000000000e+02 1.104302138483977264e-01 +8.690000000000000000e+02 1.103195841032066499e-01 +8.700000000000000000e+02 1.102094448835452545e-01 +8.710000000000000000e+02 1.100997931645726485e-01 +8.720000000000000000e+02 1.099906259455329660e-01 +8.730000000000000000e+02 1.098819402495228442e-01 +8.740000000000000000e+02 1.097737331232541552e-01 +8.750000000000000000e+02 1.096660016368270485e-01 +8.760000000000000000e+02 1.095587428834989135e-01 +8.770000000000000000e+02 1.094519539794629320e-01 +8.780000000000000000e+02 1.093456320636234935e-01 +8.790000000000000000e+02 1.092397742973746366e-01 +8.800000000000000000e+02 1.091343778643863588e-01 +8.810000000000000000e+02 1.090294399703874983e-01 +8.820000000000000000e+02 1.089249578432375659e-01 +8.830000000000000000e+02 1.088209287315776291e-01 +8.840000000000000000e+02 1.087173499063341653e-01 +8.850000000000000000e+02 1.086142186593721248e-01 +8.860000000000000000e+02 1.085115323035761581e-01 +8.870000000000000000e+02 1.084092881726523572e-01 +8.880000000000000000e+02 1.083074836209276387e-01 +8.890000000000000000e+02 1.082061160231549413e-01 +8.900000000000000000e+02 1.081051827743192001e-01 +8.910000000000000000e+02 1.080046812894456809e-01 +8.920000000000000000e+02 1.079046090034091465e-01 +8.930000000000000000e+02 1.078049633707496568e-01 +8.940000000000000000e+02 1.077057418654830817e-01 +8.950000000000000000e+02 1.076069419809209671e-01 +8.960000000000000000e+02 1.075085612294887083e-01 +8.970000000000000000e+02 1.074105971425451250e-01 +8.980000000000000000e+02 1.073130472702068655e-01 +8.990000000000000000e+02 1.072159091811721865e-01 +9.000000000000000000e+02 1.071191804625478694e-01 +9.010000000000000000e+02 1.070228587196792314e-01 +9.020000000000000000e+02 1.069269415759781655e-01 +9.030000000000000000e+02 1.068314266727576206e-01 +9.040000000000000000e+02 1.067363116690653729e-01 +9.050000000000000000e+02 1.066415942412631268e-01 +9.060000000000000000e+02 1.065472720838922943e-01 +9.070000000000000000e+02 1.064533429079696780e-01 +9.080000000000000000e+02 1.063598044418610777e-01 +9.090000000000000000e+02 1.062666544308643601e-01 +9.100000000000000000e+02 1.061738906370554847e-01 +9.110000000000000000e+02 1.060815108391354733e-01 +9.120000000000000000e+02 1.059895128322759505e-01 +9.130000000000000000e+02 1.058978944279736767e-01 +9.140000000000000000e+02 1.058066534538970177e-01 +9.150000000000000000e+02 1.057157877537720642e-01 +9.160000000000000000e+02 1.056252951871196888e-01 +9.170000000000000000e+02 1.055351736292845094e-01 +9.180000000000000000e+02 1.054454209711796486e-01 +9.190000000000000000e+02 1.053560351191724920e-01 +9.200000000000000000e+02 1.052670139949458822e-01 +9.210000000000000000e+02 1.051783555353630745e-01 +9.220000000000000000e+02 1.050900576923273072e-01 +9.230000000000000000e+02 1.050021184326503237e-01 +9.240000000000000000e+02 1.049145357379177579e-01 +9.250000000000000000e+02 1.048273076043576002e-01 +9.260000000000000000e+02 1.047404320427089558e-01 +9.270000000000000000e+02 1.046539070780948544e-01 +9.280000000000000000e+02 1.045677307498916603e-01 +9.290000000000000000e+02 1.044819011116046165e-01 +9.300000000000000000e+02 1.043964162307423199e-01 +9.310000000000000000e+02 1.043112741886936951e-01 +9.320000000000000000e+02 1.042264730806031631e-01 +9.330000000000000000e+02 1.041420110152528333e-01 +9.340000000000000000e+02 1.040578861149396989e-01 +9.350000000000000000e+02 1.039740965153587438e-01 +9.360000000000000000e+02 1.038906403654842880e-01 +9.370000000000000000e+02 1.038075158274544413e-01 +9.380000000000000000e+02 1.037247210764563748e-01 +9.390000000000000000e+02 1.036422543006128294e-01 +9.400000000000000000e+02 1.035601137008684558e-01 +9.410000000000000000e+02 1.034782974908774050e-01 +9.420000000000000000e+02 1.033968038968962194e-01 +9.430000000000000000e+02 1.033156311576721997e-01 +9.440000000000000000e+02 1.032347775243368515e-01 +9.450000000000000000e+02 1.031542412602959174e-01 +9.460000000000000000e+02 1.030740206411278059e-01 +9.470000000000000000e+02 1.029941139544764545e-01 +9.480000000000000000e+02 1.029145194999470103e-01 +9.490000000000000000e+02 1.028352355890054526e-01 +9.500000000000000000e+02 1.027562605448749944e-01 +9.510000000000000000e+02 1.026775927024359963e-01 +9.520000000000000000e+02 1.025992304081275036e-01 +9.530000000000000000e+02 1.025211720198473675e-01 +9.540000000000000000e+02 1.024434159068554478e-01 +9.550000000000000000e+02 1.023659604496773429e-01 +9.560000000000000000e+02 1.022888040400074389e-01 +9.570000000000000000e+02 1.022119450806165536e-01 +9.580000000000000000e+02 1.021353819852564293e-01 +9.590000000000000000e+02 1.020591131785672651e-01 +9.600000000000000000e+02 1.019831370959872197e-01 +9.610000000000000000e+02 1.019074521836598052e-01 +9.620000000000000000e+02 1.018320568983454300e-01 +9.630000000000000000e+02 1.017569497073313456e-01 +9.640000000000000000e+02 1.016821290883440504e-01 +9.650000000000000000e+02 1.016075935294612625e-01 +9.660000000000000000e+02 1.015333415290277097e-01 +9.670000000000000000e+02 1.014593715955653813e-01 +9.680000000000000000e+02 1.013856822476930375e-01 +9.690000000000000000e+02 1.013122720140201410e-01 +9.700000000000000000e+02 1.012391394331452615e-01 +9.710000000000000000e+02 1.011662830534516694e-01 +9.720000000000000000e+02 1.010937014331071138e-01 +9.730000000000000000e+02 1.010213931399633475e-01 +9.740000000000000000e+02 1.009493567514772594e-01 +9.750000000000000000e+02 1.008775908546286626e-01 +9.760000000000000000e+02 1.008060940458452709e-01 +9.770000000000000000e+02 1.007348649309243033e-01 +9.780000000000000000e+02 1.006639021249550736e-01 +9.790000000000000000e+02 1.005932042522420106e-01 +9.800000000000000000e+02 1.005227699462338670e-01 +9.810000000000000000e+02 1.004525978494415217e-01 +9.820000000000000000e+02 1.003826866133728235e-01 +9.830000000000000000e+02 1.003130348984518083e-01 +9.840000000000000000e+02 1.002436413739527382e-01 +9.850000000000000000e+02 1.001745047179232184e-01 +9.860000000000000000e+02 1.001056236171166819e-01 +9.870000000000000000e+02 1.000369967669191423e-01 +9.880000000000000000e+02 9.996862287128351066e-02 +9.890000000000000000e+02 9.990050064265547369e-02 +9.900000000000000000e+02 9.983262880191028088e-02 +9.910000000000000000e+02 9.976500607828095446e-02 +9.920000000000000000e+02 9.969763120929471534e-02 +9.930000000000000000e+02 9.963050294070267821e-02 +9.940000000000000000e+02 9.956362002641817865e-02 +9.950000000000000000e+02 9.949698122844877202e-02 +9.960000000000000000e+02 9.943058531683274248e-02 +9.970000000000000000e+02 9.936443106957509874e-02 +9.980000000000000000e+02 9.929851727258422189e-02 +9.990000000000000000e+02 9.923284271960974845e-02 +1.000000000000000000e+03 9.916740621217899621e-02 +1.001000000000000000e+03 9.910220655953728974e-02 +1.002000000000000000e+03 9.903724257858496915e-02 +1.003000000000000000e+03 9.897251309381864537e-02 +1.004000000000000000e+03 9.890801693727123423e-02 +1.005000000000000000e+03 9.884375294845113014e-02 +1.006000000000000000e+03 9.877971997428584838e-02 +1.007000000000000000e+03 9.871591686906150409e-02 +1.008000000000000000e+03 9.865234249436775904e-02 +1.009000000000000000e+03 9.858899571903689818e-02 +1.010000000000000000e+03 9.852587541909232915e-02 +1.011000000000000000e+03 9.846298047768844985e-02 +1.012000000000000000e+03 9.840030978505587278e-02 +1.013000000000000000e+03 9.833786223844970253e-02 +1.014000000000000000e+03 9.827563674208952826e-02 +1.015000000000000000e+03 9.821363220711037956e-02 +1.016000000000000000e+03 9.815184755150596629e-02 +1.017000000000000000e+03 9.809028170007774716e-02 +1.018000000000000000e+03 9.802893358438080629e-02 +1.019000000000000000e+03 9.796780214267399034e-02 +1.020000000000000000e+03 9.790688631986518842e-02 +1.021000000000000000e+03 9.784618506746343980e-02 +1.022000000000000000e+03 9.778569734352539344e-02 +1.023000000000000000e+03 9.772542211260881739e-02 +1.024000000000000000e+03 9.766535834571860031e-02 +1.025000000000000000e+03 9.760550502025987230e-02 +1.026000000000000000e+03 9.754586111999025144e-02 +1.027000000000000000e+03 9.748642563496903723e-02 +1.028000000000000000e+03 9.742719756151034527e-02 +1.029000000000000000e+03 9.736817590213657503e-02 +1.030000000000000000e+03 9.730935966552922700e-02 +1.031000000000000000e+03 9.725074786648370273e-02 +1.032000000000000000e+03 9.719233952586391057e-02 +1.033000000000000000e+03 9.713413367055327707e-02 +1.034000000000000000e+03 9.707612933341415451e-02 +1.035000000000000000e+03 9.701832555323749996e-02 +1.036000000000000000e+03 9.696072137470201913e-02 +1.037000000000000000e+03 9.690331584832893863e-02 +1.038000000000000000e+03 9.684610803043765259e-02 +1.039000000000000000e+03 9.678909698310296517e-02 +1.040000000000000000e+03 9.673228177411240247e-02 +1.041000000000000000e+03 9.667566147692130407e-02 +1.042000000000000000e+03 9.661923517061399291e-02 +1.043000000000000000e+03 9.656300193985919988e-02 +1.044000000000000000e+03 9.650696087487044272e-02 +1.045000000000000000e+03 9.645111107136196404e-02 +1.046000000000000000e+03 9.639545163051180254e-02 +1.047000000000000000e+03 9.633998165891942411e-02 +1.048000000000000000e+03 9.628470026856368602e-02 +1.049000000000000000e+03 9.622960657676665752e-02 +1.050000000000000000e+03 9.617469970615269426e-02 +1.051000000000000000e+03 9.611997878460853961e-02 +1.052000000000000000e+03 9.606544294524586858e-02 +1.053000000000000000e+03 9.601109132636267973e-02 +1.054000000000000000e+03 9.595692307140524235e-02 +1.055000000000000000e+03 9.590293732892923861e-02 +1.056000000000000000e+03 9.584913325256404215e-02 +1.057000000000000000e+03 9.579551000097519253e-02 +1.058000000000000000e+03 9.574206673782753585e-02 +1.059000000000000000e+03 9.568880263174839307e-02 +1.060000000000000000e+03 9.563571685629211616e-02 +1.061000000000000000e+03 9.558280858990413076e-02 +1.062000000000000000e+03 9.553007701588553391e-02 +1.063000000000000000e+03 9.547752132235758082e-02 +1.064000000000000000e+03 9.542514070222694877e-02 +1.065000000000000000e+03 9.537293435315112589e-02 +1.066000000000000000e+03 9.532090147750514608e-02 +1.067000000000000000e+03 9.526904128234559010e-02 +1.068000000000000000e+03 9.521735297937947151e-02 +1.069000000000000000e+03 9.516583578492819606e-02 +1.070000000000000000e+03 9.511448891989587873e-02 +1.071000000000000000e+03 9.506331160973686967e-02 +1.072000000000000000e+03 9.501230308442230876e-02 +1.073000000000000000e+03 9.496146257840799854e-02 +1.074000000000000000e+03 9.491078933060349831e-02 +1.075000000000000000e+03 9.486028258433819305e-02 +1.076000000000000000e+03 9.480994158733208055e-02 +1.077000000000000000e+03 9.475976559166374158e-02 +1.078000000000000000e+03 9.470975385373819888e-02 +1.079000000000000000e+03 9.465990563425860649e-02 +1.080000000000000000e+03 9.461022019819355366e-02 +1.081000000000000000e+03 9.456069681474867095e-02 +1.082000000000000000e+03 9.451133475733547451e-02 +1.083000000000000000e+03 9.446213330354294446e-02 +1.084000000000000000e+03 9.441309173510642472e-02 +1.085000000000000000e+03 9.436420933787949272e-02 +1.086000000000000000e+03 9.431548540180619000e-02 +1.087000000000000000e+03 9.426691922088922815e-02 +1.088000000000000000e+03 9.421851009316513370e-02 +1.089000000000000000e+03 9.417025732067331456e-02 +1.090000000000000000e+03 9.412216020942978933e-02 +1.091000000000000000e+03 9.407421806939772480e-02 +1.092000000000000000e+03 9.402643021446233096e-02 +1.093000000000000000e+03 9.397879596240130140e-02 +1.094000000000000000e+03 9.393131463485832056e-02 +1.095000000000000000e+03 9.388398555731815309e-02 +1.096000000000000000e+03 9.383680805907713973e-02 +1.097000000000000000e+03 9.378978147321842540e-02 +1.098000000000000000e+03 9.374290513658573021e-02 +1.099000000000000000e+03 9.369617838975655144e-02 diff --git a/spectractor/extractor/dispersers/holo4_003/ratio_order_3over2.txt b/spectractor/extractor/dispersers/holo4_003/ratio_order_3over2.txt index dda2e3d92..de6d05742 100644 --- a/spectractor/extractor/dispersers/holo4_003/ratio_order_3over2.txt +++ b/spectractor/extractor/dispersers/holo4_003/ratio_order_3over2.txt @@ -1,800 +1,800 @@ -3.000000000000000000e+02 6.509725923171346018e+00 -3.010000000000000000e+02 1.156983590235709514e+01 -3.020000000000000000e+02 2.065892767125739837e+01 -3.030000000000000000e+02 3.266384599854518456e+01 -3.040000000000000000e+02 3.688427015932408182e+01 -3.050000000000000000e+02 2.955846253730900131e+01 -3.060000000000000000e+02 2.086079963948771621e+01 -3.070000000000000000e+02 1.483391093997127363e+01 -3.080000000000000000e+02 1.101253581269824622e+01 -3.090000000000000000e+02 8.543345874672958473e+00 -3.100000000000000000e+02 6.879515790464199476e+00 -3.110000000000000000e+02 5.709608451523049411e+00 -3.120000000000000000e+02 4.855338801222115030e+00 -3.130000000000000000e+02 4.211091270164593503e+00 -3.140000000000000000e+02 3.711767709806035320e+00 -3.150000000000000000e+02 3.315685161054438446e+00 -3.160000000000000000e+02 2.995214546596440375e+00 -3.170000000000000000e+02 2.731470209997443721e+00 -3.180000000000000000e+02 2.511187170917052569e+00 -3.190000000000000000e+02 2.324821673858040505e+00 -3.200000000000000000e+02 2.165359445266830996e+00 -3.210000000000000000e+02 2.027546656272186887e+00 -3.220000000000000000e+02 1.907380888083412884e+00 -3.230000000000000000e+02 1.801766370524660932e+00 -3.240000000000000000e+02 1.708275577335355067e+00 -3.250000000000000000e+02 1.624981230221655082e+00 -3.260000000000000000e+02 1.550335869337169825e+00 -3.270000000000000000e+02 1.483084159928695689e+00 -3.280000000000000000e+02 1.422198114662133195e+00 -3.290000000000000000e+02 1.366828609434258768e+00 -3.300000000000000000e+02 1.316268651832293690e+00 -3.310000000000000000e+02 1.269925240112287579e+00 -3.320000000000000000e+02 1.227297578953946422e+00 -3.330000000000000000e+02 1.187960052992033333e+00 -3.340000000000000000e+02 1.151548799291647995e+00 -3.350000000000000000e+02 1.117751029224237636e+00 -3.360000000000000000e+02 1.086296470221350230e+00 -3.370000000000000000e+02 1.056950456212043310e+00 -3.380000000000000000e+02 1.029508310721562347e+00 -3.390000000000000000e+02 1.003790751240222878e+00 -3.400000000000000000e+02 9.796401062565228690e-01 -3.410000000000000000e+02 9.569171833460039522e-01 -3.420000000000000000e+02 9.354986621867263930e-01 -3.430000000000000000e+02 9.152749133711250984e-01 -3.440000000000000000e+02 8.961481645859491474e-01 -3.450000000000000000e+02 8.780309517196009939e-01 -3.460000000000000000e+02 8.608448048873430514e-01 -3.470000000000000000e+02 8.445191290942747342e-01 -3.480000000000000000e+02 8.289902469153803688e-01 -3.490000000000000000e+02 8.142005766414438517e-01 -3.500000000000000000e+02 8.000979241709312850e-01 -3.510000000000000000e+02 7.866348707990169498e-01 -3.520000000000000000e+02 7.737682421688460987e-01 -3.530000000000000000e+02 7.614586461696587483e-01 -3.540000000000000000e+02 7.496700696129982022e-01 -3.550000000000000000e+02 7.383695251887274491e-01 -3.560000000000000000e+02 7.275267415721883291e-01 -3.570000000000000000e+02 7.171138906805679669e-01 -3.580000000000000000e+02 7.071053470080953529e-01 -3.590000000000000000e+02 6.974774747419761889e-01 -3.600000000000000000e+02 6.882084390034897137e-01 -3.610000000000000000e+02 6.792780380986728206e-01 -3.620000000000000000e+02 6.706675541072550928e-01 -3.630000000000000000e+02 6.623596195251194585e-01 -3.640000000000000000e+02 6.543380979885390358e-01 -3.650000000000000000e+02 6.465879773821993082e-01 -3.660000000000000000e+02 6.390952738614180673e-01 -3.670000000000000000e+02 6.318469455143372882e-01 -3.680000000000000000e+02 6.248308145566628946e-01 -3.690000000000000000e+02 6.180354970939593295e-01 -3.700000000000000000e+02 6.114503396089747689e-01 -3.710000000000000000e+02 6.050653614366442445e-01 -3.720000000000000000e+02 5.988712025800647654e-01 -3.730000000000000000e+02 5.928590762992315133e-01 -3.740000000000000000e+02 5.870207259720922055e-01 -3.750000000000000000e+02 5.813483857864492066e-01 -3.760000000000000000e+02 5.758347448724864259e-01 -3.770000000000000000e+02 5.704729145303520932e-01 -3.780000000000000000e+02 5.652563982462379677e-01 -3.790000000000000000e+02 5.601790642245236818e-01 -3.800000000000000000e+02 5.552351201935545877e-01 -3.810000000000000000e+02 5.504190902687762232e-01 -3.820000000000000000e+02 5.457257936802333287e-01 -3.830000000000000000e+02 5.411503251916882640e-01 -3.840000000000000000e+02 5.366880370567861380e-01 -3.850000000000000000e+02 5.323345223733942921e-01 -3.860000000000000000e+02 5.280855997116135070e-01 -3.870000000000000000e+02 5.239372989032440309e-01 -3.880000000000000000e+02 5.198858478917152137e-01 -3.890000000000000000e+02 5.159276605514671044e-01 -3.900000000000000000e+02 5.120593253943732659e-01 -3.910000000000000000e+02 5.082775950889130145e-01 -3.920000000000000000e+02 5.045793767246775641e-01 -3.930000000000000000e+02 5.009617227611485868e-01 -3.940000000000000000e+02 4.974218226053315761e-01 -3.950000000000000000e+02 4.939569947679042228e-01 -3.960000000000000000e+02 4.905646795520252623e-01 -3.970000000000000000e+02 4.872424322331894153e-01 -3.980000000000000000e+02 4.839879166919889286e-01 -3.990000000000000000e+02 4.807988994651667958e-01 -4.000000000000000000e+02 4.776732441832539644e-01 -4.010000000000000000e+02 4.746089063657677465e-01 -4.020000000000000000e+02 4.716039285475141507e-01 -4.030000000000000000e+02 4.686564357116038138e-01 -4.040000000000000000e+02 4.657646310069922246e-01 -4.050000000000000000e+02 4.629267917299948465e-01 -4.060000000000000000e+02 4.601412655510689342e-01 -4.070000000000000000e+02 4.574064669695095398e-01 -4.080000000000000000e+02 4.547208739802010569e-01 -4.090000000000000000e+02 4.520830249377760790e-01 -4.100000000000000000e+02 4.494915156046404570e-01 -4.110000000000000000e+02 4.469449963704413276e-01 -4.120000000000000000e+02 4.444421696314884707e-01 -4.130000000000000000e+02 4.419817873194388791e-01 -4.140000000000000000e+02 4.395626485694713037e-01 -4.150000000000000000e+02 4.371835975188317347e-01 -4.160000000000000000e+02 4.348435212273337735e-01 -4.170000000000000000e+02 4.325413477119841033e-01 -4.180000000000000000e+02 4.302760440884981774e-01 -4.190000000000000000e+02 4.280466148130216975e-01 -4.200000000000000000e+02 4.258521000177492022e-01 -4.210000000000000000e+02 4.236915739346737708e-01 -4.220000000000000000e+02 4.215641434020956368e-01 -4.230000000000000000e+02 4.194689464488028929e-01 -4.240000000000000000e+02 4.174051509513057034e-01 -4.250000000000000000e+02 4.153719533597377556e-01 -4.260000000000000000e+02 4.133685774883759656e-01 -4.270000000000000000e+02 4.113942733669674334e-01 -4.280000000000000000e+02 4.094483161493540080e-01 -4.290000000000000000e+02 4.075300050760630177e-01 -4.300000000000000000e+02 4.056386624877854619e-01 -4.310000000000000000e+02 4.013912009558592842e-01 -4.320000000000000000e+02 3.971192247879613002e-01 -4.330000000000000000e+02 3.929431662759431121e-01 -4.340000000000000000e+02 3.887877778006299523e-01 -4.350000000000000000e+02 3.847991905271044843e-01 -4.360000000000000000e+02 3.808899497092754771e-01 -4.370000000000000000e+02 3.770321205610598914e-01 -4.380000000000000000e+02 3.732521381443776876e-01 -4.390000000000000000e+02 3.694158397025473217e-01 -4.400000000000000000e+02 3.656361642969984116e-01 -4.410000000000000000e+02 3.637041215579885356e-01 -4.420000000000000000e+02 3.618050021278039763e-01 -4.430000000000000000e+02 3.599573466274055278e-01 -4.440000000000000000e+02 3.581622953562234035e-01 -4.450000000000000000e+02 3.563475298726105911e-01 -4.460000000000000000e+02 3.546131012783114156e-01 -4.470000000000000000e+02 3.529171425161061748e-01 -4.480000000000000000e+02 3.511600645287158429e-01 -4.490000000000000000e+02 3.495001340366898912e-01 -4.500000000000000000e+02 3.478342642145098584e-01 -4.510000000000000000e+02 3.464230590325684256e-01 -4.520000000000000000e+02 3.448679466138410143e-01 -4.530000000000000000e+02 3.432877541094727092e-01 -4.540000000000000000e+02 3.419279637498306990e-01 -4.550000000000000000e+02 3.403899632567217726e-01 -4.560000000000000000e+02 3.388281057218366921e-01 -4.570000000000000000e+02 3.374509332583289223e-01 -4.580000000000000000e+02 3.360451544967197890e-01 -4.590000000000000000e+02 3.346336262677152562e-01 -4.600000000000000000e+02 3.331518803143234675e-01 -4.610000000000000000e+02 3.322999523736291372e-01 -4.620000000000000000e+02 3.314413399858454623e-01 -4.630000000000000000e+02 3.305725970739325503e-01 -4.640000000000000000e+02 3.297325016120075669e-01 -4.650000000000000000e+02 3.288405527362059932e-01 -4.660000000000000000e+02 3.280349124410171235e-01 -4.670000000000000000e+02 3.272181645157655749e-01 -4.680000000000000000e+02 3.264107816982220744e-01 -4.690000000000000000e+02 3.256138361259974801e-01 -4.700000000000000000e+02 3.248861836773703771e-01 -4.710000000000000000e+02 3.236703958241508583e-01 -4.720000000000000000e+02 3.224004875302849960e-01 -4.730000000000000000e+02 3.212142588947224375e-01 -4.740000000000000000e+02 3.201511185091803768e-01 -4.750000000000000000e+02 3.189554620501165449e-01 -4.760000000000000000e+02 3.178098233543905082e-01 -4.770000000000000000e+02 3.167221172560253373e-01 -4.780000000000000000e+02 3.157016581654958909e-01 -4.790000000000000000e+02 3.145593782471240440e-01 -4.800000000000000000e+02 3.134509493041701123e-01 -4.810000000000000000e+02 3.121425769791167926e-01 -4.820000000000000000e+02 3.108784129001939678e-01 -4.830000000000000000e+02 3.096797605619626692e-01 -4.840000000000000000e+02 3.085392244289119623e-01 -4.850000000000000000e+02 3.074820466880909264e-01 -4.860000000000000000e+02 3.064652653738632604e-01 -4.870000000000000000e+02 3.053357684427669416e-01 -4.880000000000000000e+02 3.043780287842099974e-01 -4.890000000000000000e+02 3.033467242744036785e-01 -4.900000000000000000e+02 3.023931681866862675e-01 -4.910000000000000000e+02 3.014207182671409524e-01 -4.920000000000000000e+02 3.004620052485332260e-01 -4.930000000000000000e+02 2.995395110481065548e-01 -4.940000000000000000e+02 2.986801932647105695e-01 -4.950000000000000000e+02 2.978709237690262412e-01 -4.960000000000000000e+02 2.970468427189997818e-01 -4.970000000000000000e+02 2.963053479931697654e-01 -4.980000000000000000e+02 2.955473664731924632e-01 -4.990000000000000000e+02 2.947567652016332418e-01 -5.000000000000000000e+02 2.941277613234809518e-01 -5.010000000000000000e+02 2.934817548728843040e-01 -5.020000000000000000e+02 2.928781479379820585e-01 -5.030000000000000000e+02 2.922706048624220676e-01 -5.040000000000000000e+02 2.916459244383286520e-01 -5.050000000000000000e+02 2.912236565535889499e-01 -5.060000000000000000e+02 2.907475290896360254e-01 -5.070000000000000000e+02 2.902677375099961266e-01 -5.080000000000000000e+02 2.897676634669539841e-01 -5.090000000000000000e+02 2.893731430640880120e-01 -5.100000000000000000e+02 2.889589445163627812e-01 -5.110000000000000000e+02 2.881700181111551684e-01 -5.120000000000000000e+02 2.873480520316719078e-01 -5.130000000000000000e+02 2.865151935771834135e-01 -5.140000000000000000e+02 2.856811667792410470e-01 -5.150000000000000000e+02 2.849473062224541775e-01 -5.160000000000000000e+02 2.840788906049899754e-01 -5.170000000000000000e+02 2.833928994179065741e-01 -5.180000000000000000e+02 2.827039766186793535e-01 -5.190000000000000000e+02 2.819754817033529593e-01 -5.200000000000000000e+02 2.812482993192523262e-01 -5.210000000000000000e+02 2.809187193137456240e-01 -5.220000000000000000e+02 2.806119449158293033e-01 -5.230000000000000000e+02 2.803365836900778563e-01 -5.240000000000000000e+02 2.800123081838547523e-01 -5.250000000000000000e+02 2.797458103743233893e-01 -5.260000000000000000e+02 2.795503012147202426e-01 -5.270000000000000000e+02 2.793651617083823813e-01 -5.280000000000000000e+02 2.791742447571493035e-01 -5.290000000000000000e+02 2.790152870372823446e-01 -5.300000000000000000e+02 2.787765316151872286e-01 -5.310000000000000000e+02 2.782614025891858578e-01 -5.320000000000000000e+02 2.777553322218797582e-01 -5.330000000000000000e+02 2.772724584393295721e-01 -5.340000000000000000e+02 2.767805116406394927e-01 -5.350000000000000000e+02 2.763191815102425952e-01 -5.360000000000000000e+02 2.758573178654324942e-01 -5.370000000000000000e+02 2.754049108370179577e-01 -5.380000000000000000e+02 2.749522072559143493e-01 -5.390000000000000000e+02 2.745113907245025353e-01 -5.400000000000000000e+02 2.740557320472344904e-01 -5.410000000000000000e+02 2.738357205008694062e-01 -5.420000000000000000e+02 2.736625084758002036e-01 -5.430000000000000000e+02 2.734110728475184771e-01 -5.440000000000000000e+02 2.731982861589927758e-01 -5.450000000000000000e+02 2.729718221333193306e-01 -5.460000000000000000e+02 2.728511995680704683e-01 -5.470000000000000000e+02 2.726255409409779062e-01 -5.480000000000000000e+02 2.725091758002506914e-01 -5.490000000000000000e+02 2.723876843379202661e-01 -5.500000000000000000e+02 2.722399028653252340e-01 -5.510000000000000000e+02 2.715911952691412168e-01 -5.520000000000000000e+02 2.709460720857740923e-01 -5.530000000000000000e+02 2.703044947435113143e-01 -5.540000000000000000e+02 2.696664253031139102e-01 -5.550000000000000000e+02 2.690318264447055796e-01 -5.560000000000000000e+02 2.684006614549652170e-01 -5.570000000000000000e+02 2.677728942146391788e-01 -5.580000000000000000e+02 2.671484891863595834e-01 -5.590000000000000000e+02 2.665274114027597063e-01 -5.600000000000000000e+02 2.659096264548642674e-01 -5.610000000000000000e+02 2.652951004807700963e-01 -5.620000000000000000e+02 2.646838001546008567e-01 -5.630000000000000000e+02 2.640756926757049650e-01 -5.640000000000000000e+02 2.634707457581375589e-01 -5.650000000000000000e+02 2.628689276203737268e-01 -5.660000000000000000e+02 2.622702069752671505e-01 -5.670000000000000000e+02 2.616745530202487235e-01 -5.680000000000000000e+02 2.610819354277570947e-01 -5.690000000000000000e+02 2.604923243358777674e-01 -5.700000000000000000e+02 2.599056903392269469e-01 -5.710000000000000000e+02 2.593220044800134683e-01 -5.720000000000000000e+02 2.587412382393369792e-01 -5.730000000000000000e+02 2.581633635286694761e-01 -5.740000000000000000e+02 2.575883526815297420e-01 -5.750000000000000000e+02 2.570161784453716680e-01 -5.760000000000000000e+02 2.564468139736207908e-01 -5.770000000000000000e+02 2.558802328179256569e-01 -5.780000000000000000e+02 2.553164089205607334e-01 -5.790000000000000000e+02 2.547553166070181674e-01 -5.800000000000000000e+02 2.541969305787496469e-01 -5.810000000000000000e+02 2.536412259060807917e-01 -5.820000000000000000e+02 2.530881780567449391e-01 -5.830000000000000000e+02 2.525377627468738395e-01 -5.840000000000000000e+02 2.519899561483122663e-01 -5.850000000000000000e+02 2.514447347391092213e-01 -5.860000000000000000e+02 2.509020753330470366e-01 -5.870000000000000000e+02 2.503619550399095450e-01 -5.880000000000000000e+02 2.498243513939016058e-01 -5.890000000000000000e+02 2.492892421454347696e-01 -5.900000000000000000e+02 2.487566053905642949e-01 -5.910000000000000000e+02 2.482264195314022592e-01 -5.920000000000000000e+02 2.476986632705741043e-01 -5.930000000000000000e+02 2.471733156057744074e-01 -5.940000000000000000e+02 2.466503558244548810e-01 -5.950000000000000000e+02 2.461297634986228111e-01 -5.960000000000000000e+02 2.456115184797426632e-01 -5.970000000000000000e+02 2.450956008937515973e-01 -5.980000000000000000e+02 2.445819911361842014e-01 -5.990000000000000000e+02 2.440706698673940078e-01 -6.000000000000000000e+02 2.435616180078764292e-01 -6.010000000000000000e+02 2.430548167336908649e-01 -6.020000000000000000e+02 2.425502474719749280e-01 -6.030000000000000000e+02 2.420478918965666137e-01 -6.040000000000000000e+02 2.415477319236925824e-01 -6.050000000000000000e+02 2.410497497077650209e-01 -6.060000000000000000e+02 2.405539276372625490e-01 -6.070000000000000000e+02 2.400602483306865376e-01 -6.080000000000000000e+02 2.395686946326125166e-01 -6.090000000000000000e+02 2.390792496098067821e-01 -6.100000000000000000e+02 2.385918965474450038e-01 -6.110000000000000000e+02 2.381066189453825144e-01 -6.120000000000000000e+02 2.376234005145202166e-01 -6.130000000000000000e+02 2.371422251732272779e-01 -6.140000000000000000e+02 2.366630770438537534e-01 -6.150000000000000000e+02 2.361859404492911152e-01 -6.160000000000000000e+02 2.357107999096284823e-01 -6.170000000000000000e+02 2.352376401388481530e-01 -6.180000000000000000e+02 2.347664460416065690e-01 -6.190000000000000000e+02 2.342972027100732046e-01 -6.200000000000000000e+02 2.338298954208279934e-01 -6.210000000000000000e+02 2.333645096318186229e-01 -6.220000000000000000e+02 2.329010309793958511e-01 -6.230000000000000000e+02 2.324394452753779650e-01 -6.240000000000000000e+02 2.319797385041930393e-01 -6.250000000000000000e+02 2.315218968200772609e-01 -6.260000000000000000e+02 2.310659065443141091e-01 -6.270000000000000000e+02 2.306117541625375411e-01 -6.280000000000000000e+02 2.301594263220834435e-01 -6.290000000000000000e+02 2.297089098293993159e-01 -6.300000000000000000e+02 2.292601916474861501e-01 -6.310000000000000000e+02 2.288132588934114198e-01 -6.320000000000000000e+02 2.283680988358526565e-01 -6.330000000000000000e+02 2.279246988926959816e-01 -6.340000000000000000e+02 2.274830466286782149e-01 -6.350000000000000000e+02 2.270431297530706993e-01 -6.360000000000000000e+02 2.266049361174183041e-01 -6.370000000000000000e+02 2.261684537132997164e-01 -6.380000000000000000e+02 2.257336706701522644e-01 -6.390000000000000000e+02 2.253005752531235806e-01 -6.400000000000000000e+02 2.248691558609697549e-01 -6.410000000000000000e+02 2.244394010239880444e-01 -6.420000000000000000e+02 2.240112994019895776e-01 -6.430000000000000000e+02 2.235848397823104738e-01 -6.440000000000000000e+02 2.231600110778641233e-01 -6.450000000000000000e+02 2.227368023252197793e-01 -6.460000000000000000e+02 2.223152026827190930e-01 -6.470000000000000000e+02 2.218952014286380836e-01 -6.480000000000000000e+02 2.214767879593616262e-01 -6.490000000000000000e+02 2.210599517876132847e-01 -6.500000000000000000e+02 2.206446825407070711e-01 -6.510000000000000000e+02 2.202309699588207714e-01 -6.520000000000000000e+02 2.198188038933247268e-01 -6.530000000000000000e+02 2.194081743051159161e-01 -6.540000000000000000e+02 2.189990712630012493e-01 -6.550000000000000000e+02 2.185914849420922679e-01 -6.560000000000000000e+02 2.181854056222474192e-01 -6.570000000000000000e+02 2.177808236865258207e-01 -6.580000000000000000e+02 2.173777296196790776e-01 -6.590000000000000000e+02 2.169761140066586436e-01 -6.600000000000000000e+02 2.165759675311676735e-01 -6.610000000000000000e+02 2.161772809742177892e-01 -6.620000000000000000e+02 2.157800452127254520e-01 -6.630000000000000000e+02 2.153842512181299573e-01 -6.640000000000000000e+02 2.149898900550256398e-01 -6.650000000000000000e+02 2.145969528798400972e-01 -6.660000000000000000e+02 2.142054309395081124e-01 -6.670000000000000000e+02 2.138153155701894848e-01 -6.680000000000000000e+02 2.134265981959994340e-01 -6.690000000000000000e+02 2.130392703277668165e-01 -6.700000000000000000e+02 2.126533235618015827e-01 -6.710000000000000000e+02 2.122687495787007605e-01 -6.720000000000000000e+02 2.118855401421630702e-01 -6.730000000000000000e+02 2.115036870978229122e-01 -6.740000000000000000e+02 2.111231823721143319e-01 -6.750000000000000000e+02 2.107440179711427275e-01 -6.760000000000000000e+02 2.103661859795838140e-01 -6.770000000000000000e+02 2.099896785595972704e-01 -6.780000000000000000e+02 2.096144879497590652e-01 -6.790000000000000000e+02 2.092406064640178198e-01 -6.800000000000000000e+02 2.088680264906531692e-01 -6.810000000000000000e+02 2.084967404912727307e-01 -6.820000000000000000e+02 2.081267409998037721e-01 -6.830000000000000000e+02 2.077580206215242642e-01 -6.840000000000000000e+02 2.073905720320884938e-01 -6.850000000000000000e+02 2.070243879765835127e-01 -6.860000000000000000e+02 2.066594612685986321e-01 -6.870000000000000000e+02 2.062957847893023000e-01 -6.880000000000000000e+02 2.059333514865440695e-01 -6.890000000000000000e+02 2.055721543739636448e-01 -6.900000000000000000e+02 2.052121865301247128e-01 -6.910000000000000000e+02 2.048534410976490527e-01 -6.920000000000000000e+02 2.044959112823747094e-01 -6.930000000000000000e+02 2.041395903525253519e-01 -6.940000000000000000e+02 2.037844716378908461e-01 -6.950000000000000000e+02 2.034305485290265891e-01 -6.960000000000000000e+02 2.030778144764594784e-01 -6.970000000000000000e+02 2.027262629899092006e-01 -6.980000000000000000e+02 2.023758876375233162e-01 -6.990000000000000000e+02 2.020266820451206424e-01 -7.000000000000000000e+02 2.016786398954537873e-01 -7.010000000000000000e+02 2.013317549274782348e-01 -7.020000000000000000e+02 2.009860209356282568e-01 -7.030000000000000000e+02 2.006414317691171401e-01 -7.040000000000000000e+02 2.002979813312388280e-01 -7.050000000000000000e+02 1.999556635786803871e-01 -7.060000000000000000e+02 1.996144725208495729e-01 -7.070000000000000000e+02 1.992744022192144138e-01 -7.080000000000000000e+02 1.989354467866432108e-01 -7.090000000000000000e+02 1.985976003867695738e-01 -7.100000000000000000e+02 1.982608572333535712e-01 -7.110000000000000000e+02 1.979252115896589503e-01 -7.120000000000000000e+02 1.975906577678417098e-01 -7.130000000000000000e+02 1.972571901283477480e-01 -7.140000000000000000e+02 1.969248030793145365e-01 -7.150000000000000000e+02 1.965934910759837284e-01 -7.160000000000000000e+02 1.962632486266521481e-01 -7.170000000000000000e+02 1.959340702659196076e-01 -7.180000000000000000e+02 1.956059505935459353e-01 -7.190000000000000000e+02 1.952788842475245701e-01 -7.200000000000000000e+02 1.949528659101645856e-01 -7.210000000000000000e+02 1.946278903075495947e-01 -7.220000000000000000e+02 1.943039522090126980e-01 -7.230000000000000000e+02 1.939810464266206180e-01 -7.240000000000000000e+02 1.936591678146649953e-01 -7.250000000000000000e+02 1.933383112691586525e-01 -7.260000000000000000e+02 1.930184717273383255e-01 -7.270000000000000000e+02 1.926996441671788018e-01 -7.280000000000000000e+02 1.923818236069127496e-01 -7.290000000000000000e+02 1.920650051045573736e-01 -7.300000000000000000e+02 1.917491837574481495e-01 -7.310000000000000000e+02 1.914343547017823277e-01 -7.320000000000000000e+02 1.911205131121570255e-01 -7.330000000000000000e+02 1.908076542011389876e-01 -7.340000000000000000e+02 1.904957732188080066e-01 -7.350000000000000000e+02 1.901848654523400350e-01 -7.360000000000000000e+02 1.898749262255676751e-01 -7.370000000000000000e+02 1.895659508985683972e-01 -7.380000000000000000e+02 1.892579348672460138e-01 -7.390000000000000000e+02 1.889508735629232272e-01 -7.400000000000000000e+02 1.886447624519428656e-01 -7.410000000000000000e+02 1.883395970352690352e-01 -7.420000000000000000e+02 1.880353728480916031e-01 -7.430000000000000000e+02 1.877320854594486943e-01 -7.440000000000000000e+02 1.874297304676837694e-01 -7.450000000000000000e+02 1.871283035167833897e-01 -7.460000000000000000e+02 1.868278002708305685e-01 -7.470000000000000000e+02 1.865282164305049062e-01 -7.480000000000000000e+02 1.862295477284785505e-01 -7.490000000000000000e+02 1.859317899290809373e-01 -7.500000000000000000e+02 1.856349388279329160e-01 -7.510000000000000000e+02 1.853389902516112964e-01 -7.520000000000000000e+02 1.850439400573179460e-01 -7.530000000000000000e+02 1.847497841325274892e-01 -7.540000000000000000e+02 1.844565183946765274e-01 -7.550000000000000000e+02 1.841641387908259930e-01 -7.560000000000000000e+02 1.838726412973519520e-01 -7.570000000000000000e+02 1.835820219196187264e-01 -7.580000000000000000e+02 1.832922766916768587e-01 -7.590000000000000000e+02 1.830034016759543858e-01 -7.600000000000000000e+02 1.827153929629482532e-01 -7.610000000000000000e+02 1.824282466709342965e-01 -7.620000000000000000e+02 1.821419589456655663e-01 -7.630000000000000000e+02 1.818565259600903039e-01 -7.640000000000000000e+02 1.815719439140544011e-01 -7.650000000000000000e+02 1.812882090340306451e-01 -7.660000000000000000e+02 1.810053175728312536e-01 -7.670000000000000000e+02 1.807232658093354816e-01 -7.680000000000000000e+02 1.804420500482230294e-01 -7.690000000000000000e+02 1.801616666197011218e-01 -7.700000000000000000e+02 1.798821118792424678e-01 -7.710000000000000000e+02 1.796033822073268282e-01 -7.720000000000000000e+02 1.793254740091770050e-01 -7.730000000000000000e+02 1.790483837145204760e-01 -7.740000000000000000e+02 1.787721077773175293e-01 -7.750000000000000000e+02 1.784966426755400792e-01 -7.760000000000000000e+02 1.782219849109021037e-01 -7.770000000000000000e+02 1.779481310086448720e-01 -7.780000000000000000e+02 1.776750775172805386e-01 -7.790000000000000000e+02 1.774028210083636037e-01 -7.800000000000000000e+02 1.771313580762706452e-01 -7.810000000000000000e+02 1.768606853379534605e-01 -7.820000000000000000e+02 1.765907994327330643e-01 -7.830000000000000000e+02 1.763216970220653768e-01 -7.840000000000000000e+02 1.760533747893261169e-01 -7.850000000000000000e+02 1.757858294395991117e-01 -7.860000000000000000e+02 1.755190576994557772e-01 -7.870000000000000000e+02 1.752530563167477573e-01 -7.880000000000000000e+02 1.749878220603999501e-01 -7.890000000000000000e+02 1.747233517202063102e-01 -7.900000000000000000e+02 1.744596421066213210e-01 -7.910000000000000000e+02 1.741966900505709792e-01 -7.920000000000000000e+02 1.739344924032440176e-01 -7.930000000000000000e+02 1.736730460359040829e-01 -7.940000000000000000e+02 1.734123478396928930e-01 -7.950000000000000000e+02 1.731523947254474949e-01 -7.960000000000000000e+02 1.728931836235040598e-01 -7.970000000000000000e+02 1.726347114835185270e-01 -7.980000000000000000e+02 1.723769752742830286e-01 -7.990000000000000000e+02 1.721199719835446451e-01 -8.000000000000000000e+02 1.718636986178233017e-01 -8.010000000000000000e+02 1.716081522022455674e-01 -8.020000000000000000e+02 1.713533297803551958e-01 -8.030000000000000000e+02 1.710992284139661035e-01 -8.040000000000000000e+02 1.708458451829648339e-01 -8.050000000000000000e+02 1.705931771851603995e-01 -8.060000000000000000e+02 1.703412215361158055e-01 -8.070000000000000000e+02 1.700899753689843197e-01 -8.080000000000000000e+02 1.698394358343452148e-01 -8.090000000000000000e+02 1.695896001000487541e-01 -8.100000000000000000e+02 1.693404653510564017e-01 -8.110000000000000000e+02 1.690920287892863638e-01 -8.120000000000000000e+02 1.688442876334581011e-01 -8.130000000000000000e+02 1.685972391189455299e-01 -8.140000000000000000e+02 1.683508804976205087e-01 -8.150000000000000000e+02 1.681052090377070374e-01 -8.160000000000000000e+02 1.678602220236431464e-01 -8.170000000000000000e+02 1.676159167559223562e-01 -8.180000000000000000e+02 1.673722905509618664e-01 -8.190000000000000000e+02 1.671293407409534248e-01 -8.200000000000000000e+02 1.668870646737345698e-01 -8.210000000000000000e+02 1.666454597126409143e-01 -8.220000000000000000e+02 1.664045232363741689e-01 -8.230000000000000000e+02 1.661642526388682484e-01 -8.240000000000000000e+02 1.659246453291537693e-01 -8.250000000000000000e+02 1.656856987312289031e-01 -8.260000000000000000e+02 1.654474102839309790e-01 -8.270000000000000000e+02 1.652097774408066155e-01 -8.280000000000000000e+02 1.649727976699829068e-01 -8.290000000000000000e+02 1.647364684540476298e-01 -8.300000000000000000e+02 1.645007872899181545e-01 -8.310000000000000000e+02 1.642657516887252311e-01 -8.320000000000000000e+02 1.640313591756905609e-01 -8.330000000000000000e+02 1.637976072900084734e-01 -8.340000000000000000e+02 1.635644935847182513e-01 -8.350000000000000000e+02 1.633320156266034329e-01 -8.360000000000000000e+02 1.631001709960651080e-01 -8.370000000000000000e+02 1.628689572870125335e-01 -8.380000000000000000e+02 1.626383721067453936e-01 -8.390000000000000000e+02 1.624084130758482736e-01 -8.400000000000000000e+02 1.621790778280755296e-01 -8.410000000000000000e+02 1.619503640102446240e-01 -8.420000000000000000e+02 1.617222692821323748e-01 -8.430000000000000000e+02 1.614947913163576332e-01 -8.440000000000000000e+02 1.612679277982875803e-01 -8.450000000000000000e+02 1.610416764259272326e-01 -8.460000000000000000e+02 1.608160349098172459e-01 -8.470000000000000000e+02 1.605910009729304699e-01 -8.480000000000000000e+02 1.603665723505774410e-01 -8.490000000000000000e+02 1.601427467903011326e-01 -8.500000000000000000e+02 1.599195220517799498e-01 -8.510000000000000000e+02 1.596968959067274485e-01 -8.520000000000000000e+02 1.594748661388046829e-01 -8.530000000000000000e+02 1.592534305435133468e-01 -8.540000000000000000e+02 1.590325869281131177e-01 -8.550000000000000000e+02 1.588123331115195436e-01 -8.560000000000000000e+02 1.585926669242151421e-01 -8.570000000000000000e+02 1.583735862081580015e-01 -8.580000000000000000e+02 1.581550888166957658e-01 -8.590000000000000000e+02 1.579371726144669363e-01 -8.600000000000000000e+02 1.577198354773206301e-01 -8.610000000000000000e+02 1.575030752922284283e-01 -8.620000000000000000e+02 1.572868899571963908e-01 -8.630000000000000000e+02 1.570712773811751839e-01 -8.640000000000000000e+02 1.568562354839878881e-01 -8.650000000000000000e+02 1.566417621962336304e-01 -8.660000000000000000e+02 1.564278554592107573e-01 -8.670000000000000000e+02 1.562145132248342894e-01 -8.680000000000000000e+02 1.560017334555549029e-01 -8.690000000000000000e+02 1.557895141242813808e-01 -8.700000000000000000e+02 1.555778532142964576e-01 -8.710000000000000000e+02 1.553667487191800478e-01 -8.720000000000000000e+02 1.551561986427322515e-01 -8.730000000000000000e+02 1.549462009989035216e-01 -8.740000000000000000e+02 1.547367538117028762e-01 -8.750000000000000000e+02 1.545278551151350876e-01 -8.760000000000000000e+02 1.543195029531224949e-01 -8.770000000000000000e+02 1.541116953794353095e-01 -8.780000000000000000e+02 1.539044304576116795e-01 -8.790000000000000000e+02 1.536977062608885503e-01 -8.800000000000000000e+02 1.534915208721329694e-01 -8.810000000000000000e+02 1.532858723837701720e-01 -8.820000000000000000e+02 1.530807588977079747e-01 -8.830000000000000000e+02 1.528761785252807925e-01 -8.840000000000000000e+02 1.526721293871620977e-01 -8.850000000000000000e+02 1.524686096133157365e-01 -8.860000000000000000e+02 1.522656173429173809e-01 -8.870000000000000000e+02 1.520631507242903302e-01 -8.880000000000000000e+02 1.518612079148390914e-01 -8.890000000000000000e+02 1.516597870809909543e-01 -8.900000000000000000e+02 1.514588863981203293e-01 -8.910000000000000000e+02 1.512585040504949851e-01 -8.920000000000000000e+02 1.510586382312030795e-01 -8.930000000000000000e+02 1.508592871421043369e-01 -8.940000000000000000e+02 1.506604489937514169e-01 -8.950000000000000000e+02 1.504621220053430630e-01 -8.960000000000000000e+02 1.502643044046546028e-01 -8.970000000000000000e+02 1.500669944279820200e-01 -8.980000000000000000e+02 1.498701903200784780e-01 -8.990000000000000000e+02 1.496738903341030824e-01 -9.000000000000000000e+02 1.494780927315501329e-01 -9.010000000000000000e+02 1.492827957822062956e-01 -9.020000000000000000e+02 1.490879977640773291e-01 -9.030000000000000000e+02 1.488936969633467555e-01 -9.040000000000000000e+02 1.486998916743114685e-01 -9.050000000000000000e+02 1.485065801993235846e-01 -9.060000000000000000e+02 1.483137608487412606e-01 -9.070000000000000000e+02 1.481214319408722668e-01 -9.080000000000000000e+02 1.479295918019182809e-01 -9.090000000000000000e+02 1.477382387659270380e-01 -9.100000000000000000e+02 1.475473711747292971e-01 -9.110000000000000000e+02 1.473569873778970418e-01 -9.120000000000000000e+02 1.471670857326824733e-01 -9.130000000000000000e+02 1.469776646039736012e-01 -9.140000000000000000e+02 1.467887223642389827e-01 -9.150000000000000000e+02 1.466002573934792330e-01 -9.160000000000000000e+02 1.464122680791772602e-01 -9.170000000000000000e+02 1.462247528162418098e-01 -9.180000000000000000e+02 1.460377100069734368e-01 -9.190000000000000000e+02 1.458511380610005848e-01 -9.200000000000000000e+02 1.456650353952339827e-01 -9.210000000000000000e+02 1.454794004338342273e-01 -9.220000000000000000e+02 1.452942316081404783e-01 -9.230000000000000000e+02 1.451095273566402610e-01 -9.240000000000000000e+02 1.449252861249199775e-01 -9.250000000000000000e+02 1.447415063656136980e-01 -9.260000000000000000e+02 1.445581865383607223e-01 -9.270000000000000000e+02 1.443753251097650570e-01 -9.280000000000000000e+02 1.441929205533447889e-01 -9.290000000000000000e+02 1.440109713494855948e-01 -9.300000000000000000e+02 1.438294759854008842e-01 -9.310000000000000000e+02 1.436484329550934413e-01 -9.320000000000000000e+02 1.434678407592990534e-01 -9.330000000000000000e+02 1.432876979054597266e-01 -9.340000000000000000e+02 1.431080029076605975e-01 -9.350000000000000000e+02 1.429287542866095329e-01 -9.360000000000000000e+02 1.427499505695824511e-01 -9.370000000000000000e+02 1.425715902903854915e-01 -9.380000000000000000e+02 1.423936719893119374e-01 -9.390000000000000000e+02 1.422161942131080214e-01 -9.400000000000000000e+02 1.420391555149262408e-01 -9.410000000000000000e+02 1.418625544542850281e-01 -9.420000000000000000e+02 1.416863895970347786e-01 -9.430000000000000000e+02 1.415106595153154956e-01 -9.440000000000000000e+02 1.413353627875172103e-01 -9.450000000000000000e+02 1.411604979982417074e-01 -9.460000000000000000e+02 1.409860637382658599e-01 -9.470000000000000000e+02 1.408120586045039091e-01 -9.480000000000000000e+02 1.406384811999666640e-01 -9.490000000000000000e+02 1.404653301337304150e-01 -9.500000000000000000e+02 1.402926040208922198e-01 -9.510000000000000000e+02 1.401203014825386228e-01 -9.520000000000000000e+02 1.399484211457112381e-01 -9.530000000000000000e+02 1.397769616433654771e-01 -9.540000000000000000e+02 1.396059216143341053e-01 -9.550000000000000000e+02 1.394352997033027897e-01 -9.560000000000000000e+02 1.392650945607592228e-01 -9.570000000000000000e+02 1.390953048429723615e-01 -9.580000000000000000e+02 1.389259292119498224e-01 -9.590000000000000000e+02 1.387569663354068783e-01 -9.600000000000000000e+02 1.385884148867320420e-01 -9.610000000000000000e+02 1.384202735449500676e-01 -9.620000000000000000e+02 1.382525409946983586e-01 -9.630000000000000000e+02 1.380852159261809764e-01 -9.640000000000000000e+02 1.379182970351448267e-01 -9.650000000000000000e+02 1.377517830228466855e-01 -9.660000000000000000e+02 1.375856725960163951e-01 -9.670000000000000000e+02 1.374199644668294418e-01 -9.680000000000000000e+02 1.372546573528691805e-01 -9.690000000000000000e+02 1.370897499771081551e-01 -9.700000000000000000e+02 1.369252410678593879e-01 -9.710000000000000000e+02 1.367611293587581434e-01 -9.720000000000000000e+02 1.365974135887278729e-01 -9.730000000000000000e+02 1.364340925019515149e-01 -9.740000000000000000e+02 1.362711648478356352e-01 -9.750000000000000000e+02 1.361086293809845860e-01 -9.760000000000000000e+02 1.359464848611711407e-01 -9.770000000000000000e+02 1.357847300533093771e-01 -9.780000000000000000e+02 1.356233637274189829e-01 -9.790000000000000000e+02 1.354623846585962799e-01 -9.800000000000000000e+02 1.353017916269985965e-01 -9.810000000000000000e+02 1.351415834177943087e-01 -9.820000000000000000e+02 1.349817588211591479e-01 -9.830000000000000000e+02 1.348223166322229105e-01 -9.840000000000000000e+02 1.346632556510622969e-01 -9.850000000000000000e+02 1.345045746826611932e-01 -9.860000000000000000e+02 1.343462725368876065e-01 -9.870000000000000000e+02 1.341883480615597701e-01 -9.880000000000000000e+02 1.340308000100528529e-01 -9.890000000000000000e+02 1.338736272398056149e-01 -9.900000000000000000e+02 1.337168285799549550e-01 -9.910000000000000000e+02 1.335604028643794794e-01 -9.920000000000000000e+02 1.334043489316852071e-01 -9.930000000000000000e+02 1.332486656251746504e-01 -9.940000000000000000e+02 1.330933517596697702e-01 -9.950000000000000000e+02 1.329384062540855949e-01 -9.960000000000000000e+02 1.327838279325198600e-01 -9.970000000000000000e+02 1.326296156568088636e-01 -9.980000000000000000e+02 1.324757682933597747e-01 -9.990000000000000000e+02 1.323222847131252378e-01 -1.000000000000000000e+03 1.321691637915768103e-01 -1.001000000000000000e+03 1.320164044086875599e-01 -1.002000000000000000e+03 1.318640054489006730e-01 -1.003000000000000000e+03 1.317119658011041139e-01 -1.004000000000000000e+03 1.315602843586153869e-01 -1.005000000000000000e+03 1.314089600191504226e-01 -1.006000000000000000e+03 1.312579916848016226e-01 -1.007000000000000000e+03 1.311073782620212347e-01 -1.008000000000000000e+03 1.309571186615844929e-01 -1.009000000000000000e+03 1.308072117985737415e-01 -1.010000000000000000e+03 1.306576565923632527e-01 -1.011000000000000000e+03 1.305084519665871690e-01 -1.012000000000000000e+03 1.303595968491136625e-01 -1.013000000000000000e+03 1.302110901720373859e-01 -1.014000000000000000e+03 1.300629308716407251e-01 -1.015000000000000000e+03 1.299151178883825863e-01 -1.016000000000000000e+03 1.297676501668720561e-01 -1.017000000000000000e+03 1.296205266558471958e-01 -1.018000000000000000e+03 1.294737463081559459e-01 -1.019000000000000000e+03 1.293273080807343656e-01 -1.020000000000000000e+03 1.291812109345764348e-01 -1.021000000000000000e+03 1.290354538347310565e-01 -1.022000000000000000e+03 1.288900357502606731e-01 -1.023000000000000000e+03 1.287449556542367146e-01 -1.024000000000000000e+03 1.286002125237113713e-01 -1.025000000000000000e+03 1.284558053396971655e-01 -1.026000000000000000e+03 1.283117330871465511e-01 -1.027000000000000000e+03 1.281679947549354548e-01 -1.028000000000000000e+03 1.280245893358402387e-01 -1.029000000000000000e+03 1.278815158265200203e-01 -1.030000000000000000e+03 1.277387732274901377e-01 -1.031000000000000000e+03 1.275963605431077452e-01 -1.032000000000000000e+03 1.274542767815606825e-01 -1.033000000000000000e+03 1.273125209548309766e-01 -1.034000000000000000e+03 1.271710920786854604e-01 -1.035000000000000000e+03 1.270299891726599240e-01 -1.036000000000000000e+03 1.268892112600283895e-01 -1.037000000000000000e+03 1.267487573677982815e-01 -1.038000000000000000e+03 1.266086265266815614e-01 -1.039000000000000000e+03 1.264688177710780737e-01 -1.040000000000000000e+03 1.263293301390636669e-01 -1.041000000000000000e+03 1.261901626723622161e-01 -1.042000000000000000e+03 1.260513144163321331e-01 -1.043000000000000000e+03 1.259127844199509350e-01 -1.044000000000000000e+03 1.257745717357948156e-01 -1.045000000000000000e+03 1.256366754200144431e-01 -1.046000000000000000e+03 1.254990945323299356e-01 -1.047000000000000000e+03 1.253618281360048825e-01 -1.048000000000000000e+03 1.252248752978292745e-01 -1.049000000000000000e+03 1.250882350881037663e-01 -1.050000000000000000e+03 1.249519065806236479e-01 -1.051000000000000000e+03 1.248158888526591098e-01 -1.052000000000000000e+03 1.246801809849393816e-01 -1.053000000000000000e+03 1.245447820616378681e-01 -1.054000000000000000e+03 1.244096911703505004e-01 -1.055000000000000000e+03 1.242749074020829819e-01 -1.056000000000000000e+03 1.241404298512330112e-01 -1.057000000000000000e+03 1.240062576155750995e-01 -1.058000000000000000e+03 1.238723897962429737e-01 -1.059000000000000000e+03 1.237388254977097868e-01 -1.060000000000000000e+03 1.236055638277841762e-01 -1.061000000000000000e+03 1.234726038975752782e-01 -1.062000000000000000e+03 1.233399448214995836e-01 -1.063000000000000000e+03 1.232075857172361122e-01 -1.064000000000000000e+03 1.230755257057444263e-01 -1.065000000000000000e+03 1.229437639112212627e-01 -1.066000000000000000e+03 1.228122994611028224e-01 -1.067000000000000000e+03 1.226811314860330876e-01 -1.068000000000000000e+03 1.225502591198685542e-01 -1.069000000000000000e+03 1.224196814996454802e-01 -1.070000000000000000e+03 1.222893977655738068e-01 -1.071000000000000000e+03 1.221594070610183269e-01 -1.072000000000000000e+03 1.220297085324840297e-01 -1.073000000000000000e+03 1.219003013296086069e-01 -1.074000000000000000e+03 1.217711846051361124e-01 -1.075000000000000000e+03 1.216423575149093717e-01 -1.076000000000000000e+03 1.215138192178531612e-01 -1.077000000000000000e+03 1.213855688759627321e-01 -1.078000000000000000e+03 1.212576056542851444e-01 -1.079000000000000000e+03 1.211299287209078035e-01 -1.080000000000000000e+03 1.210025372469445554e-01 -1.081000000000000000e+03 1.208754304065162571e-01 -1.082000000000000000e+03 1.207486073767464752e-01 -1.083000000000000000e+03 1.206220673377426111e-01 -1.084000000000000000e+03 1.204958094725742113e-01 -1.085000000000000000e+03 1.203698329672737016e-01 -1.086000000000000000e+03 1.202441370108142116e-01 -1.087000000000000000e+03 1.201187207950938918e-01 -1.088000000000000000e+03 1.199935835149330970e-01 -1.089000000000000000e+03 1.198687243680439246e-01 -1.090000000000000000e+03 1.197441425550360011e-01 -1.091000000000000000e+03 1.196198372793898096e-01 -1.092000000000000000e+03 1.194958077474480018e-01 -1.093000000000000000e+03 1.193720531684009240e-01 -1.094000000000000000e+03 1.192485727542798996e-01 -1.095000000000000000e+03 1.191253657199293631e-01 -1.096000000000000000e+03 1.190024312830151171e-01 -1.097000000000000000e+03 1.188797686639917334e-01 -1.098000000000000000e+03 1.187573770861034689e-01 -1.099000000000000000e+03 1.186352557753638376e-01 +3.000000000000000000e+02 7.961299851462676214e-02 +3.010000000000000000e+02 1.332288155026307430e-01 +3.020000000000000000e+02 2.140794239934083465e-01 +3.030000000000000000e+02 3.358020697199494697e-01 +3.040000000000000000e+02 5.203650267662797146e-01 +3.050000000000000000e+02 8.039346299497034387e-01 +3.060000000000000000e+02 1.246857969960517787e+00 +3.070000000000000000e+02 1.948756173976117223e+00 +3.080000000000000000e+02 3.061564326085904231e+00 +3.090000000000000000e+02 4.754068346658284483e+00 +3.100000000000000000e+02 6.980099788528115745e+00 +3.110000000000000000e+02 8.989994104067182690e+00 +3.120000000000000000e+02 9.568274014305636399e+00 +3.130000000000000000e+02 8.602215291399884833e+00 +3.140000000000000000e+02 7.064599362725426879e+00 +3.150000000000000000e+02 5.654047497876379502e+00 +3.160000000000000000e+02 4.554202335271595459e+00 +3.170000000000000000e+02 3.734874132958712512e+00 +3.180000000000000000e+02 3.125853968470231337e+00 +3.190000000000000000e+02 2.666882617112256604e+00 +3.200000000000000000e+02 2.314416691882152044e+00 +3.210000000000000000e+02 2.038406572548078888e+00 +3.220000000000000000e+02 1.818230229845627210e+00 +3.230000000000000000e+02 1.639595893845350316e+00 +3.240000000000000000e+02 1.492441797633357714e+00 +3.250000000000000000e+02 1.369558229931185922e+00 +3.260000000000000000e+02 1.265686753132716502e+00 +3.270000000000000000e+02 1.176926314575905907e+00 +3.280000000000000000e+02 1.100336288900929382e+00 +3.290000000000000000e+02 1.033666940003522106e+00 +3.300000000000000000e+02 9.751734048420805934e-01 +3.310000000000000000e+02 9.234852495649015225e-01 +3.320000000000000000e+02 8.775135804346393398e-01 +3.330000000000000000e+02 8.363839278155630330e-01 +3.340000000000000000e+02 7.993870835692526988e-01 +3.350000000000000000e+02 7.659426242203544177e-01 +3.360000000000000000e+02 7.355715196817254053e-01 +3.370000000000000000e+02 7.078753324939935920e-01 +3.380000000000000000e+02 6.825202553748643819e-01 +3.390000000000000000e+02 6.592247409811804459e-01 +3.400000000000000000e+02 6.377498271070528579e-01 +3.410000000000000000e+02 6.178915046436176395e-01 +3.420000000000000000e+02 5.994746482197726989e-01 +3.430000000000000000e+02 5.823481528430023424e-01 +3.440000000000000000e+02 5.663810090244997264e-01 +3.450000000000000000e+02 5.514591139482380999e-01 +3.460000000000000000e+02 5.374826641907224367e-01 +3.470000000000000000e+02 5.243640111435605711e-01 +3.480000000000000000e+02 5.120258870188540978e-01 +3.490000000000000000e+02 5.003999295189858199e-01 +3.500000000000000000e+02 4.894254486430644757e-01 +3.510000000000000000e+02 4.790483909090546000e-01 +3.520000000000000000e+02 4.692204653945375448e-01 +3.530000000000000000e+02 4.598984030952154023e-01 +3.540000000000000000e+02 4.510433266541649666e-01 +3.550000000000000000e+02 4.426202118881453762e-01 +3.560000000000000000e+02 4.345974260009224932e-01 +3.570000000000000000e+02 4.269463301312558245e-01 +3.580000000000000000e+02 4.196409360911090292e-01 +3.590000000000000000e+02 4.126576089255324931e-01 +3.600000000000000000e+02 4.059748083617220060e-01 +3.610000000000000000e+02 3.995728633805583629e-01 +3.620000000000000000e+02 3.934337750951352741e-01 +3.630000000000000000e+02 3.875410439001367724e-01 +3.640000000000000000e+02 3.818795174965109451e-01 +3.650000000000000000e+02 3.764352569253868741e-01 +3.660000000000000000e+02 3.711954181837090472e-01 +3.670000000000000000e+02 3.661481473589716096e-01 +3.680000000000000000e+02 3.612824875251964829e-01 +3.690000000000000000e+02 3.565882958973327632e-01 +3.700000000000000000e+02 3.520561699557953061e-01 +3.710000000000000000e+02 3.476773814336127644e-01 +3.720000000000000000e+02 3.434438172114515075e-01 +3.730000000000000000e+02 3.393479262955031439e-01 +3.740000000000000000e+02 3.353826721633714203e-01 +3.750000000000000000e+02 3.315414898571716340e-01 +3.760000000000000000e+02 3.278182472833725547e-01 +3.770000000000000000e+02 3.242072102478924522e-01 +3.780000000000000000e+02 3.207030108140977442e-01 +3.790000000000000000e+02 3.173006186224021641e-01 +3.800000000000000000e+02 3.139953148542299344e-01 +3.810000000000000000e+02 3.107826685611519424e-01 +3.820000000000000000e+02 3.076585151131501772e-01 +3.830000000000000000e+02 3.046189365486084988e-01 +3.840000000000000000e+02 3.016602436337605386e-01 +3.850000000000000000e+02 2.987789594610280042e-01 +3.860000000000000000e+02 2.959718044349548549e-01 +3.870000000000000000e+02 2.932356825109964649e-01 +3.880000000000000000e+02 2.905676685672203274e-01 +3.890000000000000000e+02 2.879649968019114548e-01 +3.900000000000000000e+02 2.854250500613068620e-01 +3.910000000000000000e+02 2.829453500119029075e-01 +3.920000000000000000e+02 2.805235480805149395e-01 +3.930000000000000000e+02 2.781574170931823686e-01 +3.940000000000000000e+02 2.758448435509671670e-01 +3.950000000000000000e+02 2.735838204868805135e-01 +3.960000000000000000e+02 2.713724408536276611e-01 +3.970000000000000000e+02 2.692088913968753716e-01 +3.980000000000000000e+02 2.670914469729461227e-01 +3.990000000000000000e+02 2.650184652738983848e-01 +4.000000000000000000e+02 2.629883819263793554e-01 +4.010000000000000000e+02 2.609997059337193503e-01 +4.020000000000000000e+02 2.590510154336600479e-01 +4.030000000000000000e+02 2.571409537464698358e-01 +4.040000000000000000e+02 2.552682256906250169e-01 +4.050000000000000000e+02 2.534315941451266152e-01 +4.060000000000000000e+02 2.516298768394835683e-01 +4.070000000000000000e+02 2.498619433539414070e-01 +4.080000000000000000e+02 2.481267123141129294e-01 +4.090000000000000000e+02 2.464231487654904296e-01 +4.100000000000000000e+02 2.447502617145134174e-01 +4.110000000000000000e+02 2.431071018240412718e-01 +4.120000000000000000e+02 2.414927592520367816e-01 +4.130000000000000000e+02 2.399063616231849327e-01 +4.140000000000000000e+02 2.383470721240262269e-01 +4.150000000000000000e+02 2.368140877129318866e-01 +4.160000000000000000e+02 2.353066374369191249e-01 +4.170000000000000000e+02 2.338239808479604664e-01 +4.180000000000000000e+02 2.323654065119738765e-01 +4.190000000000000000e+02 2.309302306042842479e-01 +4.200000000000000000e+02 2.295177955857041763e-01 +4.210000000000000000e+02 2.281274689539329326e-01 +4.220000000000000000e+02 2.267586420653266988e-01 +4.230000000000000000e+02 2.254107290224274251e-01 +4.240000000000000000e+02 2.240831656230506952e-01 +4.250000000000000000e+02 2.227754083669700180e-01 +4.260000000000000000e+02 2.214869335165711162e-01 +4.270000000000000000e+02 2.202172362080710710e-01 +4.280000000000000000e+02 2.189658296101751611e-01 +4.290000000000000000e+02 2.177322441272342146e-01 +4.300000000000000000e+02 2.165160266441842063e-01 +4.310000000000000000e+02 2.153167398107430908e-01 +4.320000000000000000e+02 2.141339613625038996e-01 +4.330000000000000000e+02 2.129672834767183942e-01 +4.340000000000000000e+02 2.118163121607318511e-01 +4.350000000000000000e+02 2.106806666711602549e-01 +4.360000000000000000e+02 2.095599789620027076e-01 +4.370000000000000000e+02 2.084538931600571632e-01 +4.380000000000000000e+02 2.073620650660302211e-01 +4.390000000000000000e+02 2.062841616799475086e-01 +4.400000000000000000e+02 2.052198607494348237e-01 +4.410000000000000000e+02 2.041688503396373866e-01 +4.420000000000000000e+02 2.031308284235689432e-01 +4.430000000000000000e+02 2.021055024917489673e-01 +4.440000000000000000e+02 2.010925891801146337e-01 +4.450000000000000000e+02 2.000918139151833253e-01 +4.460000000000000000e+02 1.991029105755633688e-01 +4.470000000000000000e+02 1.981256211689262081e-01 +4.480000000000000000e+02 1.971596955236434578e-01 +4.490000000000000000e+02 1.962048909942987196e-01 +4.500000000000000000e+02 1.952609721803653386e-01 +4.510000000000000000e+02 1.943277106573545743e-01 +4.520000000000000000e+02 1.934048847198230336e-01 +4.530000000000000000e+02 1.924922791356010188e-01 +4.540000000000000000e+02 1.915896849107006916e-01 +4.550000000000000000e+02 1.906968990643508333e-01 +4.560000000000000000e+02 1.898137244136666735e-01 +4.570000000000000000e+02 1.889399693674656822e-01 +4.580000000000000000e+02 1.880754477287910620e-01 +4.590000000000000000e+02 1.872199785057147292e-01 +4.600000000000000000e+02 1.863733857300050589e-01 +4.610000000000000000e+02 1.855354982833024580e-01 +4.620000000000000000e+02 1.847061497304345323e-01 +4.630000000000000000e+02 1.838851781595266521e-01 +4.640000000000000000e+02 1.830724260285875316e-01 +4.650000000000000000e+02 1.822677400182809437e-01 +4.660000000000000000e+02 1.814709708905761498e-01 +4.670000000000000000e+02 1.806819733530212746e-01 +4.680000000000000000e+02 1.799006059283672354e-01 +4.690000000000000000e+02 1.791267308293136296e-01 +4.700000000000000000e+02 1.783602138381267521e-01 +4.710000000000000000e+02 1.776009241909256298e-01 +4.720000000000000000e+02 1.768487344664192995e-01 +4.730000000000000000e+02 1.761035204788990172e-01 +4.740000000000000000e+02 1.753651611752923556e-01 +4.750000000000000000e+02 1.746335385361159898e-01 +4.760000000000000000e+02 1.739085374801370154e-01 +4.770000000000000000e+02 1.731900457725939479e-01 +4.780000000000000000e+02 1.724779539368175296e-01 +4.790000000000000000e+02 1.717721551691251125e-01 +4.800000000000000000e+02 1.710725452568100935e-01 +4.810000000000000000e+02 1.703790224991346414e-01 +4.820000000000000000e+02 1.696914876311798881e-01 +4.830000000000000000e+02 1.690098437504338191e-01 +4.840000000000000000e+02 1.683339962460135286e-01 +4.850000000000000000e+02 1.676638527303926374e-01 +4.860000000000000000e+02 1.669993229735621254e-01 +4.870000000000000000e+02 1.663403188394913523e-01 +4.880000000000000000e+02 1.656867542248213754e-01 +4.890000000000000000e+02 1.650385449996839560e-01 +4.900000000000000000e+02 1.643956089505726470e-01 +4.910000000000000000e+02 1.637578657251728687e-01 +4.920000000000000000e+02 1.631252367790876068e-01 +4.930000000000000000e+02 1.624976453243637819e-01 +4.940000000000000000e+02 1.618750162797696068e-01 +4.950000000000000000e+02 1.612572762227393597e-01 +4.960000000000000000e+02 1.606443533429307291e-01 +4.970000000000000000e+02 1.600361773973174306e-01 +4.980000000000000000e+02 1.594326796667862034e-01 +4.990000000000000000e+02 1.588337929141440674e-01 +5.000000000000000000e+02 1.582394513435155803e-01 +5.010000000000000000e+02 1.576495905610547088e-01 +5.020000000000000000e+02 1.570641475369312923e-01 +5.030000000000000000e+02 1.564830605685475218e-01 +5.040000000000000000e+02 1.559062692449307008e-01 +5.050000000000000000e+02 1.553337144122596547e-01 +5.060000000000000000e+02 1.547653381404952011e-01 +5.070000000000000000e+02 1.542010836910570060e-01 +5.080000000000000000e+02 1.536408954855126019e-01 +5.090000000000000000e+02 1.530847190752566700e-01 +5.100000000000000000e+02 1.525325011121264895e-01 +5.110000000000000000e+02 1.519841893199313232e-01 +5.120000000000000000e+02 1.514397324668538269e-01 +5.130000000000000000e+02 1.508990803386966173e-01 +5.140000000000000000e+02 1.503621837129602012e-01 +5.150000000000000000e+02 1.498289943336809926e-01 +5.160000000000000000e+02 1.492994648870618890e-01 +5.170000000000000000e+02 1.487735489778009845e-01 +5.180000000000000000e+02 1.482512011061621615e-01 +5.190000000000000000e+02 1.477323766457019349e-01 +5.200000000000000000e+02 1.472170318216717566e-01 +5.210000000000000000e+02 1.467051236415289894e-01 +5.220000000000000000e+02 1.461966100694034876e-01 +5.230000000000000000e+02 1.456914497601094205e-01 +5.240000000000000000e+02 1.451896020471993842e-01 +5.250000000000000000e+02 1.446910271597220132e-01 +5.260000000000000000e+02 1.441956860136566487e-01 +5.270000000000000000e+02 1.437035402421477648e-01 +5.280000000000000000e+02 1.432145521784317366e-01 +5.290000000000000000e+02 1.427286848392624319e-01 +5.300000000000000000e+02 1.422459019087904397e-01 +5.310000000000000000e+02 1.417661677229094530e-01 +5.320000000000000000e+02 1.412894472540359159e-01 +5.330000000000000000e+02 1.408157060963131368e-01 +5.340000000000000000e+02 1.403449104512287382e-01 +5.350000000000000000e+02 1.398770271136304533e-01 +5.360000000000000000e+02 1.394120234581230355e-01 +5.370000000000000000e+02 1.389498674258441147e-01 +5.380000000000000000e+02 1.384905275116004308e-01 +5.390000000000000000e+02 1.380339727513476555e-01 +5.400000000000000000e+02 1.375801727100182115e-01 +5.410000000000000000e+02 1.371290974696694198e-01 +5.420000000000000000e+02 1.366807176179598571e-01 +5.430000000000000000e+02 1.362350042369165071e-01 +5.440000000000000000e+02 1.357919288920213519e-01 +5.450000000000000000e+02 1.353514636215761568e-01 +5.460000000000000000e+02 1.349135809263443952e-01 +5.470000000000000000e+02 1.344782537594772232e-01 +5.480000000000000000e+02 1.340454555166927519e-01 +5.490000000000000000e+02 1.336151600267161399e-01 +5.500000000000000000e+02 1.331873415419657092e-01 +5.510000000000000000e+02 1.327619747294848385e-01 +5.520000000000000000e+02 1.323390346621011182e-01 +5.530000000000000000e+02 1.319184968098135180e-01 +5.540000000000000000e+02 1.315003370313998776e-01 +5.550000000000000000e+02 1.310845315662466370e-01 +5.560000000000000000e+02 1.306710570263680538e-01 +5.570000000000000000e+02 1.302598903886419413e-01 +5.580000000000000000e+02 1.298510089872303985e-01 +5.590000000000000000e+02 1.294443905062016287e-01 +5.600000000000000000e+02 1.290400129723235645e-01 +5.610000000000000000e+02 1.286378547480406531e-01 +5.620000000000000000e+02 1.282378945246333557e-01 +5.630000000000000000e+02 1.278401113154921109e-01 +5.640000000000000000e+02 1.274444844497578389e-01 +5.650000000000000000e+02 1.270509935657559153e-01 +5.660000000000000000e+02 1.266596186048500883e-01 +5.670000000000000000e+02 1.262703398055137760e-01 +5.680000000000000000e+02 1.258831376973126581e-01 +5.690000000000000000e+02 1.254979930951669320e-01 +5.700000000000000000e+02 1.251148870937316415e-01 +5.710000000000000000e+02 1.247338010619008508e-01 +5.720000000000000000e+02 1.243547166374542462e-01 +5.730000000000000000e+02 1.239776157218182850e-01 +5.740000000000000000e+02 1.236024804749573935e-01 +5.750000000000000000e+02 1.232292933103926735e-01 +5.760000000000000000e+02 1.228580368903178094e-01 +5.770000000000000000e+02 1.224886941208494368e-01 +5.780000000000000000e+02 1.221212481473756550e-01 +5.790000000000000000e+02 1.217556823500183238e-01 +5.800000000000000000e+02 1.213919803391943636e-01 +5.810000000000000000e+02 1.210301259512846506e-01 +5.820000000000000000e+02 1.206701032444012500e-01 +5.830000000000000000e+02 1.203118964942487962e-01 +5.840000000000000000e+02 1.199554901900795889e-01 +5.850000000000000000e+02 1.196008690307446137e-01 +5.860000000000000000e+02 1.192480179208306595e-01 +5.870000000000000000e+02 1.188969219668824795e-01 +5.880000000000000000e+02 1.185475664737183077e-01 +5.890000000000000000e+02 1.181999369408137240e-01 +5.900000000000000000e+02 1.178540190587768349e-01 +5.910000000000000000e+02 1.175097987059009891e-01 +5.920000000000000000e+02 1.171672619447881175e-01 +5.930000000000000000e+02 1.168263950190492340e-01 +5.940000000000000000e+02 1.164871843500789456e-01 +5.950000000000000000e+02 1.161496165338983394e-01 +5.960000000000000000e+02 1.158136783380677715e-01 +5.970000000000000000e+02 1.154793566986649367e-01 +5.980000000000000000e+02 1.151466387173311207e-01 +5.990000000000000000e+02 1.148155116583784441e-01 +6.000000000000000000e+02 1.144859629459602929e-01 +6.010000000000000000e+02 1.141579801613047396e-01 +6.020000000000000000e+02 1.138315510610745790e-01 +6.030000000000000000e+02 1.135066634902111432e-01 +6.040000000000000000e+02 1.131833054857417364e-01 +6.050000000000000000e+02 1.128614652721903477e-01 +6.060000000000000000e+02 1.125411311557544813e-01 +6.070000000000000000e+02 1.122222916051521246e-01 +6.080000000000000000e+02 1.119049352283636445e-01 +6.090000000000000000e+02 1.115890507702966272e-01 +6.100000000000000000e+02 1.112746271105028162e-01 +6.110000000000000000e+02 1.109616532609311729e-01 +6.120000000000000000e+02 1.106501183637413621e-01 +6.130000000000000000e+02 1.103400116891502525e-01 +6.140000000000000000e+02 1.100313226333304029e-01 +6.150000000000000000e+02 1.097240407163439790e-01 +6.160000000000000000e+02 1.094181555801294059e-01 +6.170000000000000000e+02 1.091136569865165939e-01 +6.180000000000000000e+02 1.088105348152902385e-01 +6.190000000000000000e+02 1.085087790622894233e-01 +6.200000000000000000e+02 1.082083798375482048e-01 +6.210000000000000000e+02 1.079093273634639805e-01 +6.220000000000000000e+02 1.076116119730188142e-01 +6.230000000000000000e+02 1.073152241080153890e-01 +6.240000000000000000e+02 1.070201543173670139e-01 +6.250000000000000000e+02 1.067263932554120415e-01 +6.260000000000000000e+02 1.064339316802580815e-01 +6.270000000000000000e+02 1.061427604521662099e-01 +6.280000000000000000e+02 1.058528705319620317e-01 +6.290000000000000000e+02 1.055642529794833112e-01 +6.300000000000000000e+02 1.052768989520453252e-01 +6.310000000000000000e+02 1.049907997029521783e-01 +6.320000000000000000e+02 1.047059465800220385e-01 +6.330000000000000000e+02 1.044223310241524094e-01 +6.340000000000000000e+02 1.041399445679029173e-01 +6.350000000000000000e+02 1.038587788341130691e-01 +6.360000000000000000e+02 1.035788255345441305e-01 +6.370000000000000000e+02 1.033000764685384071e-01 +6.380000000000000000e+02 1.030225235217194779e-01 +6.390000000000000000e+02 1.027461586647041569e-01 +6.400000000000000000e+02 1.024709739518415291e-01 +6.410000000000000000e+02 1.021969615199819770e-01 +6.420000000000000000e+02 1.019241135872587661e-01 +6.430000000000000000e+02 1.016524224518972896e-01 +6.440000000000000000e+02 1.013818804910511656e-01 +6.450000000000000000e+02 1.011124801596522821e-01 +6.460000000000000000e+02 1.008442139892827411e-01 +6.470000000000000000e+02 1.005770745870757932e-01 +6.480000000000000000e+02 1.003110546346218795e-01 +6.490000000000000000e+02 1.000461468869114218e-01 +6.500000000000000000e+02 9.978234417128330203e-02 +6.510000000000000000e+02 9.951963938640100149e-02 +6.520000000000000000e+02 9.925802550124120105e-02 +6.530000000000000000e+02 9.899749555410496116e-02 +6.540000000000000000e+02 9.873804265164554117e-02 +6.550000000000000000e+02 9.847965996791052667e-02 +6.560000000000000000e+02 9.822234074340530086e-02 +6.570000000000000000e+02 9.796607828417108754e-02 +6.580000000000000000e+02 9.771086596087912024e-02 +6.590000000000000000e+02 9.745669720793985469e-02 +6.600000000000000000e+02 9.720356552263154093e-02 +6.610000000000000000e+02 9.695146446423963393e-02 +6.620000000000000000e+02 9.670038765321312124e-02 +6.630000000000000000e+02 9.645032877033810070e-02 +6.640000000000000000e+02 9.620128155591793628e-02 +6.650000000000000000e+02 9.595323980897974003e-02 +6.660000000000000000e+02 9.570619738648178387e-02 +6.670000000000000000e+02 9.546014820254186684e-02 +6.680000000000000000e+02 9.521508622767922703e-02 +6.690000000000000000e+02 9.497100548806669540e-02 +6.700000000000000000e+02 9.472790006479210601e-02 +6.710000000000000000e+02 9.448576409314531077e-02 +6.720000000000000000e+02 9.424459176189903253e-02 +6.730000000000000000e+02 9.400437731261848673e-02 +6.740000000000000000e+02 9.376511503896947652e-02 +6.750000000000000000e+02 9.352679928604872017e-02 +6.760000000000000000e+02 9.328942444971767556e-02 +6.770000000000000000e+02 9.305298497595046459e-02 +6.780000000000000000e+02 9.281747536019520350e-02 +6.790000000000000000e+02 9.258289014673913575e-02 +6.800000000000000000e+02 9.234922392809159775e-02 +6.810000000000000000e+02 9.211647134437117579e-02 +6.820000000000000000e+02 9.188462708270714319e-02 +6.830000000000000000e+02 9.165368587664779465e-02 +6.840000000000000000e+02 9.142364250558188132e-02 +6.850000000000000000e+02 9.119449179416302953e-02 +6.860000000000000000e+02 9.096622861175272801e-02 +6.870000000000000000e+02 9.073884787186277390e-02 +6.880000000000000000e+02 9.051234453161291493e-02 +6.890000000000000000e+02 9.028671359119457007e-02 +6.900000000000000000e+02 9.006195009334588830e-02 +6.910000000000000000e+02 8.983804912283120669e-02 +6.920000000000000000e+02 8.961500580592933474e-02 +6.930000000000000000e+02 8.939281530993493929e-02 +6.940000000000000000e+02 8.917147284266045693e-02 +6.950000000000000000e+02 8.895097365195243910e-02 +6.960000000000000000e+02 8.873131302520982644e-02 +6.970000000000000000e+02 8.851248628891514314e-02 +6.980000000000000000e+02 8.829448880816814782e-02 +6.990000000000000000e+02 8.807731598622996205e-02 +7.000000000000000000e+02 8.786096326407055734e-02 +7.010000000000000000e+02 8.764542611993125787e-02 +7.020000000000000000e+02 8.743070006888306600e-02 +7.030000000000000000e+02 8.721678066239943461e-02 +7.040000000000000000e+02 8.700366348793345250e-02 +7.050000000000000000e+02 8.679134416850203815e-02 +7.060000000000000000e+02 8.657981836227203465e-02 +7.070000000000000000e+02 8.636908176216102906e-02 +7.080000000000000000e+02 8.615913009543682555e-02 +7.090000000000000000e+02 8.594995912332500931e-02 +7.100000000000000000e+02 8.574156464062566985e-02 +7.110000000000000000e+02 8.553394247532862538e-02 +7.120000000000000000e+02 8.532708848824398229e-02 +7.130000000000000000e+02 8.512099857262904468e-02 +7.140000000000000000e+02 8.491566865382750573e-02 +7.150000000000000000e+02 8.471109468890775096e-02 +7.160000000000000000e+02 8.450727266631387347e-02 +7.170000000000000000e+02 8.430419860551655042e-02 +7.180000000000000000e+02 8.410186855666709760e-02 +7.190000000000000000e+02 8.390027860026526285e-02 +7.200000000000000000e+02 8.369942484682130202e-02 +7.210000000000000000e+02 8.349930343653337583e-02 +7.220000000000000000e+02 8.329991053895692554e-02 +7.230000000000000000e+02 8.310124235269428228e-02 +7.240000000000000000e+02 8.290329510507447874e-02 +7.250000000000000000e+02 8.270606505184592561e-02 +7.260000000000000000e+02 8.250954847687301530e-02 +7.270000000000000000e+02 8.231374169183171274e-02 +7.280000000000000000e+02 8.211864103591502706e-02 +7.290000000000000000e+02 8.192424287554087026e-02 +7.300000000000000000e+02 8.173054360406327434e-02 +7.310000000000000000e+02 8.153753964148807709e-02 +7.320000000000000000e+02 8.134522743419352053e-02 +7.330000000000000000e+02 8.115360345465280623e-02 +7.340000000000000000e+02 8.096266420116210449e-02 +7.350000000000000000e+02 8.077240619757197759e-02 +7.360000000000000000e+02 8.058282599302331317e-02 +7.370000000000000000e+02 8.039392016168322996e-02 +7.380000000000000000e+02 8.020568530248957384e-02 +7.390000000000000000e+02 8.001811803889698205e-02 +7.400000000000000000e+02 7.983121501862579239e-02 +7.410000000000000000e+02 7.964497291341322838e-02 +7.420000000000000000e+02 7.945938841877041303e-02 +7.430000000000000000e+02 7.927445825374186683e-02 +7.440000000000000000e+02 7.909017916066828080e-02 +7.450000000000000000e+02 7.890654790495252313e-02 +7.460000000000000000e+02 7.872356127482506294e-02 +7.470000000000000000e+02 7.854121608112407671e-02 +7.480000000000000000e+02 7.835950915705916509e-02 +7.490000000000000000e+02 7.817843735799966109e-02 +7.500000000000000000e+02 7.799799756125053163e-02 +7.510000000000000000e+02 7.781818666583417698e-02 +7.520000000000000000e+02 7.763900159228455389e-02 +7.530000000000000000e+02 7.746043928242785093e-02 +7.540000000000000000e+02 7.728249669917981735e-02 +7.550000000000000000e+02 7.710517082634169017e-02 +7.560000000000000000e+02 7.692845866839373437e-02 +7.570000000000000000e+02 7.675235725029716516e-02 +7.580000000000000000e+02 7.657686361729941493e-02 +7.590000000000000000e+02 7.640197483473448736e-02 +7.600000000000000000e+02 7.622768798783630118e-02 +7.610000000000000000e+02 7.605400018154383213e-02 +7.620000000000000000e+02 7.588090854031788457e-02 +7.630000000000000000e+02 7.570841020795456011e-02 +7.640000000000000000e+02 7.553650234740082181e-02 +7.650000000000000000e+02 7.536518214057852383e-02 +7.660000000000000000e+02 7.519444678820114136e-02 +7.670000000000000000e+02 7.502429350960332366e-02 +7.680000000000000000e+02 7.485471954256316118e-02 +7.690000000000000000e+02 7.468572214313343172e-02 +7.700000000000000000e+02 7.451729858547094520e-02 +7.710000000000000000e+02 7.434944616167016296e-02 +7.720000000000000000e+02 7.418216218159577602e-02 +7.730000000000000000e+02 7.401544397272466491e-02 +7.740000000000000000e+02 7.384928887997892211e-02 +7.750000000000000000e+02 7.368369426557253021e-02 +7.760000000000000000e+02 7.351865750884771511e-02 +7.770000000000000000e+02 7.335417600612696709e-02 +7.780000000000000000e+02 7.319024717055415408e-02 +7.790000000000000000e+02 7.302686843194303168e-02 +7.800000000000000000e+02 7.286403723663467669e-02 +7.810000000000000000e+02 7.270175104734004357e-02 +7.820000000000000000e+02 7.254000734299849429e-02 +7.830000000000000000e+02 7.237880361863653633e-02 +7.840000000000000000e+02 7.221813738521926096e-02 +7.850000000000000000e+02 7.205800616951270332e-02 +7.860000000000000000e+02 7.189840751394413476e-02 +7.870000000000000000e+02 7.173933897646456170e-02 +7.880000000000000000e+02 7.158079813041265393e-02 +7.890000000000000000e+02 7.142278256437989414e-02 +7.900000000000000000e+02 7.126528988207803117e-02 +7.910000000000000000e+02 7.110831770220976678e-02 +7.920000000000000000e+02 7.095186365833487663e-02 +7.930000000000000000e+02 7.079592539874554613e-02 +7.940000000000000000e+02 7.064050058633830620e-02 +7.950000000000000000e+02 7.048558689848902215e-02 +7.960000000000000000e+02 7.033118202692904830e-02 +7.970000000000000000e+02 7.017728367762288144e-02 +7.980000000000000000e+02 7.002388957064674402e-02 +7.990000000000000000e+02 6.987099744006955437e-02 +8.000000000000000000e+02 6.971860503383361940e-02 +8.010000000000000000e+02 6.956671011364025381e-02 +8.020000000000000000e+02 6.941531045483030626e-02 +8.030000000000000000e+02 6.926440384627337299e-02 +8.040000000000000000e+02 6.911398809025275092e-02 +8.050000000000000000e+02 6.896406100235479009e-02 +8.060000000000000000e+02 6.881462041135676111e-02 +8.070000000000000000e+02 6.866566415912081500e-02 +8.080000000000000000e+02 6.851719010048246128e-02 +8.090000000000000000e+02 6.836919610314487472e-02 +8.100000000000000000e+02 6.822168004757425686e-02 +8.110000000000000000e+02 6.807463982689469784e-02 +8.120000000000000000e+02 6.792807334678388487e-02 +8.130000000000000000e+02 6.778197852537252988e-02 +8.140000000000000000e+02 6.763635329314113265e-02 +8.150000000000000000e+02 6.749119559282232284e-02 +8.160000000000000000e+02 6.734650337930052355e-02 +8.170000000000000000e+02 6.720227461951526482e-02 +8.180000000000000000e+02 6.705850729236101371e-02 +8.190000000000000000e+02 6.691519938859687155e-02 +8.200000000000000000e+02 6.677234891074584899e-02 +8.210000000000000000e+02 6.662995387300783834e-02 +8.220000000000000000e+02 6.648801230115966576e-02 +8.230000000000000000e+02 6.634652223246935432e-02 +8.240000000000000000e+02 6.620548171560201867e-02 +8.250000000000000000e+02 6.606488881053071416e-02 +8.260000000000000000e+02 6.592474158844759125e-02 +8.270000000000000000e+02 6.578503813167710379e-02 +8.280000000000000000e+02 6.564577653358878717e-02 +8.290000000000000000e+02 6.550695489850784370e-02 +8.300000000000000000e+02 6.536857134163538696e-02 +8.310000000000000000e+02 6.523062398895929093e-02 +8.320000000000000000e+02 6.509311097717457306e-02 +8.330000000000000000e+02 6.495603045359808758e-02 +8.340000000000000000e+02 6.481938057608727100e-02 +8.350000000000000000e+02 6.468315951296153832e-02 +8.360000000000000000e+02 6.454736544291815592e-02 +8.370000000000000000e+02 6.441199655495803700e-02 +8.380000000000000000e+02 6.427705104830210014e-02 +8.390000000000000000e+02 6.414252713231743952e-02 +8.400000000000000000e+02 6.400842302644024762e-02 +8.410000000000000000e+02 6.387473696009483837e-02 +8.420000000000000000e+02 6.374146717262732520e-02 +8.430000000000000000e+02 6.360861191322132735e-02 +8.440000000000000000e+02 6.347616944083175894e-02 +8.450000000000000000e+02 6.334413802410918115e-02 +8.460000000000000000e+02 6.321251594132408502e-02 +8.470000000000000000e+02 6.308130148030240136e-02 +8.480000000000000000e+02 6.295049293834584225e-02 +8.490000000000000000e+02 6.282008862216974243e-02 +8.500000000000000000e+02 6.269008684783013152e-02 +8.510000000000000000e+02 6.256048594065226343e-02 +8.520000000000000000e+02 6.243128423516935283e-02 +8.530000000000000000e+02 6.230248007504667063e-02 +8.540000000000000000e+02 6.217407181302170988e-02 +8.550000000000000000e+02 6.204605781083433191e-02 +8.560000000000000000e+02 6.191843643916138812e-02 +8.570000000000000000e+02 6.179120607755436700e-02 +8.580000000000000000e+02 6.166436511437235757e-02 +8.590000000000000000e+02 6.153791194671959230e-02 +8.600000000000000000e+02 6.141184498038079059e-02 +8.610000000000000000e+02 6.128616262976280260e-02 +8.620000000000000000e+02 6.116086331782810692e-02 +8.630000000000000000e+02 6.103594547603619774e-02 +8.640000000000000000e+02 6.091140754428196052e-02 +8.650000000000000000e+02 6.078724797083638609e-02 +8.660000000000000000e+02 6.066346521228518224e-02 +8.670000000000000000e+02 6.054005773347347769e-02 +8.680000000000000000e+02 6.041702400744229651e-02 +8.690000000000000000e+02 6.029436251537583641e-02 +8.700000000000000000e+02 6.017207174654047586e-02 +8.710000000000000000e+02 6.005015019822931843e-02 +8.720000000000000000e+02 5.992859637570507186e-02 +8.730000000000000000e+02 5.980740879214777039e-02 +8.740000000000000000e+02 5.968658596859374027e-02 +8.750000000000000000e+02 5.956612643388636830e-02 +8.760000000000000000e+02 5.944602872461682980e-02 +8.770000000000000000e+02 5.932629138507602290e-02 +8.780000000000000000e+02 5.920691296719701041e-02 +8.790000000000000000e+02 5.908789203050245076e-02 +8.800000000000000000e+02 5.896922714205522775e-02 +8.810000000000000000e+02 5.885091687640416069e-02 +8.820000000000000000e+02 5.873295981553382922e-02 +8.830000000000000000e+02 5.861535454881306589e-02 +8.840000000000000000e+02 5.849809967294432311e-02 +8.850000000000000000e+02 5.838119379191560043e-02 +8.860000000000000000e+02 5.826463551694777143e-02 +8.870000000000000000e+02 5.814842346644778087e-02 +8.880000000000000000e+02 5.803255626596106470e-02 +8.890000000000000000e+02 5.791703254812029245e-02 +8.900000000000000000e+02 5.780185095260030603e-02 +8.910000000000000000e+02 5.768701012606759770e-02 +8.920000000000000000e+02 5.757250872213757337e-02 +8.930000000000000000e+02 5.745834540132586238e-02 +8.940000000000000000e+02 5.734451883100093877e-02 +8.950000000000000000e+02 5.723102768533962909e-02 +8.960000000000000000e+02 5.711787064528337649e-02 +8.970000000000000000e+02 5.700504639849190286e-02 +8.980000000000000000e+02 5.689255363929695414e-02 +8.990000000000000000e+02 5.678039106866154123e-02 +9.000000000000000000e+02 5.666855739413403925e-02 +9.010000000000000000e+02 5.655705132980475697e-02 +9.020000000000000000e+02 5.644587159626474060e-02 +9.030000000000000000e+02 5.633501692056052529e-02 +9.040000000000000000e+02 5.622448603615591567e-02 +9.050000000000000000e+02 5.611427768288385770e-02 +9.060000000000000000e+02 5.600439060691189685e-02 +9.070000000000000000e+02 5.589482356069510466e-02 +9.080000000000000000e+02 5.578557530293885847e-02 +9.090000000000000000e+02 5.567664459855761749e-02 +9.100000000000000000e+02 5.556803021863365027e-02 +9.110000000000000000e+02 5.545973094037940504e-02 +9.120000000000000000e+02 5.535174554709338529e-02 +9.130000000000000000e+02 5.524407282812886927e-02 +9.140000000000000000e+02 5.513671157884629526e-02 +9.150000000000000000e+02 5.502966060058165493e-02 +9.160000000000000000e+02 5.492291870060433956e-02 +9.170000000000000000e+02 5.481648469208057900e-02 +9.180000000000000000e+02 5.471035739403662390e-02 +9.190000000000000000e+02 5.460453563132046384e-02 +9.200000000000000000e+02 5.449901823456317074e-02 +9.210000000000000000e+02 5.439380404014901305e-02 +9.220000000000000000e+02 5.428889189017009620e-02 +9.230000000000000000e+02 5.418428063239608822e-02 +9.240000000000000000e+02 5.407996912023766561e-02 +9.250000000000000000e+02 5.397595621270976501e-02 +9.260000000000000000e+02 5.387224077439715930e-02 +9.270000000000000000e+02 5.376882167542018642e-02 +9.280000000000000000e+02 5.366569779140005492e-02 +9.290000000000000000e+02 5.356286800342188043e-02 +9.300000000000000000e+02 5.346033119800532030e-02 +9.310000000000000000e+02 5.335808626706761704e-02 +9.320000000000000000e+02 5.325613210788914670e-02 +9.330000000000000000e+02 5.315446762308459472e-02 +9.340000000000000000e+02 5.305309172056539568e-02 +9.350000000000000000e+02 5.295200331351098549e-02 +9.360000000000000000e+02 5.285120132033131746e-02 +9.370000000000000000e+02 5.275068466464050143e-02 +9.380000000000000000e+02 5.265045227522070770e-02 +9.390000000000000000e+02 5.255050308599330117e-02 +9.400000000000000000e+02 5.245083603598438282e-02 +9.410000000000000000e+02 5.235145006929694395e-02 +9.420000000000000000e+02 5.225234413507608144e-02 +9.430000000000000000e+02 5.215351718748354598e-02 +9.440000000000000000e+02 5.205496818566268669e-02 +9.450000000000000000e+02 5.195669609370881514e-02 +9.460000000000000000e+02 5.185869988064253228e-02 +9.470000000000000000e+02 5.176097852037665065e-02 +9.480000000000000000e+02 5.166353099168728008e-02 +9.490000000000000000e+02 5.156635627818639822e-02 +9.500000000000000000e+02 5.146945336829008427e-02 +9.510000000000000000e+02 5.137282125519330306e-02 +9.520000000000000000e+02 5.127645893683676487e-02 +9.530000000000000000e+02 5.118036541588092542e-02 +9.540000000000000000e+02 5.108453969968018010e-02 +9.550000000000000000e+02 5.098898080025093121e-02 +9.560000000000000000e+02 5.089368773424415848e-02 +9.570000000000000000e+02 5.079865952292122316e-02 +9.580000000000000000e+02 5.070389519212406548e-02 +9.590000000000000000e+02 5.060939377224725477e-02 +9.600000000000000000e+02 5.051515429821440417e-02 +9.610000000000000000e+02 5.042117580944818767e-02 +9.620000000000000000e+02 5.032745734984433311e-02 +9.630000000000000000e+02 5.023399796774737081e-02 +9.640000000000000000e+02 5.014079671592251708e-02 +9.650000000000000000e+02 5.004785265153038898e-02 +9.660000000000000000e+02 4.995516483610217690e-02 +9.670000000000000000e+02 4.986273233551228451e-02 +9.680000000000000000e+02 4.977055421995346673e-02 +9.690000000000000000e+02 4.967862956391449342e-02 +9.700000000000000000e+02 4.958695744614960432e-02 +9.710000000000000000e+02 4.949553694966054435e-02 +9.720000000000000000e+02 4.940436716166575482e-02 +9.730000000000000000e+02 4.931344717357958457e-02 +9.740000000000000000e+02 4.922277608098767077e-02 +9.750000000000000000e+02 4.913235298362070291e-02 +9.760000000000000000e+02 4.904217698533338415e-02 +9.770000000000000000e+02 4.895224719407928471e-02 +9.780000000000000000e+02 4.886256272188840150e-02 +9.790000000000000000e+02 4.877312268483927071e-02 +9.800000000000000000e+02 4.868392620304506924e-02 +9.810000000000000000e+02 4.859497240061909362e-02 +9.820000000000000000e+02 4.850626040566254071e-02 +9.830000000000000000e+02 4.841778935023247771e-02 +9.840000000000000000e+02 4.832955837032919255e-02 +9.850000000000000000e+02 4.824156660586283174e-02 +9.860000000000000000e+02 4.815381320064161114e-02 +9.870000000000000000e+02 4.806629730233984849e-02 +9.880000000000000000e+02 4.797901806248633383e-02 +9.890000000000000000e+02 4.789197463643337510e-02 +9.900000000000000000e+02 4.780516618334321177e-02 +9.910000000000000000e+02 4.771859186615777515e-02 +9.920000000000000000e+02 4.763225085158701716e-02 +9.930000000000000000e+02 4.754614231007906616e-02 +9.940000000000000000e+02 4.746026541580609936e-02 +9.950000000000000000e+02 4.737461934663952240e-02 +9.960000000000000000e+02 4.728920328412990204e-02 +9.970000000000000000e+02 4.720401641348708627e-02 +9.980000000000000000e+02 4.711905792356008843e-02 +9.990000000000000000e+02 4.703432700681647177e-02 +1.000000000000000000e+03 4.694982285932213645e-02 +1.001000000000000000e+03 4.686554468072069018e-02 +1.002000000000000000e+03 4.678149167421420673e-02 +1.003000000000000000e+03 4.669766304654451861e-02 +1.004000000000000000e+03 4.661405800797140814e-02 +1.005000000000000000e+03 4.653067577225675905e-02 +1.006000000000000000e+03 4.644751555664054787e-02 +1.007000000000000000e+03 4.636457658182494695e-02 +1.008000000000000000e+03 4.628185807195582535e-02 +1.009000000000000000e+03 4.619935925460127296e-02 +1.010000000000000000e+03 4.611707936073305286e-02 +1.011000000000000000e+03 4.603501762471245290e-02 +1.012000000000000000e+03 4.595317328426416076e-02 +1.013000000000000000e+03 4.587154558046479397e-02 +1.014000000000000000e+03 4.579013375772208322e-02 +1.015000000000000000e+03 4.570893706375506876e-02 +1.016000000000000000e+03 4.562795474957732911e-02 +1.017000000000000000e+03 4.554718606948134074e-02 +1.018000000000000000e+03 4.546663028101787657e-02 +1.019000000000000000e+03 4.538628664497876969e-02 +1.020000000000000000e+03 4.530615442537974658e-02 +1.021000000000000000e+03 4.522623288944378761e-02 +1.022000000000000000e+03 4.514652130758237819e-02 +1.023000000000000000e+03 4.506701895338031255e-02 +1.024000000000000000e+03 4.498772510357602894e-02 +1.025000000000000000e+03 4.490863903804732243e-02 +1.026000000000000000e+03 4.482976003979229768e-02 +1.027000000000000000e+03 4.475108739491331922e-02 +1.028000000000000000e+03 4.467262039260247453e-02 +1.029000000000000000e+03 4.459435832512118059e-02 +1.030000000000000000e+03 4.451630048778755511e-02 +1.031000000000000000e+03 4.443844617895682109e-02 +1.032000000000000000e+03 4.436079470000889313e-02 +1.033000000000000000e+03 4.428334535532755384e-02 +1.034000000000000000e+03 4.420609745229023280e-02 +1.035000000000000000e+03 4.412905030124629480e-02 +1.036000000000000000e+03 4.405220321550581963e-02 +1.037000000000000000e+03 4.397555551132076995e-02 +1.038000000000000000e+03 4.389910650787198082e-02 +1.039000000000000000e+03 4.382285552725249944e-02 +1.040000000000000000e+03 4.374680189445174366e-02 +1.041000000000000000e+03 4.367094493734085398e-02 +1.042000000000000000e+03 4.359528398665875326e-02 +1.043000000000000000e+03 4.351981837599327302e-02 +1.044000000000000000e+03 4.344454744177256300e-02 +1.045000000000000000e+03 4.336947052324281043e-02 +1.046000000000000000e+03 4.329458696245927496e-02 +1.047000000000000000e+03 4.321989610426901773e-02 +1.048000000000000000e+03 4.314539729629629505e-02 +1.049000000000000000e+03 4.307108988892886792e-02 +1.050000000000000000e+03 4.299697323530446424e-02 +1.051000000000000000e+03 4.292304669129345940e-02 +1.052000000000000000e+03 4.284930961548822498e-02 +1.053000000000000000e+03 4.277576136918651711e-02 +1.054000000000000000e+03 4.270240131637885461e-02 +1.055000000000000000e+03 4.262922882373330891e-02 +1.056000000000000000e+03 4.255624326058293772e-02 +1.057000000000000000e+03 4.248344399891215012e-02 +1.058000000000000000e+03 4.241083041334093445e-02 +1.059000000000000000e+03 4.233840188111369363e-02 +1.060000000000000000e+03 4.226615778208513835e-02 +1.061000000000000000e+03 4.219409749870575016e-02 +1.062000000000000000e+03 4.212222041601004080e-02 +1.063000000000000000e+03 4.205052592160153646e-02 +1.064000000000000000e+03 4.197901340564186290e-02 +1.065000000000000000e+03 4.190768226083528558e-02 +1.066000000000000000e+03 4.183653188241730214e-02 +1.067000000000000000e+03 4.176556166814170828e-02 +1.068000000000000000e+03 4.169477101826717796e-02 +1.069000000000000000e+03 4.162415933554438480e-02 +1.070000000000000000e+03 4.155372602520363695e-02 +1.071000000000000000e+03 4.148347049494242877e-02 +1.072000000000000000e+03 4.141339215491256914e-02 +1.073000000000000000e+03 4.134349041770881555e-02 +1.074000000000000000e+03 4.127376469835493389e-02 +1.075000000000000000e+03 4.120421441429165943e-02 +1.076000000000000000e+03 4.113483898536566402e-02 +1.077000000000000000e+03 4.106563783381777383e-02 +1.078000000000000000e+03 4.099661038426729437e-02 +1.079000000000000000e+03 4.092775606370514102e-02 +1.080000000000000000e+03 4.085907430147769220e-02 +1.081000000000000000e+03 4.079056452927744270e-02 +1.082000000000000000e+03 4.072222618113039566e-02 +1.083000000000000000e+03 4.065405869338484246e-02 +1.084000000000000000e+03 4.058606150469744323e-02 +1.085000000000000000e+03 4.051823405602600348e-02 +1.086000000000000000e+03 4.045057579061465958e-02 +1.087000000000000000e+03 4.038308615398251977e-02 +1.088000000000000000e+03 4.031576459391483097e-02 +1.089000000000000000e+03 4.024861056044839319e-02 +1.090000000000000000e+03 4.018162350586326065e-02 +1.091000000000000000e+03 4.011480288466880151e-02 +1.092000000000000000e+03 4.004814815359631491e-02 +1.093000000000000000e+03 3.998165877158500747e-02 +1.094000000000000000e+03 3.991533419976994040e-02 +1.095000000000000000e+03 3.984917390147672128e-02 +1.096000000000000000e+03 3.978317734220530866e-02 +1.097000000000000000e+03 3.971734398962056128e-02 +1.098000000000000000e+03 3.965167331354341879e-02 +1.099000000000000000e+03 3.958616478593766919e-02 diff --git a/spectractor/extractor/extractor.py b/spectractor/extractor/extractor.py index bce64c9e6..3b0e5154e 100644 --- a/spectractor/extractor/extractor.py +++ b/spectractor/extractor/extractor.py @@ -16,7 +16,7 @@ from spectractor.extractor.background import extract_spectrogram_background_sextractor from spectractor.extractor.chromaticpsf import ChromaticPSF from spectractor.extractor.psf import load_PSF -from spectractor.tools import ensure_dir, plot_image_simple, from_lambda_to_colormap, plot_spectrum_simple +from spectractor.tools import ensure_dir, plot_image_simple, from_lambda_to_colormap, plot_spectrum_simple, mask_cosmics from spectractor.fit.fitter import (run_minimisation, run_minimisation_sigma_clipping, write_fitparameter_json, RegFitWorkspace, FitWorkspace, FitParameters) @@ -63,19 +63,21 @@ def __init__(self, spectrum, amplitude_priors_method="noprior", verbose=False, p psf_poly_params_names = np.copy(spectrum.chromatic_psf.params.axis_names[length:]) psf_poly_params_bounds = spectrum.chromatic_psf.set_bounds() D2CCD = np.copy(spectrum.header['D2CCD']) - p = np.array([1, 1, 1, D2CCD, np.copy(spectrum.header['PIXSHIFT']), 0, - np.copy(spectrum.rotation_angle), 1, parameters.OBS_CAMERA_ROTATION, + p = np.array([1, 1, 0, D2CCD, np.copy(spectrum.header['PIXSHIFT']), 0, + np.copy(spectrum.rotation_angle), 1, 1, parameters.OBS_CAMERA_ROTATION, np.copy(spectrum.pressure), np.copy(spectrum.temperature), np.copy(spectrum.airmass)]) - self.psf_params_start_index = np.array([12 + len(self.psf_poly_params) * k for k in range(len(self.diffraction_orders))]) + self.psf_params_start_index = np.array([p.size + len(self.psf_poly_params) * k for k in range(len(self.diffraction_orders))]) self.saturation = spectrum.spectrogram_saturation p = np.concatenate([p] + [self.psf_poly_params] * len(self.diffraction_orders)) + # for order in self.diffraction_orders: + # p = np.concatenate([p] + [self.psf_poly_params * order]) input_labels = [f"A{order}" for order in self.diffraction_orders] - input_labels += [r"D_CCD [mm]", r"shift_x [pix]", r"shift_y [pix]", r"angle [deg]", "B", "R", "P [hPa]", "T [Celsius]", "z"] + input_labels += [r"D_CCD [mm]", r"shift_x [pix]", r"shift_y [pix]", r"angle [deg]", "B", "A_star", "R", "P [hPa]", "T [Celsius]", "z"] for order in self.diffraction_orders: input_labels += [label+f"_{order}" for label in psf_poly_params_labels] axis_names = [f"$A_{order}$" for order in self.diffraction_orders] axis_names += [r"$D_{CCD}$ [mm]", r"$\delta_{\mathrm{x}}^{(\mathrm{fit})}$ [pix]", - r"$\delta_{\mathrm{y}}^{(\mathrm{fit})}$ [pix]", r"$\alpha$ [deg]", "$B$", "R", + r"$\delta_{\mathrm{y}}^{(\mathrm{fit})}$ [pix]", r"$\alpha$ [deg]", "$B$", r"$A_{star}$", "R", r"$P_{\mathrm{atm}}$ [hPa]", r"$T_{\mathrm{atm}}$ [Celcius]", "$z$"] for order in self.diffraction_orders: axis_names += [label+rf"$\!_{order}$" for label in psf_poly_params_names] @@ -83,7 +85,7 @@ def __init__(self, spectrum, amplitude_priors_method="noprior", verbose=False, p [D2CCD - 3 * parameters.DISTANCE2CCD_ERR, D2CCD + 3 * parameters.DISTANCE2CCD_ERR], [-parameters.PIXSHIFT_PRIOR, parameters.PIXSHIFT_PRIOR], [-10 * parameters.PIXSHIFT_PRIOR, 10 * parameters.PIXSHIFT_PRIOR], - [-90, 90], [0.2, 5], [-360, 360], [300, 1100], [-100, 100], [1.001, 3]] + [-90, 90], [0.2, 5], [0., np.inf], [-360, 360], [0, np.inf], [-100, 100], [1.001, 3]] bounds += list(psf_poly_params_bounds) * len(self.diffraction_orders) fixed = [False] * p.size for k, par in enumerate(input_labels): @@ -91,7 +93,20 @@ def __init__(self, spectrum, amplitude_priors_method="noprior", verbose=False, p fixed[k] = True for k, par in enumerate(input_labels): if "y_c" in par: - fixed[k] = False + fixed[k] = True + p[k] = 0 + for k, par in enumerate(input_labels): + #if "y_c" in par and (("y_c_0" not in par and "y_c_1" not in par)) and par[-2:] == f"_{spectrum.order}": # or (par[-2:] == "_2" or par[-2:] == "_3")): + # fixed[k] = False + # p[k] = 0 + #if k >= self.psf_params_start_index[0] and "y_c" in par and par[-2:] != f"_{spectrum.order}": # and (("y_c_0" in par or "y_c_1" in par)): # or (par[-2:] == "_2" or par[-2:] == "_3")): + # fixed[k] = False + # p[k] = 0 + if k >= self.psf_params_start_index[0] and "y_c" not in par and "x_c" not in par and par[-2:] != f"_{spectrum.order}" and "_0_" not in par: + fixed[k] = True + p[k] = 0 + if k >= self.psf_params_start_index[0] and "eta" in par and par[-2:] != f"_{spectrum.order}": + fixed[k] = True p[k] = 0 params = FitParameters(p, labels=input_labels, axis_names=axis_names, fixed=fixed, bounds=bounds, @@ -103,13 +118,15 @@ def __init__(self, spectrum, amplitude_priors_method="noprior", verbose=False, p params.fixed[params.get_index(f"A{order}")] = True if "A2" in params.labels: params.fixed[params.get_index("A2")] = (not spectrum.disperser.flat_ratio_order_2over1) and (not ("A2_T" in spectrum.header)) + if spectrum.spectrogram_starfield is None: + params.fixed[params.get_index("A_star")] = True # Astar params.fixed[params.get_index("D_CCD [mm]")] = True # D2CCD: spectrogram can not tell something on this parameter: rely on calibrate_spectrum params.fixed[params.get_index("shift_x [pix]")] = True # delta x: if False, extracted spectrum is biased compared with truth - params.fixed[params.get_index("shift_y [pix]")] = True # delta y - params.fixed[params.get_index("angle [deg]")] = True # angle + params.fixed[params.get_index("shift_y [pix]")] = False # delta y + params.fixed[params.get_index("angle [deg]")] = False # angle params.fixed[params.get_index("B")] = True # B: not needed in simulations, to check with data params.fixed[params.get_index("R")] = True # camera rot - params.fixed[params.get_index("P [hPa]")] = True # pressure + params.fixed[params.get_index("P [hPa]")] = False # pressure params.fixed[params.get_index("T [Celsius]")] = True # temperature params.fixed[params.get_index("z")] = True # airmass @@ -119,13 +136,31 @@ def __init__(self, spectrum, amplitude_priors_method="noprior", verbose=False, p # crop data to fit faster self.lambdas = self.spectrum.lambdas self.bgd_width = parameters.PIXWIDTH_BACKGROUND + parameters.PIXDIST_BACKGROUND - parameters.PIXWIDTH_SIGNAL - self.data = spectrum.spectrogram[self.bgd_width:-self.bgd_width, :] - self.err = spectrum.spectrogram_err[self.bgd_width:-self.bgd_width, :] - self.bgd = spectrum.spectrogram_bgd[self.bgd_width:-self.bgd_width, :] - self.bgd_flat = self.bgd.flatten() - self.Ny, self.Nx = self.data.shape + if spectrum.spectrogram_data.shape[0] < 2 * self.bgd_width: + # Data has been already cropped + self.bgd_width = 0 + rows = np.arange(self.bgd_width, spectrum.spectrogram_data.shape[0]-self.bgd_width) + self.Ny, self.Nx = spectrum.spectrogram_data[rows, :].shape yy, xx = np.mgrid[:self.Ny, :self.Nx] self.pixels = np.asarray([xx, yy], dtype=int) + self.data = spectrum.spectrogram_data[rows, :].flatten() + self.err = spectrum.spectrogram_err[rows, :].flatten() + self.bgd = spectrum.spectrogram_bgd[rows, :].flatten() + if spectrum.spectrogram_flat is not None: + self.flat = spectrum.spectrogram_flat[rows, :].flatten() + self.bgd *= self.flat + else: + self.flat = None + if spectrum.spectrogram_starfield is not None: + self.starfield = spectrum.spectrogram_starfield[rows, :].flatten() + if self.flat is not None: + self.starfield *= self.flat + else: + self.starfield = None + if spectrum.spectrogram_mask is not None: + self.mask = list(np.where(spectrum.spectrogram_mask[rows, :].astype(bool).ravel())[0]) + else: + self.mask = [] # adapt the ChromaticPSF table shape if self.Nx != self.spectrum.chromatic_psf.Nx: @@ -157,23 +192,13 @@ def __init__(self, spectrum, amplitude_priors_method="noprior", verbose=False, p self.psf_profile_params[order] = None self.fix_psf_cube = False - # prepare the background, data and errors - self.bgd_std = float(np.std(np.random.poisson(np.abs(self.bgd)))) - # error matrix # here image uncertainties are assumed to be uncorrelated # (which is not exactly true in rotated images) self.W = 1. / (self.err * self.err) - self.W = self.W.flatten() - - # flat data for fitworkspace - self.data = self.data.flatten() - self.bgd_flat - self.err = self.err.flatten() self.data_before_mask = np.copy(self.data) - self.W_before_mask = np.copy(self.W) - - # create mask - self.sqrtW = sparse.diags(np.sqrt(self.W), format="dia", dtype="float32") + self.W_before_mask = self.W.copy() + self.mask_before_mask = list(np.copy(self.mask)) # design matrix self.M = None @@ -199,7 +224,7 @@ def __init__(self, spectrum, amplitude_priors_method="noprior", verbose=False, p self.reg = float(spectrum.header['PSF_REG']) if self.reg < 0: self.reg = parameters.PSF_FIT_REG_PARAM - self.trace_r = self.Nx / np.min(self.fwhm_priors) # spectrophotometric uncertainty principle + self.trace_r = self.Nx / np.median(self.fwhm_priors) # spectrophotometric uncertainty principle self.my_logger.info(f"\n\tFull forward model fitting with regularisation parameter r={self.reg}.") self.Q = np.zeros((self.Nx, self.Nx), dtype="float32") self.Q_dot_A0 = np.zeros(self.Nx, dtype="float32") @@ -260,7 +285,7 @@ def set_mask(self, params=None, fwhmx_clip=3*parameters.PSF_FWHM_CLIP, fwhmy_cli self.my_logger.info("\n\tReset spectrogram mask with current parameters.") if params is None: params = self.params.values - A1, A2, A3, D2CCD, dx0, dy0, angle, B, rot, pressure, temperature, airmass, *psf_poly_params_all = params + A1, A2, A3, D2CCD, dx0, dy0, angle, B, Astar, rot, pressure, temperature, airmass, *psf_poly_params_all = params poly_params = np.array(psf_poly_params_all).reshape((len(self.diffraction_orders), -1)) lambdas = self.spectrum.compute_lambdas_in_spectrogram(D2CCD, dx0, dy0, angle, niter=5, with_adr=True, @@ -285,30 +310,48 @@ def set_mask(self, params=None, fwhmx_clip=3*parameters.PSF_FWHM_CLIP, fwhmy_cli self.psf_cubes_masked[order] = self.spectrum.chromatic_psf.convolve_psf_cube_masked(psf_cube_masked) # make rectangular mask per wavelength - self.boundaries[order], self.psf_cubes_masked[order] = self.spectrum.chromatic_psf.get_boundaries(self.psf_cubes_masked[order]) - self.psf_cube_sparse_indices[order], self.M_sparse_indices[order] = self.spectrum.chromatic_psf.get_sparse_indices(self.psf_cubes_masked[order]) - mask = np.sum(self.psf_cubes_masked[self.diffraction_orders[0]].reshape(psf_cube_masked.shape[0], psf_cube_masked[0].size), axis=0) == 0 - self.W = np.copy(self.W_before_mask) - self.W[mask] = 0 - self.sqrtW = sparse.diags(np.sqrt(self.W), format="dia", dtype="float32") - self.mask = list(np.where(mask)[0]) + self.boundaries[order], self.psf_cubes_masked[order] = self.spectrum.chromatic_psf.set_rectangular_boundaries(self.psf_cubes_masked[order]) + if k > 0: + # spectrogram model must be accurate inside the k=0 order footprint: enlarge the next order footprints + self.boundaries[order]["ymin"] = np.zeros_like(self.boundaries[order]["ymin"]) + self.boundaries[order]["ymax"] = self.Ny * np.ones_like(self.boundaries[order]["ymax"]) + self.psf_cube_sparse_indices[order], self.M_sparse_indices[order] = self.spectrum.chromatic_psf.get_sparse_indices(self.boundaries[order]) + # mask = np.sum(self.psf_cubes_masked[self.diffraction_orders[0]].reshape(psf_cube_masked.shape[0], psf_cube_masked[0].size), axis=0) == 0 + # cumulate the boolean values as int + weight_mask = np.sum(self.psf_cubes_masked[self.diffraction_orders[0]], axis=0) + # look for indices with maximum weight per column (all sheets of the psf cube have contributed) + res = np.max(weight_mask, axis=0)[np.newaxis,:] * np.ones((weight_mask.shape[0],1)) + # keep only the pixels where all psf_cube sheets have contributed per column + mask = (weight_mask != res).ravel() + self.W = self.W_before_mask.copy() + self.mask = list(np.copy(self.mask_before_mask)) + self.mask += list(np.where(mask)[0]) + self.mask = list(set(self.mask)) + self.W[self.mask] = 0 def simulate(self, *params): r""" Compute a ChromaticPSF2D model given PSF shape parameters and minimizing amplitude parameters using a spectrogram data array. - The ChromaticPSF2D model :math:`\vec{m}(\vec{x},\vec{p})` can be written as + The full forward model of the spectrogram image :math:`\vec{I}(\vec{x},\vec{p})` can be written as .. math :: - :label: chromaticpsf2d + :label: ffm + + \vec{I}(\vec{x},\vec{p}) = \sum_{i=0}^{N_x} A_i F_i \phi\left(\vec{x},\vec{p}_i\right) + + \bar F B b\left(\vec{x}\right) + \bar F S s\left(\vec{x}\right) - \vec{m}(\vec{x},\vec{p}) = \sum_{i=0}^{N_x} A_i \phi\left(\vec{x},\vec{p}_i\right) + with + - :math:`\vec{x}` the 2D array of the pixel coordinates, + - :math:`\vec{A}` the amplitude parameter array along the x axis of the spectrogram, + - :math:`\phi\left(\vec{x},\vec{p}_i\right)` the 2D PSF kernel whose integral is normalised to one parametrized + with the :math:`\vec{p}_i` non-linear parameter array, + - math:`B b\left(\vec{x}\right)` the background function weighted by a scalar math:`B`, + - math:`S s\left(\vec{x}\right)` the star field function weighted by a scalar math:`S`, + - :math:`F_i` a flat cube (wavelengths indexed by :math:`i`) and \bar F the mean flat. - with :math:`\vec{x}` the 2D array of the pixel coordinates, :math:`\vec{A}` the amplitude parameter array - along the x axis of the spectrogram, :math:`\phi\left(\vec{x},\vec{p}_i\right)` the 2D PSF kernel whose integral - is normalised to one parametrized with the :math:`\vec{p}_i` non-linear parameter array. If the :math:`\vec{x}` - 2D array is flatten in 1D, equation :eq:`chromaticpsf2d` is + If the :math:`\vec{x}` 2D array is flatten in 1D, equation :eq:`ffm` is .. math :: :label: chromaticpsf2d_matrix @@ -318,11 +361,11 @@ def simulate(self, *params): \vec{m}(\vec{x},\vec{p}) & = \mathbf{M}\left(\vec{x},\vec{p}\right) \mathbf{A} \\ \mathbf{M}\left(\vec{x},\vec{p}\right) & = \left(\begin{array}{cccc} - \phi\left(\vec{x}_1,\vec{p}_1\right) & \phi\left(\vec{x}_2,\vec{p}_1\right) & ... - & \phi\left(\vec{x}_{N_x},\vec{p}_1\right) \\ + F_1\phi\left(\vec{x}_1,\vec{p}_1\right) & F_2\phi\left(\vec{x}_2,\vec{p}_1\right) & ... + & F_{N_x}\phi\left(\vec{x}_{N_x},\vec{p}_1\right) \\ ... & ... & ... & ...\\ - \phi\left(\vec{x}_1,\vec{p}_{N_x}\right) & \phi\left(\vec{x}_2,\vec{p}_{N_x}\right) & ... - & \phi\left(\vec{x}_{N_x},\vec{p}_{N_x}\right) \\ + F_1\phi\left(\vec{x}_1,\vec{p}_{N_x}\right) & F_2\phi\left(\vec{x}_2,\vec{p}_{N_x}\right) & ... + & F_{N_x}\phi\left(\vec{x}_{N_x},\vec{p}_{N_x}\right) \\ \end{array}\right) \end{align} @@ -330,26 +373,26 @@ def simulate(self, *params): with :math:`\mathbf{M}` the design matrix. The goal of this function is to perform a minimisation of the amplitude vector :math:`\mathbf{A}` given - a set of non-linear parameters :math:`\mathbf{p}` and a spectrogram data array :math:`mathbf{y}` modelise as + a set of non-linear parameters :math:`\mathbf{p}` and a spectrogram data array :math:`\mathbf{D}` modelised as - .. math:: \mathbf{y} = \mathbf{m}(\vec{x},\vec{p}) + \vec{\epsilon} + .. math:: \mathbf{D} = \mathbf{m}(\vec{x},\vec{p}) + \bar F B b\left(\vec{x}\right) + \bar F S s\left(\vec{x}\right) + \vec{\epsilon} with :math:`\vec{\epsilon}` a random noise vector. The :math:`\chi^2` function to minimise is .. math:: - :label: chromaticspsf2d_chi2 + :label: ffm_chi2 - \chi^2(\mathbf{A})= \left(\mathbf{y} - \mathbf{M}\left(\vec{x},\vec{p}\right) \mathbf{A}\right)^T \mathbf{W} - \left(\mathbf{y} - \mathbf{M}\left(\vec{x},\vec{p}\right) \mathbf{A} \right) + \chi^2(\mathbf{A})= \left(\mathbf{D} - \bar F B b\left(\vec{x}\right) - \bar F S s\left(\vec{x}\right) - \mathbf{M}\left(\vec{x},\vec{p}\right) \mathbf{A}\right)^T \mathbf{W} + \left(\mathbf{D} - \bar F B b\left(\vec{x}\right) - \bar F S s\left(\vec{x}\right) -\mathbf{M}\left(\vec{x},\vec{p}\right) \mathbf{A} \right) with :math:`\mathbf{W}` the weight matrix, inverse of the covariance matrix. In our case this matrix is diagonal - as the pixels are considered all independent. The minimum of equation :eq:`chromaticspsf2d_chi2` is reached for + as the pixels are considered all independent. The minimum of equation :eq:`ffm_chi2` is reached for a set of amplitude parameters :math:`\hat{\mathbf{A}}` given by .. math:: - \hat{\mathbf{A}} = (\mathbf{M}^T \mathbf{W} \mathbf{M})^{-1} \mathbf{M}^T \mathbf{W} \mathbf{y} + \hat{\mathbf{A}} = (\mathbf{M}^T \mathbf{W} \mathbf{M})^{-1} \mathbf{M}^T \mathbf{W}\left( \mathbf{D} - \bar F B b\left(\vec{x}\right) - \bar F S s\left(\vec{x}\right) \right) The error matrix on the :math:`\hat{\mathbf{A}}` coefficient is simply :math:`(\mathbf{M}^T \mathbf{W} \mathbf{M})^{-1}`. @@ -369,6 +412,7 @@ def simulate(self, *params): Load data: >>> spec = Spectrum("./tests/data/sim_20170530_134_spectrum.fits") + >>> spec.plot_spectrogram() Simulate the data with fixed amplitude priors: @@ -396,19 +440,23 @@ def simulate(self, *params): # linear regression for the amplitude parameters # prepare the vectors self.params.values = np.asarray(params) - A1, A2, A3, D2CCD, dx0, dy0, angle, B, rot, pressure, temperature, airmass, *poly_params_all = params + A1, A2, A3, D2CCD, dx0, dy0, angle, B, Astar, rot, pressure, temperature, airmass, *poly_params_all = params poly_params = np.array(poly_params_all).reshape((len(self.diffraction_orders), -1)) self.spectrum.adr_params[2] = temperature self.spectrum.adr_params[3] = pressure self.spectrum.adr_params[-1] = airmass parameters.OBS_CAMERA_ROTATION = rot - W_dot_data = (self.W * (self.data + (1 - B) * self.bgd_flat)).astype("float32") + R = self.data - B * self.bgd + if self.starfield is not None: + R -= self.starfield + W_dot_data = (self.W * R).astype("float32") # Evaluate ADR and compute wavelength arrays self.lambdas = self.spectrum.compute_lambdas_in_spectrogram(D2CCD, dx0, dy0, angle, niter=5, with_adr=True, order=self.diffraction_orders[0]) M = None + # distance = None for k, order in enumerate(self.diffraction_orders): if self.tr[k] is None or self.params[f"A{order}"] == 0: # diffraction order undefined self.psf_profile_params[order] = None @@ -429,34 +477,40 @@ def simulate(self, *params): self.psf_profile_params[order][:, 1] = dispersion_law.real + self.spectrum.spectrogram_x0 self.psf_profile_params[order][:, 2] += dispersion_law.imag - self.bgd_width - # Matrix filling - # Older piece of code, using full matrices (non sparse). Keep here for temporary archive. - # psf_cube_order = self.spectrum.chromatic_psf.build_psf_cube(self.pixels, profile_params[-1], fwhmx_clip=3 * parameters.PSF_FWHM_CLIP, fwhmy_clip=parameters.PSF_FWHM_CLIP, dtype="float32", mask=self.psf_cubes_masked[order], boundaries=self.boundaries[order]) - # if self.sparse_indices is None: - # self.sparse_indices = np.concatenate([np.where(self.psf_cube_masked[k].ravel() > 0)[0] for k in range(len(profile_params))]) - # if psf_cube is None: - # psf_cube = psf_cube_order + # if k == 0: + # distance = np.abs(dispersion_law) # else: - # psf_cube += psf_cube_order + # distance_order = np.abs(dispersion_law) + # for p in range(3, self.psf_profile_params[order].shape[1]): + # self.psf_profile_params[order][:, p] = np.copy(self.psf_profile_params[self.spectrum.order][:, p]) + # self.psf_profile_params[order][:, p] = interpolate.interp1d(distance, self.psf_profile_params[order][:, p], + # kind="cubic", fill_value="extrapolate")(distance_order) + + # Matrix filling M_order = self.spectrum.chromatic_psf.build_sparse_M(self.pixels, self.psf_profile_params[order], - dtype="float32", M_sparse_indices=self.M_sparse_indices[order], boundaries=self.boundaries[order]) + dtype="float32", M_sparse_indices=self.M_sparse_indices[order], + boundaries=self.boundaries[order]) if M is None: M = M_order else: M += M_order - # M = psf_cube.reshape(len(profile_params[0]), self.pixels[0].size).T # flattening - # if self.sparse_indices is None: - # self.sparse_indices = np.where(M > 0) - # M = sparse.csc_matrix((M[self.sparse_indices].ravel(), self.sparse_indices), shape=M.shape, dtype="float32") + if self.flat is not None: + # multiply each M matrix columns by the flat array (see the docstring) + # TODO: if flat array is a cube flat, needs to multiply directly in build_sparse_M + dia = sparse.dia_matrix(([self.flat], [0]), shape=(self.flat.size, self.flat.size)) + M = (dia @ M).tocsc() + + # Algebra to compute amplitude parameters if self.amplitude_priors_method != "fixed": - M_dot_W = M.T @ self.sqrtW + M_dot_W = M.T @ sparse.diags(np.sqrt(self.W), format="dia", dtype="float32") if sparse_dot_mkl is None: M_dot_W_dot_M = M_dot_W @ M_dot_W.T else: tri = sparse_dot_mkl.gram_matrix_mkl(M_dot_W, transpose=True) - dia = sparse.csr_matrix((tri.diagonal(), (np.arange(tri.shape[0]), np.arange(tri.shape[0]))), shape=tri.shape, dtype="float32") + dia = sparse.csr_matrix((tri.diagonal(), (np.arange(tri.shape[0]), np.arange(tri.shape[0]))), + shape=tri.shape, dtype="float32") M_dot_W_dot_M = (tri + tri.T - dia).toarray() if self.amplitude_priors_method != "spectrum": if self.amplitude_priors_method == "keep": @@ -512,6 +566,9 @@ def simulate(self, *params): # Compute the model self.model = M @ amplitude_params + self.model += B * self.bgd + if self.starfield is not None: + self.model += Astar * self.starfield self.model_err = np.zeros_like(self.model) return self.pixels, self.model, self.model_err @@ -521,7 +578,6 @@ def jacobian(self, params, epsilon, model_input=None): lambdas, model, model_err = model_input else: lambdas, model, model_err = self.simulate(*params) - model = model.flatten() J = np.zeros((params.size, model.size)) method = copy.copy(self.amplitude_priors_method) self.amplitude_priors_method = "keep" @@ -535,7 +591,7 @@ def jacobian(self, params, epsilon, model_input=None): epsilon[ip] = - epsilon[ip] tmp_p[ip] += epsilon[ip] tmp_lambdas, tmp_model, tmp_model_err = self.simulate(*tmp_p) - J[ip] = (tmp_model.flatten() - model) / epsilon[ip] + J[ip] = (tmp_model - model) / epsilon[ip] self.amplitude_priors_method = method for k, order in enumerate(self.diffraction_orders): if self.psf_profile_params[order] is None: @@ -591,7 +647,7 @@ def amplitude_derivatives(self): """ # compute matrices without derivatives WM = sparse.dia_matrix((self.W, 0), shape=(self.W.size, self.W.size), dtype="float32") @ self.M - WD = (self.W * (self.data + (1 - self.params.values[self.params.get_index("B")]) * self.bgd_flat)).astype("float32") + WD = (self.W * (self.data + (1 - self.params.values[self.params.get_index("B")]) * self.bgd)).astype("float32") MWD = self.M.T @ WD if self.amplitude_priors_method == "spectrum": MWD += np.float32(self.reg) * self.Q_dot_A0 @@ -642,10 +698,10 @@ def plot_spectrogram_comparison_simple(self, ax, title='', extent=None, dispersi lambdas = self.spectrum.lambdas sub = np.where((lambdas > parameters.LAMBDA_MIN) & (lambdas < parameters.LAMBDA_MAX))[0] - sub = np.where(sub < self.spectrum.spectrogram.shape[1])[0] - data = (data + self.bgd_flat).reshape((self.Ny, self.Nx)) + sub = np.where(sub < self.spectrum.spectrogram_data.shape[1])[0] + data = data.reshape((self.Ny, self.Nx)) err = self.err.reshape((self.Ny, self.Nx)) - model = (self.model + self.params["B"] * self.bgd_flat).reshape((self.Ny, self.Nx)) + model = self.model.reshape((self.Ny, self.Nx)) if extent is not None: sub = np.where((lambdas > extent[0]) & (lambdas < extent[1]))[0] if len(sub) > 0: @@ -768,11 +824,18 @@ def adjust_spectrogram_position_parameters(self): epsilon[epsilon == 0] = 1e-4 fixed_default = np.copy(self.params.fixed) self.params.fixed = [True] * len(self.params.values) + strategy = copy.copy(self.amplitude_priors_method) + self.amplitude_priors_method = "fixed" + # let A1 free to help finding the spectrogram trace, with amplitude fixed to prior + self.params.fixed[self.params.get_index(r"A1")] = False # A1 self.params.fixed[self.params.get_index(r"shift_y [pix]")] = False # shift y self.params.fixed[self.params.get_index(r"angle [deg]")] = False # angle run_minimisation(self, "newton", epsilon, xtol=1e-2, ftol=0.01, with_line_search=False) # 1000 / self.data.size) self.params.fixed = fixed_default self.set_mask(params=self.params.values, fwhmx_clip=3 * parameters.PSF_FWHM_CLIP, fwhmy_clip=parameters.PSF_FWHM_CLIP) + # refix A1=1 and let amplitude parameters free + self.amplitude_priors_method = strategy + self.params.values[self.params.get_index(r"A1")] = 1 def run_ffm_minimisation(w, method="newton", niter=2): @@ -797,7 +860,7 @@ def run_ffm_minimisation(w, method="newton", niter=2): >>> spec = Spectrum("./tests/data/sim_20170530_134_spectrum.fits") >>> parameters.VERBOSE = True - >>> w = FullForwardModelFitWorkspace(spec, verbose=True, plot=True, live_fit=True, amplitude_priors_method="spectrum") + >>> w = FullForwardModelFitWorkspace(spec, verbose=True, plot=True, live_fit=False, amplitude_priors_method="spectrum") >>> spec = run_ffm_minimisation(w, method="newton") # doctest: +ELLIPSIS >>> if 'LBDAS_T' in spec.header: plot_comparison_truth(spec, w) @@ -883,23 +946,6 @@ def run_ffm_minimisation(w, method="newton", niter=2): if parameters.DEBUG and parameters.DISPLAY: w.plot_fit() - # recompute angle and dy0 if fixed while y_c parameters are free - # if w.fixed[3] and w.fixed[4] and not np.any([w.fixed[k] for k, par in enumerate(w.input_labels) if "y_c" in par]): - # pval_leg = [w.p[k] for k, par in enumerate(w.input_labels) if "y_c" in par][ - # :w.spectrum.chromatic_psf.degrees["y_c"] + 1] - # pval_poly = np.polynomial.legendre.leg2poly(pval_leg) - # new_dy0, new_angle = w.p[2], w.p[4] - # from numpy.polynomial import Polynomial as P - # p = P(pval_poly) - # pX = P([0, 0.5 * (w.spectrum.spectrogram_Nx)]) - # pfinal = p(pX) - # pval_poly = pfinal.coef - # for k in range(pval_poly.size): - # if k == 0: - # new_dy0 += pval_poly[k] - # if k == 1: - # new_angle += np.arctan(pval_poly[k]) * 180 / np.pi - w.spectrum.lambdas = np.copy(w.lambdas) w.spectrum.chromatic_psf.table['lambdas'] = np.copy(w.lambdas) w.spectrum.data = np.copy(w.amplitude_params) @@ -909,8 +955,8 @@ def run_ffm_minimisation(w, method="newton", niter=2): w.spectrum.chromatic_psf.table["amplitude"] = np.copy(w.amplitude_params) w.spectrum.chromatic_psf.from_profile_params_to_shape_params(w.psf_profile_params[w.diffraction_orders[0]]) w.spectrum.chromatic_psf.params.values = w.spectrum.chromatic_psf.from_table_to_poly_params() - w.spectrum.spectrogram_fit = w.model - w.spectrum.spectrogram_residuals = (w.data - w.spectrum.spectrogram_fit) / w.err + w.spectrum.spectrogram_fit = w.model.reshape((w.Ny, w.Nx)) + w.spectrum.spectrogram_residuals = (w.data.reshape((w.Ny, w.Nx)) - w.spectrum.spectrogram_fit) / w.err.reshape((w.Ny, w.Nx)) w.spectrum.header['CHI2_FIT'] = w.costs[-1] / (w.data.size - len(w.mask)) w.spectrum.header['PIXSHIFT'] = w.params[r"shift_x [pix]"] w.spectrum.header['D2CCD'] = w.params[r"D_CCD [mm]"] @@ -929,6 +975,15 @@ def run_ffm_minimisation(w, method="newton", niter=2): w.params.set(r"shift_x [pix]", w.spectrum.header['PIXSHIFT']) w.spectrum.convert_from_flam_to_ADUrate() + # Mask forgotten cosmics + cr_mask = mask_cosmics(w.spectrum.spectrogram_residuals, maxiter=3, sigma_clip=5, convolve_kernel_size=0) + if np.sum(cr_mask) > 0: + my_logger.info(f"\n\t{np.sum(cr_mask)} new pixels identified and masked as cosmics.") + cr_mask_flat = cr_mask.flatten() + w.mask += [i for i in range(cr_mask_flat.size) if cr_mask_flat[i]] + w.mask = list(set(w.mask)) + w.mask.sort() + if w.filename != "": parameters.SAVE = True w.params.plot_correlation_matrix() @@ -939,14 +994,13 @@ def run_ffm_minimisation(w, method="newton", niter=2): parameters.SAVE = False # Propagate parameters - A1, A2, A3, D2CCD, dx0, dy0, angle, B, rot, pressure, temperature, airmass, *poly_params_all = w.params.values - w.spectrum.rotation_angle = angle - w.spectrum.spectrogram_bgd *= B - w.spectrum.spectrogram_bgd_rms *= B - w.spectrum.spectrogram_x0 += dx0 - w.spectrum.spectrogram_y0 += dy0 - w.spectrum.x0[0] += dx0 - w.spectrum.x0[1] += dy0 + w.spectrum.rotation_angle = w.params.values[w.params.get_index("angle [deg]")] + w.spectrum.spectrogram_bgd *= w.params.values[w.params.get_index("B")] + w.spectrum.spectrogram_bgd_rms *= w.params.values[w.params.get_index("B")] + w.spectrum.spectrogram_x0 += w.params.values[w.params.get_index("shift_x [pix]")] + w.spectrum.spectrogram_y0 += w.params.values[w.params.get_index("shift_y [pix]")] + w.spectrum.x0[0] += w.params.values[w.params.get_index("shift_x [pix]")] + w.spectrum.x0[1] += w.params.values[w.params.get_index("shift_y [pix]")] w.spectrum.header["TARGETX"] = w.spectrum.x0[0] w.spectrum.header["TARGETY"] = w.spectrum.x0[1] w.spectrum.header['MEANFWHM'] = np.mean(np.array(w.spectrum.chromatic_psf.table['fwhm'])) @@ -1037,7 +1091,7 @@ def SpectractorRun(image, output_directory, guess=None): spectrum: Spectrum The extracted spectrum object. w: FullForwardModelFitWorkspace - The FFM wrokspace. + The FFM workspace. Examples -------- @@ -1080,11 +1134,11 @@ def SpectractorRun(image, output_directory, guess=None): my_logger.info(f"\n\tNo guess position of order 0 has been given. Assuming the spectrum to extract comes " f"from the brightest object, guess position is set as {image.target_guess}.") if parameters.DEBUG: - image.plot_image(scale='symlog', title="before rebinning", target_pixcoords=image.target_guess, cmap='gray', vmax=1e3) + image.plot_image(scale='symlog', title="before rebinning", target_pixcoords=image.target_guess, vmax=1e3) # Use fast mode if parameters.CCD_REBIN > 1: - my_logger.info('\n\t ======================= REBIN =============================') + my_logger.info('\n\t ======================= REBIN =============================') image.rebin() if parameters.DEBUG: image.plot_image(scale='symlog', title="after rebinning ", target_pixcoords=image.target_guess) @@ -1095,26 +1149,29 @@ def SpectractorRun(image, output_directory, guess=None): output_filename = output_filename.replace('.fits', '_spectrum.fits') output_filename = output_filename.replace('.fz', '_spectrum.fits') output_filename = os.path.join(output_directory, output_filename) + # Find the exact target position in the raw cut image: several methods my_logger.info(f'\n\tSearch for the target in the image with guess={image.target_guess}...') find_target(image, image.target_guess, widths=(parameters.XWINDOW, parameters.YWINDOW)) + # Simulate star field + if parameters.SPECTRACTOR_SIMULATE_STARFIELD: + image.starfield = image.simulate_starfield_with_gaia() # Rotate the image turn_image(image) + # Find the exact target position in the rotated image: several methods my_logger.info('\n\tSearch for the target in the rotated image...') - find_target(image, image.target_guess, rotated=True, widths=(parameters.XWINDOW_ROT, parameters.YWINDOW_ROT)) # Create Spectrum object spectrum = Spectrum(image=image, order=parameters.SPEC_ORDER) - # First 1D spectrum extraction and background extraction + # First 1D spectrum extraction and background extraction my_logger.info('\n\t ======================== PSF1D Extraction ====================================') w_psf1d, bgd_model_func = extract_spectrum_from_image(image, spectrum, signal_width=parameters.PIXWIDTH_SIGNAL, ws=(parameters.PIXDIST_BACKGROUND, parameters.PIXDIST_BACKGROUND - + parameters.PIXWIDTH_BACKGROUND), - right_edge=image.data.shape[1]) + + parameters.PIXWIDTH_BACKGROUND)) # PSF2D deconvolution if parameters.SPECTRACTOR_DECONVOLUTION_PSF2D: @@ -1131,14 +1188,15 @@ def SpectractorRun(image, output_directory, guess=None): spectrum.err_next_order = np.zeros_like(spectrum.lambdas) # Full forward model extraction: add transverse ADR and order 2 subtraction + w = None if parameters.SPECTRACTOR_DECONVOLUTION_FFM: - my_logger.info('\n\t ======================= FFM DECONVOLUTION =============================') + my_logger.info('\n\t ======================= FFM DECONVOLUTION =============================') w = FullForwardModelFitWorkspace(spectrum, verbose=parameters.VERBOSE, plot=True, live_fit=False, amplitude_priors_method="spectrum") spectrum = run_ffm_minimisation(w, method="newton", niter=2) # Save the spectrum - my_logger.info('\n\t ======================= SAVE SPECTRUM =============================') + my_logger.info('\n\t ======================= SAVE SPECTRUM =============================') spectrum.save_spectrum(output_filename, overwrite=True) spectrum.lines.table = spectrum.lines.build_detected_line_table(amplitude_units=spectrum.units) @@ -1205,7 +1263,7 @@ def Spectractor(file_name, output_directory, target_label='', guess=None, disper return spectrum -def extract_spectrum_from_image(image, spectrum, signal_width=10, ws=(20, 30), right_edge=parameters.CCD_IMSIZE): +def extract_spectrum_from_image(image, spectrum, signal_width=10, ws=(20, 30)): """Extract the 1D spectrum from the image. Method : remove a uniform background estimated from the rectangular lateral bands @@ -1231,8 +1289,6 @@ def extract_spectrum_from_image(image, spectrum, signal_width=10, ws=(20, 30), r Half width of central region where the spectrum is extracted and summed (default: 10) ws: list up/down region extension where the sky background is estimated with format [int, int] (default: [20,30]) - right_edge: int - Right-hand pixel position above which no pixel should be used (default: parameters.CCD_IMSIZE) """ my_logger = set_logger(__name__) @@ -1240,17 +1296,17 @@ def extract_spectrum_from_image(image, spectrum, signal_width=10, ws=(20, 30), r ws = [signal_width + 20, signal_width + 30] my_logger.info('\n\t ======================= extract_spectrum_from_image =============================') - my_logger.info( - f'\n\tExtracting spectrum from image: spectrum with width 2*{signal_width:.0f} pixels ' - f'and background from {ws[0]:.0f} to {ws[1]:.0f} pixels') + my_logger.info(f'\n\tExtracting spectrum from image: spectrum with width 2*{signal_width:.0f} pixels ' + f'and background from {ws[0]:.0f} to {ws[1]:.0f} pixels') # Make a data copy - data = np.copy(image.data_rotated)#[:, 0:right_edge] - err = np.copy(image.stat_errors_rotated)#[:, 0:right_edge] + data = np.copy(image.data_rotated) + err = np.copy(image.err_rotated) # Lateral bands to remove sky background Ny, Nx = data.shape y0 = int(image.target_pixcoords_rotated[1]) + right_edge = image.data_rotated.shape[1] ymax = min(Ny, y0 + ws[1]) ymin = max(0, y0 - ws[1]) @@ -1269,10 +1325,24 @@ def extract_spectrum_from_image(image, spectrum, signal_width=10, ws=(20, 30), r order=spectrum.order) xmin = int(np.argmin(np.abs(lambdas - parameters.LAMBDA_MIN))) xmax = int(np.argmin(np.abs(lambdas - parameters.LAMBDA_MAX))) + # remove last pixel column of rotated image if it is full of nan values in signal region + while np.all(data[max(0, y0 - ws[0]):min(Ny, y0 + ws[0]), xmax]==0) or np.all(np.isnan(data[max(0, y0 - ws[0]):min(Ny, y0 + ws[0]), xmax])): + image.my_logger.debug(f"Last data column is invalid (full of nan or zeros). Subtract 1 to {xmax=}->{xmax-1}") + xmax -= 1 # Create spectrogram data = data[ymin:ymax, xmin:xmax] err = err[ymin:ymax, xmin:xmax] + + # clean the data: this is truly a backward spectrum extraction to feed correctly the forward model + # if available, apply flats + if image.flat_rotated is not None: + data /= image.flat_rotated[ymin:ymax, xmin:xmax] + if image.mask_rotated is not None: + mask = image.mask_rotated[ymin:ymax, xmin:xmax] + else: + mask = np.zeros_like(data).astype(bool) + Ny, Nx = data.shape my_logger.info(f'\n\tExtract spectrogram: crop rotated image [{xmin}:{xmax},{ymin}:{ymax}] (size ({Nx}, {Ny}))') @@ -1285,7 +1355,6 @@ def bgd_model_func(x, y): return np.zeros((y.size, x.size)) if parameters.SPECTRACTOR_BACKGROUND_SUBTRACTION: bgd_model_func, bgd_res, bgd_rms = extract_spectrogram_background_sextractor(data, err, ws=ws, mask_signal_region=True) - # while np.nanmean(bgd_res)/np.nanstd(bgd_res) < -0.2 and parameters.PIXWIDTH_BOXSIZE >= 5: while (np.abs(np.nanmean(bgd_res)) > 0.5 or np.nanstd(bgd_res) > 1.3) and parameters.PIXWIDTH_BOXSIZE > 5: parameters.PIXWIDTH_BOXSIZE = max(5, parameters.PIXWIDTH_BOXSIZE // 2) my_logger.debug(f"\n\tPull distribution of background residuals differs too much from mean=0 and std=1. " @@ -1300,8 +1369,15 @@ def bgd_model_func(x, y): # Fit the transverse profile my_logger.info('\n\t ======================= Fit the transverse profile =============================') - my_logger.info(f'\n\tStart PSF1D transverse fit...') + # clean the data: this is truly a backward spectrum extraction to feed correctly the forward model + # if available, subtract starfield before 1D spectrum estimate + # it is important to have a clean 1D spectrum as it is used as a prior for regularisation + if image.starfield_rotated is not None: + # data -= image.starfield_rotated[ymin:ymax, xmin:xmax] + starfield = np.copy(image.starfield_rotated[ymin:ymax, xmin:xmax]) + mask += starfield > 2 * np.median(starfield) # + np.std(starfield) + psf = load_PSF(psf_type=parameters.PSF_TYPE, target=image.target, clip=False) s = ChromaticPSF(psf, Nx=Nx, Ny=Ny, x0=target_pixcoords_spectrogram[0], y0=target_pixcoords_spectrogram[1], deg=parameters.PSF_POLY_ORDER, saturation=image.saturation) @@ -1309,6 +1385,7 @@ def bgd_model_func(x, y): debug = copy.copy(parameters.DEBUG) parameters.VERBOSE = False parameters.DEBUG = False + s.fit_transverse_PSF1D_profile(data, err, signal_width, ws, pixel_step=parameters.PSF_PIXEL_STEP_TRANSVERSE_FIT, sigma_clip=5, bgd_model_func=bgd_model_func, saturation=image.saturation, live_fit=False) @@ -1322,6 +1399,8 @@ def bgd_model_func(x, y): my_logger.debug(f'\n\tTransverse fit table:\n{s.table}') if parameters.DEBUG: s.plot_summary() + spectrum.lambdas = spectrum.pixels + spectrum.plot_spectrum(xlim=[xmin, xmax]) # Fit the data: method = "noprior" @@ -1330,7 +1409,7 @@ def bgd_model_func(x, y): my_logger.info('\n\t ======================= ChromaticPSF1D polynomial fit =============================') my_logger.info(f'\n\tStart ChromaticPSF polynomial fit with ' f'mode={mode} and amplitude_priors_method={method}...') - w = s.fit_chromatic_psf(data, bgd_model_func=bgd_model_func, data_errors=err, + w = s.fit_chromatic_psf(data, bgd_model_func=bgd_model_func, data_errors=err, mask=mask, amplitude_priors_method=method, mode=mode, verbose=parameters.VERBOSE, analytical=True) Dx_rot = spectrum.pixels.astype(float) - image.target_pixcoords_rotated[0] @@ -1354,11 +1433,11 @@ def bgd_model_func(x, y): spectrum.err = np.copy(w.amplitude_params_err[:new_Nx]) spectrum.cov_matrix = np.copy(w.amplitude_cov_matrix[:new_Nx, :new_Nx]) spectrum.chromatic_psf = s + spectrum.lambdas = np.arange(0, spectrum.data.size, 1) + spectrum.plot_spectrum(xlim=[0, spectrum.data.size]) # Extract the spectrogram edges - data = np.copy(image.data)[:, 0:right_edge] - err = np.copy(image.stat_errors)[:, 0:right_edge] - Ny, Nx = data.shape + Ny, Nx = image.data.shape x0 = int(image.target_pixcoords[0]) y0 = int(image.target_pixcoords[1]) ymax = min(Ny, y0 + int(s.table['Dy_disp_axis'].max()) + ws[1] + 1) # +1 to include edges @@ -1368,7 +1447,7 @@ def bgd_model_func(x, y): lambda_min_index = int(np.argmin(np.abs(lambdas[::np.sign(spectrum.order)] - parameters.LAMBDA_MIN))) lambda_max_index = int(np.argmin(np.abs(lambdas[::np.sign(spectrum.order)] - parameters.LAMBDA_MAX))) xmin = max(0, int(s.table['Dx'][lambda_min_index] + x0)) - xmax = min(right_edge, int(s.table['Dx'][lambda_max_index] + x0) + 1) # +1 to include edges + xmax = min(Nx, int(s.table['Dx'][lambda_max_index] + x0) + 1) # +1 to include edges # Position of the order 0 in the spectrogram coordinates target_pixcoords_spectrogram = [image.target_pixcoords[0] - xmin, image.target_pixcoords[1] - ymin] s.y0 = target_pixcoords_spectrogram[1] @@ -1381,28 +1460,43 @@ def bgd_model_func(x, y): f"\n{s.table[['amplitude', 'x_c', 'y_c', 'Dx', 'Dy', 'Dy_disp_axis']]}") # Create spectrogram - data = data[ymin:ymax, xmin:xmax] - err = err[ymin:ymax, xmin:xmax] - Ny, Nx = data.shape + spectrum.spectrogram_data = np.copy(image.data[ymin:ymax, xmin:xmax]) + spectrum.spectrogram_err = np.copy(image.err[ymin:ymax, xmin:xmax]) + if image.starfield is not None: + spectrum.spectrogram_starfield = np.copy(image.starfield[ymin:ymax, xmin:xmax]) + else: + spectrum.spectrogram_starfield = None # np.zeros_like(spectrum.spectrogram_data) + if image.flat is not None: + spectrum.spectrogram_flat = np.copy(image.flat[ymin:ymax, xmin:xmax]) + else: + spectrum.spectrogram_flat = None # np.ones_like(spectrum.spectrogram_data) + if image.mask is not None: + spectrum.spectrogram_mask = np.copy(image.mask[ymin:ymax, xmin:xmax]) + else: + spectrum.spectrogram_mask = None # np.ones_like(spectrum.spectrogram_data) + + Ny, Nx = spectrum.spectrogram_data.shape my_logger.info(f'\n\tExtract spectrogram: crop raw image [{xmin}:{xmax},{ymin}:{ymax}] (size ({Nx}, {Ny}))') - # Extract the non rotated background + # Extract the non-rotated background my_logger.info('\n\t ======================= Extract the non rotated background =============================') if parameters.SPECTRACTOR_BACKGROUND_SUBTRACTION: - bgd_model_func, bgd_res, bgd_rms = extract_spectrogram_background_sextractor(data, err, ws=ws, Dy_disp_axis=s.table['y_c']) + data = np.copy(spectrum.spectrogram_data) + if spectrum.spectrogram_flat is not None: + data /= spectrum.spectrogram_flat + bgd_model_func, bgd_res, bgd_rms = extract_spectrogram_background_sextractor(data, spectrum.spectrogram_err, + ws=ws, Dy_disp_axis=s.table['y_c']) bgd = bgd_model_func(np.arange(Nx), np.arange(Ny)) my_logger.info(f"\n\tBackground statistics: mean={np.nanmean(bgd):.3f} {image.units}, " f"RMS={np.nanmean(bgd_rms):.3f} {image.units}.") # Propagate background uncertainties - err = np.sqrt(err * err + bgd_rms * bgd_rms) + spectrum.spectrogram_err = np.sqrt(spectrum.spectrogram_err * spectrum.spectrogram_err + bgd_rms * bgd_rms) spectrum.spectrogram_bgd = bgd spectrum.spectrogram_bgd_rms = bgd_rms # First guess for lambdas - my_logger.info('\n\t ======================= first guess for lambdas =============================') - first_guess_lambdas = image.disperser.grating_pixel_to_lambda(s.get_algebraic_distance_along_dispersion_axis(), x0=image.target_pixcoords, order=spectrum.order) s.table['lambdas'] = first_guess_lambdas @@ -1413,8 +1507,6 @@ def bgd_model_func(x, y): f'\n\tNew target position in spectrogram frame: {target_pixcoords_spectrogram}') # Save results - spectrum.spectrogram = data - spectrum.spectrogram_err = err spectrum.spectrogram_x0 = target_pixcoords_spectrogram[0] spectrum.spectrogram_y0 = target_pixcoords_spectrogram[1] spectrum.spectrogram_xmin = xmin @@ -1449,7 +1541,8 @@ def bgd_model_func(x, y): gs_kw = dict(width_ratios=[3, 0.08], height_ratios=[1, 1]) fig, ax = plt.subplots(2, 2, sharex='none', figsize=(16, 6), gridspec_kw=gs_kw) xx = np.arange(s.table['Dx'].size) - plot_image_simple(ax[1, 0], data=data, scale="symlog", title='', units=image.units, aspect='auto', cax=ax[1, 1]) + plot_image_simple(ax[1, 0], data=spectrum.spectrogram_data, scale="symlog", title='', mask=spectrum.spectrogram_mask, + units=image.units, aspect='auto', cax=ax[1, 1]) ax[1, 0].plot(xx, target_pixcoords_spectrogram[1] + s.table['Dy_disp_axis'], label='Dispersion axis', color="r") ax[1, 0].scatter(xx, target_pixcoords_spectrogram[1] + s.table['Dy'], c=s.table['lambdas'], edgecolors='None', cmap=from_lambda_to_colormap(s.table['lambdas']), @@ -1474,6 +1567,8 @@ def bgd_model_func(x, y): plt.show() if parameters.LSST_SAVEFIGPATH: fig.savefig(os.path.join(parameters.LSST_SAVEFIGPATH, 'intermediate_spectrum.pdf')) + if parameters.DEBUG: + spectrum.plot_spectrum() return w, bgd_model_func @@ -1493,7 +1588,7 @@ def run_spectrogram_deconvolution_psf2d(spectrum, bgd_model_func): """ my_logger = set_logger(__name__) s = spectrum.chromatic_psf - Ny, Nx = spectrum.spectrogram.shape + Ny, Nx = spectrum.spectrogram_data.shape # build 1D priors Dx_rot = np.copy(s.table['Dx']) @@ -1527,11 +1622,20 @@ def run_spectrogram_deconvolution_psf2d(spectrum, bgd_model_func): f"\n{s.table[['amplitude', 'x_c', 'y_c', 'Dx', 'Dy', 'Dy_disp_axis']]}") my_logger.info(f'\n\tStart ChromaticPSF polynomial fit with ' f'mode={mode} and amplitude_priors_method={method}...') - data = spectrum.spectrogram - err = spectrum.spectrogram_err + data = np.copy(spectrum.spectrogram_data) + err = np.copy(spectrum.spectrogram_err) + + # clean the data: this is truly a backward spectrum extraction to feed correctly the forward model + # if available, apply flats + if spectrum.spectrogram_flat is not None: + data /= spectrum.spectrogram_flat + # if available, subtract starfield before 1D spectrum estimate + # (important as it is used as a prior for regularisation) + #if spectrum.spectrogram_starfield is not None: + # data -= spectrum.spectrogram_starfield my_logger.info('\n\t ======================= ChromaticPSF2D polynomial fit =============================') - w = s.fit_chromatic_psf(data, bgd_model_func=bgd_model_func, data_errors=err, live_fit=False, + w = s.fit_chromatic_psf(data, bgd_model_func=bgd_model_func, data_errors=err, live_fit=False, mask=spectrum.spectrogram_mask, amplitude_priors_method=method, mode=mode, verbose=parameters.VERBOSE, analytical=True) # save results @@ -1555,6 +1659,7 @@ def run_spectrogram_deconvolution_psf2d(spectrum, bgd_model_func): # Plot FHWM(lambda) if parameters.DEBUG: # pragma: no cover + spectrum.plot_spectrum() fig, ax = plt.subplots(2, 1, figsize=(10, 8), sharex="all") ax[0].plot(spectrum.lambdas, np.array(s.table['fwhm'])) ax[0].set_xlabel(r"$\lambda$ [nm]") @@ -1576,11 +1681,11 @@ def run_spectrogram_deconvolution_psf2d(spectrum, bgd_model_func): def plot_comparison_truth(spectrum, w): # pragma: no cover s = spectrum.chromatic_psf - lambdas_truth = np.fromstring(spectrum.header['LBDAS_T'][1:-1], sep=' ') - psf_poly_truth = np.fromstring(spectrum.header['PSF_P_T'][1:-1], sep=' ', dtype=float) + lambdas_truth = np.fromstring(spectrum.header['LBDAS_T'][1:-1], sep=',') + psf_poly_truth = np.fromstring(spectrum.header['PSF_P_T'][1:-1], sep=',', dtype=float) deg_truth = int(spectrum.header["PSF_DEG"]) psf_poly_truth[-1] = spectrum.spectrogram_saturation - amplitude_truth = np.fromstring(spectrum.header['AMPLIS_T'][1:-1], sep=' ', dtype=float) + amplitude_truth = np.fromstring(spectrum.header['AMPLIS_T'][1:-1], sep=',', dtype=float) amplitude_truth *= parameters.FLAM_TO_ADURATE * lambdas_truth * np.gradient(lambdas_truth) * parameters.CCD_REBIN s0 = ChromaticPSF(s.psf, lambdas_truth.size, s.Ny, deg=deg_truth, saturation=spectrum.spectrogram_saturation) diff --git a/spectractor/extractor/images.py b/spectractor/extractor/images.py index 896482107..3956408b0 100644 --- a/spectractor/extractor/images.py +++ b/spectractor/extractor/images.py @@ -34,14 +34,26 @@ class Image(object): Units of the image. data: array Image 2D array in self.units units. - stat_errors: array + err: array Image 2D uncertainty array in self.units units. target_pixcoords: array Target position [x,y] in the image in pixels. data_rotated: array Rotated image 2D array in self.units units. - stat_errors_rotated: array + err_rotated: array Rotated image 2D uncertainty array in self.units units. + flat: array + Flat 2D array without units and median of 1. + starfield: array + Star field simulation, no units needed but better in ADU/s. + mask: array + Boolean array to mask defects. + flat_rotated: array + Rotated flat 2D array without units and median of 1. + starfield_rotated: array + Rotated star field simulation, no units needed but better in ADU/s. + mask_rotated: array + Rotated boolean array to mask defects. target_pixcoords_rotated: array Target position [x,y] in the rotated image in pixels. date_obs: str @@ -116,7 +128,7 @@ def __init__(self, file_name, *, target_label="", disperser_label="", :hide: >>> assert im.data is not None and np.mean(im.data) > 0 - >>> assert im.stat_errors is not None and np.mean(im.stat_errors) > 0 + >>> assert im.err is not None and np.mean(im.err) > 0 >>> assert im.header is not None >>> assert im.gain is not None and np.mean(im.gain) > 0 @@ -140,8 +152,8 @@ def __init__(self, file_name, *, target_label="", disperser_label="", self.data_rotated = None self.gain = None # in e-/ADU self.read_out_noise = None - self.stat_errors = None - self.stat_errors_rotated = None + self.err = None + self.err_rotated = None self.rotation_angle = 0 self.parallactic_angle = None self.saturation = None @@ -154,6 +166,13 @@ def __init__(self, file_name, *, target_label="", disperser_label="", self.pressure = 0 self.humidity = 0 + self.flat = None + self.flat_rotated = None + self.starfield = None + self.starfield_rotated = None + self.mask = None + self.mask_rotated = None + if parameters.CALLING_CODE != 'LSST_DM' and file_name != "": self.load_image(file_name) else: @@ -193,20 +212,28 @@ def rebin(self): -------- >>> parameters.CCD_REBIN = 2 >>> im = Image('tests/data/reduc_20170605_028.fits') + >>> im.mask = np.zeros_like(im.data).astype(bool) + >>> im.mask[700:750, 800:850] = True >>> im.target_guess = [810, 590] >>> im.data.shape (2048, 2048) >>> im.rebin() >>> im.data.shape (1024, 1024) - >>> im.stat_errors.shape + >>> im.err.shape (1024, 1024) >>> im.target_guess array([405., 295.]) """ new_shape = np.asarray(self.data.shape) // parameters.CCD_REBIN self.data = rebin(self.data, new_shape) - self.stat_errors = np.sqrt(rebin(self.stat_errors ** 2, new_shape)) + self.err = np.sqrt(rebin(self.err ** 2, new_shape)) + if self.mask is not None: + self.mask = rebin(self.mask, new_shape, FLAG_MAKESUM=True).astype(bool) + if self.flat is not None: + self.flat = rebin(self.flat, new_shape, FLAG_MAKESUM=False) + if self.starfield is not None: + self.starfield = rebin(self.starfield, new_shape) if self.target_guess is not None: self.target_guess = np.asarray(self.target_guess) / parameters.CCD_REBIN @@ -284,9 +311,9 @@ def convert_to_ADU_rate_units(self): >>> assert np.all(np.isclose(data_before, im.data * im.expo)) """ self.data = self.data.astype(np.float64) / self.expo - self.stat_errors /= self.expo - if self.stat_errors_rotated is not None: - self.stat_errors_rotated /= self.expo + self.err /= self.expo + if self.err_rotated is not None: + self.err_rotated /= self.expo self.units = 'ADU/s' def convert_to_ADU_units(self): @@ -308,9 +335,9 @@ def convert_to_ADU_units(self): >>> assert np.all(np.isclose(data_before, im.data)) """ self.data *= self.expo - self.stat_errors *= self.expo - if self.stat_errors_rotated is not None: - self.stat_errors_rotated *= self.expo + self.err *= self.expo + if self.err_rotated is not None: + self.err_rotated *= self.expo self.units = 'ADU' def compute_statistical_error(self): @@ -350,9 +377,9 @@ def compute_statistical_error(self): # remove negative values (due to dead columns for instance min_noz = np.min(err2[err2 > 0]) err2[err2 <= 0] = min_noz - self.stat_errors = np.sqrt(err2) + self.err = np.sqrt(err2) # convert in ADU - self.stat_errors /= self.gain + self.err /= self.gain # check uncertainty model self.check_statistical_error() @@ -398,7 +425,7 @@ def check_statistical_error(self): data = np.copy(self.data) min_noz = np.min(data[data > 0]) data[data <= 0] = min_noz - y = self.stat_errors.flatten() ** 2 + y = self.err.flatten() ** 2 x = data.flatten() fit, cov, model = fit_poly1d(x, y, order=1) gain = 1 / fit[0] @@ -446,7 +473,7 @@ def plot_statistical_error(self): ax[0].grid() ax[0].set_ylabel(r"$\sigma_{\mathrm{ADU}}^2$ [ADU$^2$]") ax[0].set_xlabel(r"Data pixel values [ADU]") - plot_image_simple(ax[1], data=self.stat_errors, scale="log10", title="Statistical uncertainty map", + plot_image_simple(ax[1], data=self.err, scale="log10", title="Statistical uncertainty map", units=self.units, target_pixcoords=None, aspect="auto", cmap=None) fig.tight_layout() if parameters.LSST_SAVEFIGPATH: # pragma: no cover @@ -471,7 +498,7 @@ def compute_parallactic_angle(self): def plot_image(self, ax=None, scale="lin", title="", units="", plot_stats=False, target_pixcoords=None, figsize=(7.3, 6), aspect=None, vmin=None, vmax=None, - cmap=None, cax=None): + cmap=None, cax=None, use_flat=True): """Plot image. Parameters @@ -500,10 +527,14 @@ def plot_image(self, ax=None, scale="lin", title="", units="", plot_stats=False, Figure size (default: [9.3, 8]). plot_stats: bool If True, plot the uncertainty map instead of the image (default: False). + use_flat: bool + If True and self.flat exists, divide the image by the flat (default: True). Examples -------- >>> im = Image('tests/data/reduc_20170605_028.fits', config="./config/ctio.ini") + >>> im.mask = np.zeros_like(im.data).astype(bool) + >>> im.mask[700:705, 1250:1260] = True # test masking of some pixels like cosmic rays >>> im.plot_image(target_pixcoords=[820, 580], scale="symlog") >>> if parameters.DISPLAY: plt.show() """ @@ -512,10 +543,12 @@ def plot_image(self, ax=None, scale="lin", title="", units="", plot_stats=False, ax = plt.gca() data = np.copy(self.data) if plot_stats: - data = np.copy(self.stat_errors) + data = np.copy(self.err) if units == "": units = self.units - plot_image_simple(ax, data=data, scale=scale, title=title, units=units, cax=cax, + if self.flat is not None and use_flat: + data /= self.flat + plot_image_simple(ax, data=data, scale=scale, title=title, units=units, cax=cax, mask=self.mask, target_pixcoords=target_pixcoords, aspect=aspect, vmin=vmin, vmax=vmax, cmap=cmap) if parameters.OBS_OBJECT_TYPE == "STAR": plot_compass_simple(ax, self.parallactic_angle, arrow_size=0.1, origin=[0.15, 0.15]) @@ -528,6 +561,16 @@ def plot_image(self, ax=None, scale="lin", title="", units="", plot_stats=False, if parameters.PdfPages: parameters.PdfPages.savefig() + def simulate_starfield_with_gaia(self): + from spectractor.simulation.image_simulation import StarFieldModel + starfield = StarFieldModel(self, flux_factor=1) + yy, xx = np.mgrid[0:self.data.shape[1]:1, 0:self.data.shape[0]:1] + starfield.model(xx, yy) + if parameters.DEBUG: + self.plot_image(scale='symlog', target_pixcoords=starfield.pixcoords) + starfield.plot_model() + return starfield.field + def load_CTIO_image(image): """Specific routine to load CTIO fits files and load their data and properties for Spectractor. @@ -566,6 +609,8 @@ def load_CTIO_image(image): # compute CCD gain map build_CTIO_gain_map(image) build_CTIO_read_out_noise_map(image) + image.flat = image.gain / np.mean(image.gain) + # parallactic angle image.compute_parallactic_angle() # WCS wcs_file_name = set_wcs_file_name(image.file_name) @@ -679,7 +724,10 @@ def load_AUXTEL_image(image): # pragma: no cover image.my_logger.info(f'\n\tLoading AUXTEL image {image.file_name}...') with fits.open(image.file_name) as hdu_list: image.header = hdu_list[0].header - image.data = hdu_list[1].data.astype(np.float64) + if hdu_list[0].data is not None: + image.data = hdu_list[0].data.astype(np.float64) + else: + image.data = hdu_list[1].data.astype(np.float64) image.date_obs = image.header['DATE'] image.expo = float(image.header['EXPTIME']) if "empty" not in image.header['FILTER'].lower(): @@ -722,7 +770,7 @@ def load_AUXTEL_image(image): # pragma: no cover if parameters.OBS_CAMERA_ROTATION < -360: parameters.OBS_CAMERA_ROTATION += 360 image.header["CAM_ROT"] = parameters.OBS_CAMERA_ROTATION - if "CD2_1" in hdu_list[1].header: + if len(hdu_list) > 1 and "CD2_1" in hdu_list[1].header: rotation_wcs = 180 / np.pi * np.arctan2(hdu_list[1].header["CD2_1"], hdu_list[1].header["CD1_1"]) + 90 if not np.isclose(rotation_wcs % 360, parameters.OBS_CAMERA_ROTATION % 360, atol=2): image.my_logger.warning(f"\n\tWCS rotation angle is {rotation_wcs} degree while " @@ -759,20 +807,33 @@ def load_STARDICE_image(image): # pragma: no cover if "BSCALE" in image.header: del image.header["BSCALE"] - #Set the flip signs depending on the side of the pillar + ILLUREGION = slice(None, 1032), slice(1, 1057) + OVERSCANA = slice(1032, None), slice(None) + OVERSCANB = slice(None, 1032), slice(1059, None) + + def detrend(im): + res = im - np.mean(im[OVERSCANA], axis=0) # [:-100] + return np.subtract(res[ILLUREGION].T, np.mean(res[OVERSCANB], axis=1)).T + + if image.data.shape[0] > 1032 and image.data.shape[1] > 1057: + image.data = detrend(image.data) + # transformations so that stars are like in Stellarium up to a rotation + # with spectrogram nearly horizontal and on the right of central star + # no transformation if data are simulated + image.data = image.data[::-1, ::-1] + + #Set the flip signs depending on the side of the pillar if image.header['MOUNTTAU'] < 90: parameters.OBS_CAMERA_ROTATION = 180 elif image.header['MOUNTTAU'] >= 90: parameters.OBS_CAMERA_ROTATION = 0 + image.units = 'ADU' image.target_label = image.header['mountTARGET'] image.date_obs = image.header['DATE-OBS'] image.expo = float(image.header['cameraexptime']) image.filter_label = 'EMPTY' - # transformations so that stars are like in Stellarium up to a rotation - # with spectrogram nearly horizontal and on the right of central star - image.data = image.data[::-1, ::-1] image.airmass = 1/np.cos(np.radians(90-image.header['MOUNTALT'])) image.my_logger.info('\n\tImage loaded') @@ -786,10 +847,26 @@ def load_STARDICE_image(image): # pragma: no cover if image.header['MOUNTTAU'] >= 90: image.hour_angle = image.hour_angle - 180*units.deg image.dec = 180*units.deg - image.dec - image.temperature = 10 - image.pressure = 1000 - image.humidity = 87 - image.units = 'ADU' + + if "weatherAir temperature [C]" in image.header: + image.temperature = float(image.header["weatherAir temperature [C]"]) + else: + image.temperature = 10. + if "weatherAir pressure [hPa]" in image.header: + image.pressure = float(image.header["weatherAir pressure [hPa]"]) + else: + image.pressure = 950. + if "weatherRelative humidity [%]" in image.header: + image.humidity = float(image.header["weatherRelative humidity [%]"]) + else: + image.humidity = 50. + + # WCS + wcs_file_name = set_wcs_file_name(image.file_name) + if os.path.isfile(wcs_file_name): + image.my_logger.info(f"\n\tUse WCS {wcs_file_name}.") + image.wcs = load_wcs_from_file(wcs_file_name) + if "PC2_1" in image.header: rotation_wcs = 180 / np.pi * np.arctan2(-hdu_list[0].header["PC2_1"]/hdu_list[0].header["CDELT2"], hdu_list[0].header["PC1_1"]/hdu_list[0].header["CDELT1"]) atol = 0.02 @@ -934,6 +1011,8 @@ def find_target(image, guess=None, rotated=False, widths=[parameters.XWINDOW, pa image.target.image_x0 = sub_image_x0 image.target.image_y0 = sub_image_y0 image.target_pixcoords = [theX, theY] + if image.starfield is not None: + image.target.starfield = np.copy(image.starfield[int(theY) - Dy:int(theY) + Dy, int(theX) - Dx:int(theX) + Dx]) image.header['TARGETX'] = theX image.header.comments['TARGETX'] = 'target position on X axis' image.header['TARGETY'] = theY @@ -984,10 +1063,10 @@ def find_target_init(image, guess, rotated=False, widths=[parameters.XWINDOW, pa Dx, Dy = widths if rotated: sub_image = np.copy(image.data_rotated[y0 - Dy:y0 + Dy, x0 - Dx:x0 + Dx]) - sub_errors = np.copy(image.stat_errors[y0 - Dy:y0 + Dy, x0 - Dx:x0 + Dx]) + sub_errors = np.copy(image.err_rotated[y0 - Dy:y0 + Dy, x0 - Dx:x0 + Dx]) else: sub_image = np.copy(image.data[y0 - Dy:y0 + Dy, x0 - Dx:x0 + Dx]) - sub_errors = np.copy(image.stat_errors[y0 - Dy:y0 + Dy, x0 - Dx:x0 + Dx]) + sub_errors = np.copy(image.err[y0 - Dy:y0 + Dy, x0 - Dx:x0 + Dx]) # usually one rebin by adding pixel contents image.saturation = parameters.CCD_MAXADU / image.expo *parameters.CCD_REBIN**2 @@ -1411,11 +1490,21 @@ def turn_image(image): if not np.isnan(image.rotation_angle): image.data_rotated = ndimage.rotate(image.data, image.rotation_angle, prefilter=parameters.ROT_PREFILTER, order=parameters.ROT_ORDER) - image.stat_errors_rotated = np.sqrt( - np.abs(ndimage.rotate(image.stat_errors ** 2, image.rotation_angle, + image.err_rotated = np.sqrt( + np.abs(ndimage.rotate(image.err ** 2, image.rotation_angle, prefilter=parameters.ROT_PREFILTER, order=parameters.ROT_ORDER))) - min_noz = np.min(image.stat_errors_rotated[image.stat_errors_rotated > 0]) - image.stat_errors_rotated[image.stat_errors_rotated <= 0] = min_noz + min_noz = np.min(image.err_rotated[image.err_rotated > 0]) + image.err_rotated[image.err_rotated <= 0] = min_noz + if image.flat is not None: + image.flat_rotated = ndimage.rotate(image.flat, image.rotation_angle, + prefilter=parameters.ROT_PREFILTER, order=parameters.ROT_ORDER) + if image.starfield is not None: + image.starfield_rotated = ndimage.rotate(image.starfield, image.rotation_angle, + prefilter=parameters.ROT_PREFILTER, order=parameters.ROT_ORDER) + if image.mask is not None: + image.mask_rotated = ndimage.rotate(image.mask, image.rotation_angle, + prefilter=parameters.ROT_PREFILTER, order=parameters.ROT_ORDER) + if parameters.DEBUG: margin = 100 // parameters.CCD_REBIN y0 = int(image.target_pixcoords[1]) diff --git a/spectractor/extractor/psf.py b/spectractor/extractor/psf.py index 63acf2bc4..2e19b8e09 100644 --- a/spectractor/extractor/psf.py +++ b/spectractor/extractor/psf.py @@ -319,6 +319,107 @@ def evaluate_moffatgauss1d(y, amplitude, y_c, gamma, alpha, eta_gauss, sigma, no return a +@njit(["float32[:](int64[:], float32, float32, float32, float32, float32, float32, float32, float32, float32)", + "float32[:](float32[:], float32, float32, float32, float32, float32, float32, float32, float32, float32)"], fastmath=True, cache=True) +def evaluate_doublemoffat1d(y, amplitude, y_c, gamma1, alpha1, eta, gamma2, alpha2, norm1, norm2): # pragma: no cover + r"""Compute a 1D DoubleMoffat function, whose integral is normalised to unity. + + .. math :: + + f(y) \propto A \left\lbrace + \frac{1}{\left[ 1 +\left(\frac{y-y_c}{\gamma}\right)^2 \right]^\alpha}+ \eta e^{-(y-y_c)^2/(2\sigma^2)}\right\rbrace + \quad\text{ and } \quad \eta < 0, \alpha > 1/2 + + Note that this function is defined only for :math:`\alpha > 1/2`. The normalisation factor for the Moffat+Gauss + :math:`\frac{\Gamma(\alpha)}{\gamma \sqrt{\pi} \Gamma(\alpha -1/2)} + \eta \sqrt{2\pi} \sigma` is not included as special functions + are not supproted by the numba library. + + Parameters + ---------- + y: array_like + 1D array of pixels :math:`y`, regularly spaced. + amplitude: float + Integral :math:`A` of the function. + y_c: float + Center :math:`y_c` of the function. + gamma1: float + Width :math:`\gamma_1` of the Moffat function. + alpha1: float + Exponent :math:`\alpha_1` of the Moffat function. + eta: float + Relative amplitude of the second Moffat function. + gamma2: float + Width :math:`\gamma_2` of the second Moffat function. + alpha2: float + Exponent :math:`\alpha_2` of the second Moffat function. + norm1: float + Normalisation :math:`\frac{\Gamma(\alpha_1)}{\gamma_1 \sqrt{\pi} \Gamma(\alpha_1 -1/2)}`. + norm2: float + Normalisation :math:`\frac{\Gamma(\alpha_2)}{\gamma_2 \sqrt{\pi} \Gamma(\alpha_2 -1/2)}`. + + Returns + ------- + output: array_like + 1D array of the function evaluated on the y pixel array. + + Examples + -------- + + >>> Ny = 50 + >>> y = np.arange(Ny) + >>> amplitude = 10 + >>> gamma1 = 5 + >>> alpha1 = 2 + >>> eta = 2 + >>> gamma2 = 4 + >>> alpha2 = 3 + >>> norm1 = evaluate_moffat1d_normalisation(gamma1, alpha1) + >>> norm2 = evaluate_moffat1d_normalisation(gamma2, alpha2) + >>> a = evaluate_doublemoffat1d(y, amplitude=amplitude, y_c=Ny/2, gamma1=gamma1, alpha1=alpha1, eta=eta, gamma2=gamma2, alpha2=alpha2, norm1=norm1, norm2=norm2) + >>> print(f"{np.sum(a):.6f}") + 9.985071 + >>> a.dtype + dtype('float32') + + .. doctest:: + :hide: + + >>> assert np.isclose(np.sum(a), amplitude, atol=0.5) + >>> assert np.isclose(np.argmax(a), Ny/2, atol=0.5) + + .. plot:: + + import numpy as np + import matplotlib.pyplot as plt + from spectractor.extractor.psf import * + Ny = 50 + y = np.arange(Ny) + amplitude = 10 + gamma1 = 5 + alpha1 = 2 + eta = 2 + gamma2 = 4 + alpha2 = 3 + norm1 = evaluate_moffat1d_normalisation(gamma1, alpha1) + norm2 = evaluate_moffat1d_normalisation(gamma2, alpha2) + a = evaluate_doublemoffat1d(y, amplitude=amplitude, y_c=Ny/2, gamma1=gamma1, alpha1=alpha1, eta=eta, gamma2=gamma2, alpha2=alpha2, norm1=norm1, norm2=norm2) + plt.plot(a) + plt.grid() + plt.xlabel("y") + plt.ylabel("DoubleMoffat") + plt.show() + + """ + yc = y - y_c + rr = yc * yc + rr_gg1 = rr / (gamma1 * gamma1) + rr_gg2 = rr / (gamma2 * gamma2) + norm = 1. / norm1 + eta / norm2 + a = (1 + rr_gg1) ** -alpha1 + eta * (1 + rr_gg2) ** -alpha2 + a *= (amplitude / norm) + return a + + @njit(["float32[:,:](int64[:], float32, float32, float32, float32, float32, float32, float32, float32, boolean[:])"], fastmath=True, cache=True) def evaluate_moffatgauss1d_jacobian(y, amplitude, y_c, gamma, alpha, eta_gauss, sigma, norm_moffat, dnormda, fixed): # pragma: no cover r"""Compute a 1D Moffat-Gaussian Jacobian, whose integral is normalised to unity. @@ -418,6 +519,118 @@ def evaluate_moffatgauss1d_jacobian(y, amplitude, y_c, gamma, alpha, eta_gauss, return J +@njit(["float32[:,:](int64[:], float32, float32, float32, float32, float32, float32, float32, float32, float32, float32, float32, boolean[:])"], fastmath=True, cache=True) +def evaluate_doublemoffat1d_jacobian(y, amplitude, y_c, gamma1, alpha1, eta, gamma2, alpha2, norm1, dnormda1, norm2, dnormda2, fixed): # pragma: no cover + r"""Compute a 1D DoubleMoffat Jacobian, whose integral is normalised to unity. + + .. math :: + + f(y) \propto A \left\lbrace + \frac{1}{\left[ 1 +\left(\frac{y-y_c}{\gamma}\right)^2 \right]^\alpha} \times \frac{\Gamma(\alpha)}{\gamma \sqrt{\pi} \Gamma(\alpha -1/2)} + - \eta e^{-(y-y_c)^2/(2\sigma^2)}\right\rbrace + \quad\text{ and } \quad \eta < 0, \alpha > 1/2 + + Note that this function is defined only for :math:`\alpha > 1/2`. The normalisation factor for the Moffat + :math:`\frac{\Gamma(\alpha)}{\gamma \sqrt{\pi} \Gamma(\alpha -1/2)} + \eta \sqrt{2\pi} \sigma` is not included as special functions + are not supproted by the numba library. + + Parameters + ---------- + y: array_like + 1D array of pixels :math:`y`, regularly spaced. + amplitude: float + Integral :math:`A` of the function. + y_c: float + Center :math:`y_c` of the function. + gamma1: float + Width :math:`\gamma_1` of the Moffat function. + alpha1: float + Exponent :math:`\alpha_1` of the Moffat function. + eta: float + Relative amplitude of the second Moffat function. + gamma2: float + Width :math:`\gamma_2` of the second Moffat function. + alpha2: float + Exponent :math:`\alpha_2` of the second Moffat function. + norm1: float + Normalisation :math:`\frac{\Gamma(\alpha_1)}{\gamma_1 \sqrt{\pi} \Gamma(\alpha_1 -1/2)}`. + dnormda1: float + Derivatives of the normalisation with respect to alpha1. + norm2: float + Normalisation :math:`\frac{\Gamma(\alpha_2)}{\gamma_2 \sqrt{\pi} \Gamma(\alpha_2 -1/2)}`. + dnormda2: float + Derivatives of the normalisation with respect to alpha2. + fixed: array_like + Array of booleans, with True values for fixed parameters. + + Returns + ------- + J: array_like + 2D array of the model Jacobian. + + Examples + -------- + + >>> Ny = 50 + >>> y = np.arange(Ny) + >>> amplitude = 10 + >>> gamma1 = 5 + >>> alpha1 = 2 + >>> gamma2 = 4 + >>> alpha2 = 3 + >>> eta = 2 + >>> norm1 = evaluate_moffat1d_normalisation(gamma1, alpha1) + >>> dnormda1 = evaluate_moffat1d_normalisation_dalpha(norm1, alpha1) + >>> norm2 = eta * evaluate_moffat1d_normalisation(gamma2, alpha2) + >>> dnormda2 = evaluate_moffat1d_normalisation_dalpha(norm2, alpha2) + >>> a = evaluate_doublemoffat1d(y, amplitude=amplitude, y_c=Ny/2, gamma1=gamma1, alpha1=alpha1, eta=eta, gamma2=gamma2, alpha2=alpha2, norm1=norm1, norm2=norm2) + >>> J = evaluate_doublemoffat1d_jacobian(y, amplitude=amplitude, y_c=Ny/2, gamma1=gamma1, alpha1=alpha1, + ... eta=eta, gamma2=gamma2, alpha2=alpha2, norm1=norm1, dnormda1=dnormda1, norm2=norm2, dnormda2=dnormda2, + ... fixed=np.array([False, False, True, False, False, False, False])) + >>> J.shape + (8, 50) + >>> J.dtype + dtype('float32') + >>> np.allclose(J[2], 0) + True + + .. doctest:: + :hide: + + >>> assert np.allclose(J[0], a.ravel()/amplitude) + + """ + yc = y - y_c + rr = yc * yc + rr_gg1 = rr / (gamma1 * gamma1) + rr_gg2 = rr / (gamma2 * gamma2) + inv_moffat1 = 1 / (1 + rr_gg1) + psf_moffat1 = inv_moffat1 ** alpha1 + dpsf_moffat1 = alpha1 * inv_moffat1 * psf_moffat1 + inv_moffat2 = 1 / (1 + rr_gg2) + psf_moffat2 = inv_moffat2 ** alpha2 + dpsf_moffat2 = alpha2 * inv_moffat2 * psf_moffat2 + psf = psf_moffat1 + eta * psf_moffat2 + norm = amplitude / (1/norm1 + eta/norm2) + J = np.zeros((8, y.size), dtype=np.float32) + if not fixed[0]: + J[0] = (norm / amplitude) * psf # amplitude + # fixed x_c so J[1] = 0 + if not fixed[2]: + J[2] = (2 * norm / (gamma1 * gamma1)) * yc * dpsf_moffat1 + eta * (2 * norm / (gamma2 * gamma2)) * yc * dpsf_moffat2 # y_c + if not fixed[3]: + J[3] = (2 * norm / gamma1) * rr_gg1 * dpsf_moffat1 - (norm * norm / (amplitude * norm1 * gamma1)) * psf # gamma1 + if not fixed[4]: + J[4] = -norm * psf_moffat1 * np.log(1 + rr_gg1) + psf * (norm * norm / amplitude) * (dnormda1 / (norm1 * norm1)) # alpha1 + if not fixed[5]: + J[5] = norm * psf_moffat2 - (1/norm2 * norm * norm / amplitude) * psf # eta + if not fixed[6]: + J[6] = eta * (2 * norm / gamma2) * rr_gg2 * dpsf_moffat2 - (eta * norm * norm / (amplitude * norm2 * gamma2)) * psf # gamma2 + if not fixed[7]: + J[7] = -eta * norm * psf_moffat2 * np.log(1 + rr_gg2) + psf * (norm * norm / amplitude) * (eta * dnormda2 / (norm2 * norm2)) # alpha2 + return J + + @njit(["float32[:,:](int64[:,:], int64[:,:], float32, float32, float32, float32, float32)", "float64[:,:](float64[:,:], float64[:,:], float32, float32, float32, float32, float32)"], fastmath=True, cache=True) def evaluate_moffat2d(x, y, amplitude, x_c, y_c, gamma, alpha): # pragma: no cover @@ -575,7 +788,7 @@ def evaluate_moffat2d_jacobian(x, y, amplitude, x_c, y_c, gamma, alpha, fixed): @njit(["float32[:,:](int64[:,:], int64[:,:], float32, float32, float32, float32, float32, float32, float32)"], fastmath=True, cache=True) def evaluate_moffatgauss2d(x, y, amplitude, x_c, y_c, gamma, alpha, eta_gauss, sigma): # pragma: no cover - r"""Compute a 2D Moffat-Gaussian function, whose integral is normalised to unity. + r"""Compute a 2D Moffat+Gauss function, whose integral is normalised to unity. .. math :: @@ -604,7 +817,7 @@ def evaluate_moffatgauss2d(x, y, amplitude, x_c, y_c, gamma, alpha, eta_gauss, s y_c: float Y axis center :math:`y_c` of the function. gamma: float - Width :math:`\gamma` of the function. + Width :math:`\gamma` of the Moffat function. alpha: float Exponent :math:`\alpha` of the Moffat function. eta_gauss: float @@ -665,6 +878,101 @@ def evaluate_moffatgauss2d(x, y, amplitude, x_c, y_c, gamma, alpha, eta_gauss, s return a +@njit(["float32[:,:](int64[:,:], int64[:,:], float32, float32, float32, float32, float32, float32, float32, float32)"], fastmath=True, cache=True) +def evaluate_doublemoffat2d(x, y, amplitude, x_c, y_c, gamma1, alpha1, eta, gamma2, alpha2): # pragma: no cover + r"""Compute a 2D Double Moffat function, whose integral is normalised to unity. + + .. math :: + + f(x, y) = \frac{A}{\frac{\pi \gamma_1^2}{\alpha_1-1} + \eta \frac{\pi \gamma_2^2}{\alpha_2-1}}\left\lbrace \frac{1}{ + \left[ 1 +\frac{\left(x-x_c\right)^2+\left(y-y_c\right)^2}{\gamma_1^2} \right]^\alpha_1} + + \eta \frac{1}{ + \left[ 1 +\frac{\left(x-x_c\right)^2+\left(y-y_c\right)^2}{\gamma_2^2} \right]^\alpha_2} + \right\rbrace + + .. math :: + \quad\text{with}\quad + \int_{-\infty}^{\infty}\int_{-\infty}^{\infty}f(x, y) \mathrm{d}x \mathrm{d}y = A + \quad\text{and} \quad \eta < 0 + + Note that this function is defined only for :math:`\alpha > 1`. + + Parameters + ---------- + x: array_like + 2D array of pixels :math:`x`, regularly spaced. + y: array_like + 2D array of pixels :math:`y`, regularly spaced. + amplitude: float + Integral :math:`A` of the function. + x_c: float + X axis center :math:`x_c` of the function. + y_c: float + Y axis center :math:`y_c` of the function. + gamma1: float + Width :math:`\gamma_1` of the Moffat function. + alpha1: float + Exponent :math:`\alpha_1` of the Moffat function. + eta: float + Relative amplitude of the second Moffat function. + gamma2: float + Width :math:`\gamma_2` of the second Moffat function. + alpha2: float + Exponent :math:`\alpha_2` of the second Moffat function. + + Returns + ------- + output: array_like + 2D array of the function evaluated on the y pixel array. + + Examples + -------- + + >>> Nx = 50 + >>> Ny = 50 + >>> yy, xx = np.mgrid[:Ny, :Nx] + >>> amplitude = 10 + >>> a = evaluate_doublemoffat2d(xx, yy, amplitude=amplitude, x_c=Nx/2, y_c=Ny/2, gamma1=5, alpha1=2, + ... eta=2, gamma2=4, alpha2=3) + >>> print(f"{np.sum(a):.6f}") + 9.805085 + >>> a.dtype + dtype('float32') + + .. doctest:: + :hide: + + >>> assert not np.isclose(np.sum(a), amplitude) + + .. plot:: + + import numpy as np + import matplotlib.pyplot as plt + from spectractor.extractor.psf import * + Nx = 50 + Ny = 50 + yy, xx = np.mgrid[:Nx, :Ny] + amplitude = 10 + a = evaluate_doublemoffat2d(xx, yy, amplitude=amplitude, x_c=Nx/2, y_c=Ny/2, gamma1=5, alpha1=2, eta=2, gamma2=4, alpha2=1.5) + im = plt.pcolor(xx, yy, a) + plt.grid() + plt.xlabel("x") + plt.ylabel("y") + plt.colorbar(im, label="Double Moffat 2D") + plt.show() + + """ + xc = x - x_c + yc = y - y_c + rr = xc * xc + yc * yc + rr_gg1 = rr / (gamma1 * gamma1) + rr_gg2 = rr / (gamma2 * gamma2) + a = (1 + rr_gg1) ** -alpha1 + eta * (1 + rr_gg2) ** -alpha2 + norm = (np.pi * gamma1 * gamma1) / (alpha1 - 1) + eta * (np.pi * gamma2 * gamma2) / (alpha2 - 1) + a *= amplitude / norm + return a + + @njit(["float32[:](int64[:], float32, float32, float32)", "float32[:](float32[:], float32, float32, float32)"], fastmath=True, cache=False) def evaluate_gauss1d(y, amplitude, y_c, sigma): # pragma: no cover @@ -949,7 +1257,7 @@ def evaluate_gauss2d_jacobian(x, y, amplitude, x_c, y_c, sigma, fixed): # pragm @njit(["float32[:,:](int64[:,:], int64[:,:], float32, float32, float32, float32, float32, float32, float32, boolean[:])"], fastmath=True, cache=True) def evaluate_moffatgauss2d_jacobian(x, y, amplitude, x_c, y_c, gamma, alpha, eta_gauss, sigma, fixed): # pragma: no cover - r"""Compute a 2D Moffat Jacobian, whose integral is normalised to unity. + r"""Compute a 2D Moffat+Gauss Jacobian, whose integral is normalised to unity. Parameters ---------- @@ -1021,7 +1329,7 @@ def evaluate_moffatgauss2d_jacobian(x, y, amplitude, x_c, y_c, gamma, alpha, eta if not fixed[1]: J[1] = (norm / (sigma * sigma)) * xc * eta_gauss * psf_gauss + (2 * norm / (gamma * gamma)) * xc * dpsf_moffat # x_c if not fixed[2]: - J[2] = (norm / (sigma * sigma)) * yc * eta_gauss * psf_gauss + (2 * norm / (gamma * gamma)) * yc * dpsf_moffat # x_c + J[2] = (norm / (sigma * sigma)) * yc * eta_gauss * psf_gauss + (2 * norm / (gamma * gamma)) * yc * dpsf_moffat # y_c if not fixed[3]: J[3] = (-2 * np.pi * gamma * norm * norm / (alpha-1) / amplitude) * psf + (2 * norm / gamma) * rr_gg * dpsf_moffat # gamma if not fixed[4]: @@ -1033,6 +1341,98 @@ def evaluate_moffatgauss2d_jacobian(x, y, amplitude, x_c, y_c, gamma, alpha, eta return J +@njit(["float32[:,:](int64[:,:], int64[:,:], float32, float32, float32, float32, float32, float32, float32, float32, boolean[:])"], fastmath=True, cache=True) +def evaluate_doublemoffat2d_jacobian(x, y, amplitude, x_c, y_c, gamma1, alpha1, eta, gamma2, alpha2, fixed): # pragma: no cover + r"""Compute a 2D Double Moffat Jacobian, whose integral is normalised to unity. + + Parameters + ---------- + x: array_like + 2D array of pixels :math:`x`, regularly spaced. + y: array_like + 2D array of pixels :math:`y`, regularly spaced. + amplitude: float + Integral :math:`A` of the function. + x_c: float + X axis center :math:`x_c` of the function. + y_c: float + Y axis center :math:`y_c` of the function. + gamma1: float + Width :math:`\gamma_1` of the Moffat function. + alpha1: float + Exponent :math:`\alpha_1` of the Moffat function. + eta: float + Relative amplitude of the second Moffat function. + gamma2: float + Width :math:`\gamma_2` of the second Moffat function. + alpha2: float + Exponent :math:`\alpha_2` of the second Moffat function. + fixed: array_like + Array of booleans, with True values for fixed parameters. + + + Returns + ------- + J: array_like + 2D array of the model Jacobian. + + Examples + -------- + + >>> Nx = 50 + >>> Ny = 50 + >>> yy, xx = np.mgrid[:Ny, :Nx] + >>> amplitude = 10 + >>> a = evaluate_doublemoffat2d(xx, yy, amplitude=amplitude, x_c=Nx/2, y_c=Ny/2, gamma1=5, alpha1=2, + ... eta=2, gamma2=1, alpha2=3) + >>> J = evaluate_doublemoffat2d_jacobian(xx, yy, amplitude=amplitude, x_c=Nx/2, y_c=Ny/2, gamma1=5, alpha1=2, + ... eta=2, gamma2=1, alpha2=3, fixed=np.array([False, False, True, False, False, False, False, False])) + >>> J.shape + (8, 2500) + >>> J.dtype + dtype('float32') + >>> np.allclose(J[2], 0) + True + + .. doctest:: + :hide: + + >>> assert np.allclose(J[0], a.ravel()/amplitude) + + """ + xc = (x - x_c).ravel() + yc = (y - y_c).ravel() + rr = xc * xc + yc * yc + rr_gg1 = rr / (gamma1 * gamma1) + rr_gg2 = rr / (gamma2 * gamma2) + inv_moffat1 = 1 / (1 + rr_gg1) + psf_moffat1 = inv_moffat1 ** alpha1 + inv_moffat2 = 1 / (1 + rr_gg2) + psf_moffat2 = inv_moffat2 ** alpha2 + dpsf_moffat1 = alpha1 * inv_moffat1 * psf_moffat1 + dpsf_moffat2 = alpha2 * inv_moffat2 * psf_moffat2 + psf = psf_moffat1 + eta * psf_moffat2 + norm = amplitude / ((np.pi * gamma1 * gamma1) / (alpha1 - 1) + eta * (np.pi * gamma2 * gamma2) / (alpha2 - 1)) + J = np.zeros((8, x.size), dtype=np.float32) + if not fixed[0]: + J[0] = (norm / amplitude) * psf # amplitude + if not fixed[1]: + J[1] = (2 * norm / (gamma1 * gamma1)) * xc * dpsf_moffat1 + eta * (2 * norm / (gamma2 * gamma2)) * xc * dpsf_moffat2 # x_c + if not fixed[2]: + J[2] = (2 * norm / (gamma1 * gamma1)) * yc * dpsf_moffat1 + eta * (2 * norm / (gamma2 * gamma2)) * yc * dpsf_moffat2 # y_c + if not fixed[3]: + J[3] = (-2 * np.pi * gamma1 * norm * norm / (alpha1-1) / amplitude) * psf + (2 * norm / gamma1) * rr_gg1 * dpsf_moffat1 # gamma1 + if not fixed[4]: + J[4] = (np.pi * gamma1 * gamma1) * norm * norm / (amplitude * (alpha1-1) * (alpha1-1)) * psf - norm * psf_moffat1 * np.log(1 + rr_gg1) # alpha1 + if not fixed[5]: + J[5] = norm * psf_moffat2 - ((np.pi * gamma2 * gamma2) / (alpha2 - 1) * norm * norm / amplitude) * psf + if not fixed[6]: + J[6] = eta * (-2 * np.pi * gamma2 * norm * norm / (alpha2-1) / amplitude) * psf + eta * (2 * norm / gamma2) * rr_gg2 * dpsf_moffat2 # gamma2 + if not fixed[7]: + J[7] = eta * (np.pi * gamma2 * gamma2) * norm * norm / (amplitude * (alpha2-1) * (alpha2-1)) * psf - eta * norm * psf_moffat2 * np.log(1 + rr_gg2) # alpha2 + return J + + class PSF: """Generic PSF model class. @@ -1187,15 +1587,15 @@ def __init__(self, values=None, clip=False): values = np.copy(self.values_default) labels = ["amplitude", "x_c", "y_c", "gamma", "alpha", "saturation"] axis_names = ["$A$", r"$x_c$", r"$y_c$", r"$\gamma$", r"$\alpha$", "saturation"] - bounds = [(0, np.inf), (-np.inf, np.inf), (-np.inf, np.inf), (0.1, np.inf), - (1.1, 100), (0, np.inf)] + bounds = [(0, np.inf), (-np.inf, np.inf), (-np.inf, np.inf), (1, np.inf), + (1.1, 10), (0, np.inf)] self.params = FitParameters(values=values, labels=labels, axis_names=axis_names, bounds=bounds) def apply_max_width_to_bounds(self, max_half_width=None): if max_half_width is not None: self.max_half_width = max_half_width - self.params.bounds[2] = (0, 2 * self.max_half_width) - self.params.bounds[3] = (0.1, self.max_half_width) + self.params.bounds[2] = (-2 * self.max_half_width, 2 * self.max_half_width) + self.params.bounds[3] = (1, self.max_half_width) def evaluate(self, pixels, values=None): r"""Evaluate the Moffat function. @@ -1390,7 +1790,7 @@ def __init__(self, values=None, clip=False): def apply_max_width_to_bounds(self, max_half_width=None): if max_half_width is not None: self.max_half_width = max_half_width - self.params.bounds[2] = (0, 2 * self.max_half_width) + self.params.bounds[2] = (-2 * self.max_half_width, 2 * self.max_half_width) self.params.bounds[3] = (1, self.max_half_width) def evaluate(self, pixels, values=None): @@ -1556,16 +1956,16 @@ def __init__(self, values=None, clip=False): values = np.copy(self.values_default) labels = ["amplitude", "x_c", "y_c", "gamma", "alpha", "eta_gauss", "stddev", "saturation"] axis_names = ["$A$", r"$x_c$", r"$y_c$", r"$\gamma$", r"$\alpha$", r"$\eta$", r"$\sigma$", "saturation"] - bounds = [(0, np.inf), (-np.inf, np.inf), (-np.inf, np.inf), (0.1, np.inf), (1.1, 100), - (-1, -5e-3), (0.5, np.inf), (0, np.inf)] + bounds = [(0, np.inf), (-np.inf, np.inf), (-np.inf, np.inf), (1, np.inf), (1.1, 10), + (-1, -5e-3), (1, np.inf), (0, np.inf)] self.params = FitParameters(values=values, labels=labels, axis_names=axis_names, bounds=bounds) def apply_max_width_to_bounds(self, max_half_width=None): if max_half_width is not None: self.max_half_width = max_half_width - self.params.bounds[2] = (0, 2 * self.max_half_width) - self.params.bounds[3] = (0.1, self.max_half_width) - self.params.bounds[6] = (0.5, self.max_half_width) + self.params.bounds[2] = (-2 * self.max_half_width, 2 * self.max_half_width) + self.params.bounds[3] = (1, self.max_half_width) + self.params.bounds[6] = (1, self.max_half_width) def evaluate(self, pixels, values=None): r"""Evaluate the MoffatGauss function. @@ -1729,6 +2129,191 @@ def jacobian(self, pixels, params, epsilon=None, model_input=None, analytical=Tr return J +class DoubleMoffat(PSF): + + def __init__(self, values=None, clip=False): + PSF.__init__(self, clip=clip) + self.values_default = np.array([1, 0, 0, 3, 2, 0.005, 3, 1.5, 10]).astype(float) + if values is None: + values = np.copy(self.values_default) + labels = ["amplitude", "x_c", "y_c", "gamma1", "alpha1", "eta", "gamma2", "alpha2", "saturation"] + axis_names = ["$A$", r"$x_c$", r"$y_c$", r"$\gamma_1$", r"$\alpha_1$", r"$\eta$", r"$\gamma_2$", r"$\alpha_2$", "saturation"] + bounds = [(0, np.inf), (-np.inf, np.inf), (-np.inf, np.inf), (1, np.inf), (1.1, 10), + (0, 1), (1, np.inf), (1.1, 10), (0, np.inf)] + self.params = FitParameters(values=values, labels=labels, axis_names=axis_names, bounds=bounds) + + def apply_max_width_to_bounds(self, max_half_width=None): + if max_half_width is not None: + self.max_half_width = max_half_width + self.params.bounds[2] = (-2 * self.max_half_width, 2 * self.max_half_width) + self.params.bounds[3] = (1, self.max_half_width) + self.params.bounds[5] = (1, self.max_half_width) + + def evaluate(self, pixels, values=None): + r"""Evaluate the DoubleMoffat function. + + The function is normalized to have an integral equal to amplitude parameter, with normalisation factor: + + .. math:: + + f(y) \propto \frac{A}{ \frac{\Gamma(\alpha_1)}{\gamma_1 \sqrt{\pi} \Gamma(\alpha_1 -1/2)}+\eta\frac{\Gamma(\alpha_2)}{\gamma_2 \sqrt{\pi} \Gamma(\alpha_2 -1/2)}, + \quad \int_{y_{\text{min}}}^{y_{\text{max}}} f(y) \mathrm{d}y = A + + Parameters + ---------- + pixels: list + List containing the X abscisse 2D array and the Y abscisse 2D array. + values: array_like + The parameter array. If None, the array used to instanciate the class is taken. + If given, the class instance parameter array is updated. + + Returns + ------- + output: array_like + The PSF function evaluated. + + Examples + -------- + >>> p = [2,20,30,4,2,2,5,1.5,20] + >>> psf = DoubleMoffat(p) + >>> yy, xx = np.mgrid[:50, :60] + >>> out = psf.evaluate(pixels=np.array([xx, yy]), values=p) + + .. plot:: + + import matplotlib.pyplot as plt + import numpy as np + from spectractor.extractor.psf import DoubleMoffat + p = [2,20,30,4,2,2,5,1.5,20] + psf = DoubleMoffat(p) + yy, xx = np.mgrid[:50, :60] + out = psf.evaluate(pixels=np.array([xx, yy]), values=p) + fig = plt.figure(figsize=(5,5)) + plt.imshow(out, origin="lower") + plt.xlabel("X [pixels]") + plt.ylabel("Y [pixels]") + plt.show() + + """ + if values is not None: + self.params.values = np.asarray(values).astype(float) + amplitude, x_c, y_c, gamma1, alpha1, eta, gamma2, alpha2, saturation = self.params.values + if pixels.ndim == 3 and pixels.shape[0] == 2: + x, y = pixels # .astype(np.float32) # float32 to increase rapidity + out = evaluate_doublemoffat2d(x, y, amplitude, x_c, y_c, gamma1, alpha1, eta, gamma2, alpha2) + if self.clip: + out = np.clip(out, 0, saturation) + return out + elif pixels.ndim == 1: + y = np.array(pixels) + if alpha1 > 0.5 and alpha2 > 0.5: + norm1 = evaluate_moffat1d_normalisation(gamma1, alpha1) + norm2 = evaluate_moffat1d_normalisation(gamma2, alpha2) + out = evaluate_doublemoffat1d(y, amplitude, y_c, gamma1, alpha1, eta, gamma2, alpha2, norm1, norm2) + if self.clip: + out = np.clip(out, 0, saturation) + return out + else: + return np.zeros_like(y) + else: # pragma: no cover + raise ValueError(f"Pixels array must have dimension 1 or shape=(2,Nx,Ny). Here pixels.ndim={pixels.shape}.") + + def jacobian(self, pixels, params, epsilon=None, model_input=None, analytical=True): + r"""Evaluate the PSF DoubleMoffat Jacobian. + + The function is normalized to have an integral equal to amplitude parameter, with normalisation factor: + + Parameters + ---------- + pixels: array_like + List containing the X abscisse 2D array and the Y abscisse 2D array. + params: array_like + The parameter array. If None, the array used to instanciate the class is taken. + If given, the class instance parameter array is updated. + epsilon: array_like, optional + The array of small steps to compute the partial derivatives of the model if analytical=False (default: None). + model_input: array_like, optional + A model input as a list with (x, model, model_err) to avoid an additional call to simulate() if analytical=False (default: None). + analytical: bool, optional + If True, use analytical derivatives to compute Jacobian operator. Otherwise use numerical differenciations + with steps given by epsilon argument (default: True). + + Returns + ------- + jacobian: array_like + The PSF Jacobian. + + Examples + -------- + >>> p = [2,20,30,4,2,0.5,3,3,20] + >>> epsilon = [0.001] * len(p) + >>> psf = DoubleMoffat(p) + >>> psf.params.fixed = [True, True, False, False, False, False, False, False, True] # fix amplitude, x_c, saturation + + 2D case + + >>> yy, xx = np.mgrid[:50, :60] + >>> J_ana = psf.jacobian(pixels=np.array([xx, yy]), params=p, epsilon=epsilon, analytical=True) + >>> J_num = psf.jacobian(pixels=np.array([xx, yy]), params=p, epsilon=epsilon, analytical=False) + >>> np.allclose(J_num, J_ana, rtol=1e-4, atol=1e-4) + True + >>> np.allclose(J_ana[0:2], 0) + True + + .. doctest:: + :hide: + + >>> assert J_ana.shape == (len(p), xx.size) + >>> assert J_num.shape == (len(p), xx.size) + + 1D case + + >>> y = np.mgrid[:50] + >>> J_ana = psf.jacobian(pixels=y, params=p, epsilon=epsilon, analytical=True) + >>> J_num = psf.jacobian(pixels=y, params=p, epsilon=epsilon, analytical=False) + >>> np.allclose(J_num, J_ana, rtol=1e-3, atol=1e-3) + True + >>> np.allclose(J_ana[0:2], 0) + True + + .. doctest:: + :hide: + + >>> assert J_ana.shape == (len(p), y.size) + >>> assert J_num.shape == (len(p), y.size) + """ + if epsilon is None and not analytical: + raise ValueError(f"If analytical=False, must give epsilon values for numerical differentiation.") + amplitude, x_c, y_c, gamma1, alpha1, eta, gamma2, alpha2, saturation = self.params.values.astype(float) + J = super().jacobian(pixels, params, epsilon=epsilon, model_input=model_input, analytical=analytical) + if not analytical: + if model_input is None: + model = self.evaluate(pixels, values=params) + else: + x, model, model_err = model_input + for ip, p in enumerate(params): + if self.params.fixed[ip]: + continue + tmp_p = np.copy(params).astype(float) + if tmp_p[ip] + epsilon[ip] < self.params.bounds[ip][0] or tmp_p[ip] + epsilon[ip] > self.params.bounds[ip][1]: + epsilon[ip] = - epsilon[ip] + tmp_p[ip] += epsilon[ip] + tmp_model = self.evaluate(pixels, values=tmp_p) + J[ip] = (tmp_model.ravel() - model.ravel()) / epsilon[ip] + else: + fixed = np.array(self.params.fixed) + if pixels.ndim == 1: + norm1 = evaluate_moffat1d_normalisation(gamma1, alpha1) + norm2 = evaluate_moffat1d_normalisation(gamma2, alpha2) + dnormda1 = evaluate_moffat1d_normalisation_dalpha(norm1, alpha1) + dnormda2 = evaluate_moffat1d_normalisation_dalpha(norm2, alpha2) + J[:-1] = evaluate_doublemoffat1d_jacobian(pixels, amplitude, y_c, gamma1, alpha1, eta, gamma2, alpha2, norm1, dnormda1, norm2, dnormda2, fixed=fixed) # [:-1] assume saturation is fixed + else: + xx, yy = pixels + J[:-1] = evaluate_doublemoffat2d_jacobian(xx, yy, amplitude, x_c, y_c, gamma1, alpha1, eta, gamma2, alpha2, fixed=fixed) # [:-1] assume saturation is fixed + return J + + class Order0(PSF): def __init__(self, target, values=None, clip=False): @@ -1769,7 +2354,7 @@ def func(x, y, amplitude, x_c, y_c, gamma): def apply_max_width_to_bounds(self, max_half_width=None): if max_half_width is not None: self.max_half_width = max_half_width - self.params.bounds[2] = (0, 2 * self.max_half_width) + self.params.bounds[2] = (-2 * self.max_half_width, 2 * self.max_half_width) def evaluate(self, pixels, values=None): r"""Evaluate the Order 0 interpolated function. @@ -2093,8 +2678,9 @@ def plot_fit(self): if self.bgd_model_func is not None: data = data + self.bgd_model_func(self.pixels) ax[0].errorbar(self.pixels, data, yerr=self.err, fmt='ro', label="Data") - if len(self.outliers) > 0: - ax[0].errorbar(self.outliers, data[self.outliers], yerr=self.err[self.outliers], fmt='go', + if len(self.outliers) > 0 or len(self.mask) > 0: + bads = list(np.unique(np.concatenate([self.mask, self.outliers])).astype(int)) + ax[0].errorbar(bads, data[bads], yerr=self.err[bads], fmt='go', label=rf"Outliers ({self.sigma_clip}$\sigma$)") if self.bgd_model_func is not None: ax[0].plot(self.pixels, self.bgd_model_func(self.pixels), 'b--', label="fitted bgd") @@ -2124,10 +2710,11 @@ def plot_fit(self): residuals = (data - model) / self.err residuals_err = np.ones_like(self.err) ax[1].errorbar(self.pixels, residuals, yerr=residuals_err, fmt='ro') - if len(self.outliers) > 0: - residuals_outliers = (data[self.outliers] - model[self.outliers]) / self.err[self.outliers] + if len(self.outliers) > 0 or len(self.mask) > 0: + bads = list(np.unique(np.concatenate([self.mask, self.outliers])).astype(int)) + residuals_outliers = (data[bads] - model[bads]) / self.err[bads] residuals_outliers_err = np.ones_like(residuals_outliers) - ax[1].errorbar(self.outliers, residuals_outliers, yerr=residuals_outliers_err, fmt='go') + ax[1].errorbar(bads, residuals_outliers, yerr=residuals_outliers_err, fmt='go') ax[1].axhline(0, color='b') ax[1].grid(True) std = np.std(residuals) @@ -2252,6 +2839,8 @@ def load_PSF(psf_type=parameters.PSF_TYPE, target=None, clip=False): psf = MoffatGauss(clip=clip) elif psf_type == "Gauss": psf = Gauss(clip=clip) + elif psf_type == "DoubleMoffat": + psf = DoubleMoffat(clip=clip) elif psf_type == "Order0": if target is None: raise ValueError(f"A Target instance must be given when PSF_TYPE='Order0'. I got target={target}.") diff --git a/spectractor/extractor/spectroscopy.py b/spectractor/extractor/spectroscopy.py index c741b0eb1..618949068 100644 --- a/spectractor/extractor/spectroscopy.py +++ b/spectractor/extractor/spectroscopy.py @@ -501,8 +501,8 @@ def build_detected_line_table(self, amplitude_units="", calibration_only=False): # Hydrogen lines HALPHA = Line(656.3, atmospheric=False, label='$H\\alpha$', label_pos=[-0.02, 0.02], use_for_calibration=True) HBETA = Line(486.3, atmospheric=False, label='$H\\beta$', label_pos=[0.007, 0.02], use_for_calibration=True) -HGAMMA = Line(434.0, atmospheric=False, label='$H\\gamma$', label_pos=[0.007, 0.02], use_for_calibration=False) -HDELTA = Line(410.2, atmospheric=False, label='$H\\delta$', label_pos=[0.007, 0.02], use_for_calibration=False) +HGAMMA = Line(434.0, atmospheric=False, label='$H\\gamma$', label_pos=[0.007, 0.02], use_for_calibration=True) +HDELTA = Line(410.2, atmospheric=False, label='$H\\delta$', label_pos=[0.007, 0.02], use_for_calibration=True) HEPSILON = Line(397.0, atmospheric=False, label='$H\\epsilon$', label_pos=[-0.02, 0.02], use_for_calibration=False) HYDROGEN_LINES = [HALPHA, HBETA, HGAMMA, HDELTA, HEPSILON] diff --git a/spectractor/extractor/spectrum.py b/spectractor/extractor/spectrum.py index c3641e06f..fb09fa5f2 100644 --- a/spectractor/extractor/spectrum.py +++ b/spectractor/extractor/spectrum.py @@ -133,7 +133,7 @@ class Spectrum: Outside relative humidity in fraction of one. throughput: callable Instrumental throughput of the telescope. - spectrogram: array + spectrogram_data: array Spectrogram 2D image in image units. spectrogram_bgd: array Estimated 2D background fitted below the spectrogram in image units. @@ -145,6 +145,12 @@ class Spectrum: Best fitting model of the spectrogram in image units. spectrogram_residuals: array Residuals between the spectrogram data and the best fitting model of the spectrogram in image units. + spectrogram_flat: array + Flat array for the spectrogram with average=1. + spectrogram_starfield: array + Star field simulation array for the spectrogram in ADU/s. + spectrogram_mask: array + Boolean mask array to flag the defects. spectrogram_x0: float Relative position of the target in the spectrogram array along the x axis. spectrogram_y0: float @@ -237,12 +243,15 @@ def __init__(self, file_name="", image=None, order=1, target=None, config="", fa self.rotation_angle = 0 self.parallactic_angle = None self.camera_angle = 0 - self.spectrogram = None + self.spectrogram_data = None self.spectrogram_bgd = None self.spectrogram_bgd_rms = None self.spectrogram_err = None self.spectrogram_residuals = None self.spectrogram_fit = None + self.spectrogram_flat = None + self.spectrogram_starfield = None + self.spectrogram_mask = None self.spectrogram_x0 = None self.spectrogram_y0 = None self.spectrogram_xmin = None @@ -504,7 +513,7 @@ def plot_spectrogram(self, ax=None, scale="lin", title="", units="Image units", if ax is None: plt.figure(figsize=figsize) ax = plt.gca() - data = np.copy(self.spectrogram) + data = np.copy(self.spectrogram_data) if plot_stats: data = np.copy(self.spectrogram_err) plot_image_simple(ax, data=data, scale=scale, title=title, units=units, cax=cax, @@ -587,7 +596,7 @@ def generate_axes(fig): widthPlot.set_xlabel(r'$\lambda$ [nm]') widthPlot.grid() - spectrogram = np.copy(self.spectrogram) + spectrogram = np.copy(self.spectrogram_data) res = self.spectrogram_residuals.reshape((-1, self.spectrogram_Nx)) std = np.std(res) if spectrogram.shape[0] != res.shape[0]: @@ -647,8 +656,8 @@ def save_spectrum(self, output_file_name, overwrite=False): """ from spectractor._version import __version__ self.header["VERSION"] = str(__version__) - self.header["REBIN"] = parameters.CCD_REBIN - self.header.comments['REBIN'] = 'original image rebinning factor to get spectrum.' + self.header["CCD_REBIN"] = parameters.CCD_REBIN + self.header.comments['CCD_REBIN'] = 'original image rebinning factor to get spectrum.' self.header['UNIT1'] = "nanometer" self.header['UNIT2'] = self.units self.header['COMMENTS'] = 'First column gives the wavelength in unit UNIT1, ' \ @@ -669,7 +678,7 @@ def save_spectrum(self, output_file_name, overwrite=False): # print(f"Set header key {header_key} to {value} from attr {attribute}") extnames = ["SPECTRUM", "SPEC_COV", "ORDER2", "ORDER0"] # spectrum data - extnames += ["S_DATA", "S_ERR", "S_BGD", "S_BGD_ER", "S_FIT", "S_RES"] # spectrogram data + extnames += ["S_DATA", "S_ERR", "S_BGD", "S_BGD_ER", "S_FIT", "S_RES", "S_FLAT", "S_STAR", "S_MASK"] extnames += ["PSF_TAB"] # PSF parameter table extnames += ["LINES"] # spectroscopic line table extnames += ["CONFIG"] # config parameters @@ -682,13 +691,16 @@ def save_spectrum(self, output_file_name, overwrite=False): if extname == "SPEC_COV": hdus[extname].data = self.cov_matrix elif extname == "ORDER2": - hdus[extname].data = [self.lambdas, self.data_next_order, self.err_next_order] + if self.data_next_order is not None: + hdus[extname].data = [self.lambdas, self.data_next_order, self.err_next_order] + else: + hdus[extname].data = [self.lambdas, np.zeros_like(self.lambdas), np.zeros_like(self.lambdas)] elif extname == "ORDER0": hdus[extname].data = self.target.image hdus[extname].header["IM_X0"] = self.target.image_x0 hdus[extname].header["IM_Y0"] = self.target.image_y0 elif extname == "S_DATA": - hdus[extname].data = self.spectrogram + hdus[extname].data = self.spectrogram_data hdus[extname].header['UNIT1'] = self.units elif extname == "S_ERR": hdus[extname].data = self.spectrogram_err @@ -700,6 +712,15 @@ def save_spectrum(self, output_file_name, overwrite=False): hdus[extname].data = self.spectrogram_fit elif extname == "S_RES": hdus[extname].data = self.spectrogram_residuals + elif extname == "S_FLAT": + hdus[extname].data = self.spectrogram_flat + elif extname == "S_STAR": + hdus[extname].data = self.spectrogram_starfield + elif extname == "S_MASK": + if self.spectrogram_mask is not None: + hdus[extname].data = self.spectrogram_mask.astype(int) + else: + hdus[extname].data = self.spectrogram_mask elif extname == "PSF_TAB": hdus[extname] = fits.table_to_hdu(self.chromatic_psf.table) elif extname == "LINES": @@ -784,7 +805,7 @@ def save_spectrogram(self, output_file_name, overwrite=False): # pragma: no cov hdu6 = fits.ImageHDU() hdu6.header["EXTNAME"] = "S_RES" hdu1.header = self.header - hdu1.data = self.spectrogram + hdu1.data = self.spectrogram_data hdu2.data = self.spectrogram_err hdu3.data = self.spectrogram_bgd hdu4.data = self.spectrogram_bgd_rms @@ -967,7 +988,7 @@ def load_spectrum_older_24(self, input_file_name, spectrogram_file_name_override self.target.image_y0 = float(hdu_list["ORDER0"].header["IM_Y0"]) # load spectrogram info if len(hdu_list) > 4: - self.spectrogram = hdu_list["S_DATA"].data + self.spectrogram_data = hdu_list["S_DATA"].data self.spectrogram_err = hdu_list["S_ERR"].data self.spectrogram_bgd = hdu_list["S_BGD"].data if len(hdu_list) > 7: @@ -1072,7 +1093,7 @@ def load_spectrum_latest(self, input_file_name): self.chromatic_psf.opt_reg = float(self.header["PSF_REG"]) if not self.fast_load: - with fits.open(input_file_name) as hdu_list: + with (fits.open(input_file_name) as hdu_list): # load other spectrum info self.cov_matrix = hdu_list["SPEC_COV"].data _, self.data_next_order, self.err_next_order = hdu_list["ORDER2"].data @@ -1080,12 +1101,20 @@ def load_spectrum_latest(self, input_file_name): self.target.image_x0 = float(hdu_list["ORDER0"].header["IM_X0"]) self.target.image_y0 = float(hdu_list["ORDER0"].header["IM_Y0"]) # load spectrogram info - self.spectrogram = hdu_list["S_DATA"].data + self.spectrogram_data = hdu_list["S_DATA"].data self.spectrogram_err = hdu_list["S_ERR"].data self.spectrogram_bgd = hdu_list["S_BGD"].data self.spectrogram_bgd_rms = hdu_list["S_BGD_ER"].data self.spectrogram_fit = hdu_list["S_FIT"].data self.spectrogram_residuals = hdu_list["S_RES"].data + if "S_FLAT" in [hdu.name for hdu in hdu_list]: + self.spectrogram_flat = hdu_list["S_FLAT"].data + if "S_STAR" in [hdu.name for hdu in hdu_list]: + self.spectrogram_starfield = hdu_list["S_STAR"].data + if "S_MASK" in [hdu.name for hdu in hdu_list]: + self.spectrogram_mask = hdu_list["S_MASK"].data + if self.spectrogram_mask is not None: + self.spectrogram_mask = self.spectrogram_mask.astype(bool) self.chromatic_psf.init_from_table(Table.read(hdu_list["PSF_TAB"]), saturation=self.spectrogram_saturation) self.lines.table = Table.read(hdu_list["LINES"], unit_parse_strict="silent") @@ -1106,7 +1135,7 @@ def load_spectrogram(self, input_file_name): # pragma: no cover if os.path.isfile(input_file_name): with fits.open(input_file_name) as hdu_list: header = hdu_list[0].header - self.spectrogram = hdu_list[0].data + self.spectrogram_data = hdu_list[0].data self.spectrogram_err = hdu_list[1].data self.spectrogram_bgd = hdu_list[2].data if len(hdu_list) > 3: @@ -1787,8 +1816,8 @@ def detect_lines(lines, lambdas, spec, spec_err=None, cov_matrix=None, fwhm_func Y = -Gauss / Continuum Ydata = 1 - spectr_data / Continuum - line.fit_eqwidth_mod = integrate.simps(Y, x_int) # sol1 - line.fit_eqwidth_data = integrate.simps(Ydata, x_int) # sol2 + line.fit_eqwidth_mod = integrate.simpson(Y, x=x_int) # sol1 + line.fit_eqwidth_data = integrate.simpson(Ydata, x=x_int) # sol2 line.fit_popt = popt line.fit_pcov = pcov diff --git a/spectractor/extractor/targets.py b/spectractor/extractor/targets.py index 25c830633..6a29e8cd0 100644 --- a/spectractor/extractor/targets.py +++ b/spectractor/extractor/targets.py @@ -86,6 +86,7 @@ def __init__(self, label, verbose=False): self.image = None self.image_x0 = None self.image_y0 = None + self.starfield = None class ArcLamp(Target): @@ -230,6 +231,9 @@ def __init__(self, label, verbose=False): """ Target.__init__(self, label, verbose=verbose) self.my_logger = set_logger(self.__class__.__name__) + self.lines = Lines(HYDROGEN_LINES + ATMOSPHERIC_LINES + STELLAR_LINES, + redshift=self.redshift, emission_spectrum=self.emission_spectrum, + hydrogen_only=self.hydrogen_only) self.simbad_table = None self.load() diff --git a/spectractor/fit/fit_multispectra.py b/spectractor/fit/fit_multispectra.py index 521f1adf2..c8db045d7 100644 --- a/spectractor/fit/fit_multispectra.py +++ b/spectractor/fit/fit_multispectra.py @@ -51,7 +51,7 @@ def _build_sim_sample(spectra, aerosols=0.05, ozone=300, pwv=5, angstrom_exponen # fast_sim must be True to avoid biases (the rebinning is done after in _prepare_data()) s = SpectrumSimulation(spec, atmosphere=atm, fast_sim=True, with_adr=True) s.simulate(A1=1, A2=0, aerosols=aerosols, angstrom_exponent=angstrom_exponent, ozone=ozone, pwv=pwv, - reso=-1, D=parameters.DISTANCE2CCD, shift_x=0, B=0) + reso=-1, D=parameters.DISTANCE2CCD, shift_x=0) sim_spectra.append(s) return sim_spectra @@ -99,7 +99,7 @@ def _build_test_sample(targets=["HD111980"]*3, zs=np.linspace(1, 2, 3), aerosols s.temperature = temperature s.adr_params = [s.dec, s.hour_angle, temperature, pressure, s.humidity, airmass] s.simulate(A1=1, A2=0, aerosols=aerosols, angstrom_exponent=angstrom_exponent, ozone=ozone, pwv=pwv, - reso=-1, D=parameters.DISTANCE2CCD, shift_x=0, B=0) + reso=-1, D=parameters.DISTANCE2CCD, shift_x=0) spectra.append(s) return spectra diff --git a/spectractor/fit/fit_spectrogram.py b/spectractor/fit/fit_spectrogram.py index 80fdf8b97..22cb70421 100644 --- a/spectractor/fit/fit_spectrogram.py +++ b/spectractor/fit/fit_spectrogram.py @@ -67,26 +67,30 @@ def __init__(self, spectrum, atmgrid_file_name="", fit_angstrom_exponent=False, self.psf_poly_params = self.spectrum.chromatic_psf.from_table_to_poly_params()[length:] self.saturation = self.spectrum.spectrogram_saturation D2CCD = np.copy(spectrum.header['D2CCD']) - p = np.array([1, 1, 1, 0.05, 1.2, 400, 5, D2CCD, self.spectrum.header['PIXSHIFT'], - 0, self.spectrum.rotation_angle, 1]) - self.psf_params_start_index = np.array([12 + len(self.psf_poly_params) * k for k in range(len(self.diffraction_orders))]) + p = np.array([1, 1, 0, 0.05, 1.2, 400, 5, 1, 1, D2CCD, self.spectrum.header['PIXSHIFT'], + 0, self.spectrum.rotation_angle, self.spectrum.pressure]) + # parameter indices for which we don't need to recompute the PSF cube for model evaluation + # warning: they must be contiguous to preserve psf_cube in jacobian function loop + self.fixed_psf_params = np.arange(0, 9, dtype=int) + self.psf_params_start_index = np.array([p.size + len(self.psf_poly_params) * k for k in range(len(self.diffraction_orders))]) psf_poly_params_labels = np.copy(self.spectrum.chromatic_psf.params.labels[length:]) psf_poly_params_names = np.copy(self.spectrum.chromatic_psf.params.axis_names[length:]) psf_poly_params_bounds = self.spectrum.chromatic_psf.set_bounds() p = np.concatenate([p] + [self.psf_poly_params] * len(self.diffraction_orders)) input_labels = [f"A{order}" for order in self.diffraction_orders] - input_labels += ["VAOD", "angstrom_exp", "ozone [db]", "PWV [mm]", r"D_CCD [mm]", - r"shift_x [pix]", r"shift_y [pix]", r"angle [deg]", "B"] + input_labels += ["VAOD", "angstrom_exp", "ozone [db]", "PWV [mm]", "B", "A_star", + r"D_CCD [mm]", r"shift_x [pix]", r"shift_y [pix]", r"angle [deg]", "P [hPa]"] for order in self.diffraction_orders: input_labels += [label + f"_{order}" for label in psf_poly_params_labels] axis_names = [f"$A_{order}$" for order in self.diffraction_orders] - axis_names += ["VAOD", r'$\"a$', "ozone [db]", "PWV [mm]", r"$D_{CCD}$ [mm]", - r"$\Delta_{\mathrm{x}}$ [pix]", r"$\Delta_{\mathrm{y}}$ [pix]", r"$\theta$ [deg]", "$B$"] + axis_names += ["VAOD", r'$\"a$', "ozone [db]", "PWV [mm]", "$B$", r"$A_{star}$", r"$D_{CCD}$ [mm]", + r"$\Delta_{\mathrm{x}}$ [pix]", r"$\Delta_{\mathrm{y}}$ [pix]", r"$\theta$ [deg]", + r"$P_{\mathrm{atm}}$ [hPa]"] for order in self.diffraction_orders: axis_names += [label+rf"$\!_{order}$" for label in psf_poly_params_names] - bounds = [[0, 2], [0, 2], [0, 2], [0, 0.1], [0, 3], [100, 700], [0, 20], + bounds = [[0, 2], [0, 2], [0, 2], [0, 1], [0, 3], [100, 700], [0, 20], [0.8, 1.2], [0, np.inf], [D2CCD - 5 * parameters.DISTANCE2CCD_ERR, D2CCD + 5 * parameters.DISTANCE2CCD_ERR], [-2, 2], - [-10, 10], [-90, 90], [0.8, 1.2]] + [-10, 10], [-90, 90], [0, np.inf]] bounds += list(psf_poly_params_bounds) * len(self.diffraction_orders) fixed = [False] * p.size for k, par in enumerate(input_labels): @@ -94,22 +98,34 @@ def __init__(self, spectrum, atmgrid_file_name="", fit_angstrom_exponent=False, fixed[k] = True for k, par in enumerate(input_labels): if "y_c" in par: - fixed[k] = False + fixed[k] = True p[k] = 0 + for k, par in enumerate(input_labels): + if k >= self.psf_params_start_index[0] and "y_c" not in par and "x_c" not in par and par[-2:] != f"_{spectrum.order}" and "_0_" not in par: + fixed[k] = True + p[k] = 0 + if k >= self.psf_params_start_index[0] and "eta" in par and par[-2:] != f"_{spectrum.order}": + fixed[k] = True + p[k] = 0 + # for k, par in enumerate(input_labels): + # if k >= self.psf_params_start_index[0] and "y_c" not in par and "x_c" not in par and par[-2:] != f"_{spectrum.order}" and "_0_" not in par: + # fixed[k] = True + # p[k] = 0 params = FitParameters(p, labels=input_labels, axis_names=axis_names, bounds=bounds, fixed=fixed, truth=truth, filename=self.filename) - self.fixed_psf_params = np.array([0, 1, 2, 3, 4, 5, 6, 9]) + params.fixed[params.get_index(f"A{self.diffraction_orders[0]}")] = True # A1 self.atm_params_indices = np.array([params.get_index(label) for label in ["VAOD", "angstrom_exp", "ozone [db]", "PWV [mm]"]]) # A2 is free only if spectrogram is a simulation or if the order 2/1 ratio is not known and flat if "A2" in params.labels: - params.fixed[params.get_index(f"A{self.diffraction_orders[1]}")] = "A2_T" not in self.spectrum.header + params.fixed[params.get_index(f"A{self.diffraction_orders[1]}")] = False #"A2_T" not in self.spectrum.header if "A3" in params.labels: params.fixed[params.get_index(f"A{self.diffraction_orders[2]}")] = "A3_T" not in self.spectrum.header - params.fixed[params.get_index(r"shift_x [pix]")] = True # Delta x - params.fixed[params.get_index(r"shift_y [pix]")] = True # Delta y - params.fixed[params.get_index(r"angle [deg]")] = True # angle + params.fixed[params.get_index(r"shift_x [pix]")] = False # Delta x + params.fixed[params.get_index(r"shift_y [pix]")] = False # Delta y + params.fixed[params.get_index(r"angle [deg]")] = False # angle params.fixed[params.get_index("B")] = True # B + params.fixed[params.get_index("P [hPa]")] = False # pressure for ADR FitWorkspace.__init__(self, params, verbose=verbose, plot=plot, live_fit=live_fit, file_name=self.filename) self.my_logger = set_logger(self.__class__.__name__) @@ -129,16 +145,29 @@ def __init__(self, spectrum, atmgrid_file_name="", fit_angstrom_exponent=False, if self.spectrum.spectrogram_Ny > 2 * parameters.PIXDIST_BACKGROUND: self.crop_spectrogram() self.lambdas = self.spectrum.lambdas - self.Ny, self.Nx = self.spectrum.spectrogram.shape - self.data = self.spectrum.spectrogram.flatten() + self.Ny, self.Nx = self.spectrum.spectrogram_data.shape + self.data = self.spectrum.spectrogram_data.flatten() self.err = self.spectrum.spectrogram_err.flatten() + self.bgd = self.spectrum.spectrogram_bgd.flatten() + if self.spectrum.spectrogram_flat is not None: + self.flat = self.spectrum.spectrogram_flat.flatten() + else: + self.flat = None + if self.spectrum.spectrogram_starfield is not None: + self.starfield = self.spectrum.spectrogram_starfield.flatten() + else: + self.starfield = None + if self.spectrum.spectrogram_mask is not None: + self.mask = list(np.where(spectrum.spectrogram_mask.astype(bool).ravel())[0]) + else: + self.mask = [] self.fit_angstrom_exponent = fit_angstrom_exponent if not fit_angstrom_exponent: self.params.fixed[self.params.get_index("angstrom_exp")] = True # angstrom exponent self.params.values[self.params.get_index("angstrom_exp")] = self.atmosphere.angstrom_exponent_default - self.simulation = SpectrogramModel(self.spectrum, atmosphere=self.atmosphere, + self.spectrogram_simulation = SpectrogramModel(self.spectrum, atmosphere=self.atmosphere, diffraction_orders=self.diffraction_orders, - with_background=True, fast_sim=False, with_adr=True) + fast_sim=False, with_adr=True) self.lambdas_truth = None self.amplitude_truth = None self.get_spectrogram_truth() @@ -152,6 +181,7 @@ def __init__(self, spectrum, atmgrid_file_name="", fit_angstrom_exponent=False, # flat data for fitworkspace self.data_before_mask = np.copy(self.data) self.W_before_mask = np.copy(self.W) + self.mask_before_mask = list(np.copy(self.mask)) # create mask self.set_mask() @@ -164,11 +194,17 @@ def crop_spectrogram(self): self.spectrum.spectrogram_ymax = self.spectrum.spectrogram_ymax - bgd_width self.spectrum.spectrogram_ymin += bgd_width self.spectrum.spectrogram_bgd = self.spectrum.spectrogram_bgd[bgd_width:-bgd_width, :] - self.spectrum.spectrogram = self.spectrum.spectrogram[bgd_width:-bgd_width, :] + self.spectrum.spectrogram_data = self.spectrum.spectrogram_data[bgd_width:-bgd_width, :] self.spectrum.spectrogram_err = self.spectrum.spectrogram_err[bgd_width:-bgd_width, :] + if self.spectrum.spectrogram_flat is not None: + self.spectrum.spectrogram_flat = self.spectrum.spectrogram_flat[bgd_width:-bgd_width, :] + if self.spectrum.spectrogram_starfield is not None: + self.spectrum.spectrogram_starfield = self.spectrum.spectrogram_starfield[bgd_width:-bgd_width, :] + if self.spectrum.spectrogram_mask is not None: + self.spectrum.spectrogram_mask = self.spectrum.spectrogram_mask[bgd_width:-bgd_width, :] self.spectrum.spectrogram_y0 -= bgd_width self.spectrum.chromatic_psf.y0 -= bgd_width - self.spectrum.spectrogram_Ny, self.spectrum.spectrogram_Nx = self.spectrum.spectrogram.shape + self.spectrum.spectrogram_Ny, self.spectrum.spectrogram_Nx = self.spectrum.spectrogram_data.shape self.spectrum.chromatic_psf.table["y_c"] -= bgd_width self.my_logger.debug(f'\n\tSize of the spectrogram region after cropping: ' f'({self.spectrum.spectrogram_Nx},{self.spectrum.spectrogram_Ny})') @@ -194,11 +230,12 @@ def set_mask(self, params=None): self.my_logger.info("\n\tReset spectrogram mask with current parameters.") if params is None: params = self.params.values - A1, A2, A3, aerosols, angstrom_exponent, ozone, pwv, D, shift_x, shift_y, angle, B, *psf_poly_params_all = params + A1, A2, A3, aerosols, angstrom_exponent, ozone, pwv, B, Astar, D, shift_x, shift_y, angle, pressure, *psf_poly_params_all = params poly_params = np.array(psf_poly_params_all).reshape((len(self.diffraction_orders), -1)) - self.simulation.psf_cubes_masked = {} - self.simulation.M_sparse_indices = {} - self.simulation.psf_cube_sparse_indices = {} + self.spectrogram_simulation.psf_cubes_masked = {} + self.spectrogram_simulation.M_sparse_indices = {} + self.spectrogram_simulation.psf_cube_sparse_indices = {} + self.spectrum.adr_params[3] = pressure for k, order in enumerate(self.diffraction_orders): profile_params = self.spectrum.chromatic_psf.from_poly_params_to_profile_params(poly_params[k], apply_bounds=True) @@ -208,19 +245,30 @@ def set_mask(self, params=None): niter=5, with_adr=True, order=order) profile_params[:, 0] = 1 - profile_params[:, 1] = dispersion_law.real + self.simulation.r0.real - profile_params[:, 2] += dispersion_law.imag - psf_cube_masked = self.spectrum.chromatic_psf.build_psf_cube_masked(self.simulation.pixels, profile_params, + profile_params[:, 1] = dispersion_law.real + self.spectrogram_simulation.r0.real + profile_params[:, 2] += dispersion_law.imag # - self.bgd_width + psf_cube_masked = self.spectrum.chromatic_psf.build_psf_cube_masked(self.spectrogram_simulation.pixels, profile_params, fwhmx_clip=3 * parameters.PSF_FWHM_CLIP, fwhmy_clip=parameters.PSF_FWHM_CLIP) psf_cube_masked = self.spectrum.chromatic_psf.convolve_psf_cube_masked(psf_cube_masked) # make rectangular mask per wavelength - self.simulation.boundaries[order], self.simulation.psf_cubes_masked[order] = self.spectrum.chromatic_psf.get_boundaries(psf_cube_masked) - self.simulation.psf_cube_sparse_indices[order], self.simulation.M_sparse_indices[order] = self.spectrum.chromatic_psf.get_sparse_indices(psf_cube_masked) - mask = np.sum(self.simulation.psf_cubes_masked[self.diffraction_orders[0]].reshape(psf_cube_masked.shape[0], self.simulation.pixels[0].size), axis=0) == 0 + self.spectrogram_simulation.boundaries[order], self.spectrogram_simulation.psf_cubes_masked[order] = self.spectrum.chromatic_psf.set_rectangular_boundaries(psf_cube_masked) + if k > 0: + # spectrogram model must be accurate inside the k=0 order footprint: enlarge the next order footprints + self.spectrogram_simulation.boundaries[order]["ymin"] = np.zeros_like(self.spectrogram_simulation.boundaries[order]["ymin"]) + self.spectrogram_simulation.boundaries[order]["ymax"] = self.Ny * np.ones_like(self.spectrogram_simulation.boundaries[order]["ymax"]) + self.spectrogram_simulation.psf_cube_sparse_indices[order], self.spectrogram_simulation.M_sparse_indices[order] = self.spectrum.chromatic_psf.get_sparse_indices(self.spectrogram_simulation.boundaries[order]) + # mask = np.sum(self.spectrogram_simulation.psf_cubes_masked[self.diffraction_orders[0]].reshape(psf_cube_masked.shape[0], self.spectrogram_simulation.pixels[0].size), axis=0) == 0 + # cumulate the boolean values as int + weight_mask = np.sum(self.spectrogram_simulation.psf_cubes_masked[self.diffraction_orders[0]], axis=0) + # look for indices with maximum weight per column (all sheets of the psf cube have contributed) + res = np.max(weight_mask, axis=0)[np.newaxis,:] * np.ones((weight_mask.shape[0],1)) + # keep only the pixels where all psf_cube sheets have contributed per column + mask = (weight_mask != res).ravel() + self.mask = list(self.mask_before_mask) + list(np.where(mask)[0]) + self.mask = list(set(self.mask)) self.W = np.copy(self.W_before_mask) - self.W[mask] = 0 - self.mask = list(np.where(mask)[0]) + self.W[self.mask] = 0 def get_spectrogram_truth(self): """Load the truth parameters (if provided) from the file header. @@ -241,11 +289,13 @@ def get_spectrogram_truth(self): shifty_truth = 0 rotation_angle = self.spectrum.header['ROT_T'] B = 1 - poly_truth = np.fromstring(self.spectrum.header['PSF_P_T'][1:-1], sep=' ', dtype=float) + Astar = 1 + pressure = self.spectrum.header["OUTPRESS"] + poly_truth = np.fromstring(self.spectrum.header['PSF_P_T'][1:-1], sep=',', dtype=float) self.truth = (A1_truth, A2_truth, A3_truth, aerosols_truth, ozone_truth, pwv_truth, - D_truth, shiftx_truth, shifty_truth, rotation_angle, B, *poly_truth) - self.lambdas_truth = np.fromstring(self.spectrum.header['LBDAS_T'][1:-1], sep=' ', dtype=float) - self.amplitude_truth = np.fromstring(self.spectrum.header['AMPLIS_T'][1:-1], sep=' ', dtype=float) + D_truth, shiftx_truth, shifty_truth, rotation_angle, B, Astar, pressure, *poly_truth) + self.lambdas_truth = np.fromstring(self.spectrum.header['LBDAS_T'][1:-1], sep=',', dtype=float) + self.amplitude_truth = np.fromstring(self.spectrum.header['AMPLIS_T'][1:-1], sep=',', dtype=float) else: self.truth = None @@ -349,14 +399,21 @@ def simulate(self, *params): >>> w.plot_fit() """ - A1, A2, A3, aerosols, angstrom_exponent, ozone, pwv, D, shift_x, shift_y, angle, B, *psf_poly_params = params + A1, A2, A3, aerosols, angstrom_exponent, ozone, pwv, B, Astar, D, shift_x, shift_y, angle, pressure, *psf_poly_params = params self.params.values = np.asarray(params) + self.spectrogram_simulation.adr_params[3] = pressure if not self.fit_angstrom_exponent: angstrom_exponent = None - lambdas, model, model_err = self.simulation.simulate(A1, A2, A3, aerosols, angstrom_exponent, ozone, pwv, D, shift_x, shift_y, angle, B, psf_poly_params) + lambdas, model, model_err = self.spectrogram_simulation.simulate(A1, A2, A3, aerosols, angstrom_exponent, ozone, pwv, D, shift_x, shift_y, angle, psf_poly_params) self.lambdas = lambdas self.model = model.flatten() self.model_err = model_err.flatten() + self.model += B * self.bgd + if self.starfield is not None: + self.model += Astar * self.starfield + if self.flat is not None: + # TODO: if flat array is a cube flat, needs to multiply directly in build_psf_cube + self.model *= self.flat return self.lambdas, self.model, self.model_err def jacobian(self, params, epsilon, model_input=None): @@ -367,19 +424,19 @@ def jacobian(self, params, epsilon, model_input=None): lambdas, model, model_err = self.simulate(*params) model = model.flatten() J = np.zeros((params.size, model.size)) - strategy = copy.copy(self.simulation.fix_psf_cube) - atmosphere = copy.copy(self.simulation.atmosphere_sim) + strategy = copy.copy(self.spectrogram_simulation.fix_psf_cube) + atmosphere = copy.copy(self.spectrogram_simulation.atmosphere_sim) for ip, p in enumerate(params): if self.params.fixed[ip]: continue if ip in self.fixed_psf_params: - self.simulation.fix_psf_cube = True + self.spectrogram_simulation.fix_psf_cube = True else: - self.simulation.fix_psf_cube = False + self.spectrogram_simulation.fix_psf_cube = False if ip in self.atm_params_indices: - self.simulation.fix_atm_sim = False + self.spectrogram_simulation.fix_atm_sim = False else: - self.simulation.fix_atm_sim = True + self.spectrogram_simulation.fix_atm_sim = True if ip >= self.psf_params_start_index[0]: continue tmp_p = np.copy(params) @@ -387,21 +444,21 @@ def jacobian(self, params, epsilon, model_input=None): epsilon[ip] = - epsilon[ip] tmp_p[ip] += epsilon[ip] tmp_lambdas, tmp_model, tmp_model_err = self.simulate(*tmp_p) - if self.simulation.fix_atm_sim is False: - self.simulation.atmosphere_sim = atmosphere + if self.spectrogram_simulation.fix_atm_sim is False: + self.spectrogram_simulation.atmosphere_sim = atmosphere J[ip] = (tmp_model.flatten() - model) / epsilon[ip] - self.simulation.fix_atm_sim = True - self.simulation.fix_psf_cube = False + self.spectrogram_simulation.fix_atm_sim = True + self.spectrogram_simulation.fix_psf_cube = False for k, order in enumerate(self.diffraction_orders): - if self.simulation.profile_params[order] is None: + if self.spectrogram_simulation.profile_params[order] is None: continue start = self.psf_params_start_index[k] - profile_params = np.copy(self.simulation.profile_params[order]) - J[start:start+len(self.psf_poly_params)] = self.simulation.chromatic_psf.build_psf_jacobian(self.simulation.pixels, profile_params=profile_params, - psf_cube_sparse_indices=self.simulation.psf_cube_sparse_indices[order], - boundaries=self.simulation.boundaries[order], dtype="float32") - self.simulation.fix_psf_cube = strategy - self.simulation.fix_atm_sim = False + profile_params = np.copy(self.spectrogram_simulation.profile_params[order]) + J[start:start+len(self.psf_poly_params)] = self.spectrogram_simulation.chromatic_psf.build_psf_jacobian(self.spectrogram_simulation.pixels, profile_params=profile_params, + psf_cube_sparse_indices=self.spectrogram_simulation.psf_cube_sparse_indices[order], + boundaries=self.spectrogram_simulation.boundaries[order], dtype="float32") + self.spectrogram_simulation.fix_psf_cube = strategy + self.spectrogram_simulation.fix_atm_sim = False self.my_logger.debug(f"\n\tJacobian time computation = {time.time() - start:.1f}s") return J @@ -520,7 +577,7 @@ def run_spectrogram_minimisation(fit_workspace, method="newton", verbose=False): my_logger.info(f"\n\tStart guess: {guess}\n\twith {fit_workspace.params.labels}") epsilon = 1e-4 * guess epsilon[epsilon == 0] = 1e-4 - fixed = np.copy(fit_workspace.params.fixed) + fixed_default = np.copy(fit_workspace.params.fixed) # fit_workspace.simulation.fast_sim = True # fit_workspace.simulation.fix_psf_cube = False @@ -540,9 +597,18 @@ def run_spectrogram_minimisation(fit_workspace, method="newton", verbose=False): # run_minimisation(fit_workspace, method="newton", epsilon=epsilon, fix=fit_workspace.fixed, # xtol=1e-2, ftol=10 / fit_workspace.data.size, verbose=False) - fit_workspace.simulation.fast_sim = False - fit_workspace.simulation.fix_psf_cube = False - fit_workspace.params.fixed = np.copy(fixed) + fit_workspace.spectrogram_simulation.fast_sim = False + fit_workspace.spectrogram_simulation.fix_psf_cube = False + fit_workspace.params.fixed = [True] * len(fit_workspace.params.values) + # fit_workspace.params.fixed[fit_workspace.params.get_index(r"A1")] = False # A1 + fit_workspace.params.fixed[fit_workspace.params.get_index(r"shift_y [pix]")] = False # shift y + fit_workspace.params.fixed[fit_workspace.params.get_index(r"angle [deg]")] = False # angle + run_minimisation(fit_workspace, "newton", epsilon, xtol=1e-2, ftol=0.01, with_line_search=False) + fit_workspace.params.fixed = fixed_default + + fit_workspace.spectrogram_simulation.fast_sim = False + fit_workspace.spectrogram_simulation.fix_psf_cube = False + fit_workspace.params.fixed = np.copy(fixed_default) # guess = fit_workspace.p # params_table, costs = run_gradient_descent(fit_workspace, guess, epsilon, params_table, costs, # fix=fit_workspace.fixed, xtol=1e-6, ftol=1 / fit_workspace.data.size, diff --git a/spectractor/fit/fit_spectrum.py b/spectractor/fit/fit_spectrum.py index 75981ba12..3a5ffb0e9 100644 --- a/spectractor/fit/fit_spectrum.py +++ b/spectractor/fit/fit_spectrum.py @@ -62,7 +62,7 @@ def __init__(self, spectrum, atmgrid_file_name="", fit_angstrom_exponent=False, self.spectrum = spectrum p = np.array([1, 0, 0.05, 1.2, 400, 5, 1, self.spectrum.header['D2CCD'], self.spectrum.header['PIXSHIFT'], 0]) fixed = [False] * p.size - # fixed[0] = True + fixed[0] = True fixed[1] = "A2_T" not in self.spectrum.header # fit A2 only on sims to evaluate extraction biases fixed[5] = False # fixed[6:8] = [True, True] @@ -71,13 +71,13 @@ def __init__(self, spectrum, atmgrid_file_name="", fit_angstrom_exponent=False, # fixed[-1] = True if not fit_angstrom_exponent: fixed[3] = True # angstrom_exponent - bounds = [(0, 2), (0, 2/parameters.GRATING_ORDER_2OVER1), (0, 0.1), (0, 3), (100, 700), (0, 20), + bounds = [(0, 2), (0, 2/parameters.GRATING_ORDER_2OVER1), (0, 1), (0, 3), (100, 700), (0, 20), (0.1, 10),(p[7] - 5 * parameters.DISTANCE2CCD_ERR, p[7] + 5 * parameters.DISTANCE2CCD_ERR), (-2, 2), (-np.inf, np.inf)] params = FitParameters(p, labels=["A1", "A2", "VAOD", "angstrom_exp", "ozone [db]", "PWV [mm]", - "reso [pix]", r"D_CCD [mm]", r"alpha_pix [pix]", "B"], + "reso [nm]", r"D_CCD [mm]", r"alpha_pix [pix]", "B"], axis_names=["$A_1$", "$A_2$", "VAOD", r'$\"a$', "ozone [db]", "PWV [mm]", - "reso [pix]", r"$D_{CCD}$ [mm]", r"$\alpha_{\mathrm{pix}}$ [pix]", "$B$"], + "reso [nm]", r"$D_{CCD}$ [mm]", r"$\alpha_{\mathrm{pix}}$ [pix]", "$B$"], bounds=bounds, fixed=fixed, truth=truth, filename=spectrum.filename) FitWorkspace.__init__(self, params, verbose=verbose, plot=plot, live_fit=live_fit, file_name=spectrum.filename) if atmgrid_file_name == "": @@ -145,8 +145,15 @@ def plot_spectrum_comparison_simple(self, ax, title='', extent=None, size=0.4): sub = np.where((lambdas > parameters.LAMBDA_MIN) & (lambdas < parameters.LAMBDA_MAX)) if extent is not None: sub = np.where((lambdas > extent[0]) & (lambdas < extent[1])) + bad_indices = None + if len(self.outliers) > 0 or len(self.mask) > 0: + bad_indices = np.array(list(self.get_bad_indices()) + list(self.mask)).astype(int) + plot_spectrum_simple(ax, lambdas=lambdas, data=self.data, data_err=self.err, units=self.spectrum.units) + if bad_indices is not None: + plot_spectrum_simple(ax, lambdas=lambdas[bad_indices], data=self.data[bad_indices], data_err=self.err[bad_indices], + units=self.spectrum.units, color='gray') p0 = ax.plot(lambdas, self.model, label='model') ax.fill_between(lambdas, self.model - self.model_err, self.model + self.model_err, alpha=0.3, color=p0[0].get_color()) @@ -168,7 +175,7 @@ def plot_spectrum_comparison_simple(self, ax, title='', extent=None, size=0.4): ax2.axhline(0, color=p0[0].get_color()) ax2.grid(True) ylim = ax2.get_ylim() - residuals_model = self.model_err[sub][idx] / self.err[sub][idx] + residuals_model = self.model_err[sub][idx] / norm ax2.fill_between(lambdas[sub][idx], -residuals_model, residuals_model, alpha=0.3, color=p0[0].get_color()) std = np.nanstd(residuals) # max(np.std(residuals), np.std(residuals_model)) ax2.set_ylim(-5*std, 5*std) @@ -229,7 +236,9 @@ def simulate(self, A1, A2, aerosols, angstrom_exponent, ozone, pwv, reso, D, shi """ if not self.fit_angstrom_exponent: angstrom_exponent = None - lambdas, model, model_err = self.simulation.simulate(A1, A2, aerosols, angstrom_exponent, ozone, pwv, reso, D, shift_x, B) + lambdas, model, model_err = self.simulation.simulate(A1, A2, aerosols, angstrom_exponent, ozone, pwv, reso, D, shift_x) + if B != 0: + model += B / (lambdas * np.gradient(lambdas)) self.model = model self.model_err = model_err return lambdas, model, model_err @@ -321,7 +330,7 @@ def lnprob_spectrum(p): # pragma: no cover return lp + w.lnlike(p) -def run_spectrum_minimisation(fit_workspace, method="newton"): +def run_spectrum_minimisation(fit_workspace, method="newton", sigma_clip=20): """Interface function to fit spectrum simulation parameters to data. Parameters @@ -364,16 +373,14 @@ def run_spectrum_minimisation(fit_workspace, method="newton"): # verbose=False) fit_workspace.simulation.fast_sim = False - # fit_workspace.fixed[0] = True fixed = copy.copy(fit_workspace.params.fixed) - fit_workspace.params.fixed = [True] * len(fit_workspace.params.values) - fit_workspace.params.fixed[0] = False - run_minimisation(fit_workspace, method="newton", epsilon=epsilon, xtol=1e-3, ftol=100 / fit_workspace.data.size, - verbose=False) - # fit_workspace.fixed[0] = False + #fit_workspace.params.fixed = [True] * len(fit_workspace.params.values) + #fit_workspace.params.fixed[0] = False + #run_minimisation(fit_workspace, method="newton", epsilon=epsilon, xtol=1e-3, ftol=100 / fit_workspace.data.size, + # verbose=False) fit_workspace.params.fixed = fixed run_minimisation_sigma_clipping(fit_workspace, method="newton", epsilon=epsilon, xtol=1e-6, - ftol=1 / fit_workspace.data.size, sigma_clip=20, niter_clip=3, verbose=False) + ftol=1 / fit_workspace.data.size, sigma_clip=sigma_clip, niter_clip=3, verbose=False) fit_workspace.params.plot_correlation_matrix() fit_workspace.plot_fit() diff --git a/spectractor/fit/fitter.py b/spectractor/fit/fitter.py index c09ee81ad..24eba6ec8 100644 --- a/spectractor/fit/fitter.py +++ b/spectractor/fit/fitter.py @@ -219,6 +219,24 @@ def __eq__(self, other): out *= getattr(self, key) == getattr(other, key) return out + def __repr__(self): + """Print the best fitting parameters on screen. + Labels are from self.labels. + + Examples + -------- + >>> parameters.VERBOSE = True + >>> params = FitParameters(values=[1, 2, 3, 4], labels=["x", "y", "z", "t"], fixed=[True, False, True, False]) + >>> params.cov = np.array([[1, -0.5], [-0.5, 4]]) + >>> params + x: 1.0 (fixed) + y: 2 +1 -1 bounds=[-inf, inf] + z: 3.0 (fixed) + t: 4 +2 -2 bounds=[-inf, inf] + + """ + return self.print_parameters_summary() + def get_index(self, label): """Get parameter index given its label. @@ -401,7 +419,7 @@ def get_fixed_parameters(self): return np.array(np.where(np.array(self.fixed).astype(int) == 1)[0]) def print_parameters_summary(self): - """Print the best fitting parameters on screen. + """Build a string with the best fitting parameters to display on screen. Labels are from self.labels. Returns @@ -424,12 +442,15 @@ def print_parameters_summary(self): txt += "%s: %s +%s -%s" % formatting_numbers(self.values[ip], np.sqrt(np.abs(self.cov[icov, icov])), np.sqrt(np.abs(self.cov[icov, icov])), label=self.labels[ip]) - txt += f" bounds={self.bounds[ip]}\n\t" + txt += f" bounds={self.bounds[ip]}" icov += 1 else: - txt += f"{self.labels[ip]}: {self.values[ip]} (fixed)\n\t" + txt += f"{self.labels[ip]}: {self.values[ip]} (fixed)" + if ip != self.ndim-1: + txt += "\n" return txt + def get_parameter(self, key): """Return a FitParameter instance. key argument can be the parameter label or its index value. @@ -666,6 +687,7 @@ def __init__(self, params=None, file_name="", verbose=False, plot=False, live_fi self.err = None self.data_cov = None self.W = None + self.W_before_mask = None self.x = None self.outliers = [] self.mask = [] @@ -686,22 +708,29 @@ def get_bad_indices(self): Examples -------- >>> w = FitWorkspace() + >>> w.data = np.array([1,2,3,4,5,6]) + >>> w.mask = [2, 4] + >>> w.outliers = [2, 6] + >>> w.get_bad_indices() + array([2, 4, 6]) >>> w.data = np.array([np.array([1,2,3]), np.array([1,2,3,4])], dtype=object) + >>> w.mask = [2, 4] >>> w.outliers = [2, 6] >>> w.get_bad_indices() - [array([2]), array([3])] + [array([2]), array([1, 3])] """ - bad_indices = np.asarray(self.outliers, dtype=int) + bad_indices = np.unique(np.concatenate([self.outliers, self.mask])).astype(int) if self.data.dtype == object: - if len(self.outliers) > 0: + if len(self.outliers) > 0 or len(self.mask) > 0: bad_indices = [] + bads = np.unique(np.concatenate([self.outliers, self.mask])).astype(int) start_index = 0 for k in range(self.data.shape[0]): mask = np.zeros(self.data[k].size, dtype=bool) - outliers = np.asarray(self.outliers)[np.logical_and(np.asarray(self.outliers) > start_index, - np.asarray(self.outliers) < start_index + + bad = np.asarray(bads)[np.logical_and(np.asarray(bads) > start_index, + np.asarray(bads) < start_index + self.data[k].size)] - mask[outliers - start_index] = True + mask[bad - start_index] = True bad_indices.append(np.arange(self.data[k].size)[mask]) start_index += self.data[k].size else: @@ -831,7 +860,8 @@ def weighted_residuals(self, p): # pragma: nocover def prepare_weight_matrices(self): r"""Compute weight matrix :math:`\mathbf{W}` `self.W` as the inverse of data covariance matrix `self.data_cov`. - Cancel weights of data outliers given by `self.outliers`. + Cancel weights of data outliers given by `self.outliers` or masked data given by `self.mask`. + It uses `self.W_before_mask` to reset the null weights at each computation. Examples -------- @@ -865,8 +895,8 @@ def prepare_weight_matrices(self): Use sparse matrix: - >>> w.W = scipy.sparse.diags(np.ones(3)) - >>> w.W.toarray() + >>> w.W_before_mask = scipy.sparse.diags(np.ones(3)) + >>> w.W_before_mask.toarray() array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) @@ -878,29 +908,39 @@ def prepare_weight_matrices(self): [0., 1., 0.], [0., 0., 0.]]) + Add mask but no outliers on same matrix: + + >>> w.outliers = [] + >>> w.mask = np.array([1]) + >>> w.prepare_weight_matrices() + >>> w.W.toarray() + array([[1., 0., 0.], + [0., 0., 0.], + [0., 0., 1.]]) """ # Prepare covariance matrix for data if self.data_cov is None: self.data_cov = np.asarray(self.err.flatten() ** 2) # Prepare inverse covariance matrix for data - if self.W is None: + if self.W_before_mask is None: if self.data_cov.ndim == 1 and self.data_cov.dtype != object: - self.W = 1 / self.data_cov + self.W_before_mask = 1 / self.data_cov elif self.data_cov.ndim == 2 and self.data_cov.dtype != object: - self.W = np.linalg.inv(self.data_cov) + self.W_before_mask = np.linalg.inv(self.data_cov) elif self.data_cov.dtype is object: if self.data_cov[0].ndim == 1: - self.W = np.array([1 / self.data_cov[k] for k in range(self.data_cov.shape[0])]) + self.W_before_mask = np.array([1 / self.data_cov[k] for k in range(self.data_cov.shape[0])]) else: - self.W = [] + self.W_before_mask = [] for k in range(len(self.data_cov)): L = np.linalg.inv(np.linalg.cholesky(self.data_cov[k])) - self.W[k] = L.T @ L - self.W = np.asarray(self.W) - if len(self.outliers) > 0: + self.W_before_mask[k] = L.T @ L + self.W_before_mask = np.asarray(self.W_before_mask) + self.W = self.W_before_mask.copy() + if len(self.outliers) > 0 or len(self.mask) > 0: bad_indices = self.get_bad_indices() - if not scipy.sparse.issparse(self.W): + if not scipy.sparse.issparse(self.W_before_mask): if self.W.ndim == 1 and self.W.dtype != object: self.W[bad_indices] = 0 elif self.W.ndim == 2 and self.W.dtype != object: @@ -921,11 +961,15 @@ def prepare_weight_matrices(self): f"\nHere W type is {type(self.W)}, shape is {self.W.shape} and W is {self.W}.") else: format = self.W.getformat() - W = self.W.tocsr() - W[:, bad_indices] = 0 - W[bad_indices, :] = 0 - W.eliminate_zeros() - self.W = W.asformat(format=format) + if format == 'dia': + self.W.data[0, bad_indices] = 0 + else: + W = self.W.tolil() + W[:, bad_indices] = 0 + W[bad_indices, :] = 0 + W = self.W.asformat(format='csr') + W.eliminate_zeros() + self.W = W.asformat(format=format) def compute_W_with_model_error(self, model_err): """Propagate model uncertainties to weight matrix W. @@ -1006,13 +1050,13 @@ def compute_W_with_model_error(self, model_err): elif self.W.ndim == 2 and self.W.dtype != object: cov = self.data_cov + np.diag(model_err * model_err) self.W = np.linalg.inv(cov) - # needs to reapply the mask of outliers + # needs to reapply the mask of outliers and masked data self.W[zeros] = 0 else: cov = self.data_cov + np.diag(model_err * model_err) L = np.linalg.inv(np.linalg.cholesky(cov)) W = L.T @ L - # needs to reapply the mask of outliers + # needs to reapply the mask of outliers and masked data rows, cols = self.W.nonzero() self.W = scipy.sparse.csr_matrix((W[rows, cols], (rows, cols)), dtype=self.W.dtype, shape=self.W.shape) return self.W @@ -1283,11 +1327,11 @@ def gradient_descent(fit_workspace, epsilon, niter=10, xtol=1e-3, ftol=1e-3, wit if ip == jp or jp not in ipar: continue inner = np.abs(J_vectors[ip] @ J_vectors[jp]) - if np.abs(inner - J_norms[ip] * J_norms[jp]) < 1e-8 * inner: + if inner != 0 and np.abs(inner - J_norms[ip] * J_norms[jp]) < 1e-8 * inner: ipar = np.delete(ipar, list(ipar).index(jp)) fit_workspace.params.fixed[jp] = True my_logger.warning( - f"\n\tStep {i}: {fit_workspace.params.labels[ip]} is degenerated with {fit_workspace.params.labels[jp]}; " + f"\n\tStep {i}: {fit_workspace.params.labels[jp]} is degenerated with {fit_workspace.params.labels[ip]}; " f"parameter {fit_workspace.params.labels[jp]} is fixed at its last known current value ({tmp_params[jp]}).") continue # remove fixed and degenerated parameters; then transpose @@ -1519,7 +1563,7 @@ def run_gradient_descent(fit_workspace, epsilon, xtol, ftol, niter, verbose=Fals fit_workspace.params_table = np.concatenate([fit_workspace.params_table, tmp_params_table]) fit_workspace.costs = np.concatenate([fit_workspace.costs, tmp_costs]) if verbose or fit_workspace.verbose: - fit_workspace.my_logger.info(f"\n\t{fit_workspace.params.print_parameters_summary()}") + fit_workspace.my_logger.info(f"\n{fit_workspace.params.print_parameters_summary()}") if parameters.DEBUG and (verbose or fit_workspace.verbose): fit_workspace.plot_gradient_descent() if len(fit_workspace.params.get_free_parameters()) > 1: @@ -1531,7 +1575,7 @@ def run_simple_newton_minimisation(fit_workspace, epsilon, xtol=1e-8, ftol=1e-8, epsilon, niter=niter, xtol=xtol, ftol=ftol) if verbose or fit_workspace.verbose: - fit_workspace.my_logger.info(f"\n\t{fit_workspace.params.print_parameters_summary()}") + fit_workspace.my_logger.info(f"\n{fit_workspace.params.print_parameters_summary()}") if parameters.DEBUG and (verbose or fit_workspace.verbose): fit_workspace.plot_gradient_descent() if len(fit_workspace.params.get_free_parameters()) > 1: @@ -1633,12 +1677,14 @@ def run_minimisation_sigma_clipping(fit_workspace, method="newton", epsilon=None data = np.concatenate(fit_workspace.data).ravel() # [indices_no_nan] model = np.concatenate(fit_workspace.model).ravel() # [indices_no_nan] err = np.concatenate(fit_workspace.err).ravel() # [indices_no_nan] + model_err = np.concatenate(fit_workspace.model_err).ravel() # [indices_no_nan] else: # indices_no_nan = ~np.isnan(fit_workspace.data.flatten()) data = fit_workspace.data.flatten() # [indices_no_nan] model = fit_workspace.model.flatten() # [indices_no_nan] err = fit_workspace.err.flatten() # [indices_no_nan] - residuals = np.abs(data - model) / err + model_err = fit_workspace.model_err.flatten() # [indices_no_nan] + residuals = np.abs(data - model) / np.sqrt(err**2 + model_err**2) outliers = residuals > sigma_clip outliers = [i for i in range(data.size) if outliers[i]] outliers.sort() diff --git a/spectractor/parameters.py b/spectractor/parameters.py index 6469ea505..3b7603a77 100644 --- a/spectractor/parameters.py +++ b/spectractor/parameters.py @@ -40,6 +40,7 @@ def __getattr__(name): SPECTRACTOR_FIT_TIMEOUT_PER_ITER = 600 # maximum time per gradient descent iteration before TimeoutError in seconds SPECTRACTOR_FIT_TIMEOUT = 3600 # maximum time per gradient descent before TimeoutError in seconds SPECTRACTOR_ATMOSPHERE_SIM = "none" # library to compute atmospheric transmission: none, libradtran, getobsatmo +SPECTRACTOR_SIMULATE_STARFIELD = False # simulate star field with Gaia catalog: False, True # Paths DISPERSER_DIR = "./extractor/dispersers/" @@ -113,6 +114,7 @@ def __getattr__(name): PSF_FIT_REG_PARAM = 0.01 # regularisation parameter for the chisq minimisation to extract the spectrum PSF_PIXEL_STEP_TRANSVERSE_FIT = 10 # step size in pixels for the first transverse PSF1D fit PSF_FWHM_CLIP = 2 # PSF is not evaluated outside a region larger than max(PIXWIDTH_SIGNAL, PSF_FWHM_CLIP*fwhm) pixels +PSF_POLY_TYPE = "polynomial" # polynomial type: must be polynomial or legendre # Detection line algorithm CALIB_BGD_ORDER = 3 # order of the background polynome to fit diff --git a/spectractor/simulation/AuxTelThroughput/NOTES b/spectractor/simulation/AuxTelThroughput/NOTES index 2cf97eed1..400093047 100644 --- a/spectractor/simulation/AuxTelThroughput/NOTES +++ b/spectractor/simulation/AuxTelThroughput/NOTES @@ -1,3 +1,5 @@ FELH0600.txt from multispectra_FELH0600_holo4_003_HD142331_AuxTel_throughput.txt file, fit from 20220630 end of night Auxtel data BG40 is from vendor -BG40_65mm_1 and OG550_65mm_1 are copied from BG40.txt \ No newline at end of file +BG40_65mm_1 and OG550_65mm_1 are copied from BG40.txt + +- multispectra_holo4_003_HD142331_20230802_348-594_HD146233_AuxTel_v3.1.0_doSensorFlat_FreePressure_BG40ReScaled1.09_throughput.txt was created using v3.1.0 1a65d73cddf078472e7df082552cb75b6f39a9a4 commit, with 20230802 HD142331 data extracted with ratio 2/1 where BG40 data were rescaled by a factor 1.09, fixed A1s, binning=1, free angstrom exponent, free ozone, masking of curve edges and absorption lines \ No newline at end of file diff --git a/spectractor/simulation/AuxTelThroughput/SDSSg.txt b/spectractor/simulation/AuxTelThroughput/SDSSg.txt new file mode 100644 index 000000000..995cf6ead --- /dev/null +++ b/spectractor/simulation/AuxTelThroughput/SDSSg.txt @@ -0,0 +1,221 @@ +380 0.0000 +381 0.0000 +382 0.0000 +383 0.0000 +384 0.0000 +385 0.0000 +386 0.0000 +387 0.0000 +388 0.0000 +389 0.0000 +390 0.00005 +391 0.000149999999999999 +392 0.000599999999999999 +393 0.0027 +394 0.0249 +395 0.1686 +396 0.4554 +397 0.6898 +398 0.7937 +399 0.8518 +400 0.8893 +401 0.90645 +402 0.91595 +403 0.9241 +404 0.93125 +405 0.93795 +406 0.93915 +407 0.94105 +408 0.9456 +409 0.95105 +410 0.9532 +411 0.95715 +412 0.9597 +413 0.96175 +414 0.9605 +415 0.9611 +416 0.96505 +417 0.9713 +418 0.97295 +419 0.9717 +420 0.9714 +421 0.9745 +422 0.9758 +423 0.9711 +424 0.96195 +425 0.96105 +426 0.9665 +427 0.97565 +428 0.9812 +429 0.97955 +430 0.97655 +431 0.97665 +432 0.97865 +433 0.97795 +434 0.9756 +435 0.9718 +436 0.97215 +437 0.97775 +438 0.9837 +439 0.9861 +440 0.9858 +441 0.9833 +442 0.9828 +443 0.98345 +444 0.9853 +445 0.98515 +446 0.9839 +447 0.98385 +448 0.98445 +449 0.987 +450 0.9867 +451 0.9842 +452 0.97975 +453 0.9758 +454 0.97525 +455 0.9779 +456 0.98265 +457 0.98525 +458 0.9852 +459 0.98545 +460 0.9853 +461 0.9863 +462 0.9877 +463 0.988649999999999 +464 0.98705 +465 0.9837 +466 0.9818 +467 0.98225 +468 0.9848 +469 0.9873 +470 0.98885 +471 0.98775 +472 0.9839 +473 0.9806 +474 0.9792 +475 0.98035 +476 0.98205 +477 0.98335 +478 0.9833 +479 0.98355 +480 0.9826 +481 0.98295 +482 0.9856 +483 0.98925 +484 0.99005 +485 0.98845 +486 0.9826 +487 0.9784 +488 0.97425 +489 0.974599999999999 +490 0.9795 +491 0.98585 +492 0.99045 +493 0.9903 +494 0.98655 +495 0.9795 +496 0.9734 +497 0.97195 +498 0.97395 +499 0.97935 +500 0.9859 +501 0.9896 +502 0.9906 +503 0.9876 +504 0.9833 +505 0.9809 +506 0.98035 +507 0.98235 +508 0.98455 +509 0.98515 +510 0.98305 +511 0.97925 +512 0.97535 +513 0.97265 +514 0.9731 +515 0.97495 +516 0.9793 +517 0.98115 +518 0.9797 +519 0.9753 +520 0.96845 +521 0.9624 +522 0.95935 +523 0.9598 +524 0.96425 +525 0.9694 +526 0.9734 +527 0.97435 +528 0.9703 +529 0.9638 +530 0.95705 +531 0.95155 +532 0.9501 +533 0.95115 +534 0.95485 +535 0.9596 +536 0.9648 +537 0.9694 +538 0.97425 +539 0.97815 +540 0.98 +541 0.97815 +542 0.97005 +543 0.9588 +544 0.94475 +545 0.93505 +546 0.9309 +547 0.9338 +548 0.9316 +549 0.9093 +550 0.84955 +551 0.74365 +552 0.6038 +553 0.46095 +554 0.33455 +555 0.2317 +556 0.1552 +557 0.1012 +558 0.06525 +559 0.0419 +560 0.02715 +561 0.01795 +562 0.01205 +563 0.0084 +564 0.0061 +565 0.0046 +566 0.00354999999999999 +567 0.0028 +568 0.00225 +569 0.0018 +570 0.0015 +571 0.00119999999999999 +572 0.001 +573 0.0008 +574 0.000599999999999999 +575 0.00045 +576 0.00035 +577 0.000299999999999999 +578 0.0002 +579 0.0002 +580 0.000149999999999999 +581 0.0001 +582 0.0001 +583 0.00005 +584 0.00005 +585 0.00005 +586 0.00005 +587 0.00005 +588 0.0000 +589 0.00005 +590 0.0000 +591 0.00005 +592 0.0000 +593 0.0000 +594 0.0000 +595 0.0000 +596 0.0000 +597 0.0000 +598 0.0000 +599 0.0000 +600 0.0000 \ No newline at end of file diff --git a/spectractor/simulation/AuxTelThroughput/multispectra_holo4_003_HD142331_20230802_348-594_HD146233_AuxTel_v3.1.0_doSensorFlat_FreePressure_BG40ReScaled1.09_throughput.txt b/spectractor/simulation/AuxTelThroughput/multispectra_holo4_003_HD142331_20230802_348-594_HD146233_AuxTel_v3.1.0_doSensorFlat_FreePressure_BG40ReScaled1.09_throughput.txt new file mode 100644 index 000000000..88b164ec3 --- /dev/null +++ b/spectractor/simulation/AuxTelThroughput/multispectra_holo4_003_HD142331_20230802_348-594_HD146233_AuxTel_v3.1.0_doSensorFlat_FreePressure_BG40ReScaled1.09_throughput.txt @@ -0,0 +1,800 @@ +3.000000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.010000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.020000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.030000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.040000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.050000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.060000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.070000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.080000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.090000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.100000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.110000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.120000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.130000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.140000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.150000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.160000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.170000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.180000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.190000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.200000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.210000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.220000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.230000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.240000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.250000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.260000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.270000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.280000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.290000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.300000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.310000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.320000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.330000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.340000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.350000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.360000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.370000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.380000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.390000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.400000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.410000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.420000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.430000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.440000000000000000e+02 0.000000000000000000e+00 1.000000000000000056e-01 +3.450000000000000000e+02 1.223475307796860825e-02 1.000000000000000056e-01 +3.460000000000000000e+02 2.267817761604837973e-02 1.000000000000000056e-01 +3.470000000000000000e+02 3.312160215412814773e-02 1.000000000000000056e-01 +3.480000000000000000e+02 4.356502669220792268e-02 1.000000000000000056e-01 +3.490000000000000000e+02 5.400845123028769068e-02 1.000000000000000056e-01 +3.500000000000000000e+02 6.445187576836745869e-02 1.000000000000000056e-01 +3.510000000000000000e+02 7.489530030644722669e-02 1.000000000000000056e-01 +3.520000000000000000e+02 8.533872484452699470e-02 1.000000000000000056e-01 +3.530000000000000000e+02 9.578214938260676270e-02 1.000000000000000056e-01 +3.540000000000000000e+02 1.062255739206865307e-01 1.000000000000000056e-01 +3.550000000000000000e+02 1.166689984587662432e-01 1.000000000000000056e-01 +3.560000000000000000e+02 1.258433118578039800e-01 1.000000000000000056e-01 +3.570000000000000000e+02 1.351655942470698923e-01 1.000000000000000056e-01 +3.580000000000000000e+02 1.446963595394460678e-01 1.000000000000000056e-01 +3.590000000000000000e+02 1.543121012644246282e-01 1.000000000000000056e-01 +3.600000000000000000e+02 1.638292566813799311e-01 1.000000000000000056e-01 +3.610000000000000000e+02 1.676123604874799611e-01 1.000000000000000056e-01 +3.620000000000000000e+02 1.713995253325571733e-01 1.000000000000000056e-01 +3.630000000000000000e+02 1.754984738903282437e-01 1.000000000000000056e-01 +3.640000000000000000e+02 1.807661122168339185e-01 1.000000000000000056e-01 +3.650000000000000000e+02 1.876604049544178254e-01 1.000000000000000056e-01 +3.660000000000000000e+02 1.951359236459879742e-01 1.000000000000000056e-01 +3.670000000000000000e+02 2.016312952204327158e-01 1.000000000000000056e-01 +3.680000000000000000e+02 2.067450189666832916e-01 1.000000000000000056e-01 +3.690000000000000000e+02 2.109705114453636066e-01 1.000000000000000056e-01 +3.700000000000000000e+02 2.148897137050483630e-01 1.000000000000000056e-01 +3.710000000000000000e+02 2.186371899760470860e-01 1.000000000000000056e-01 +3.720000000000000000e+02 2.229815454716516931e-01 1.000000000000000056e-01 +3.730000000000000000e+02 2.287356820529017065e-01 1.000000000000000056e-01 +3.740000000000000000e+02 2.352685223846567308e-01 1.000000000000000056e-01 +3.750000000000000000e+02 2.416338480108665143e-01 1.000000000000000056e-01 +3.760000000000000000e+02 2.481372508638984009e-01 1.000000000000000056e-01 +3.770000000000000000e+02 2.552802933831848087e-01 1.000000000000000056e-01 +3.780000000000000000e+02 2.627756140557480635e-01 1.000000000000000056e-01 +3.790000000000000000e+02 2.695614398811218559e-01 1.000000000000000056e-01 +3.800000000000000000e+02 2.749813623247027161e-01 1.000000000000000056e-01 +3.810000000000000000e+02 2.797526003104602865e-01 1.000000000000000056e-01 +3.820000000000000000e+02 2.851640038363633667e-01 1.000000000000000056e-01 +3.830000000000000000e+02 2.918303853715817908e-01 1.000000000000000056e-01 +3.840000000000000000e+02 2.986651662013793951e-01 1.000000000000000056e-01 +3.850000000000000000e+02 3.047945528129633597e-01 1.000000000000000056e-01 +3.860000000000000000e+02 3.114677874428814497e-01 1.000000000000000056e-01 +3.870000000000000000e+02 3.199004062687956784e-01 1.000000000000000056e-01 +3.880000000000000000e+02 3.288316856115037212e-01 1.000000000000000056e-01 +3.890000000000000000e+02 3.369233172212761085e-01 1.000000000000000056e-01 +3.900000000000000000e+02 3.441985819632605303e-01 1.000000000000000056e-01 +3.910000000000000000e+02 3.507826423901767576e-01 1.000000000000000056e-01 +3.920000000000000000e+02 3.568393040733134347e-01 1.000000000000000056e-01 +3.930000000000000000e+02 3.615153254638510116e-01 1.000000000000000056e-01 +3.940000000000000000e+02 3.666182166936797771e-01 1.000000000000000056e-01 +3.950000000000000000e+02 3.709747530042215025e-01 1.000000000000000056e-01 +3.960000000000000000e+02 3.756876351130540859e-01 1.000000000000000056e-01 +3.970000000000000000e+02 3.805317093841903420e-01 1.000000000000000056e-01 +3.980000000000000000e+02 3.847530203801270421e-01 1.000000000000000056e-01 +3.990000000000000000e+02 3.883384503296448687e-01 1.000000000000000056e-01 +4.000000000000000000e+02 3.926419413162932082e-01 1.000000000000000056e-01 +4.010000000000000000e+02 3.987587927522273090e-01 1.000000000000000056e-01 +4.020000000000000000e+02 4.059603518356337815e-01 1.000000000000000056e-01 +4.030000000000000000e+02 4.124322143613710634e-01 1.000000000000000056e-01 +4.040000000000000000e+02 4.127784403021699244e-01 1.000000000000000056e-01 +4.050000000000000000e+02 4.131246662429687855e-01 1.000000000000000056e-01 +4.060000000000000000e+02 4.134708921837676465e-01 1.000000000000000056e-01 +4.070000000000000000e+02 4.138171181245665076e-01 1.000000000000000056e-01 +4.080000000000000000e+02 4.141633440653653686e-01 1.000000000000000056e-01 +4.090000000000000000e+02 4.145095700061642296e-01 1.000000000000000056e-01 +4.100000000000000000e+02 4.148557959469630352e-01 5.029249523882932393e-02 +4.110000000000000000e+02 4.152020218877618962e-01 4.979212028563293618e-02 +4.120000000000000000e+02 4.155482478285607573e-01 5.033523890691534580e-02 +4.130000000000000000e+02 4.158944737693596183e-01 5.098481798228814144e-02 +4.140000000000000000e+02 4.162406997101584794e-01 5.119397964926036826e-02 +4.150000000000000000e+02 4.165869256509573404e-01 1.100208890563018904e-02 +4.160000000000000000e+02 4.169331515917562014e-01 4.172843952803257164e-03 +4.170000000000000000e+02 4.201476572030268253e-01 4.205006934103664926e-03 +4.180000000000000000e+02 4.249340802381921800e-01 4.252883223637959551e-03 +4.190000000000000000e+02 4.280188113783750525e-01 4.283730167682776868e-03 +4.200000000000000000e+02 4.286879080632951533e-01 4.290313034067984137e-03 +4.210000000000000000e+02 4.293150076756742095e-01 4.296626336865500342e-03 +4.220000000000000000e+02 4.313014837261373025e-01 4.316390181065279767e-03 +4.230000000000000000e+02 4.346350859614040996e-01 4.349801350499891625e-03 +4.240000000000000000e+02 4.392757012751298262e-01 4.396191570104283908e-03 +4.250000000000000000e+02 4.448376638086384283e-01 4.451813900534878216e-03 +4.260000000000000000e+02 4.508577239481564303e-01 4.512247093176297019e-03 +4.270000000000000000e+02 4.544436849421633062e-01 4.548350187844993515e-03 +4.280000000000000000e+02 4.546582934113062580e-01 1.177246297857255722e-02 +4.290000000000000000e+02 4.548729018804491542e-01 1.132689185043338903e-02 +4.300000000000000000e+02 4.550875103495921059e-01 1.051821792292651631e-02 +4.310000000000000000e+02 4.553021188187350021e-01 4.557416294075621738e-02 +4.320000000000000000e+02 4.555167272878779539e-01 4.641590659361816140e-02 +4.330000000000000000e+02 4.557313357570208501e-01 4.728834794470106878e-02 +4.340000000000000000e+02 4.559459442261638018e-01 4.751770815358592054e-02 +4.350000000000000000e+02 4.561605526953066980e-01 4.859657645925206937e-02 +4.360000000000000000e+02 4.563751611644496498e-01 5.044501663373460870e-02 +4.370000000000000000e+02 4.565897696335925460e-01 5.156585300808320949e-02 +4.380000000000000000e+02 4.568043781027354977e-01 1.115994087389753087e-02 +4.390000000000000000e+02 4.570189865718783939e-01 1.091955148739190244e-02 +4.400000000000000000e+02 4.572335950410213457e-01 4.575133350685178270e-03 +4.410000000000000000e+02 4.593424179027474907e-01 4.597582794496457570e-03 +4.420000000000000000e+02 4.611643412104051709e-01 4.614224361458047624e-03 +4.430000000000000000e+02 4.634004207207387815e-01 4.636596593496614474e-03 +4.440000000000000000e+02 4.660226538799314144e-01 4.663417887809844301e-03 +4.450000000000000000e+02 4.683602929260318737e-01 4.686855494389631852e-03 +4.460000000000000000e+02 4.699685418838324136e-01 4.702819065129988652e-03 +4.470000000000000000e+02 4.711205806130211449e-01 4.713574790718550421e-03 +4.480000000000000000e+02 4.724560647315612649e-01 4.727826648092229266e-03 +4.490000000000000000e+02 4.744333265487280515e-01 4.747869189228227753e-03 +4.500000000000000000e+02 4.770562964680041262e-01 4.772853410855701535e-03 +4.510000000000000000e+02 4.775422673663357598e-01 4.777736985029415115e-03 +4.520000000000000000e+02 4.776226657480584503e-01 4.779564096054667727e-03 +4.530000000000000000e+02 4.779458604442864966e-01 4.782406540955408403e-03 +4.540000000000000000e+02 4.786004991383688845e-01 4.788307042076046967e-03 +4.550000000000000000e+02 4.795282744204831804e-01 4.797574332737086777e-03 +4.560000000000000000e+02 4.803070797915804935e-01 4.805271100211465710e-03 +4.570000000000000000e+02 4.806895565392607650e-01 4.809156339228482305e-03 +4.580000000000000000e+02 4.807699014210154442e-01 4.809922931339558755e-03 +4.590000000000000000e+02 4.808261829648352026e-01 4.810414596561056466e-03 +4.600000000000000000e+02 4.812092492479576600e-01 4.814241906613567559e-03 +4.610000000000000000e+02 4.821904556976658318e-01 4.823998970929769224e-03 +4.620000000000000000e+02 4.834260069749135580e-01 4.836398616488656564e-03 +4.630000000000000000e+02 4.845893639708558909e-01 4.848072217680670509e-03 +4.640000000000000000e+02 4.852804608014892329e-01 4.854931074283178397e-03 +4.650000000000000000e+02 4.856612734849684587e-01 4.858777239136377255e-03 +4.660000000000000000e+02 4.861440107202211758e-01 4.863577597488185668e-03 +4.670000000000000000e+02 4.869184723119327485e-01 4.871340992140448835e-03 +4.680000000000000000e+02 4.879267077239729522e-01 4.881389425797375524e-03 +4.690000000000000000e+02 4.890196973753088705e-01 4.892317447504762606e-03 +4.700000000000000000e+02 4.903385319306727830e-01 4.905503975830223344e-03 +4.710000000000000000e+02 4.916239569832745460e-01 4.918297767457276842e-03 +4.720000000000000000e+02 4.928280443084688822e-01 4.930335786547976155e-03 +4.730000000000000000e+02 4.940788766374890617e-01 4.942804168163008986e-03 +4.740000000000000000e+02 4.952968538133055709e-01 4.955020482063005917e-03 +4.750000000000000000e+02 4.962184136908732168e-01 4.964222098280131334e-03 +4.760000000000000000e+02 4.967074536656028716e-01 4.969066781627252787e-03 +4.770000000000000000e+02 4.968480016367842200e-01 4.970474972918421941e-03 +4.780000000000000000e+02 4.969608770486850791e-01 4.971532106074917808e-03 +4.790000000000000000e+02 4.974284756809802532e-01 4.976215480327669978e-03 +4.800000000000000000e+02 4.974933545574509175e-01 1.110826397886455381e-02 +4.810000000000000000e+02 4.975582334339216373e-01 1.117177902080745619e-02 +4.820000000000000000e+02 4.976231123103923015e-01 1.134220703515260303e-02 +4.830000000000000000e+02 4.976879911868629658e-01 5.248101339437859225e-02 +4.840000000000000000e+02 4.977528700633336856e-01 5.313280887247989054e-02 +4.850000000000000000e+02 4.978177489398043498e-01 5.204703399830555577e-02 +4.860000000000000000e+02 4.978826278162750141e-01 4.980454075454329027e-02 +4.870000000000000000e+02 4.979475066927456783e-01 4.831925647280978231e-02 +4.880000000000000000e+02 4.980123855692163981e-01 4.817795679090828426e-02 +4.890000000000000000e+02 4.980772644456870624e-01 4.887346763059156191e-02 +4.900000000000000000e+02 4.981421433221577266e-01 4.972409746750065113e-02 +4.910000000000000000e+02 4.982070221986284464e-01 1.112235486208608057e-02 +4.920000000000000000e+02 4.982719010750991107e-01 4.984950430769013487e-03 +4.930000000000000000e+02 4.992048066171406173e-01 4.993954171907215994e-03 +4.940000000000000000e+02 5.000000227422936039e-01 5.001923183861674282e-03 +4.950000000000000000e+02 5.005273669326436581e-01 5.007138514868077379e-03 +4.960000000000000000e+02 5.008386557158515107e-01 5.010301061097611336e-03 +4.970000000000000000e+02 5.012116445898998629e-01 5.014046314729964614e-03 +4.980000000000000000e+02 5.017899081433867536e-01 5.019848800183517035e-03 +4.990000000000000000e+02 5.024669494083962018e-01 5.026934648789698444e-03 +5.000000000000000000e+02 5.030955673705070907e-01 5.033202993485150559e-03 +5.010000000000000000e+02 5.034755446388257116e-01 5.037011131560865593e-03 +5.020000000000000000e+02 5.035338975379153315e-01 5.037274159379768503e-03 +5.030000000000000000e+02 5.031298203207559272e-01 5.033204820573094172e-03 +5.040000000000000000e+02 5.025059961702391664e-01 5.026949480480900900e-03 +5.050000000000000000e+02 5.016609002673524387e-01 5.018427876573482854e-03 +5.060000000000000000e+02 5.008796548786990099e-01 5.010624421296835940e-03 +5.070000000000000000e+02 5.004380652084106096e-01 5.006181132710238804e-03 +5.080000000000000000e+02 5.005667090292056365e-01 5.007487495147164291e-03 +5.090000000000000000e+02 5.011254263795497099e-01 5.013066121967662582e-03 +5.100000000000000000e+02 5.021998780381657923e-01 5.023781538655232998e-03 +5.110000000000000000e+02 5.034015358407494256e-01 5.035832304738125861e-03 +5.120000000000000000e+02 5.040592416004637810e-01 5.042390001691708298e-03 +5.130000000000000000e+02 5.039994852279905402e-01 5.041876197054395194e-03 +5.140000000000000000e+02 5.032831944185803819e-01 5.034750899430740986e-03 +5.150000000000000000e+02 5.024565047127871331e-01 5.027506633909125874e-03 +5.160000000000000000e+02 5.024821473439543551e-01 5.028516233924794701e-03 +5.170000000000000000e+02 5.033094002070922501e-01 5.036995340985631064e-03 +5.180000000000000000e+02 5.041430436287881456e-01 5.043817368005526144e-03 +5.190000000000000000e+02 5.046038569260942186e-01 5.048096768531537201e-03 +5.200000000000000000e+02 5.047333794781851957e-01 5.050356323130619253e-03 +5.210000000000000000e+02 5.048901764435332895e-01 5.052506442181121590e-03 +5.220000000000000000e+02 5.054888614235059086e-01 5.057092046250441855e-03 +5.230000000000000000e+02 5.065660771217369573e-01 5.067953488484422224e-03 +5.240000000000000000e+02 5.076757771206529268e-01 5.079589744293773121e-03 +5.250000000000000000e+02 5.086649978468759103e-01 5.090604650618884598e-03 +5.260000000000000000e+02 5.097953407921750335e-01 5.100681155594905154e-03 +5.270000000000000000e+02 5.108584592725350371e-01 5.111004338096380474e-03 +5.280000000000000000e+02 5.116062671419202568e-01 5.118471972912733321e-03 +5.290000000000000000e+02 5.120537535569215093e-01 5.123226415267159023e-03 +5.300000000000000000e+02 5.126433992912818871e-01 5.128779887344613563e-03 +5.310000000000000000e+02 5.130922956338834773e-01 5.133237066297225218e-03 +5.320000000000000000e+02 5.132925919916923041e-01 5.135278340298256652e-03 +5.330000000000000000e+02 5.135595055089845484e-01 5.137947229950378530e-03 +5.340000000000000000e+02 5.141310076968457210e-01 5.143617305395793357e-03 +5.350000000000000000e+02 5.152876257437407626e-01 5.155212691785459808e-03 +5.360000000000000000e+02 5.167935301956370076e-01 5.170245464403136135e-03 +5.370000000000000000e+02 5.178744940034666344e-01 5.181117783276840798e-03 +5.380000000000000000e+02 5.184644349871330160e-01 5.187017155875122201e-03 +5.390000000000000000e+02 5.190265098835775692e-01 5.192961976022860901e-03 +5.400000000000000000e+02 5.197832538619863163e-01 5.200265104677206061e-03 +5.410000000000000000e+02 5.207597426866779067e-01 5.209936018568839255e-03 +5.420000000000000000e+02 5.217007136504210330e-01 5.219361290814002706e-03 +5.430000000000000000e+02 5.223172117212233623e-01 5.225464954596804358e-03 +5.440000000000000000e+02 5.225240195094537077e-01 5.227556444116982295e-03 +5.450000000000000000e+02 5.226699047837024548e-01 5.229007465061047757e-03 +5.460000000000000000e+02 5.231078532574365836e-01 5.233355884509140708e-03 +5.470000000000000000e+02 5.238650690191422044e-01 5.240967571198850393e-03 +5.480000000000000000e+02 5.248908138049552807e-01 5.251166713361460868e-03 +5.490000000000000000e+02 5.261397861140961751e-01 5.263697282513750582e-03 +5.500000000000000000e+02 5.273732380872914183e-01 5.275998798524110175e-03 +5.510000000000000000e+02 5.282907130778097260e-01 5.285177535698447684e-03 +5.520000000000000000e+02 5.289628302622857436e-01 5.291925274032398610e-03 +5.530000000000000000e+02 5.295980622310012542e-01 5.298203611876225495e-03 +5.540000000000000000e+02 5.303145910857475220e-01 5.305417773628554219e-03 +5.550000000000000000e+02 5.310713771173616315e-01 5.312971683852448293e-03 +5.560000000000000000e+02 5.317245349528092468e-01 5.319569268929063600e-03 +5.570000000000000000e+02 5.321674768136475109e-01 5.324026935729449586e-03 +5.580000000000000000e+02 5.324838110152334547e-01 5.327171734960563232e-03 +5.590000000000000000e+02 5.328810508755567055e-01 5.331183530894977041e-03 +5.600000000000000000e+02 5.335456888050558177e-01 5.337745671702273306e-03 +5.610000000000000000e+02 5.344236558352271071e-01 5.346539492209098979e-03 +5.620000000000000000e+02 5.352472949034803307e-01 5.354766562816607942e-03 +5.630000000000000000e+02 5.358774617049351097e-01 5.361067643357531054e-03 +5.640000000000000000e+02 5.364370689166464423e-01 5.366703624318723033e-03 +5.650000000000000000e+02 5.371336051201884842e-01 5.373602468251006438e-03 +5.660000000000000000e+02 5.380046371645885728e-01 5.382360305881250979e-03 +5.670000000000000000e+02 5.389438813516677085e-01 5.391726997051934402e-03 +5.680000000000000000e+02 5.399217597186514173e-01 5.401553410880358293e-03 +5.690000000000000000e+02 5.409055944870915233e-01 5.411390252144288385e-03 +5.700000000000000000e+02 5.418191881870311200e-01 5.420486956510842287e-03 +5.710000000000000000e+02 5.426181625303534428e-01 5.428511983252374065e-03 +5.720000000000000000e+02 5.433255075664572553e-01 5.435501442292212972e-03 +5.730000000000000000e+02 5.439738850968590667e-01 5.442004676740765275e-03 +5.740000000000000000e+02 5.446011421201142344e-01 5.448293524149537895e-03 +5.750000000000000000e+02 5.451829758762857248e-01 5.454120963059647456e-03 +5.760000000000000000e+02 5.456015846299467897e-01 5.458346286869115473e-03 +5.770000000000000000e+02 5.458554828436106288e-01 5.460825782414898376e-03 +5.780000000000000000e+02 5.462116740867872799e-01 5.464436445341656380e-03 +5.790000000000000000e+02 5.470008368487461192e-01 5.472255185671431876e-03 +5.800000000000000000e+02 5.479430483785660000e-01 5.481686655646031761e-03 +5.810000000000000000e+02 5.486274974220263223e-01 5.488490789421537203e-03 +5.820000000000000000e+02 5.490450938547033477e-01 5.492633421000493385e-03 +5.830000000000000000e+02 5.494543900248467505e-01 5.496789498307877789e-03 +5.840000000000000000e+02 5.499968225104375774e-01 5.502156245219657314e-03 +5.850000000000000000e+02 5.505834030380304389e-01 5.508074699633483916e-03 +5.860000000000000000e+02 5.510565201013652992e-01 5.512822232181126443e-03 +5.870000000000000000e+02 5.513883884925607770e-01 5.516511028910022797e-03 +5.880000000000000000e+02 5.516449881694237556e-01 5.519698796014759282e-03 +5.890000000000000000e+02 5.517701237427985461e-01 5.520296987712144769e-03 +5.900000000000000000e+02 5.518688939636078317e-01 5.521019099170303319e-03 +5.910000000000000000e+02 5.521555528594026541e-01 5.523787914583338371e-03 +5.920000000000000000e+02 5.527771754198902432e-01 5.530012271923681437e-03 +5.930000000000000000e+02 5.535880077747815653e-01 5.538091229643209157e-03 +5.940000000000000000e+02 5.544155965853019286e-01 5.546369225615100165e-03 +5.950000000000000000e+02 5.551743167103910803e-01 5.553996305598942265e-03 +5.960000000000000000e+02 5.559105802283614839e-01 5.561304317082828297e-03 +5.970000000000000000e+02 5.567680276327460209e-01 5.569943198993834374e-03 +5.980000000000000000e+02 5.577978654463593422e-01 5.580234406615910102e-03 +5.990000000000000000e+02 5.588093968180302129e-01 5.590660786037049586e-03 +6.000000000000000000e+02 5.594027079523624657e-01 5.596451761922464040e-03 +6.010000000000000000e+02 5.597013725674142570e-01 5.599277621164135479e-03 +6.020000000000000000e+02 5.600201108429182506e-01 5.602607800908767158e-03 +6.030000000000000000e+02 5.604606233431665974e-01 5.606919105612881427e-03 +6.040000000000000000e+02 5.609704907953856345e-01 5.612022076752559534e-03 +6.050000000000000000e+02 5.616280710654639741e-01 5.618604674550314176e-03 +6.060000000000000000e+02 5.625868161628415631e-01 5.628096369866953871e-03 +6.070000000000000000e+02 5.637852900111968157e-01 5.640111589669397248e-03 +6.080000000000000000e+02 5.650567861249805590e-01 5.652784672705707218e-03 +6.090000000000000000e+02 5.662402182775916337e-01 5.664691374787377692e-03 +6.100000000000000000e+02 5.673047848236657531e-01 5.675287461878020419e-03 +6.110000000000000000e+02 5.681105644374216945e-01 5.683392090646890819e-03 +6.120000000000000000e+02 5.685799104470401488e-01 5.688089206078165289e-03 +6.130000000000000000e+02 5.687887278817090886e-01 5.690185498369817151e-03 +6.140000000000000000e+02 5.689665643094353742e-01 5.692297658959788453e-03 +6.150000000000000000e+02 5.692867714644861410e-01 5.695429515799137025e-03 +6.160000000000000000e+02 5.697018538083410411e-01 5.699316109907750713e-03 +6.170000000000000000e+02 5.700781315679976924e-01 5.703024322328354226e-03 +6.180000000000000000e+02 5.703562300862925483e-01 5.705811907700390415e-03 +6.190000000000000000e+02 5.706028604042366892e-01 5.708255956152295980e-03 +6.200000000000000000e+02 5.709370613601142397e-01 5.711536127222527348e-03 +6.210000000000000000e+02 5.714859545561794540e-01 5.717132479923864308e-03 +6.220000000000000000e+02 5.722908596588464070e-01 5.725118078997484296e-03 +6.230000000000000000e+02 5.732483523642377676e-01 5.734750484951257367e-03 +6.240000000000000000e+02 5.742297576465283937e-01 5.744572880404253713e-03 +6.250000000000000000e+02 5.751921701617946914e-01 5.754224577058627936e-03 +6.260000000000000000e+02 5.760131687632354947e-01 5.762430606000824851e-03 +6.270000000000000000e+02 5.765187540227409979e-01 5.767442360391033217e-03 +6.280000000000000000e+02 5.767693530264501600e-01 5.770016515616106442e-03 +6.290000000000000000e+02 5.769939599031636002e-01 5.772192006814806306e-03 +6.300000000000000000e+02 5.774014237303616293e-01 5.776298365061414281e-03 +6.310000000000000000e+02 5.780292755817233452e-01 5.782551342912258842e-03 +6.320000000000000000e+02 5.788268191316080502e-01 5.790521288107757132e-03 +6.330000000000000000e+02 5.796979950599228104e-01 5.799243358438239092e-03 +6.340000000000000000e+02 5.805848938480829835e-01 5.808063909389159923e-03 +6.350000000000000000e+02 5.814391097861599800e-01 5.816596203413612609e-03 +6.360000000000000000e+02 5.821874815266925296e-01 5.824039140550052972e-03 +6.370000000000000000e+02 5.828734112799466294e-01 5.830947248492817855e-03 +6.380000000000000000e+02 5.836360928338621967e-01 5.838576167938276835e-03 +6.390000000000000000e+02 5.846186685404004546e-01 5.848362451413205605e-03 +6.400000000000000000e+02 5.860292783155507390e-01 5.862561486383821747e-03 +6.410000000000000000e+02 5.872946486272421218e-01 5.875143965578769924e-03 +6.420000000000000000e+02 5.884015297694015212e-01 5.886232737529139246e-03 +6.430000000000000000e+02 5.893487227166487319e-01 5.895693398208213393e-03 +6.440000000000000000e+02 5.901431133589596367e-01 5.903658825627078853e-03 +6.450000000000000000e+02 5.908681233988410941e-01 5.910900677023571935e-03 +6.460000000000000000e+02 5.915699701043165559e-01 5.917889957702006203e-03 +6.470000000000000000e+02 5.922627950989608481e-01 5.924899915264627073e-03 +6.480000000000000000e+02 5.930272223271495502e-01 5.932466003084010432e-03 +6.490000000000000000e+02 5.939776140423121964e-01 5.941998961681220319e-03 +6.500000000000000000e+02 5.940596023020850991e-01 1.163599764546288488e-02 +6.510000000000000000e+02 5.941415905618580018e-01 1.160922737004866506e-02 +6.520000000000000000e+02 5.942235788216309045e-01 1.167349243562955906e-02 +6.530000000000000000e+02 5.943055670814038072e-01 5.152786195850164730e-02 +6.540000000000000000e+02 5.943875553411767099e-01 5.255857013303814884e-02 +6.550000000000000000e+02 5.944695436009496126e-01 5.252213657339502295e-02 +6.560000000000000000e+02 5.945515318607225153e-01 5.103748098030048280e-02 +6.570000000000000000e+02 5.946335201204954179e-01 4.948510872177015046e-02 +6.580000000000000000e+02 5.947155083802683206e-01 4.895738775717421720e-02 +6.590000000000000000e+02 5.947974966400412233e-01 4.914525965331308088e-02 +6.600000000000000000e+02 5.948794848998141260e-01 4.949586949986977541e-02 +6.610000000000000000e+02 5.949614731595870287e-01 1.154950890209348324e-02 +6.620000000000000000e+02 5.950434614193599314e-01 5.952553302866181971e-03 +6.630000000000000000e+02 5.960384040799842076e-01 5.962827017990312770e-03 +6.640000000000000000e+02 5.968977239467008200e-01 5.971401854948100475e-03 +6.650000000000000000e+02 5.976922698916873333e-01 5.979078264912053749e-03 +6.660000000000000000e+02 5.984855639775849001e-01 5.987075868587513235e-03 +6.670000000000000000e+02 5.992811578320338395e-01 5.994962996687909669e-03 +6.680000000000000000e+02 6.001160432369694320e-01 6.003340265870438751e-03 +6.690000000000000000e+02 6.010940469366122807e-01 6.013122372698240410e-03 +6.700000000000000000e+02 6.022587092913339601e-01 6.024801616896289028e-03 +6.710000000000000000e+02 6.036016267263170088e-01 6.038228875501396725e-03 +6.720000000000000000e+02 6.048883831372682263e-01 6.051055703519278919e-03 +6.730000000000000000e+02 6.057362496528987394e-01 6.059627548447080875e-03 +6.740000000000000000e+02 6.065500753287890179e-01 6.067676275405125934e-03 +6.750000000000000000e+02 6.072132590585969103e-01 6.074346707305095135e-03 +6.760000000000000000e+02 6.076965005712926526e-01 6.079153884128151233e-03 +6.770000000000000000e+02 6.081005428793934131e-01 6.083221564365398799e-03 +6.780000000000000000e+02 6.085497946021791726e-01 6.087698508869093458e-03 +6.790000000000000000e+02 6.091668771676552741e-01 6.093817262632241112e-03 +6.800000000000000000e+02 6.099754721934742552e-01 6.101982783616372898e-03 +6.810000000000000000e+02 6.100453759554662625e-01 1.169356362483434802e-02 +6.820000000000000000e+02 6.101152797174581588e-01 1.170640798348219179e-02 +6.830000000000000000e+02 6.101851834794501661e-01 1.176351722901133705e-02 +6.840000000000000000e+02 6.102550872414420624e-01 1.189317333021930670e-02 +6.850000000000000000e+02 6.103249910034340697e-01 1.204576516500515532e-02 +6.860000000000000000e+02 6.103948947654259660e-01 1.207316573251182752e-02 +6.870000000000000000e+02 6.104647985274179733e-01 1.193395939730694695e-02 +6.880000000000000000e+02 6.105347022894098696e-01 1.179742244961136388e-02 +6.890000000000000000e+02 6.106046060514018770e-01 1.176416307890407360e-02 +6.900000000000000000e+02 6.106745098133937732e-01 1.176520546500505089e-02 +6.910000000000000000e+02 6.107444135753857806e-01 1.174122068671626905e-02 +6.920000000000000000e+02 6.108143173373776769e-01 1.170136748229359813e-02 +6.930000000000000000e+02 6.108842210993696842e-01 6.111075099658467777e-03 +6.940000000000000000e+02 6.117294527179227837e-01 6.119557883374477161e-03 +6.950000000000000000e+02 6.124556535976622973e-01 6.126768450696659998e-03 +6.960000000000000000e+02 6.131300574630795808e-01 6.133562411701733857e-03 +6.970000000000000000e+02 6.137922085955807017e-01 6.140185676517280824e-03 +6.980000000000000000e+02 6.144218337514237849e-01 6.146530381978499921e-03 +6.990000000000000000e+02 6.149933830082782160e-01 6.152289931730807113e-03 +7.000000000000000000e+02 6.155121929490919852e-01 6.157439198363633473e-03 +7.010000000000000000e+02 6.159934148496393203e-01 6.162313510756049426e-03 +7.020000000000000000e+02 6.164014252956906414e-01 6.166330507234564495e-03 +7.030000000000000000e+02 6.166783721372796068e-01 6.169120931341764286e-03 +7.040000000000000000e+02 6.166339777035890757e-01 6.168655041521853982e-03 +7.050000000000000000e+02 6.162287639354762092e-01 6.164585409466043740e-03 +7.060000000000000000e+02 6.155402127683279323e-01 6.157740411550622663e-03 +7.070000000000000000e+02 6.147272786138237022e-01 6.149550130625534849e-03 +7.080000000000000000e+02 6.141535458430902317e-01 6.143848879952605938e-03 +7.090000000000000000e+02 6.141058320870909082e-01 6.143352065071531858e-03 +7.100000000000000000e+02 6.143535108430741021e-01 6.145836877704449926e-03 +7.110000000000000000e+02 6.145400604957382829e-01 6.147718479453215777e-03 +7.120000000000000000e+02 6.145073912771688018e-01 6.147367766679501938e-03 +7.130000000000000000e+02 6.143444998419889114e-01 6.145939181808033475e-03 +7.140000000000000000e+02 6.141501315352091428e-01 6.143965238241187558e-03 +7.150000000000000000e+02 6.139256155085398570e-01 6.141808972298863287e-03 +7.160000000000000000e+02 6.136563159668735334e-01 6.139185585814509009e-03 +7.170000000000000000e+02 6.133681860385030715e-01 6.136945470874877705e-03 +7.180000000000000000e+02 6.132220009203870337e-01 6.135913222522449903e-03 +7.190000000000000000e+02 6.132725553775684180e-01 6.135623856404912035e-03 +7.200000000000000000e+02 6.135207522153017790e-01 6.137800202895407620e-03 +7.210000000000000000e+02 6.138713484506854723e-01 6.141183983611289351e-03 +7.220000000000000000e+02 6.142409828273931449e-01 6.144890232363463614e-03 +7.230000000000000000e+02 6.145605955273447663e-01 6.148058612108653342e-03 +7.240000000000000000e+02 6.148083499332714918e-01 6.150571795467503142e-03 +7.250000000000000000e+02 6.150983317276960127e-01 6.153483819726665409e-03 +7.260000000000000000e+02 6.155556681796506835e-01 6.158062921216841262e-03 +7.270000000000000000e+02 6.162072178638779985e-01 6.164961481378967989e-03 +7.280000000000000000e+02 6.170262975406589634e-01 6.173080643045885697e-03 +7.290000000000000000e+02 6.177460677330324224e-01 6.180335945250984599e-03 +7.300000000000000000e+02 6.181080853280402909e-01 6.183586536080913632e-03 +7.310000000000000000e+02 6.183218141876282159e-01 6.185711064252455774e-03 +7.320000000000000000e+02 6.186041380124399636e-01 6.188498608896910065e-03 +7.330000000000000000e+02 6.189617193418505137e-01 6.192043848040795946e-03 +7.340000000000000000e+02 6.192780561587364341e-01 6.195263002382891092e-03 +7.350000000000000000e+02 6.194978227269652971e-01 6.197406911152274211e-03 +7.360000000000000000e+02 6.196544178739592512e-01 6.199029302839305713e-03 +7.370000000000000000e+02 6.198177869052161615e-01 6.200663843308928252e-03 +7.380000000000000000e+02 6.200091724232504875e-01 6.202624646641379663e-03 +7.390000000000000000e+02 6.201061921281990630e-01 6.203606690742310102e-03 +7.400000000000000000e+02 6.200293434147486904e-01 6.202828334470550722e-03 +7.410000000000000000e+02 6.196612190013145449e-01 6.199196981106307007e-03 +7.420000000000000000e+02 6.192162593928038916e-01 6.194662261940305469e-03 +7.430000000000000000e+02 6.191072881865351540e-01 6.193590761489019964e-03 +7.440000000000000000e+02 6.190874160773827128e-01 6.193352713592541886e-03 +7.450000000000000000e+02 6.189272392184796967e-01 6.191763118185955247e-03 +7.460000000000000000e+02 6.186533434674453824e-01 6.189005778414306130e-03 +7.470000000000000000e+02 6.183976713124589297e-01 6.186461086598825203e-03 +7.480000000000000000e+02 6.182157570317060591e-01 6.184702156169985185e-03 +7.490000000000000000e+02 6.181123468884317518e-01 6.183777588453745477e-03 +7.500000000000000000e+02 6.180315425582647570e-01 6.183162459662621194e-03 +7.510000000000000000e+02 6.178844654399543446e-01 6.181650407444983474e-03 +7.520000000000000000e+02 6.176000015648049901e-01 6.179736372251176842e-03 +7.530000000000000000e+02 6.173560507300338562e-01 6.175937121716959695e-03 +7.540000000000000000e+02 6.173423539545176419e-01 1.163638405159305757e-02 +7.550000000000000000e+02 6.173286571790013166e-01 1.154475845344722640e-02 +7.560000000000000000e+02 6.173149604034851023e-01 9.859394758480953536e-02 +7.570000000000000000e+02 6.173012636279688881e-01 1.047130225914174179e-01 +7.580000000000000000e+02 6.172875668524526738e-01 1.177721745108219892e-01 +7.590000000000000000e+02 6.172738700769364595e-01 1.324788995216795440e-01 +7.600000000000000000e+02 6.172601733014201342e-01 1.326244542032908313e-01 +7.610000000000000000e+02 6.172464765259039199e-01 1.159592475305588483e-01 +7.620000000000000000e+02 6.172327797503877056e-01 1.043753305610231608e-01 +7.630000000000000000e+02 6.172190829748713803e-01 1.010733567511303832e-01 +7.640000000000000000e+02 6.172053861993551660e-01 9.940144981119973522e-02 +7.650000000000000000e+02 6.171916894238389517e-01 9.758861438142286959e-02 +7.660000000000000000e+02 6.171779926483227374e-01 9.653705250098869317e-02 +7.670000000000000000e+02 6.171642958728065231e-01 9.676459963670662467e-02 +7.680000000000000000e+02 6.171505990972901978e-01 9.801314138815997445e-02 +7.690000000000000000e+02 6.171369023217739835e-01 6.174425994892825988e-03 +7.700000000000000000e+02 6.169364608634579916e-01 6.172145985897763143e-03 +7.710000000000000000e+02 6.167036955060198888e-01 6.170364828430421715e-03 +7.720000000000000000e+02 6.164573881874404471e-01 6.167443715927372824e-03 +7.730000000000000000e+02 6.162311045596089443e-01 6.165255131902629138e-03 +7.740000000000000000e+02 6.159372073765363442e-01 6.162279226540657434e-03 +7.750000000000000000e+02 6.155681235356538217e-01 6.158665009031225220e-03 +7.760000000000000000e+02 6.151937490124377295e-01 6.154913328271320420e-03 +7.770000000000000000e+02 6.149411664390648236e-01 6.152747426812014628e-03 +7.780000000000000000e+02 6.147044606941322042e-01 6.149785070870473179e-03 +7.790000000000000000e+02 6.140657912367109006e-01 6.143298883102558255e-03 +7.800000000000000000e+02 6.132367003488229384e-01 6.135080117903955049e-03 +7.810000000000000000e+02 6.124606444335849442e-01 6.127272567783647803e-03 +7.820000000000000000e+02 6.116355891985958415e-01 6.119077749402706233e-03 +7.830000000000000000e+02 6.108799600892548254e-01 6.111516819996018132e-03 +7.840000000000000000e+02 6.104806522023792370e-01 6.108230335143345451e-03 +7.850000000000000000e+02 6.104244067550630426e-01 6.107753850392617923e-03 +7.860000000000000000e+02 6.103890711869373042e-01 6.106598833691487781e-03 +7.870000000000000000e+02 6.102369482200759032e-01 6.105134303604067142e-03 +7.880000000000000000e+02 6.099871710832099891e-01 6.102586627725685789e-03 +7.890000000000000000e+02 6.096004290178973495e-01 6.098769577163784192e-03 +7.900000000000000000e+02 6.091793761302328747e-01 6.094577143300563583e-03 +7.910000000000000000e+02 6.088072068877710130e-01 6.090905265646915680e-03 +7.920000000000000000e+02 6.084647967153142822e-01 6.088883296338891589e-03 +7.930000000000000000e+02 6.082090782148293906e-01 6.086720586350854480e-03 +7.940000000000000000e+02 6.080548133637452279e-01 6.084765654083172833e-03 +7.950000000000000000e+02 6.080471496121847563e-01 6.083337169070079410e-03 +7.960000000000000000e+02 6.080794510182301327e-01 6.083647533905368020e-03 +7.970000000000000000e+02 6.080679363885045374e-01 6.083483236464830128e-03 +7.980000000000000000e+02 6.080655042765442664e-01 6.083516665764135412e-03 +7.990000000000000000e+02 6.080761104404874828e-01 6.083674524624856431e-03 +8.000000000000000000e+02 6.080962391976499903e-01 6.084132860692992480e-03 +8.010000000000000000e+02 6.076744875165311921e-01 6.079716893842184930e-03 +8.020000000000000000e+02 6.074110424370096073e-01 6.077000212911429743e-03 +8.030000000000000000e+02 6.074471922856874428e-01 6.077438495370130443e-03 +8.040000000000000000e+02 6.075738367164221776e-01 6.078680163849782200e-03 +8.050000000000000000e+02 6.075699238366584209e-01 6.078659880611408592e-03 +8.060000000000000000e+02 6.072792289758435214e-01 6.075798636945857478e-03 +8.070000000000000000e+02 6.069116423129161664e-01 6.072050622425319462e-03 +8.080000000000000000e+02 6.066118256852561785e-01 6.069167629060588653e-03 +8.090000000000000000e+02 6.063909626022301325e-01 6.066851822242572481e-03 +8.100000000000000000e+02 6.061353628681479533e-01 6.064379380098899354e-03 +8.110000000000000000e+02 6.061200209392066940e-01 1.168447682344572053e-02 +8.120000000000000000e+02 6.061046790102655457e-01 1.176248188623205647e-02 +8.130000000000000000e+02 6.060893370813242864e-01 1.183222851000354132e-02 +8.140000000000000000e+02 6.060739951523830271e-01 1.189561930771176196e-02 +8.150000000000000000e+02 6.060586532234418788e-01 1.191950067110399483e-02 +8.160000000000000000e+02 6.060433112945006195e-01 1.190043646906926121e-02 +8.170000000000000000e+02 6.060279693655593602e-01 1.185437080157226639e-02 +8.180000000000000000e+02 6.060126274366182120e-01 1.180582988981531897e-02 +8.190000000000000000e+02 6.059972855076769527e-01 1.176915403605450529e-02 +8.200000000000000000e+02 6.059819435787356934e-01 1.177604281838092772e-02 +8.210000000000000000e+02 6.059666016497945451e-01 1.179929144105866350e-02 +8.220000000000000000e+02 6.059512597208532858e-01 1.178844826117525155e-02 +8.230000000000000000e+02 6.059359177919121375e-01 1.172195140499797741e-02 +8.240000000000000000e+02 6.059205758629708782e-01 1.168795508424322338e-02 +8.250000000000000000e+02 6.059052339340296189e-01 1.171902420965813436e-02 +8.260000000000000000e+02 6.058898920050884707e-01 1.176754237741387682e-02 +8.270000000000000000e+02 6.058745500761472114e-01 1.179332535986610947e-02 +8.280000000000000000e+02 6.058592081472059521e-01 1.179890646902640068e-02 +8.290000000000000000e+02 6.058438662182648038e-01 1.180085175120015005e-02 +8.300000000000000000e+02 6.058285242893235445e-01 6.061656661659091568e-03 +8.310000000000000000e+02 6.054245744407362739e-01 6.057696211893945533e-03 +8.320000000000000000e+02 6.050314999766095436e-01 6.053689422688576967e-03 +8.330000000000000000e+02 6.046670539839085201e-01 6.050558321937591320e-03 +8.340000000000000000e+02 6.043422434906411400e-01 6.046785359200735829e-03 +8.350000000000000000e+02 6.039970250335849888e-01 6.043341362058952948e-03 +8.360000000000000000e+02 6.035357274289562257e-01 6.038651824505625147e-03 +8.370000000000000000e+02 6.028825364895925576e-01 6.032160697864469290e-03 +8.380000000000000000e+02 6.019981250640128456e-01 6.023348467031571819e-03 +8.390000000000000000e+02 6.011921082228299795e-01 6.015182643520610925e-03 +8.400000000000000000e+02 6.006069679892781510e-01 6.009459378018548736e-03 +8.410000000000000000e+02 6.003743402788969119e-01 6.007043266613634053e-03 +8.420000000000000000e+02 5.995353642088494528e-01 5.998727063954156780e-03 +8.430000000000000000e+02 5.982501692849405694e-01 5.985846131149997508e-03 +8.440000000000000000e+02 5.972903913665257303e-01 5.976283797927479935e-03 +8.450000000000000000e+02 5.970406031631728672e-01 5.973790613248346724e-03 +8.460000000000000000e+02 5.971127896895532805e-01 5.974466752878266132e-03 +8.470000000000000000e+02 5.969602245103702298e-01 5.973079119989834970e-03 +8.480000000000000000e+02 5.963272630194342838e-01 5.967565691006044247e-03 +8.490000000000000000e+02 5.954863682150408621e-01 5.958802587400947350e-03 +8.500000000000000000e+02 5.945503787248633820e-01 5.949575428611644790e-03 +8.510000000000000000e+02 5.939475191411660582e-01 5.944004499612038500e-03 +8.520000000000000000e+02 5.936189130171823924e-01 5.939974239569098709e-03 +8.530000000000000000e+02 5.930494635253797941e-01 5.936249935730281667e-03 +8.540000000000000000e+02 5.920246182885829933e-01 5.927325426672437614e-03 +8.550000000000000000e+02 5.903631102212578696e-01 5.907765676229346542e-03 +8.560000000000000000e+02 5.889022949352215042e-01 5.893347369821114873e-03 +8.570000000000000000e+02 5.881714117567780065e-01 5.885790652170658742e-03 +8.580000000000000000e+02 5.881441758411619647e-01 5.885837080456628005e-03 +8.590000000000000000e+02 5.884251926284581602e-01 5.890158961182954782e-03 +8.600000000000000000e+02 5.885323266805149167e-01 5.893599696492057838e-03 +8.610000000000000000e+02 5.883140591070807890e-01 5.888139287288395030e-03 +8.620000000000000000e+02 5.881335485013164943e-01 5.885485075220591236e-03 +8.630000000000000000e+02 5.882283659554676802e-01 5.887119566190079749e-03 +8.640000000000000000e+02 5.885808080873384807e-01 5.890532994087809004e-03 +8.650000000000000000e+02 5.884651563638245708e-01 5.890496042786773530e-03 +8.660000000000000000e+02 5.874451605354760186e-01 5.881017028354018454e-03 +8.670000000000000000e+02 5.859801623340616938e-01 5.864959955727258069e-03 +8.680000000000000000e+02 5.846976804333030575e-01 5.850774756620828916e-03 +8.690000000000000000e+02 5.838787769617856949e-01 5.842470773114699645e-03 +8.700000000000000000e+02 5.833784624275644148e-01 5.837459450941843465e-03 +8.710000000000000000e+02 5.832023485672872543e-01 5.835571274736664309e-03 +8.720000000000000000e+02 5.827951672774579484e-01 5.831685818305693686e-03 +8.730000000000000000e+02 5.821183369149074416e-01 5.826388442152151750e-03 +8.740000000000000000e+02 5.815706938509661583e-01 5.820559950228536804e-03 +8.750000000000000000e+02 5.813082019824160618e-01 5.817280824450852400e-03 +8.760000000000000000e+02 5.814827910854140081e-01 5.818682167327032806e-03 +8.770000000000000000e+02 5.815606843466454290e-01 5.819406677204352549e-03 +8.780000000000000000e+02 5.810542781516467858e-01 5.814418288828060444e-03 +8.790000000000000000e+02 5.800317410578512689e-01 5.804742946286165634e-03 +8.800000000000000000e+02 5.788200766929769703e-01 5.792524137288443918e-03 +8.810000000000000000e+02 5.774934819022071730e-01 5.778881310239862047e-03 +8.820000000000000000e+02 5.761366612745832949e-01 5.765192163274182949e-03 +8.830000000000000000e+02 5.748272350055418922e-01 5.752148719337038182e-03 +8.840000000000000000e+02 5.737047754318040926e-01 5.740899797989305539e-03 +8.850000000000000000e+02 5.725400049177139516e-01 5.729323506002260633e-03 +8.860000000000000000e+02 5.711750985358761135e-01 5.716787286447711121e-03 +8.870000000000000000e+02 5.696238676436059523e-01 5.700157359507283285e-03 +8.880000000000000000e+02 5.680044997396266337e-01 5.684018031863411965e-03 +8.890000000000000000e+02 5.665911902922557974e-01 5.669787233167196405e-03 +8.900000000000000000e+02 5.656119966185710890e-01 5.660118069204949504e-03 +8.910000000000000000e+02 5.650238124192299427e-01 5.654179724459862388e-03 +8.920000000000000000e+02 5.645141179310245727e-01 5.649208242250935638e-03 +8.930000000000000000e+02 5.638664901928174267e-01 5.642694069007951445e-03 +8.940000000000000000e+02 5.628176247590407355e-01 5.632340320211454143e-03 +8.950000000000000000e+02 5.613754992605898275e-01 5.618312465307378871e-03 +8.960000000000000000e+02 5.596528143621353202e-01 5.602276657106902528e-03 +8.970000000000000000e+02 5.577424620994851923e-01 5.582739017634136096e-03 +8.980000000000000000e+02 5.557884106230021048e-01 5.562546819459202561e-03 +8.990000000000000000e+02 5.541594368292634964e-01 5.547114568179435483e-03 +9.000000000000000000e+02 5.528296048755674263e-01 5.533699882374630390e-03 +9.010000000000000000e+02 5.514897230609502321e-01 5.520265774718882690e-03 +9.020000000000000000e+02 5.500397366445592962e-01 5.505386568380061033e-03 +9.030000000000000000e+02 5.485580042653883659e-01 5.489902170624746600e-03 +9.040000000000000000e+02 5.471804942797864335e-01 5.476116880758385118e-03 +9.050000000000000000e+02 5.458778471723860770e-01 5.463080906040642185e-03 +9.060000000000000000e+02 5.446716807636740043e-01 5.451361163570108900e-03 +9.070000000000000000e+02 5.436759545625614587e-01 5.442690346316133784e-03 +9.080000000000000000e+02 5.428174166423322955e-01 5.434468565565296443e-03 +9.090000000000000000e+02 5.417749025491721548e-01 5.423207328667336603e-03 +9.100000000000000000e+02 5.402014951994978942e-01 5.406879230993828951e-03 +9.110000000000000000e+02 5.380016779194430887e-01 5.384731905755758830e-03 +9.120000000000000000e+02 5.352612812930818142e-01 5.357351493351927667e-03 +9.130000000000000000e+02 5.322290252670479616e-01 5.327117237211872677e-03 +9.140000000000000000e+02 5.293542966456545873e-01 5.298308400729151088e-03 +9.150000000000000000e+02 5.269589511330093901e-01 5.275211220274715271e-03 +9.160000000000000000e+02 5.249704681292468589e-01 5.255059451379993571e-03 +9.170000000000000000e+02 5.230499076938184277e-01 5.236014845210466492e-03 +9.180000000000000000e+02 5.208709603503873797e-01 5.213391906981953462e-03 +9.190000000000000000e+02 5.178707223504875889e-01 5.183412879078521870e-03 +9.200000000000000000e+02 5.139027192636547170e-01 5.143672722230476120e-03 +9.210000000000000000e+02 5.094100718521371585e-01 5.098851594536843099e-03 +9.220000000000000000e+02 5.050515353445206301e-01 5.055387626787523521e-03 +9.230000000000000000e+02 5.009341659380786016e-01 5.014656161035329317e-03 +9.240000000000000000e+02 4.970795987882178912e-01 4.975641406024694166e-03 +9.250000000000000000e+02 4.938709274606627453e-01 4.943292170745506448e-03 +9.260000000000000000e+02 4.918530002642909071e-01 4.923210878227047421e-03 +9.270000000000000000e+02 4.911778703401037394e-01 4.916429320749733135e-03 +9.280000000000000000e+02 4.909852448696899740e-01 4.915237908197927705e-03 +9.290000000000000000e+02 4.904108821268060581e-01 4.911010462287775276e-03 +9.300000000000000000e+02 4.887854657847843232e-01 4.896978602694013367e-03 +9.310000000000000000e+02 4.863809041395475430e-01 4.874556141819715201e-03 +9.320000000000000000e+02 4.833591805168604427e-01 4.845946105551898232e-03 +9.330000000000000000e+02 4.800013955992873393e-01 4.813717988507605107e-03 +9.340000000000000000e+02 4.764141364755156705e-01 4.778340105708758431e-03 +9.350000000000000000e+02 4.725337142901013809e-01 4.735258432873594610e-03 +9.360000000000000000e+02 4.687209612289795491e-01 4.698492629513694938e-03 +9.370000000000000000e+02 4.652594873596422875e-01 4.663791735349196929e-03 +9.380000000000000000e+02 4.621290077197935942e-01 4.631154830854128726e-03 +9.390000000000000000e+02 4.592023759291139484e-01 4.598411031388148322e-03 +9.400000000000000000e+02 4.567686690883495659e-01 4.573821230111622081e-03 +9.410000000000000000e+02 4.548558814410926243e-01 4.554954267400110682e-03 +9.420000000000000000e+02 4.529424004733237363e-01 4.539246953969871233e-03 +9.430000000000000000e+02 4.505800360513580460e-01 4.515379606697285213e-03 +9.440000000000000000e+02 4.479908685885618524e-01 4.487878775107125018e-03 +9.450000000000000000e+02 4.453419960864832827e-01 4.461048670260491650e-03 +9.460000000000000000e+02 4.420441232287021238e-01 4.427925401569727214e-03 +9.470000000000000000e+02 4.373970546414553406e-01 4.381012421537577514e-03 +9.480000000000000000e+02 4.312599112038008609e-01 4.319623918159576879e-03 +9.490000000000000000e+02 4.245668496598410391e-01 4.253571644675761820e-03 +9.500000000000000000e+02 4.181480848226274416e-01 4.189163132775073142e-03 +9.510000000000000000e+02 4.128377784527714756e-01 4.135453028770445967e-03 +9.520000000000000000e+02 4.084586076889037964e-01 4.091536352318768562e-03 +9.530000000000000000e+02 4.048801842702549614e-01 4.056039989437060928e-03 +9.540000000000000000e+02 4.018206150274700739e-01 4.025328457828238754e-03 +9.550000000000000000e+02 3.990444127625871196e-01 3.997706222117741910e-03 +9.560000000000000000e+02 3.964133263030448218e-01 3.971176043910774195e-03 +9.570000000000000000e+02 3.934403788826201787e-01 3.941437250624273830e-03 +9.580000000000000000e+02 3.899442997589530058e-01 3.906431517271465384e-03 +9.590000000000000000e+02 3.860867029620086988e-01 3.867679804415546062e-03 +9.600000000000000000e+02 3.820974599847587472e-01 3.827805017099819053e-03 +9.610000000000000000e+02 3.778631376225996541e-01 3.785239198980112473e-03 +9.620000000000000000e+02 3.733662525660725318e-01 3.740467934319256001e-03 +9.630000000000000000e+02 3.689671533402499870e-01 3.696280182482386979e-03 +9.640000000000000000e+02 3.649698295080780475e-01 3.656413388617010818e-03 +9.650000000000000000e+02 3.612337424987164813e-01 3.619641679690664693e-03 +9.660000000000000000e+02 3.573818916323118211e-01 3.580216093701374565e-03 +9.670000000000000000e+02 3.533818852434478242e-01 3.539896584091135109e-03 +9.680000000000000000e+02 3.494566359163692182e-01 3.500536896365816913e-03 +9.690000000000000000e+02 3.456142217024722463e-01 3.462161735473446092e-03 +9.700000000000000000e+02 3.416740752722713936e-01 3.422741473240824110e-03 +9.710000000000000000e+02 3.375499669029273786e-01 3.381912339455409467e-03 +9.720000000000000000e+02 3.333000287154199159e-01 3.339437155699763633e-03 +9.730000000000000000e+02 3.289672678238202419e-01 3.296480604019482504e-03 +9.740000000000000000e+02 3.244596182888406233e-01 3.251266219339206138e-03 +9.750000000000000000e+02 3.196647482783398497e-01 3.203464468865753565e-03 +9.760000000000000000e+02 3.146678114727977094e-01 3.153285180086820051e-03 +9.770000000000000000e+02 3.095334387444092505e-01 3.101985795663042209e-03 +9.780000000000000000e+02 3.043765124250011889e-01 3.050414722955998442e-03 +9.790000000000000000e+02 2.992591415933975596e-01 2.999045615422553726e-03 +9.800000000000000000e+02 2.942873881252527912e-01 2.949450707744354170e-03 +9.810000000000000000e+02 2.895896862004471717e-01 1.000000000000000056e-01 +9.820000000000000000e+02 2.851725039705181319e-01 1.000000000000000056e-01 +9.830000000000000000e+02 2.808876677979527670e-01 1.000000000000000056e-01 +9.840000000000000000e+02 2.765368883460332383e-01 1.000000000000000056e-01 +9.850000000000000000e+02 2.719297534472140954e-01 1.000000000000000056e-01 +9.860000000000000000e+02 2.670871439297765049e-01 1.000000000000000056e-01 +9.870000000000000000e+02 2.621311638556571011e-01 1.000000000000000056e-01 +9.880000000000000000e+02 2.571498797287008475e-01 1.000000000000000056e-01 +9.890000000000000000e+02 2.520821895472421525e-01 1.000000000000000056e-01 +9.900000000000000000e+02 2.468912706595203232e-01 1.000000000000000056e-01 +9.910000000000000000e+02 2.416148390186070305e-01 1.000000000000000056e-01 +9.920000000000000000e+02 2.363703111886830133e-01 1.000000000000000056e-01 +9.930000000000000000e+02 2.312475602917352102e-01 1.000000000000000056e-01 +9.940000000000000000e+02 2.262203793325666679e-01 1.000000000000000056e-01 +9.950000000000000000e+02 2.212683102080942321e-01 1.000000000000000056e-01 +9.960000000000000000e+02 2.163389281595638758e-01 1.000000000000000056e-01 +9.970000000000000000e+02 2.114020390398878846e-01 1.000000000000000056e-01 +9.980000000000000000e+02 2.064763076099080941e-01 1.000000000000000056e-01 +9.990000000000000000e+02 2.016184780833522316e-01 1.000000000000000056e-01 +1.000000000000000000e+03 1.968600179142609152e-01 1.000000000000000056e-01 +1.001000000000000000e+03 1.921583121981945974e-01 1.000000000000000056e-01 +1.002000000000000000e+03 1.874562670217378157e-01 1.000000000000000056e-01 +1.003000000000000000e+03 1.827181698820697087e-01 1.000000000000000056e-01 +1.004000000000000000e+03 1.780002829190756031e-01 1.000000000000000056e-01 +1.005000000000000000e+03 1.732766972233956149e-01 1.000000000000000056e-01 +1.006000000000000000e+03 1.686222715523199855e-01 1.000000000000000056e-01 +1.007000000000000000e+03 1.640166266529139993e-01 1.000000000000000056e-01 +1.008000000000000000e+03 1.594244872354226017e-01 1.000000000000000056e-01 +1.009000000000000000e+03 1.548420884323198909e-01 1.000000000000000056e-01 +1.010000000000000000e+03 1.503492279466194514e-01 1.000000000000000056e-01 +1.011000000000000000e+03 1.459756203855785694e-01 1.000000000000000056e-01 +1.012000000000000000e+03 1.417213825056695686e-01 1.000000000000000056e-01 +1.013000000000000000e+03 1.375672092700001570e-01 1.000000000000000056e-01 +1.014000000000000000e+03 1.333945150052509299e-01 1.000000000000000056e-01 +1.015000000000000000e+03 1.292208322830419587e-01 1.000000000000000056e-01 +1.016000000000000000e+03 1.250374031179704026e-01 1.000000000000000056e-01 +1.017000000000000000e+03 1.209263958029919706e-01 1.000000000000000056e-01 +1.018000000000000000e+03 1.169132138982437452e-01 1.000000000000000056e-01 +1.019000000000000000e+03 1.129912909370652252e-01 1.000000000000000056e-01 +1.020000000000000000e+03 1.090950336788828884e-01 1.000000000000000056e-01 +1.021000000000000000e+03 1.051734980339712883e-01 1.000000000000000056e-01 +1.022000000000000000e+03 1.012478665896077434e-01 1.000000000000000056e-01 +1.023000000000000000e+03 9.734549012875765017e-02 1.000000000000000056e-01 +1.024000000000000000e+03 9.347684967475322626e-02 1.000000000000000056e-01 +1.025000000000000000e+03 8.944322965331627517e-02 1.000000000000000056e-01 +1.026000000000000000e+03 8.542150646831871141e-02 1.000000000000000056e-01 +1.027000000000000000e+03 8.164755325937504693e-02 1.000000000000000056e-01 +1.028000000000000000e+03 7.856744053528684490e-02 1.000000000000000056e-01 +1.029000000000000000e+03 7.641211524243686493e-02 1.000000000000000056e-01 +1.030000000000000000e+03 7.590075261252499095e-02 1.000000000000000056e-01 +1.031000000000000000e+03 7.357170556047112897e-02 1.000000000000000056e-01 +1.032000000000000000e+03 7.124265850841729475e-02 1.000000000000000056e-01 +1.033000000000000000e+03 6.891361145636344665e-02 1.000000000000000056e-01 +1.034000000000000000e+03 6.658456440430961243e-02 1.000000000000000056e-01 +1.035000000000000000e+03 6.425551735225577821e-02 1.000000000000000056e-01 +1.036000000000000000e+03 6.192647030020193705e-02 1.000000000000000056e-01 +1.037000000000000000e+03 5.959742324814809589e-02 1.000000000000000056e-01 +1.038000000000000000e+03 5.726837619609426167e-02 1.000000000000000056e-01 +1.039000000000000000e+03 5.493932914404042051e-02 1.000000000000000056e-01 +1.040000000000000000e+03 5.261028209198658628e-02 1.000000000000000056e-01 +1.041000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.042000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.043000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.044000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.045000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.046000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.047000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.048000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.049000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.050000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.051000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.052000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.053000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.054000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.055000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.056000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.057000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.058000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.059000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.060000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.061000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.062000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.063000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.064000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.065000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.066000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.067000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.068000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.069000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.070000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.071000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.072000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.073000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.074000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.075000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.076000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.077000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.078000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.079000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.080000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.081000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.082000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.083000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.084000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.085000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.086000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.087000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.088000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.089000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.090000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.091000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.092000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.093000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.094000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.095000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.096000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.097000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.098000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 +1.099000000000000000e+03 0.000000000000000000e+00 1.000000000000000056e-01 diff --git a/spectractor/simulation/AuxTelThroughput/multispectra_holo4_003_HD142331_20230802_AuxTel_doGainsPTC_v3.0.3_throughput.txt b/spectractor/simulation/AuxTelThroughput/multispectra_holo4_003_HD142331_20230802_AuxTel_doGainsPTC_v3.0.3_throughput.txt index 01480e375..92f8f6131 100644 --- a/spectractor/simulation/AuxTelThroughput/multispectra_holo4_003_HD142331_20230802_AuxTel_doGainsPTC_v3.0.3_throughput.txt +++ b/spectractor/simulation/AuxTelThroughput/multispectra_holo4_003_HD142331_20230802_AuxTel_doGainsPTC_v3.0.3_throughput.txt @@ -1,83 +1,83 @@ -3.000000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.010000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.020000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.030000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.040000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.050000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.060000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.070000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.080000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.090000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.100000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.110000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.120000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.130000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.140000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.150000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.160000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.170000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.180000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.190000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.200000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.210000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.220000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.230000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.240000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.250000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.260000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.270000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.280000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.290000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.300000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.310000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.320000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.330000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.340000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.350000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.360000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.370000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.380000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.390000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.400000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.410000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.420000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.430000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.440000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.450000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.460000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.470000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.480000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.490000000000000000e+02 0.000000000000000000e+00 1.000000000000000021e-02 -3.500000000000000000e+02 4.460543080675311023e-04 1.000000000000000021e-02 -3.510000000000000000e+02 5.127732532376337755e-03 1.000000000000000021e-02 -3.520000000000000000e+02 9.809410756685144409e-03 1.000000000000000021e-02 -3.530000000000000000e+02 1.449108898099395193e-02 1.000000000000000021e-02 -3.540000000000000000e+02 2.151360631745716928e-02 1.000000000000000021e-02 -3.550000000000000000e+02 2.853612365392038663e-02 1.000000000000000021e-02 -3.560000000000000000e+02 4.258115832684682134e-02 1.076978108162215649e-03 -3.570000000000000000e+02 5.662619299977324216e-02 1.000000000000000021e-02 -3.580000000000000000e+02 7.067122767269960748e-02 9.179710898409596063e-04 -3.590000000000000000e+02 8.458727746713645690e-02 1.000000000000000021e-02 -3.600000000000000000e+02 9.981309525069298472e-02 1.000000000000000021e-02 -3.610000000000000000e+02 1.159818086563590006e-01 1.000000000000000021e-02 -3.620000000000000000e+02 1.320523482528832560e-01 1.663011488662912915e-03 -3.630000000000000000e+02 1.476744926766204169e-01 1.000000000000000021e-02 -3.640000000000000000e+02 1.507394599221379972e-01 8.333343236250701294e-03 -3.650000000000000000e+02 1.538044271676555774e-01 6.666686472501400645e-03 -3.660000000000000000e+02 1.568693944131731577e-01 5.000029708752101731e-03 -3.670000000000000000e+02 1.599343616586907380e-01 3.333372945002801950e-03 -3.680000000000000000e+02 1.629993289042083182e-01 1.666716181253502602e-03 -3.690000000000000000e+02 1.783612927446105167e-01 1.870126998706461013e-03 -3.700000000000000000e+02 1.936064772326762939e-01 1.970150181592436340e-03 -3.710000000000000000e+02 2.081650200601536937e-01 2.119537801644612567e-03 -3.720000000000000000e+02 2.259372492357716034e-01 2.291670345302004863e-03 -3.730000000000000000e+02 2.425423740773889891e-01 2.455992604441717755e-03 -3.740000000000000000e+02 2.620251063350992338e-01 2.646727927819524529e-03 -3.750000000000000000e+02 2.815262246846203520e-01 2.844843184435932783e-03 -3.760000000000000000e+02 3.016515719597132605e-01 3.040447514683536183e-03 -3.770000000000000000e+02 3.179438795109302274e-01 3.206015471118409035e-03 -3.780000000000000000e+02 3.388975841081813822e-01 3.412701411070339849e-03 -3.790000000000000000e+02 3.466918843041088549e-01 3.487155017944860904e-03 +3.000000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.010000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.020000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.030000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.040000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.050000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.060000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.070000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.080000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.090000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.100000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.110000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.120000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.130000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.140000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.150000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.160000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.170000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.180000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.190000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.200000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.210000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.220000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.230000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.240000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.250000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.260000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.270000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.280000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.290000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.300000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.310000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.320000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.330000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.340000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.350000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.360000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.370000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.380000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.390000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.400000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.410000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.420000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.430000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.440000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.450000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.460000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.470000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.480000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.490000000000000000e+02 0.000000000000000000e+00 1.000000000000000000e+00 +3.500000000000000000e+02 4.460543080675311023e-04 1.000000000000000000e+00 +3.510000000000000000e+02 5.127732532376337755e-03 1.000000000000000000e+00 +3.520000000000000000e+02 9.809410756685144409e-03 1.000000000000000000e+00 +3.530000000000000000e+02 1.449108898099395193e-02 1.000000000000000000e+00 +3.540000000000000000e+02 2.151360631745716928e-02 1.000000000000000000e+00 +3.550000000000000000e+02 2.853612365392038663e-02 1.000000000000000000e+00 +3.560000000000000000e+02 4.258115832684682134e-02 1.000000000000000000e+00 +3.570000000000000000e+02 5.662619299977324216e-02 1.000000000000000000e+00 +3.580000000000000000e+02 7.067122767269960748e-02 1.000000000000000000e+00 +3.590000000000000000e+02 8.458727746713645690e-02 1.000000000000000000e+00 +3.600000000000000000e+02 9.981309525069298472e-02 1.000000000000000000e+00 +3.610000000000000000e+02 1.159818086563590006e-01 1.000000000000000000e+00 +3.620000000000000000e+02 1.320523482528832560e-01 1.000000000000000000e+00 +3.630000000000000000e+02 1.476744926766204169e-01 1.000000000000000000e+00 +3.640000000000000000e+02 1.507394599221379972e-01 1.000000000000000000e+00 +3.650000000000000000e+02 1.538044271676555774e-01 1.000000000000000000e+00 +3.660000000000000000e+02 1.568693944131731577e-01 1.000000000000000000e+00 +3.670000000000000000e+02 1.599343616586907380e-01 1.000000000000000000e+00 +3.680000000000000000e+02 1.629993289042083182e-01 1.000000000000000000e+00 +3.690000000000000000e+02 1.783612927446105167e-01 1.000000000000000000e+00 +3.700000000000000000e+02 1.936064772326762939e-01 1.000000000000000000e+00 +3.710000000000000000e+02 2.081650200601536937e-01 1.000000000000000000e+00 +3.720000000000000000e+02 2.259372492357716034e-01 1.000000000000000000e+00 +3.730000000000000000e+02 2.425423740773889891e-01 1.000000000000000000e+00 +3.740000000000000000e+02 2.620251063350992338e-01 1.000000000000000000e+00 +3.750000000000000000e+02 2.815262246846203520e-01 1.000000000000000000e+00 +3.760000000000000000e+02 3.016515719597132605e-01 1.000000000000000000e+00 +3.770000000000000000e+02 3.179438795109302274e-01 1.000000000000000000e+00 +3.780000000000000000e+02 3.388975841081813822e-01 1.000000000000000000e+00 +3.790000000000000000e+02 3.466918843041088549e-01 1.000000000000000000e+00 3.800000000000000000e+02 3.537462102758726079e-01 3.575908857438699941e-03 3.810000000000000000e+02 3.604314183201944299e-01 3.651607519698463374e-03 3.820000000000000000e+02 3.681364447930130512e-01 3.714686331139742826e-03 @@ -699,102 +699,102 @@ 9.980000000000000000e+02 2.812373383558955386e-01 2.827643069676258596e-03 9.990000000000000000e+02 2.749788897718989933e-01 2.764330318055280636e-03 1.000000000000000000e+03 2.688198661347008800e-01 2.703798765187609768e-03 -1.001000000000000000e+03 2.626858331583472594e-01 2.642294925490960671e-03 -1.002000000000000000e+03 2.566380882610728720e-01 2.582674352689992743e-03 -1.003000000000000000e+03 2.506406642678879471e-01 2.523052630478435972e-03 -1.004000000000000000e+03 2.445805906376559147e-01 2.462670342248521327e-03 -1.005000000000000000e+03 2.384449151187563454e-01 2.402066659047045246e-03 -1.006000000000000000e+03 2.324181618625841272e-01 2.338632723353782032e-03 -1.007000000000000000e+03 2.263790747128379688e-01 2.278862670804639688e-03 -1.008000000000000000e+03 2.203749307534488555e-01 2.218035745811968319e-03 -1.009000000000000000e+03 2.144023626539646177e-01 2.159174455415866726e-03 -1.010000000000000000e+03 2.085083162517175626e-01 2.099530574967484707e-03 -1.011000000000000000e+03 2.027598266556651652e-01 2.042647505464125282e-03 -1.012000000000000000e+03 1.971316607775393526e-01 1.989290471299883997e-03 -1.013000000000000000e+03 1.915961281823060358e-01 1.934952990022929071e-03 -1.014000000000000000e+03 1.860896486576171516e-01 1.880464770718611204e-03 -1.015000000000000000e+03 1.806084251255839213e-01 1.826057556671594525e-03 -1.016000000000000000e+03 1.751840996217163549e-01 1.772766608616137794e-03 -1.017000000000000000e+03 1.699292533656071025e-01 1.720024025067603494e-03 -1.018000000000000000e+03 1.648253291334529913e-01 1.670169106422806542e-03 -1.019000000000000000e+03 1.599413311535699544e-01 1.620524357714481873e-03 -1.020000000000000000e+03 1.550995389730692731e-01 1.573670485639895155e-03 -1.021000000000000000e+03 1.501884077670336826e-01 1.524170542004606166e-03 -1.022000000000000000e+03 1.451769617188636563e-01 1.475043594854790309e-03 -1.023000000000000000e+03 1.400422500111145885e-01 1.424081586205500159e-03 -1.024000000000000000e+03 1.349361203646674001e-01 1.373436919252747287e-03 -1.025000000000000000e+03 1.299316336185109000e-01 1.324560078061857776e-03 -1.026000000000000000e+03 1.250822021568329667e-01 1.276046108168024098e-03 -1.027000000000000000e+03 1.203902626949029386e-01 1.230764779016065708e-03 -1.028000000000000000e+03 1.158435635843868411e-01 1.184273647097548298e-03 -1.029000000000000000e+03 1.113628634525782590e-01 1.148079837018516113e-03 -1.030000000000000000e+03 1.071331508999577159e-01 1.104077842662819914e-03 -1.031000000000000000e+03 1.030328734580701622e-01 1.069558316461686033e-03 -1.032000000000000000e+03 9.897703059925638813e-02 1.030711554635111186e-03 -1.033000000000000000e+03 9.502098388115687300e-02 9.967592639921547988e-04 -1.034000000000000000e+03 9.121032303002588049e-02 9.569960465470421507e-04 -1.035000000000000000e+03 8.758718231083717498e-02 9.236251748465754445e-04 -1.036000000000000000e+03 8.422038789529767699e-02 8.919992371290537880e-04 -1.037000000000000000e+03 8.114766280502058726e-02 8.613009439363004992e-04 -1.038000000000000000e+03 7.831952673163725120e-02 8.358958316476878007e-04 -1.039000000000000000e+03 7.564386588068071349e-02 7.968575400530856839e-04 -1.040000000000000000e+03 7.292613926279578607e-02 7.731060425568140508e-04 -1.041000000000000000e+03 7.016850977876504247e-02 7.446963329554155036e-04 -1.042000000000000000e+03 6.745740654215512389e-02 7.122153971857195188e-04 -1.043000000000000000e+03 6.495798992699892971e-02 6.947504519314385077e-04 -1.044000000000000000e+03 6.270525431671919447e-02 6.753775118836584076e-04 -1.045000000000000000e+03 6.066431717329990453e-02 6.559615538185594157e-04 -1.046000000000000000e+03 5.894564991770784995e-02 6.315141427348644129e-04 -1.047000000000000000e+03 5.746473567181502318e-02 6.297817567149599461e-04 -1.048000000000000000e+03 5.613709189995956528e-02 6.143078174291037065e-04 -1.049000000000000000e+03 5.498369486041716769e-02 6.021371346904693745e-04 -1.050000000000000000e+03 5.397177732146830192e-02 5.926933529180221025e-04 -1.051000000000000000e+03 5.280612241128356671e-02 6.143816255422037548e-04 -1.052000000000000000e+03 5.169321034488788547e-02 6.089535753514795351e-04 -1.053000000000000000e+03 5.064899427349616595e-02 5.897112727267215561e-04 -1.054000000000000000e+03 4.963468792895304321e-02 5.796219646114333717e-04 -1.055000000000000000e+03 4.874155299496014948e-02 5.475960922906729540e-04 -1.056000000000000000e+03 4.792922545752861807e-02 5.381912556774555911e-04 -1.057000000000000000e+03 4.715536370557339013e-02 5.287326911311681027e-04 -1.058000000000000000e+03 4.636232041424764166e-02 5.186969275864616565e-04 -1.059000000000000000e+03 4.555588605030019833e-02 5.361508561385514319e-04 -1.060000000000000000e+03 4.477065780367314729e-02 5.309154762718984065e-04 -1.061000000000000000e+03 4.402301902457297217e-02 4.989388995924729821e-04 -1.062000000000000000e+03 4.333220388136843626e-02 4.955957656644576588e-04 -1.063000000000000000e+03 4.280785989472904451e-02 4.925201621502814636e-04 -1.064000000000000000e+03 4.236036332700753720e-02 4.993465219291960558e-04 -1.065000000000000000e+03 4.198928768615071971e-02 5.131605353879616386e-04 -1.066000000000000000e+03 4.168687308875029113e-02 5.151988970972071983e-04 -1.067000000000000000e+03 4.128830020406685369e-02 4.947015081778467598e-04 -1.068000000000000000e+03 4.077523432980383750e-02 4.900586617293405155e-04 -1.069000000000000000e+03 4.017064276046052734e-02 4.800469433877069605e-04 -1.070000000000000000e+03 3.938520105824146189e-02 4.678362836705530960e-04 -1.071000000000000000e+03 3.860265371760809860e-02 4.721488869384776114e-04 -1.072000000000000000e+03 3.794444885152389174e-02 4.506952258253157299e-04 -1.073000000000000000e+03 3.745606571401392804e-02 4.514017268251912705e-04 -1.074000000000000000e+03 3.718445982832373209e-02 4.495596483287294439e-04 -1.075000000000000000e+03 3.690507733666610612e-02 4.490612658475153364e-04 -1.076000000000000000e+03 3.648760106433639877e-02 4.389242208124782612e-04 -1.077000000000000000e+03 3.612551329519327059e-02 4.385290842412436487e-04 -1.078000000000000000e+03 3.590296164655401578e-02 4.379362369103643625e-04 -1.079000000000000000e+03 3.596241610115500503e-02 4.453104997070488828e-04 -1.080000000000000000e+03 3.653693458020594587e-02 4.512004759485544565e-04 -1.081000000000000000e+03 3.652455959653668621e-02 4.553953438629825619e-04 -1.082000000000000000e+03 3.651218461286743350e-02 4.458842083632784696e-04 -1.083000000000000000e+03 3.649980962919818078e-02 4.570186605607101963e-04 -1.084000000000000000e+03 3.648743464552892807e-02 4.754696431392953573e-04 -1.085000000000000000e+03 3.647505966185967535e-02 4.535532179073188566e-04 -1.086000000000000000e+03 3.646268467819042264e-02 4.514732532388483267e-04 -1.087000000000000000e+03 3.645030969452116992e-02 4.471991029299272891e-04 -1.088000000000000000e+03 3.643793471085191721e-02 4.358203587333960819e-04 -1.089000000000000000e+03 3.642555972718266449e-02 4.149538629036672718e-04 -1.090000000000000000e+03 3.641318474351341178e-02 4.168680000230486006e-04 -1.091000000000000000e+03 0.000000000000000000e+00 1.000000000000000021e-02 -1.092000000000000000e+03 0.000000000000000000e+00 1.000000000000000021e-02 -1.093000000000000000e+03 0.000000000000000000e+00 1.000000000000000021e-02 -1.094000000000000000e+03 0.000000000000000000e+00 1.000000000000000021e-02 -1.095000000000000000e+03 0.000000000000000000e+00 1.000000000000000021e-02 -1.096000000000000000e+03 0.000000000000000000e+00 1.000000000000000021e-02 -1.097000000000000000e+03 0.000000000000000000e+00 1.000000000000000021e-02 -1.098000000000000000e+03 0.000000000000000000e+00 1.000000000000000021e-02 -1.099000000000000000e+03 0.000000000000000000e+00 1.000000000000000021e-02 +1.001000000000000000e+03 2.626858331583472594e-01 1.000000000000000000e+00 +1.002000000000000000e+03 2.566380882610728720e-01 1.000000000000000000e+00 +1.003000000000000000e+03 2.506406642678879471e-01 1.000000000000000000e+00 +1.004000000000000000e+03 2.445805906376559147e-01 1.000000000000000000e+00 +1.005000000000000000e+03 2.384449151187563454e-01 1.000000000000000000e+00 +1.006000000000000000e+03 2.324181618625841272e-01 1.000000000000000000e+00 +1.007000000000000000e+03 2.263790747128379688e-01 1.000000000000000000e+00 +1.008000000000000000e+03 2.203749307534488555e-01 1.000000000000000000e+00 +1.009000000000000000e+03 2.144023626539646177e-01 1.000000000000000000e+00 +1.010000000000000000e+03 2.085083162517175626e-01 1.000000000000000000e+00 +1.011000000000000000e+03 2.027598266556651652e-01 1.000000000000000000e+00 +1.012000000000000000e+03 1.971316607775393526e-01 1.000000000000000000e+00 +1.013000000000000000e+03 1.915961281823060358e-01 1.000000000000000000e+00 +1.014000000000000000e+03 1.860896486576171516e-01 1.000000000000000000e+00 +1.015000000000000000e+03 1.806084251255839213e-01 1.000000000000000000e+00 +1.016000000000000000e+03 1.751840996217163549e-01 1.000000000000000000e+00 +1.017000000000000000e+03 1.699292533656071025e-01 1.000000000000000000e+00 +1.018000000000000000e+03 1.648253291334529913e-01 1.000000000000000000e+00 +1.019000000000000000e+03 1.599413311535699544e-01 1.000000000000000000e+00 +1.020000000000000000e+03 1.550995389730692731e-01 1.000000000000000000e+00 +1.021000000000000000e+03 1.501884077670336826e-01 1.000000000000000000e+00 +1.022000000000000000e+03 1.451769617188636563e-01 1.000000000000000000e+00 +1.023000000000000000e+03 1.400422500111145885e-01 1.000000000000000000e+00 +1.024000000000000000e+03 1.349361203646674001e-01 1.000000000000000000e+00 +1.025000000000000000e+03 1.299316336185109000e-01 1.000000000000000000e+00 +1.026000000000000000e+03 1.250822021568329667e-01 1.000000000000000000e+00 +1.027000000000000000e+03 1.203902626949029386e-01 1.000000000000000000e+00 +1.028000000000000000e+03 1.158435635843868411e-01 1.000000000000000000e+00 +1.029000000000000000e+03 1.113628634525782590e-01 1.000000000000000000e+00 +1.030000000000000000e+03 1.071331508999577159e-01 1.000000000000000000e+00 +1.031000000000000000e+03 1.030328734580701622e-01 1.000000000000000000e+00 +1.032000000000000000e+03 9.897703059925638813e-02 1.000000000000000000e+00 +1.033000000000000000e+03 9.502098388115687300e-02 1.000000000000000000e+00 +1.034000000000000000e+03 9.121032303002588049e-02 1.000000000000000000e+00 +1.035000000000000000e+03 8.758718231083717498e-02 1.000000000000000000e+00 +1.036000000000000000e+03 8.422038789529767699e-02 1.000000000000000000e+00 +1.037000000000000000e+03 8.114766280502058726e-02 1.000000000000000000e+00 +1.038000000000000000e+03 7.831952673163725120e-02 1.000000000000000000e+00 +1.039000000000000000e+03 7.564386588068071349e-02 1.000000000000000000e+00 +1.040000000000000000e+03 7.292613926279578607e-02 1.000000000000000000e+00 +1.041000000000000000e+03 7.016850977876504247e-02 1.000000000000000000e+00 +1.042000000000000000e+03 6.745740654215512389e-02 1.000000000000000000e+00 +1.043000000000000000e+03 6.495798992699892971e-02 1.000000000000000000e+00 +1.044000000000000000e+03 6.270525431671919447e-02 1.000000000000000000e+00 +1.045000000000000000e+03 6.066431717329990453e-02 1.000000000000000000e+00 +1.046000000000000000e+03 5.894564991770784995e-02 1.000000000000000000e+00 +1.047000000000000000e+03 5.746473567181502318e-02 1.000000000000000000e+00 +1.048000000000000000e+03 5.613709189995956528e-02 1.000000000000000000e+00 +1.049000000000000000e+03 5.498369486041716769e-02 1.000000000000000000e+00 +1.050000000000000000e+03 5.397177732146830192e-02 1.000000000000000000e+00 +1.051000000000000000e+03 5.280612241128356671e-02 1.000000000000000000e+00 +1.052000000000000000e+03 5.169321034488788547e-02 1.000000000000000000e+00 +1.053000000000000000e+03 5.064899427349616595e-02 1.000000000000000000e+00 +1.054000000000000000e+03 4.963468792895304321e-02 1.000000000000000000e+00 +1.055000000000000000e+03 4.874155299496014948e-02 1.000000000000000000e+00 +1.056000000000000000e+03 4.792922545752861807e-02 1.000000000000000000e+00 +1.057000000000000000e+03 4.715536370557339013e-02 1.000000000000000000e+00 +1.058000000000000000e+03 4.636232041424764166e-02 1.000000000000000000e+00 +1.059000000000000000e+03 4.555588605030019833e-02 1.000000000000000000e+00 +1.060000000000000000e+03 4.477065780367314729e-02 1.000000000000000000e+00 +1.061000000000000000e+03 4.402301902457297217e-02 1.000000000000000000e+00 +1.062000000000000000e+03 4.333220388136843626e-02 1.000000000000000000e+00 +1.063000000000000000e+03 4.280785989472904451e-02 1.000000000000000000e+00 +1.064000000000000000e+03 4.236036332700753720e-02 1.000000000000000000e+00 +1.065000000000000000e+03 4.198928768615071971e-02 1.000000000000000000e+00 +1.066000000000000000e+03 4.168687308875029113e-02 1.000000000000000000e+00 +1.067000000000000000e+03 4.128830020406685369e-02 1.000000000000000000e+00 +1.068000000000000000e+03 4.077523432980383750e-02 1.000000000000000000e+00 +1.069000000000000000e+03 4.017064276046052734e-02 1.000000000000000000e+00 +1.070000000000000000e+03 3.938520105824146189e-02 1.000000000000000000e+00 +1.071000000000000000e+03 3.860265371760809860e-02 1.000000000000000000e+00 +1.072000000000000000e+03 3.794444885152389174e-02 1.000000000000000000e+00 +1.073000000000000000e+03 3.745606571401392804e-02 1.000000000000000000e+00 +1.074000000000000000e+03 3.718445982832373209e-02 1.000000000000000000e+00 +1.075000000000000000e+03 3.690507733666610612e-02 1.000000000000000000e+00 +1.076000000000000000e+03 3.648760106433639877e-02 1.000000000000000000e+00 +1.077000000000000000e+03 3.612551329519327059e-02 1.000000000000000000e+00 +1.078000000000000000e+03 3.590296164655401578e-02 1.000000000000000000e+00 +1.079000000000000000e+03 3.596241610115500503e-02 1.000000000000000000e+00 +1.080000000000000000e+03 3.653693458020594587e-02 1.000000000000000000e+00 +1.081000000000000000e+03 3.652455959653668621e-02 1.000000000000000000e+00 +1.082000000000000000e+03 3.651218461286743350e-02 1.000000000000000000e+00 +1.083000000000000000e+03 3.649980962919818078e-02 1.000000000000000000e+00 +1.084000000000000000e+03 3.648743464552892807e-02 1.000000000000000000e+00 +1.085000000000000000e+03 3.647505966185967535e-02 1.000000000000000000e+00 +1.086000000000000000e+03 3.646268467819042264e-02 1.000000000000000000e+00 +1.087000000000000000e+03 3.645030969452116992e-02 1.000000000000000000e+00 +1.088000000000000000e+03 3.643793471085191721e-02 1.000000000000000000e+00 +1.089000000000000000e+03 3.642555972718266449e-02 1.000000000000000000e+00 +1.090000000000000000e+03 3.641318474351341178e-02 1.000000000000000000e+00 +1.091000000000000000e+03 0.000000000000000000e+00 1.000000000000000000e+00 +1.092000000000000000e+03 0.000000000000000000e+00 1.000000000000000000e+00 +1.093000000000000000e+03 0.000000000000000000e+00 1.000000000000000000e+00 +1.094000000000000000e+03 0.000000000000000000e+00 1.000000000000000000e+00 +1.095000000000000000e+03 0.000000000000000000e+00 1.000000000000000000e+00 +1.096000000000000000e+03 0.000000000000000000e+00 1.000000000000000000e+00 +1.097000000000000000e+03 0.000000000000000000e+00 1.000000000000000000e+00 +1.098000000000000000e+03 0.000000000000000000e+00 1.000000000000000000e+00 +1.099000000000000000e+03 0.000000000000000000e+00 1.000000000000000000e+00 diff --git a/spectractor/simulation/image_simulation.py b/spectractor/simulation/image_simulation.py index 8db114bfe..dcdf1f5fd 100644 --- a/spectractor/simulation/image_simulation.py +++ b/spectractor/simulation/image_simulation.py @@ -1,6 +1,6 @@ from spectractor import parameters from spectractor.config import set_logger -from spectractor.tools import (pixel_rotation, set_wcs_file_name, set_sources_file_name, +from spectractor.tools import (rebin, pixel_rotation, set_wcs_file_name, set_sources_file_name, set_gaia_catalog_file_name, load_wcs_from_file, ensure_dir, plot_image_simple, iraf_source_detection) from spectractor.extractor.images import Image, find_target @@ -15,7 +15,8 @@ import astropy.units as units from astropy.coordinates import SkyCoord from astropy.table import Table -from scipy.signal import fftconvolve, gaussian +from scipy.signal import fftconvolve +from scipy.signal.windows import gaussian import matplotlib.pyplot as plt from matplotlib.ticker import MaxNLocator import numpy as np @@ -69,11 +70,10 @@ def __init__(self, centroid_coords, psf, amplitude): self.x0 = centroid_coords[0] self.y0 = centroid_coords[1] self.amplitude = amplitude - # self.target = target self.psf = copy.deepcopy(psf) self.psf.params.values[1] = self.x0 self.psf.params.values[2] = self.y0 - self.psf.params.values[0] = amplitude + self.psf.params.values[0] = self.amplitude # to be realistic, usually fitted fwhm is too big, divide gamma by 2 self.fwhm = self.psf.params.values[3] # self.sigma = self.model.stddev / 2 @@ -123,51 +123,62 @@ def __init__(self, base_image, flux_factor=1): def set_star_list(self): x0, y0 = self.image.target_pixcoords sources_file_name = set_sources_file_name(self.image.file_name) - if os.path.isfile(sources_file_name): + wcs_file_name = set_wcs_file_name(self.image.file_name) + gaia_catalog_file_name = set_gaia_catalog_file_name(self.image.file_name) + if os.path.isfile(wcs_file_name) and os.path.isfile(gaia_catalog_file_name): + # load gaia catalog + gaia_catalog = ascii.read(gaia_catalog_file_name, format="ecsv") + gaia_coord_after_motion = get_gaia_coords_after_proper_motion(gaia_catalog, self.image.date_obs) + # load WCS + wcs = load_wcs_from_file(wcs_file_name) + # catalog matching to set star positions using Gaia + target_coord = wcs.all_pix2world([x0 * parameters.CCD_REBIN], [y0 * parameters.CCD_REBIN], 0) + target_coord = SkyCoord(ra=target_coord[0] * units.deg, dec=target_coord[1] * units.deg, + frame="icrs", obstime=self.image.date_obs, equinox="J2000") + gaia_target_index, dist_2d, dist_3d = target_coord.match_to_catalog_sky(gaia_coord_after_motion) + dx, dy = 0, 0 + for gaia_i in range(len(gaia_catalog)): + x, y = np.array(wcs.all_world2pix(gaia_coord_after_motion[gaia_i].ra, + gaia_coord_after_motion[gaia_i].dec, 0)) / parameters.CCD_REBIN + if gaia_i == gaia_target_index[0]: + dx = x0 - x + dy = y0 - y + A = 10 ** (-gaia_catalog['phot_g_mean_mag'][gaia_i] / 2.5) + self.stars.append(StarModel([x, y], self.image.target_star2D, A)) + self.pixcoords.append([x, y]) + # rescale using target fitted amplitude + amplitudes = np.array([star.amplitude for star in self.stars]) + target_flux = self.image.target_star2D.params.values[0] + amplitudes *= target_flux / self.stars[gaia_target_index[0]].amplitude * self.flux_factor + for k, star in enumerate(self.stars): + star.amplitude = amplitudes[k] + # shift x,y star positions according to target position + star.x0 += dx + star.y0 += dy + star.psf.params.values[1] += dx + star.psf.params.values[2] += dy + star.psf.params.values[0] = amplitudes[k] + elif os.path.isfile(sources_file_name): # load sources positions and flux sources = Table.read(sources_file_name) sources['X'].name = "xcentroid" sources['Y'].name = "ycentroid" sources['FLUX'].name = "flux" - # test presence of WCS and gaia catalog files - wcs_file_name = set_wcs_file_name(self.image.file_name) - gaia_catalog_file_name = set_gaia_catalog_file_name(self.image.file_name) - if os.path.isfile(wcs_file_name) and os.path.isfile(gaia_catalog_file_name): - # load gaia catalog - gaia_catalog = ascii.read(gaia_catalog_file_name, format="ecsv") - gaia_coord_after_motion = get_gaia_coords_after_proper_motion(gaia_catalog, self.image.date_obs) - # load WCS - wcs = load_wcs_from_file(wcs_file_name) - # catalog matching to set star positions using Gaia - sources_coord = wcs.all_pix2world(sources['xcentroid'], sources['ycentroid'], 0) - sources_coord = SkyCoord(ra=sources_coord[0] * units.deg, dec=sources_coord[1] * units.deg, - frame="icrs", obstime=self.image.date_obs, equinox="J2000") - gaia_index, dist_2d, dist_3d = sources_coord.match_to_catalog_sky(gaia_coord_after_motion) - for k, gaia_i in enumerate(gaia_index): - x, y = wcs.all_world2pix(gaia_coord_after_motion[gaia_i].ra, gaia_coord_after_motion[gaia_i].dec, 0) - A = sources['flux'][k] * self.flux_factor - self.stars.append(StarModel([x, y], self.image.target_star2D, A)) - self.pixcoords.append([x, y]) - else: - for k, source in enumerate(sources): - x, y = sources['xcentroid'][k], sources['ycentroid'][k] - A = sources['flux'][k] * self.flux_factor - self.stars.append(StarModel([x, y], self.image.target_star2D, A)) - self.pixcoords.append([x, y]) + for k, source in enumerate(sources): + x, y = np.array([sources['xcentroid'][k], sources['ycentroid'][k]]) / parameters.CCD_REBIN + A = sources['flux'][k] * self.flux_factor + self.stars.append(StarModel([x, y], self.image.target_star2D, A)) + self.pixcoords.append([x, y]) else: + # try extraction using iraf source detection # mask background, faint stars, and saturated pixels data = np.copy(self.image.data) - # self.saturation = 0.99 * parameters.CCD_MAXADU / base_image.expo - # self.saturated_pixels = np.where(image_thresholded > self.saturation) - # image_thresholded[self.saturated_pixels] = 0. - # image_thresholded -= threshold - # image_thresholded[np.where(image_thresholded < 0)] = 0. # mask order0 and spectrum margin = 30 mask = np.zeros(data.shape, dtype=bool) for y in range(int(y0) - 100, int(y0) + 100): - for x in range(parameters.CCD_IMSIZE): - u, v = pixel_rotation(x, y, self.image.disperser.theta(x0, y0) * np.pi / 180., x0, y0) + for x in range(self.image.data.shape[1]): + u, v = pixel_rotation(x, y, self.image.disperser.theta([x0, y0]) * np.pi / 180., x0, y0) if margin > v > -margin: mask[y, x] = True # remove background and detect sources @@ -186,9 +197,9 @@ def model(self, x, y): self.field = self.stars[0].psf.evaluate(np.array([x, y])) for k in range(1, len(self.stars)): left = max(0, int(self.pixcoords[0][k]) - window) - right = min(parameters.CCD_IMSIZE, int(self.pixcoords[0][k]) + window) + right = min(np.max(x), int(self.pixcoords[0][k]) + window) low = max(0, int(self.pixcoords[1][k]) - window) - up = min(parameters.CCD_IMSIZE, int(self.pixcoords[1][k]) + window) + up = min(np.max(y), int(self.pixcoords[1][k]) + window) if up < low or left > right: continue yy, xx = np.mgrid[low:up, left:right] @@ -196,21 +207,8 @@ def model(self, x, y): return self.field def plot_model(self): - xx, yy = np.mgrid[0:parameters.CCD_IMSIZE:1, 0:parameters.CCD_IMSIZE:1] - starfield = self.model(xx, yy) fig, ax = plt.subplots(1, 1) - plot_image_simple(ax, starfield, scale="log10", target_pixcoords=self.pixcoords) - # im = plt.imshow(starfield, origin='lower', cmap='jet') - # ax.grid(color='white', ls='solid') - # ax.grid(True) - # ax.set_xlabel('X [pixels]') - # ax.set_ylabel('Y [pixels]') - # ax.set_title(f'Star field model: fwhm={self.fwhm.value:.2f}') - # cb = plt.colorbar(im, ax=ax) - # cb.formatter.set_powerlimits((0, 0)) - # cb.locator = MaxNLocator(7, prune=None) - # cb.update_ticks() - # cb.set_label('Arbitrary units') # ,fontsize=16) + plot_image_simple(ax, self.field, scale="log10", target_pixcoords=self.pixcoords) if parameters.DISPLAY: plt.show() if parameters.PdfPages: @@ -220,10 +218,12 @@ def plot_model(self): class BackgroundModel: """Class to model the background of the simulated image. - The background model size is set with the parameters.CCD_IMSIZE global keyword. - Attributes ---------- + Nx: int + Size of the background along X axis in pixels. + Ny: int + Size of the background along Y axis in pixels. level: float The mean level of the background in image units. frame: array_like @@ -231,13 +231,15 @@ class BackgroundModel: and the smoothing gaussian width (default: None). """ - def __init__(self, level, frame=None): + def __init__(self, Nx, Ny, level, frame=None): """Create a BackgroundModel instance. - The background model size is set with the parameters.CCD_IMSIZE global keyword. - Parameters ---------- + Nx: int + Size of the background along X axis in pixels. + Ny: int + Size of the background along Y axis in pixels. level: float The mean level of the background in image units. frame: array_like, None @@ -247,17 +249,19 @@ def __init__(self, level, frame=None): Examples -------- >>> from spectractor import parameters - >>> parameters.CCD_IMSIZE = 200 - >>> bgd = BackgroundModel(10) + >>> Nx, Ny = 200, 300 + >>> bgd = BackgroundModel(Nx, Ny, 10) >>> model = bgd.model() >>> np.all(model==10) True >>> model.shape (200, 200) - >>> bgd = BackgroundModel(10, frame=(160, 180, 3)) + >>> bgd = BackgroundModel(Nx, Ny, 10, frame=(160, 180, 3)) >>> bgd.plot_model() """ self.my_logger = set_logger(self.__class__.__name__) + self.Nx = Nx + self.Ny = Ny self.level = level if self.level <= 0: self.my_logger.warning('\n\tBackground level must be strictly positive.') @@ -269,7 +273,6 @@ def model(self): """Compute the background model for the image simulation in image units. A shadowing vignetting frame is roughly simulated if self.frame is set. - The background model size is set with the parameters.CCD_IMSIZE global keyword. Returns ------- @@ -277,7 +280,7 @@ def model(self): The array of the background model. """ - yy, xx = np.mgrid[0:parameters.CCD_IMSIZE:1, 0:parameters.CCD_IMSIZE:1] + xx, yy = np.mgrid[0:self.Ny:1, 0:self.Nx:1] bkgd = self.level * np.ones_like(xx) if self.frame is None: return bkgd @@ -285,9 +288,9 @@ def model(self): xlim, ylim, width = self.frame bkgd[ylim:, :] = self.level / 100 bkgd[:, xlim:] = self.level / 100 - kernel = np.outer(gaussian(parameters.CCD_IMSIZE, width), gaussian(parameters.CCD_IMSIZE, width)) + kernel = np.outer(gaussian(self.Nx, width), gaussian(self.Ny, width)) bkgd = fftconvolve(bkgd, kernel, mode='same') - bkgd *= self.level / bkgd[parameters.CCD_IMSIZE // 2, parameters.CCD_IMSIZE // 2] + bkgd *= self.level / bkgd[self.Ny // 2, self.Nx // 2] return bkgd def plot_model(self): @@ -313,6 +316,108 @@ def plot_model(self): parameters.PdfPages.savefig() +class FlatModel: + """Class to model the pixel flat of the simulated image. Flat is dimensionless and its average must be one. + + Attributes + ---------- + Nx: int + Size of the background along X axis in pixels. + Ny: int + Size of the background along Y axis in pixels. + gains: array_like + The list of gains to apply. The average must be one. + randomness_level: float + Level of random quantum efficiency to apply to pixels (default: 0.). + """ + + def __init__(self, Nx, Ny, gains, randomness_level=0.): + """Create a FlatModel instance. Flat is dimensionless and its average must be one. + + Parameters + ---------- + Nx: int + Size of the background along X axis in pixels. + Ny: int + Size of the background along Y axis in pixels. + gains: array_like + The list of gains to apply. The average must be one. + randomness_level: float + Level of random quantum efficiency to apply to pixels (default: 0.). + + Examples + -------- + >>> from spectractor import parameters + >>> Nx, Ny = 200, 300 + >>> flat = FlatModel(Nx, Ny, gains=[[1, 2, 3, 4], [4, 3, 2, 1]]) + >>> model = flat.model() + >>> print(f"{np.mean(model):.4f}") + 1.0000 + >>> model.shape + (200, 200) + >>> flat.plot_model() + """ + self.my_logger = set_logger(self.__class__.__name__) + self.Nx = Nx + self.Ny = Ny + self.gains = np.atleast_2d(gains).astype(float) + if len(self.gains) <= 0: + raise ValueError(f"Gains list is empty") + if np.any(self.gains <= 0): + raise ValueError(f"One the gain values is negative. Got {self.gains}.") + if np.mean(self.gains) != 1.: + self.my_logger.warning(f"\n\tGains list average is not one but {np.mean(self.gains)}. " + "I scaled them to have an average of one.") + self.gains /= np.mean(self.gains) + self.my_logger.warning(f'\n\tRelative gains are set to {self.gains}.') + self.randomness_level = randomness_level + + def model(self): + """Compute the flat model for the image simulation (no units). + + Returns + ------- + flat: array_like + The array of the flat model. + """ + yy, xx = np.mgrid[0:self.Nx:1, 0:self.Ny:1] + flat = np.ones_like(xx, dtype=float) + hflats = np.array_split(flat, self.gains.shape[0]) + for h in range(self.gains.shape[0]): + vflats = np.array_split(hflats[h].T, self.gains.shape[1]) + for v in range(self.gains.shape[1]): + vflats[v] *= self.gains[h,v] + hflats[h] = np.concatenate(vflats).T + flat = np.concatenate(hflats).T + if self.randomness_level != 0: + flat += np.random.uniform(-self.randomness_level, self.randomness_level, size=flat.shape) + + return flat + + def plot_model(self): + """Plot the flat model. + + """ + flat = self.model() + fig, ax = plt.subplots(1, 1) + im = plt.imshow(flat, origin='lower', cmap='jet') + ax.grid(color='white', ls='solid') + ax.grid(True) + ax.set_xlabel('X [pixels]') + ax.set_ylabel('Y [pixels]') + ax.set_title('Flat model') + cb = plt.colorbar(im, ax=ax) + cb.formatter.set_powerlimits((0, 0)) + cb.locator = MaxNLocator(7, prune=None) + cb.update_ticks() + cb.set_label('Dimensionless') # ,fontsize=16) + if parameters.DISPLAY: + plt.show() + if parameters.PdfPages: + parameters.PdfPages.savefig() + + + class ImageModel(Image): def __init__(self, filename, target_label=None): @@ -321,17 +426,27 @@ def __init__(self, filename, target_label=None): self.true_lambdas = None self.true_spectrum = None - def compute(self, star, background, spectrogram, starfield=None): + def compute(self, star, background, spectrogram, starfield=None, flat=None): yy, xx = np.mgrid[0:parameters.CCD_IMSIZE:1, 0:parameters.CCD_IMSIZE:1] - self.data = star.psf.evaluate(np.array([xx, yy])) + background.model() + if starfield is not None: + starfield_mod = starfield.model(xx, yy) + self.data = starfield_mod + self.starfield = np.copy(starfield_mod) + if parameters.DEBUG: + self.plot_image(scale='symlog', target_pixcoords=starfield.pixcoords) + starfield.plot_model() + else: + self.data = star.psf.evaluate(np.array([xx, yy])) + self.data += background.model() if spectrogram.full_image: - self.data[spectrogram.spectrogram_ymin:spectrogram.spectrogram_ymax, :] += spectrogram.spectrogram + self.data[spectrogram.spectrogram_ymin:spectrogram.spectrogram_ymax, :] += spectrogram.spectrogram_data else: self.data[spectrogram.spectrogram_ymin:spectrogram.spectrogram_ymax, - spectrogram.spectrogram_xmin:spectrogram.spectrogram_xmax] += spectrogram.spectrogram - # - spectrogram.spectrogram_bgd) - if starfield is not None: - self.data += starfield.model(xx, yy) + spectrogram.spectrogram_xmin:spectrogram.spectrogram_xmax] += spectrogram.spectrogram_data + if flat is not None: + flat_mod = flat.model() + self.data *= flat_mod + self.flat = flat_mod def add_poisson_and_read_out_noise(self): # pragma: no cover if self.units != 'ADU': @@ -366,8 +481,8 @@ def load_image(self, filename): # self.true_lambdas, self.true_spectrum = hdu_list[1].data -def ImageSim(image_filename, spectrum_filename, outputdir, pwv=5, ozone=300, aerosols=0.03, A1=1, A2=1, A3=1, angstrom_exponent=None, - psf_poly_params=None, psf_type=None, diffraction_orders=None, with_rotation=True, with_stars=True, with_adr=True, with_noise=True): +def ImageSim(image_filename, spectrum_filename, output_filename, pwv=5, ozone=300, aerosols=0.03, A1=1, A2=1, A3=1, angstrom_exponent=None, + psf_poly_params=None, psf_type=None, diffraction_orders=None, with_rotation=True, with_starfield=True, with_adr=True, with_noise=True, with_flat=True): """ The basic use of the extractor consists first to define: - the path to the fits image from which to extract the image, - the path of the output directory to save the extracted spectrum (created automatically if does not exist yet), @@ -382,17 +497,25 @@ def ImageSim(image_filename, spectrum_filename, outputdir, pwv=5, ozone=300, aer - with_rotation: rotate the spectrum according to the disperser characteristics (True by default) - with_stars: include stars in the image field (True by default) - with_adr: include ADR effect (True by default) + - with_flat: include flat (True by default) """ my_logger = set_logger(__name__) my_logger.info(f'\n\tStart IMAGE SIMULATOR') # Load reduced image spectrum = Spectrum(spectrum_filename) + parameters.CALLING_CODE = "" if diffraction_orders is None: diffraction_orders = np.arange(spectrum.order, spectrum.order + 3 * np.sign(spectrum.order), np.sign(spectrum.order)) image = ImageModel(image_filename, target_label=spectrum.target.label) guess = np.array([spectrum.header['TARGETX'], spectrum.header['TARGETY']]) - if "CCDREBIN" in spectrum.header: - guess *= spectrum.header["CCDREBIN"] + if parameters.CCD_REBIN != 1: + # these lines allow to simulate images using rebinned spectrum files + guess *= parameters.CCD_REBIN + new_shape = np.asarray((parameters.CCD_IMSIZE, parameters.CCD_IMSIZE)) + old_edge = parameters.CCD_IMSIZE * parameters.CCD_REBIN + image.gain = rebin(image.gain[:old_edge, :old_edge], new_shape, FLAG_MAKESUM=False) + image.read_out_noise = rebin(image.read_out_noise[:old_edge, :old_edge], new_shape, FLAG_MAKESUM=False) + if parameters.DEBUG: image.plot_image(scale='symlog', target_pixcoords=guess) # Fit the star 2D profile @@ -401,25 +524,31 @@ def ImageSim(image_filename, spectrum_filename, outputdir, pwv=5, ozone=300, aer # Background model my_logger.info('\n\tBackground model...') bgd_level = float(np.mean(spectrum.spectrogram_bgd)) - background = BackgroundModel(level=bgd_level, frame=None) # (1600, 1650, 100)) + background = BackgroundModel(parameters.CCD_IMSIZE, parameters.CCD_IMSIZE, level=bgd_level, frame=None) if parameters.DEBUG: background.plot_model() # Target model my_logger.info('\n\tStar model...') - # Spectrogram is simulated with spectrum.x0 target position: must be this position to simualte the target. - star = StarModel(image.target_pixcoords, image.target_star2D, image.target_star2D.params.values[0]) + # Spectrogram is simulated with spectrum.x0 target position: must be this position to simulate the target. + star = StarModel(np.array(image.target_pixcoords) / parameters.CCD_REBIN, image.target_star2D, image.target_star2D.params.values[0]) # reso = star.fwhm if parameters.DEBUG: star.plot_model() + # Star field model starfield = None - if with_stars: + if with_starfield: my_logger.info('\n\tStar field model...') - starfield = StarFieldModel(image) + starfield = StarFieldModel(image, flux_factor=1) + + # Flat model + flat = None + if with_flat: + my_logger.info('\n\tFlat model...') + flat = FlatModel(parameters.CCD_IMSIZE, parameters.CCD_IMSIZE, gains=[[1, 2, 3, 4], [4, 3, 2, 1]], randomness_level=1e-2) if parameters.DEBUG: - image.plot_image(scale='symlog', target_pixcoords=starfield.pixcoords) - starfield.plot_model() + flat.plot_model() # Spectrum model my_logger.info('\n\tSpectrum model...') @@ -455,14 +584,14 @@ def ImageSim(image_filename, spectrum_filename, outputdir, pwv=5, ozone=300, aer # Simulate spectrogram atmosphere = Atmosphere(airmass, pressure, temperature) - spectrogram = SpectrogramModel(spectrum, atmosphere=atmosphere, with_background=False, fast_sim=False, - full_image=True, with_adr=with_adr, diffraction_orders=diffraction_orders) + spectrogram = SpectrogramModel(spectrum, atmosphere=atmosphere, fast_sim=False, full_image=True, + with_adr=with_adr, diffraction_orders=diffraction_orders) spectrogram.simulate(A1, A2, A3, aerosols, angstrom_exponent, ozone, pwv, - spectrum.disperser.D, 0, 0, rotation_angle, 1, psf_poly_params) + spectrum.disperser.D, 0, 0, rotation_angle, psf_poly_params) # Image model my_logger.info('\n\tImage model...') - image.compute(star, background, spectrogram, starfield=starfield) + image.compute(star, background, spectrogram, starfield=starfield, flat=flat) # Recover true spectrum spectrogram.set_true_spectrum(spectrogram.lambdas, aerosols, ozone, pwv, shift_t=0) @@ -470,11 +599,11 @@ def ImageSim(image_filename, spectrum_filename, outputdir, pwv=5, ozone=300, aer true_spectrum = np.copy(spectrogram.true_spectrum) # Saturation effects - saturated_pixels = np.where(spectrogram.spectrogram > image.saturation)[0] + saturated_pixels = np.where(spectrogram.spectrogram_data > image.saturation)[0] if len(saturated_pixels) > 0: my_logger.warning(f"\n\t{len(saturated_pixels)} saturated pixels detected above saturation " f"level at {image.saturation} ADU/s in the spectrogram." - f"\n\tSpectrogram maximum is at {np.max(spectrogram.spectrogram)} ADU/s.") + f"\n\tSpectrogram maximum is at {np.max(spectrogram.spectrogram_data)} ADU/s.") image.data[image.data > image.saturation] = image.saturation # Convert data from ADU/s in ADU @@ -486,6 +615,8 @@ def ImageSim(image_filename, spectrum_filename, outputdir, pwv=5, ozone=300, aer # Round float ADU into closest integers # image.data = np.around(image.data) + if parameters.OBS_NAME == "AUXTEL": + image.data = image.data.T[::-1, ::-1] # Plot if parameters.VERBOSE and parameters.DISPLAY: # pragma: no cover @@ -493,12 +624,6 @@ def ImageSim(image_filename, spectrum_filename, outputdir, pwv=5, ozone=300, aer image.plot_image(scale="symlog", title="Image simulation", target_pixcoords=target_pixcoords, units=image.units) image.convert_to_ADU_units() - # Set output path - ensure_dir(outputdir) - output_filename = image_filename.split('/')[-1] - output_filename = (output_filename.replace('reduc', 'sim')).replace('trim', 'sim') - output_filename = os.path.join(outputdir, output_filename) - # Save images and parameters image.header['A1_T'] = A1 image.header['A2_T'] = A2 @@ -511,16 +636,16 @@ def ImageSim(image_filename, spectrum_filename, outputdir, pwv=5, ozone=300, aer image.header['VAOD_T'] = aerosols image.header['ROT_T'] = rotation_angle image.header['ROTATION'] = int(with_rotation) - image.header['STARS'] = int(with_stars) + image.header['STARS'] = int(with_starfield) image.header['BKGD_LEV'] = background.level image.header['PSF_DEG'] = spectrogram.chromatic_psf.deg image.header['PSF_TYPE'] = parameters.PSF_TYPE psf_poly_params_truth = np.array(psf_poly_params) if psf_poly_params_truth.size > spectrum.spectrogram_Nx: psf_poly_params_truth = psf_poly_params_truth[spectrum.spectrogram_Nx:] - image.header['LBDAS_T'] = np.array_str(true_lambdas, max_line_width=1000000, precision=2) - image.header['AMPLIS_T'] = np.array_str(true_spectrum, max_line_width=1000000, precision=2) - image.header['PSF_P_T'] = np.array_str(psf_poly_params_truth, max_line_width=1000000, precision=4) + image.header['LBDAS_T'] = str(np.round(true_lambdas, decimals=2).tolist()) + image.header['AMPLIS_T'] = str(true_spectrum.tolist()) + image.header['PSF_P_T'] = str(psf_poly_params_truth.tolist()) image.save_image(output_filename, overwrite=True) return image diff --git a/spectractor/simulation/simulator.py b/spectractor/simulation/simulator.py index c7a9b4a3f..4a1c718cd 100644 --- a/spectractor/simulation/simulator.py +++ b/spectractor/simulation/simulator.py @@ -100,7 +100,7 @@ def simulate_without_atmosphere(self, lambdas): return self.data, self.err def simulate(self, A1=1.0, A2=0., aerosols=0.05, angstrom_exponent=None, ozone=300, pwv=5, reso=0., - D=parameters.DISTANCE2CCD, shift_x=0., B=0.): + D=parameters.DISTANCE2CCD, shift_x=0.): """Simulate the cross spectrum of an object and its uncertainties after its transmission throught the instrument and the atmosphere. @@ -125,8 +125,6 @@ def simulate(self, A1=1.0, A2=0., aerosols=0.05, angstrom_exponent=None, ozone=3 Distance between the CCD and the disperser in mm (default: parameters.DISTANCE2CCD) shift_x: float Shift in pixels of the order 0 position estimate (default: 0). - B: float - Amplitude level for the background (default: 0). Returns ------- @@ -143,7 +141,7 @@ def simulate(self, A1=1.0, A2=0., aerosols=0.05, angstrom_exponent=None, ozone=3 >>> atmosphere = AtmosphereGrid(atmgrid_filename="./tests/data/reduc_20170530_134_atmsim.fits") >>> sim = SpectrumSimulation(spectrum, atmosphere=atmosphere, fast_sim=True) >>> lambdas, model, model_err = sim.simulate(A1=1, A2=1, ozone=300, pwv=5, aerosols=0.05, reso=0., - ... D=parameters.DISTANCE2CCD, shift_x=0., B=0.) + ... D=parameters.DISTANCE2CCD, shift_x=0.) >>> sim.plot_spectrum() .. doctest:: @@ -205,8 +203,6 @@ def integrand(lbda): self.data = (sim_conv(lambdas) + A2 * spectrum_order2) / lambdas self.data_order2 = A2 * spectrum_order2 / lambdas self.err = (err_conv(lambdas) + A2 * err_order2) / lambdas - if B != 0: - self.data += B / (lambdas * np.gradient(lambdas)) if np.any(self.err <= 0) and not np.all(self.err<=0): min_positive = np.min(self.err[self.err > 0]) self.err[np.isclose(self.err, 0., atol=0.01 * min_positive)] = min_positive @@ -226,7 +222,7 @@ def integrand(lbda): class SpectrogramModel(Spectrum): def __init__(self, spectrum, target=None, disperser=None, throughput=None, atmosphere=None, diffraction_orders=None, - with_background=True, fast_sim=True, full_image=False, with_adr=True): + fast_sim=True, full_image=False, with_adr=True): """Class to simulate a spectrogram. Parameters @@ -243,8 +239,6 @@ def __init__(self, spectrum, target=None, disperser=None, throughput=None, atmos Atmosphere or AtmosphereGrid instance to make the atmospheric simulation (default: None). diffraction_orders: array_like, optional List of diffraction orders to simulate. If None, takes first three (default: None). - with_background: bool, optional - If True, add the background model to the simulated spectrogram (default: True). fast_sim: bool, optional If True, perform a fast simulation of the spectrum without integrated the spectrum in pixel bins (default: True). @@ -258,7 +252,7 @@ def __init__(self, spectrum, target=None, disperser=None, throughput=None, atmos -------- >>> spectrum = Spectrum("./tests/data/reduc_20170530_134_spectrum.fits") >>> atmosphere = Atmosphere(airmass=1.2, pressure=800, temperature=10) - >>> sim = SpectrogramModel(spectrum, atmosphere=atmosphere, with_background=True, fast_sim=True) + >>> sim = SpectrogramModel(spectrum, atmosphere=atmosphere, fast_sim=True) """ Spectrum.__init__(self) if diffraction_orders is None: @@ -321,7 +315,6 @@ def __init__(self, spectrum, target=None, disperser=None, throughput=None, atmos self.fix_atm_sim = False self.atmosphere_sim = None self.fast_sim = fast_sim - self.with_background = with_background self.full_image = full_image self.with_adr = with_adr if self.full_image: @@ -395,7 +388,7 @@ def integrand(lbda): return spectrum, spectrum_err def simulate(self, A1=1.0, A2=0., A3=0., aerosols=0.05, angstrom_exponent=None, ozone=300, pwv=5, - D=parameters.DISTANCE2CCD, shift_x=0., shift_y=0., angle=0., B=1., psf_poly_params=None): + D=parameters.DISTANCE2CCD, shift_x=0., shift_y=0., angle=0., psf_poly_params=None): """ Parameters @@ -423,8 +416,6 @@ def simulate(self, A1=1.0, A2=0., A3=0., aerosols=0.05, angstrom_exponent=None, Shift in pixels along y axis of the order 0 position estimate (default: 0). angle: float Angle of the dispersion axis in degree (default: 0). - B: float - Amplitude level for the background (default: 0). psf_poly_params: array_like Polynomial parameters describing the PSF dependence in wavelength (default: None). @@ -443,7 +434,7 @@ def simulate(self, A1=1.0, A2=0., A3=0., aerosols=0.05, angstrom_exponent=None, >>> spec.disperser.ratio_ratio_order_3over2 = lambda lbda: 0.1 >>> psf_poly_params = list(spec.chromatic_psf.from_table_to_poly_params()) * 3 >>> atmosphere = Atmosphere(airmass=1.2, pressure=800, temperature=10) - >>> sim = SpectrogramModel(spec, atmosphere=atmosphere, with_background=True, fast_sim=True) + >>> sim = SpectrogramModel(spec, atmosphere=atmosphere, fast_sim=True) >>> lambdas, model, model_err = sim.simulate(A2=1, angle=-1.5, psf_poly_params=psf_poly_params) >>> sim.plot_spectrogram() @@ -522,11 +513,9 @@ def simulate(self, A1=1.0, A2=0., A3=0., aerosols=0.05, angstrom_exponent=None, self.profile_params[order][:, 0] = spec # self.spectrogram is in ADU/s units here - self.spectrogram = A1 * ima + self.spectrogram_data = A1 * ima self.spectrogram_err = A1 * np.sqrt(ima_err2) - if self.with_background: - self.spectrogram += B * self.spectrogram_bgd # Save the simulation parameters self.psf_poly_params = np.copy(poly_params[0]) self.header['OZONE_T'] = ozone @@ -540,7 +529,7 @@ def simulate(self, A1=1.0, A2=0., A3=0., aerosols=0.05, angstrom_exponent=None, self.header['Y0_T'] = shift_y self.header['ROTANGLE'] = angle - return self.lambdas, self.spectrogram, self.spectrogram_err + return self.lambdas, self.spectrogram_data, self.spectrogram_err if __name__ == "__main__": diff --git a/spectractor/tools.py b/spectractor/tools.py index d3b89ccb8..65ff7f8d7 100644 --- a/spectractor/tools.py +++ b/spectractor/tools.py @@ -1,4 +1,5 @@ import os +import copy import shutil from photutils.detection import IRAFStarFinder from scipy.optimize import curve_fit @@ -8,6 +9,7 @@ from astropy.io import fits from astropy import wcs as WCS +from matplotlib import cm import matplotlib.pyplot as plt import matplotlib.colors from matplotlib.ticker import MaxNLocator @@ -270,7 +272,7 @@ def rescale_x_from_legendre(x_norm, Xmin, Xmax): Parameters ---------- - x: np.ndarray + x_norm: np.ndarray Xmin: float Xmax: float @@ -1456,7 +1458,7 @@ def hessian_and_theta(data, margin_cut=1): # compute hessian matrices on the image order = "xy" if _SCIKIT_IMAGE_NEW_HESSIAN else "rc" - Hxx, Hxy, Hyy = hessian_matrix(data, sigma=3, order=order) + Hxx, Hxy, Hyy = hessian_matrix(data, sigma=3, order=order, use_gaussian_derivatives=False) lambda_plus = 0.5 * ((Hxx + Hyy) + np.sqrt((Hxx - Hyy) ** 2 + 4 * Hxy * Hxy)) lambda_minus = 0.5 * ((Hxx + Hyy) - np.sqrt((Hxx - Hyy) ** 2 + 4 * Hxy * Hxy)) theta = 0.5 * np.arctan2(2 * Hxy, Hxx - Hyy) * 180 / np.pi @@ -1519,6 +1521,54 @@ def fftconvolve_gaussian(array, reso): return array +def mask_cosmics(data, maxiter=3, sigma_clip=5, border_mode='mirror', convolve_kernel_size=3): + """Simple method to mask cosmic rays, inspired from L.A. Cosmic algorithm. + + Parameters + ---------- + data + maxiter + border_mode + + Returns + ------- + mask: np.ndarray + + Examples + -------- + >>> data = np.zeros((50, 100)) + >>> data[20, 50:60] = 1 + >>> cr_mask = mask_cosmics(data, maxiter=3, convolve_kernel_size=0) + >>> fig = plt.figure() + >>> _ = plt.imshow(cr_mask, cmap='gray', aspect='auto', origin='lower') + >>> plt.show() + >>> assert np.sum(data) == np.sum(cr_mask) + + """ + from astropy.nddata import block_reduce, block_replicate + from scipy import ndimage + block_size = 2.0 + kernel = np.array([[0.0, -1.0, 0.0], [-1.0, 4.0, -1.0], [0.0, -1.0, 0.0]]) + + clean_data = data.copy() + final_crmask = np.zeros(data.shape, dtype=bool) + + for iteration in range(maxiter): + sampled_img = block_replicate(clean_data, block_size) + convolved_img = ndimage.convolve(sampled_img, kernel, + mode=border_mode) #.clip(min=0.0) + laplacian_img = block_reduce(convolved_img, block_size) + + final_crmask[laplacian_img > 5*np.nanstd(laplacian_img)] = True + clean_data[final_crmask] = np.nan + + if convolve_kernel_size > 0: + final_crmask = fftconvolve(final_crmask, + np.ones((convolve_kernel_size, convolve_kernel_size), dtype=int), + mode='same').astype(int) + return final_crmask.astype(bool) + + def formatting_numbers(value, error_high, error_low, std=None, label=None): """Format a physical value and its uncertainties. Round the uncertainties to the first significant digit, and do the same for the physical value. @@ -1726,7 +1776,7 @@ def clean_target_spikes(data, saturation): # pragma: no cover return data -def plot_image_simple(ax, data, scale="lin", title="", units="Image units", cmap=None, +def plot_image_simple(ax, data, scale="lin", title="", units="Image units", cmap=None, mask=None, target_pixcoords=None, vmin=None, vmax=None, aspect=None, cax=None): """Simple function to plot a spectrum with error bars and labels. @@ -1744,6 +1794,8 @@ def plot_image_simple(ax, data, scale="lin", title="", units="Image units", cmap Units of the image to be written in the color bar label (default: "Image units") cmap: colormap Color map label (default: None) + mask: array_like + Mask array (default: None) target_pixcoords: array_like, optional 2D array giving the (x,y) coordinates of the targets on the image: add a scatter plot (default: None) vmin: float @@ -1771,6 +1823,18 @@ def plot_image_simple(ax, data, scale="lin", title="", units="Image units", cmap ... title="tests/data/reduc_20170605_028.fits") >>> if parameters.DISPLAY: plt.show() """ + if cmap is not None and isinstance(cmap, str): + colormap = copy.copy(cm.get_cmap(cmap)) + elif isinstance(cmap, matplotlib.colors.Colormap): + colormap = cmap + else: + colormap = copy.copy(cm.get_cmap('viridis')) + cmap_nan = copy.copy(colormap) + cmap_nan.set_bad(color='lightgrey') + + data = np.copy(data) + if mask is not None: + data[mask] = np.nan if scale == "log" or scale == "log10": # removes the zeros and negative pixels first zeros = np.where(data <= 0) @@ -1784,7 +1848,7 @@ def plot_image_simple(ax, data, scale="lin", title="", units="Image units", cmap norm = matplotlib.colors.SymLogNorm(vmin=vmin, vmax=vmax, linthresh=10, base=10) else: norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax) - im = ax.imshow(data, origin='lower', cmap=cmap, norm=norm, aspect=aspect) + im = ax.imshow(data, origin='lower', cmap=cmap, norm=norm, aspect=aspect, interpolation="none") ax.grid(color='silver', ls='solid') ax.grid(True) ax.set_xlabel(parameters.PLOT_XLABEL) @@ -1800,7 +1864,7 @@ def plot_image_simple(ax, data, scale="lin", title="", units="Image units", cmap if title != "": ax.set_title(title) if target_pixcoords is not None: - ax.scatter(target_pixcoords[0], target_pixcoords[1], marker='o', s=100, edgecolors='k', facecolors='none', + ax.scatter(target_pixcoords[0], target_pixcoords[1], marker='o', s=100, edgecolors='r', facecolors='none', label='Target', linewidth=2) diff --git a/tests/data/cache/astropy/download/url/2c303169e6bbbb2b9c683391733d2931/contents b/tests/data/cache/astropy/download/url/2c303169e6bbbb2b9c683391733d2931/contents new file mode 100644 index 000000000..04468f14b --- /dev/null +++ b/tests/data/cache/astropy/download/url/2c303169e6bbbb2b9c683391733d2931/contents @@ -0,0 +1,401 @@ +SIMPLE = T / BITPIX = 16 / NAXIS = 0 / EXTEND = T /FITS extensions present? TARGETID= 'HD111980' / DBTABLE = 'CRSPECTRUM' / MAPKEY = 'calspec ' / AIRMASS = 0.00000 /Mean airmass of the observation DESCRIP = 'Standard star flux with an HST/STIS calibration------' / SOURCE = 'Flux scale of Bohlin, et al.2020, AJ, 160, 21' / USEAFTER= 'Jan 01 2000 00:00:00' / COMMENT = 'HST Flux scale is based on TMAP AND TLUSTY WD NLTE MODELS' / COMMENT Model Normalized to obs. by 2.48727e-18 at 6800.0-7700.0 Ang PEDIGREE= 'INFLIGHT 1997 to 2022' / HISTORY FILE WRITTEN BY stismrg.PRO ON 27-Jan-2023 16:01:53.00 HISTORY FILE WRITTEN BY STISREDUCE.PRO ON 27-Jan-2023 16:01:53.00 HISTORY coadd lst for G230LB from dir=dat/: HISTORY oc3i04010 HISTORY EPOCH: 2012.336:03:46:21-2012.336:03:46:21 HISTORY gwidth for G230LB flux cal=11 HISTORY Sensitivity file: /Users/bohlin/stisidl/scal/sens11_g230lb.fits HISTORY SYS-ERROR is the broadband ~1% SYSTEMATIC UNCERTAINTY of STIS fluxes. HISTORY Bohlin(2014,PASP,126,711). BOTH THE STAT-ERR AND SYS-ERR ARE 1-SIGMA.HISTORY Net & Flux corr for time(2019,AJ,158,211)&CTE loss(2022, CTE update, in HISTORY coadd lst for G430L from dir=dat/: HISTORY oc3i04020 oc3i04030 HISTORY EPOCH: 2012.336:04:10:41-2012.336:05:11:53 HISTORY gwidth for G430L flux cal=11 HISTORY Net and Flux corr for time(2019,AJ,158,211)&CTE loss(2022, CTE update, iHISTORY MERGE POINT = 3065.0 HISTORY coadd lst for G750L from dir=dat/: HISTORY oc3i04040 HISTORY EPOCH: 2012.336:05:15:07-2012.336:05:15:07 HISTORY gwidth for G750L flux cal=11 HISTORY MERGE POINT = 5450.0 HISTORY HISTORY HISTORY HISTORY Units: Angstroms(A) and erg s-1 cm-2 A-1 HISTORY Written by MAKE_STIS_CALSPEC.pro 16-Feb-2023 HISTORY Sources for this spectrum: HISTORY ---------------- ---------------------- ---------- HISTORY WAVELENGTH RANGE SOURCE FILE HISTORY ---------------- ---------------------- ---------- HISTORY 1710 10120 STIS hd111980.mrg HISTORY 10120 318789 Bohlin et al. 2017 BOSZ2022 R=500 Model HISTORY Model Normalized to Observed Flux at 6800-7700A HISTORY Method:Bohlin, et al. 2017, AJ, 153, 234 HISTORY Model with Teff,log g,log z,E(B-V)= 5860 3.40 -1.21 0.008 HISTORY BOSZ2022 model with good sampling in the IR HISTORY All wavelengths are in vacuum w/ model adjusted for radial vel= 155.0 HISTORY CHANGES from previous version: HISTORY Revised BOSZ2022 models & Gordon extinction HISTORY For details see: HISTORY http://www.stsci.edu/hst/instrumentation/reference- HISTORY data-for-calibration-and-tools/astronomical- HISTORY catalogs/calspec FILENAME= 'hd111980_stis_006.fits' / WMIN = 1710.76721200 /Minimum Wavelength WMAX = 318789.625000 /Maximum Wavelength END XTENSION= 'BINTABLE' /Written by IDL: Thu Feb 16 16:36:49 2023 BITPIX = 8 / NAXIS = 2 /Binary table NAXIS1 = 30 /Number of bytes per row NAXIS2 = 6815 /Number of rows PCOUNT = 0 /Random parameter count GCOUNT = 1 /Group count TFIELDS = 7 /Number of columns EXTNAME = 'SCI ' / EXTVER = 1 / INHERIT = T / TFORM1 = '1D ' /Real*8 (double precision) TTYPE1 = 'WAVELENGTH' /Label for column 1 TUNIT1 = 'ANGSTROMS' /Units of column 1 TDISP1 = 'G10.4 ' /Display format for column 1 TFORM2 = '1E ' /Real*4 (floating point) TTYPE2 = 'FLUX ' /Absolutely calibrated net spectrum TUNIT2 = 'FLAM ' /Units of column 2 TDISP2 = 'E12.4 ' /Display format for column 2 TFORM3 = '1E ' /Real*4 (floating point) TTYPE3 = 'STATERROR' /Statistical flux error TUNIT3 = 'FLAM ' /Units of column 3 TDISP3 = 'E12.4 ' /Display format for column 3 TFORM4 = '1E ' /Real*4 (floating point) TTYPE4 = 'SYSERROR' /Systematic flux error=0.01*FLAM TUNIT4 = 'FLAM ' /Units of column 4 TDISP4 = 'E12.4 ' /Display format for column 4 TFORM5 = '1E ' /Real*4 (floating point) TTYPE5 = 'FWHM ' /FWHM spectral resolution TUNIT5 = 'ANGSTROMS' /Units of column 5 TDISP5 = 'G6.2 ' /Display format for column 5 TFORM6 = '1I ' /Integer*2 (short integer) TTYPE6 = 'DATAQUAL' /Data quality: 1=good, 0=bad TUNIT6 = 'NONE ' /Units of column 6 TDISP6 = 'I2 ' /Display format for column 6 TFORM7 = '1E ' /Real*4 (floating point) TTYPE7 = 'TOTEXP ' /Total exposure time TUNIT7 = 'SEC ' /Units of column 7 TDISP7 = 'G10.2 ' /Display format for column 7 END @e(ͷ&'Z%j@/}D@CR(L':%i@/}D@ l(&'%pr@/}D@˅_mY(׆6'%@/|D@@F(ө'%vg@/}D@}?_('`%;@/}D@L(QO.'#%<@/~D@u D(' +%R + @/D@ <(ϋ(&%f(`@/D@mOU(ݖ'J%a@/D@L(';%@/D@e D(iO'd%9(@/D@@F))(%%H@/D@]?_('%YA@/D@_a(v'%M1@/D@ U_mY)P'i%@/D@р +|[({O'3%JF@/D@M](~b'S%"@/D@ɿ~)t'%@/D@#E덂(v{'~%Ƶ@/D@((&'q%d&@/D@.> (Ά'|%F'@/D@3` (lr'j%da@/D@96('u\%I@/D@>h(֦'y%`Y@/D@D.( 'v%r@/D@I?(e'tT% @/D@O'Q(~,'>.%vd@/D@T(.r'hx%]@/D@Z (K='m8%{A@/D@_@W (l'm%-@/D@e #('_%9=j@/D@jM/(ˤ'b%T@/D@p@F(~'kk\% P@/D@uCR('f%@/D@{ i(h'%ؕ@/D@@ (CJ'{%h@/D@(..'\@Q%@/D@~('vތ%O@/D@_B) h'[Y%"@/D@w*(b'%7@/D@?(ޙ'k7%[C@/D@p>(.'N|%@/D@OU(/'OX%(@/D@i6v('Z%@/D@(}'_%{@/D@b('Nlc%F2@/D@ !(q'Na%{@/D@[)'Kf%=`@/D@ )B'H%Et@/D@T%('D[a%}@/D@@F)'Ep%5@/D@M q('JZ&%@/D@` (D'R%@/D@G1)R'@%~@/D@ß`) r'KFD%6@/D@@?(G<': %@/D@@)'%t9@/D@9l) 0'gO%$@/D@(':Z%I@/D@2('h`%@/D@ (w'>*%@/D@,@W ('?y%k@/D@8(OS'88%֜@/D@%m)'E%@/D@_t)'iQ%ɼ@/D@% !) !O'3.%@/D@*~)&'72%;@/D@0 #) p'-)_%v@/D@5_mY) +S'5A%W@/D@;?,(<',%@/D@@(g'4X%0@/D@F ~({',Fz%1@/D@K #) +p''%4<@/D@Qc(g5'Q˲%t@/D@V_t)'#%c@/D@[@O(r'%%h8@/D@a| )'-%@/D@fB(„' [%h@/D@lu덂)F'Р%B@/D@qh(ſ'J_%@/D@wo')n +'n%@/D@|/+)''%H@/D@il) '%%p@/D@(?~'^A%p@/D@c)'6%@/D@ ))Y'7P%@/D@]CR)v'U%oM@/D@ڀJ)'(%ǵ@/D@WQ)2S'r%Ab@/D@Ԁu)0'6%H@/D@Q +|[)B'Ot-%Ƽ@/D@Ο˰)'%$@/D@K)#!'HL%=@/D@>-) r'%@/D@EEx(Շ' %{%i@/D@(&'>%@/D@@)y' %@/D@ԽOU(t'N%@/D@:@(YG'B%v4@/D@߷_ (b'\j%e?6@/D@4u(d'x%}G@/D@걠e('<%cr@/D@.[(᱂'+8%q@/D@(!C' %I@/D@)?^W) '%^@/D@`Ɋ)@A'%@/D@#`))' +A%xF@/D@ H)Ȏ' r%>&@/D@ )W'Nz%@/D@_B) ];'%D"@/D@ #)F' , %s@/D@!덂)2'}j%?@/D@' @)"I' 0$%ϺF@/D@,_)9;' mm%+@/D@2 g)]' ɩ& J@/D@7j)kA)'.&@/D@=`f)h,'>&@/D@Bm)b'T&@/D@H)NP}'p& +@/D@M_)Tv' +d&V@/D@Rg)F['%Z@/D@X{)P'2f&@/D@])_ϖ'9&=-@/D@cu덂)D-C' %7@/D@h@ )fJ'&@/D@nph4)f'T&@/D@s )tP' k&\@/D@yk)5' u&#X@/D@~B)h'x&0@/D@f`Ɋ)s'&1@/D@){'&!@/D@a`4P)t' +uk&,@/D@[)pR3'w&5@/D@\`)|J'FG&!ww@/D@i)uޙ'&[C@/D@W_ )q' N&@/D@M/)bGc&&ч@/D@R_t)Q;'W&@/D@)B &D%@/D@MCR)TQU&=&"@/D@)`$'J&/8@/D@H #)'Q&62@/D@@ )&0''&7;@/D@C)'*&:M@/D@`4P)i'Z&0*@/D@>)H'v&+c@/D@἟/+) 2' J&8a@/D@:@)Z'nM:&7~D@/D@*)'8t&G"@/D@5c)!T'&K@/D@@ )\' n&S@/D@0H)'#k&LG@/D@)w' &ON@/D@,@W )1'&b@/D@ i)È'A&Uu)@/D@')g':Q&M@/D@_mY)D&A&B~@/D@#)~']&,'|@/D@#>)\z'O&4@@/D@))LlC&&ԥ@/D@.@W )(&*%R@/D@4*s)+/&ح\%V@/D@9)4'U%^H@/D@?m),;-&d.%t@/D@D`),I'%%܆j@/D@J <)o&䉲&|@/D@O)%Z&&=t@/D@U w6)vY'*&a*@/D@Z)/' &T@/D@``f)̘'&@/D@e@ ),{'&w@/D@k)# +'0&w7@/D@p)ʧ)'l&@/D@u)3['&@/D@{}g)qX'&@/D@)|W' Z)&x@/D@yl)'&pA"@/D@_ )o'݊&@/D@u@%N)A&d&o@/D@ @)ǘ'H&| +@/D@q <)&&z@/D@)ʷN&b&@/D@lJ)1Y&c&y@/D@")Ă&g&{k@/D@h8)Č&&{@/D@)'f&n@/D@dM/)b~'+&@/D@h)v' +&F@/D@`>)'&4@/D@޿)')&/R@/D@\w6)&^q&W@/D@ڿڲ)&7&p@/D@X8)i&}0&'@/D@)H &i&u@/D@TM/)&&i +?@/D@)Cj&fp&f@/D@Q\1)&:&mP@/D@)̞i&6E&@/D@MOU)&蒶&z|@/D@?)K&웻&*@/D@ +I?^W)s'ϛ&lc@/D@_ )^&"&[@/D@Ec)o[&ҹ&F@/D@ß`)e&-A&`j@/D@ A o)2$&]&g@/D@%)t&@&@/D@+>c|)ޫ&9&@/D@0 )=&6&?@/D@6:@)&(&n@/D@;`f)'f&@/D@A6)k&>D&@/D@F%)Fv&&V@/D@L2*&&@/D@Q <* &`&F@/D@W/@O)&}&\4@/D@\CR*'f&@/D@b+*' &:@/D@gi*0Y&&R]@/D@m( *b&G&@/D@r`Ɋ*x&Ե&H@/D@x$u* ^5&&w@/D@}h*w&&z@/D@!\1* T&0&3@/D@@O*N' f@&@/D@CR*&^q&ù @/D@~*'&@/D@ r~* O&&@/D@`f*ߤ&WE&@/D@Y*2&&a@/D@ :)M&Cd&@/D@@ )H&8&n@/D@e* {&}e&[@/D@*k'&AY@/D@?*%8&!&P@/D@ !*%&<&m@/D@ʊ"*܃'K&a@/D@ ?^W*Ź&&@/D@ՇQ*'&&֋V@/D@덂*)C&i&T@/D@?* &>&H@/D@*&W&HQ@/D@\1*.'s*&ߘ?@/D@`*6&&q@/D@}g*8'c&YR@/D@ *@8&e&@/D@@%N*? &E&@/D@|!*=,x&&$p@/D@;*?&%&f;@/D@"*?'[&#@/D@ *=&s&8@/D@y`4P*7)Q'&rT@/D@8*!'o&Չ@/D@ o*&[+&G@/D@1*v&k&P@/D@v?*$^&蒶&d@/D@5c*# '%&е&@/D@/+*&ܘ&Uo@/D@!**d&&@/D@$s @*/,'& /@/D@'2` **(B&&!@/D@)e*6R'.&@/D@,8*@&E&J@/D@/pH +*L&')@/D@2/_ *L&_'@/D@4˰*UN&A'Se@/D@7 q*Z*f&Z' B@/D@:m D*iU&;'@/D@=,`*kMD'di'@/D@?*`B&1'n>@/D@Bj*_!&/'@/D@Ej@*Z5'י' @/D@H) +|[*SӪ&<'@/D@J>-*Vj&' Lm@/D@MH +*Z>&6' +@/D@Pg_ *in&>x'e@/D@S&˰*j&3f'A'@/D@U q*do&'2@/D@X@%N*ht&vm'_@/D@[d!*t&t'@/D@^#*r&5'x@/D@` @*rՇ''i@/D@c` *{&%v' @/D@fa o*}'}'"A@/D@i B*{U&$' ګ@/D@k_*x+&]'P@/D@n'*~H&X'"@/D@q_1*o,&ﭏ'k@/D@t?*:' +n'/6@/D@vݟm*ޚ' _'9n@/D@y@*'I',Z@/D@|\@W *h&C/'x@/D@`*p>' t'@/D@"*&XK'%>@/D@@*&`J''S/@/D@Y +|[*&.'#@/D@8*s&4l'5"@/D@?*'^'G@/D@'*`''?R@/D@V*''K@/D@?*&'<a@/D@՟m*i&v'@/D@ :*!-&ċW&G@/D@T@W *F|"& &@/D@`*&v8'%ļ@/D@j*,j&'+@/D@` *Ͱ&'(]@/D@Q o*uw&s'@/D@L*r<&no'+@/D@Ѐ*hĿ&'@/D@*R#Q&R['}@/D@O?*nN&ݭ'a@/D@*&''= @/D@ q*qD''i@/D@@%N*`&8'7 +@/D@L/+*IB&%'H @/D@ *I&jT'Hx@/D@ˀ*׋&!'KQU@/D@Ɗ"*&';@/D@J@*x&'6]@/D@ e*X&`'64p@/D@B*& '6@/D@ш_*H&B'0iR@/D@G o*' +'?@/D@y*V;&'Ht@/D@*@&?'A@/D@܆c|*'x'9@/D@E_mY*G&'(@/D@w6*mD&m',@/D@ *m'&T2'Db@/D@烀*&'G(@/D@Bj*&&:+'=:@/D@` *Z&ޝ_',U@/D@ o*f&'P@/D@L*{&`'!;@/D@@ #*&ٶ'(\@/D@*u&='9@/D@_ *&믜'?*eg&r'&1@/D@m*z&^'*@/D@ D*R&\'*m@/D@|!*C:&'@V @/D@ <*&_x'Zv@/D@ `*W&F 'lWz@/D@"*o&48'j̷@/D@z@*9&'R|@/D@9e*&('U@/D@L*&'5@/D@*ɨ&'L=@/D@x*c&Q'S@/D@!7_ *w&T'W@/D@#*&%'`@/D@&?*R&t'ws@/D@)uEx*&e'v@/D@,5 D*s&z'oDj@/D@./+*ħ&)'{@/D@1 *&'wջ@/D@4s*&{X'Ta@/D@72j*$6&5'o@/D@9` *A.&-*,M&ܽ'D@/D@D?*|x&'54@/D@G'*l&'@/D@Joy*e&>z'@/D@M.˰*l&.'C@/D@Oc|*H5&ߔ'E{&@/D@Rc*۸&F'9k)@/D@Um :*{P&)'!>G@/D@X,`* &'7-@/D@Z*G &'[<8@/D@]`*&m'hU@/D@`j"*&Z'c2@/D@c*@*&'b@/D@e o*&@'a @/D@h?^W*c&'^@/D@kh>-*s&X'djV@/D@n(H +*&xE's @/D@p'*''r@/D@sy*Ϭ&J''@/D@vf˰*J&Di'm@/D@y&c|*Մ&-u'h@/D@{c*F'4r'[@/D@~ :*Ԋ&m'@/D@d!*K&B('o@/D@#9*&'/@/D@`*0&j'wG@/D@"*a&'jg@/D@b` *M&'h@/D@!Tz*E&ߒ'@/D@`4P*K"&'}@/D@8*W&-A'h@/D@`?*&']B@/D@ o*&˲'^-@/D@?*;&ݓ'aej@/D@ *!&Ԋ'T>@/D@^?*#&Ձ'ZNA@/D@Ex*v&ٕ'b@/D@@%N*&y'k5@/D@w6*&A'Xy@/D@\@W *& B'T`@/D@`*7&ٝ+'e[@/D@ @*k3&бv'Q-@/D@*w&'G[@/D@Z*$&rU'@ +k@/D@e*&æ'@/D@*&Ž'^@/D@H*T&'iaQ@/D@Q*!&'mƑ@/D@ 1*&'gC@/D@#_;*&'U7@/D@&E q*ݖ&L'a@/D@)_mY*KE&"'@/D@+@*ԑ&Ъ'h@/D@.`*b&'Oi@/D@1C*2&{&'I^@/D@4`*n7&6'U@/D@6"*p&'`o@/D@9` *&'4@/D@c&-&@/D@];*d8L&'@/D@_@ *&"'HU@/D@bڲ*&b'b^r@/D@ez@*3&&'kǗ@/D@h9 o*{ &'QAX@/D@j?^W*K&'W@/D@m>-*&}'fFC@/D@px?*b&'=i@/D@s7'*P[&'Y@/D@uy*&T'&y@/D@x˰*&'D@/D@{v *&'3@/D@~5m*~Qz&'"Á@/D@ D*ȕ&'-͌@/D@/+*-z& '-*,& q'rv@/D@H +*&G'l>@/D@W'*3,&H'&@/D@1*=&''@/D@_;*Δ&='6@/D@Ex* &qO'U@/D@ U@%N*$&͛'|@/D@#/+*&.'qĄ@/D@%9*U6&'o;@/D@(*8&*'\\@/D@+R"*x&$ +'XR@/D@.@*>D&'WY@/D@0Ѡe*&W'cU@/D@3B*ݸ&/'d@/D@6P*&'o@/D@9*x&$'n@/D@;?*&']^>@/D@>˰**&I'G@/D@ANc|*^&':@/D@D _mY*&n'Ro@/D@F̿w6*&'_sZ@/D@I@W *jK&'`@/D@LK`*&@Q'l@/D@O +j*hV&'mRZ@/D@Q` *hy&'q)@/D@T o*&'Y +@/D@WIL*J&^'rK-@/D@Z*&`'yv@/D@\*9&u'g@/D@_?*pp&'O@/D@bF˰*+&'4@/D@e q*t&Q'T@/D@g@%N*<&b'5@/D@j/+*S &'l@/D@mC9*x&U'$=@/D@p`*H&]:'$4q@/D@r¿ڲ*wj&Ջ'X@/D@u*S@&'@/D@xA`4P*4dE&E&@/D@{>-*eJ&0C')@/D@}H +*&='FOI@/D@Q*F&]'tԁ@/D@> *g-&yN'@/D@ *ĩ3&@'{@/D@c*&hK' +@/D@|@*4&Lk'±@/D@< *&B'_w @/D@*&W'qm@/D@ڲ*b&#'p6@/D@z*Xt&'C@/D@9 +|[*X&' +ܸ@/D@>-*:&'=@/D@H +*&9['d:@/D@w_ *&'@x@/D@6 *&'. D@/D@c|*?~9&M&r@/D@_mY)j&Wzh&@/D@t/+)W&Mr&R@/D@39* +k &dE&,@/D@@ *d&i!&ß9@/D@J*YX&' r$@/D@qTz*H&'i@/D@1L*:&cw5&@/D@_*&hl&ù @/D@ o**s2&&- @/D@o1*{ +&p&,@/D@.?* &b!&,@/D@c*W&' @/D@ʬ@*&e'/Ke@/D@l *T@&'8@/D@+`*]&h'1@/D@*Ep& '-%@/D@թTz*l&''2 @/D@iL*&'5@/D@(* &s]'B1@/D@ o*&':E@/D@1*Q&'Qh@/D@f?*!&']>@/D@%c*}&6'Mm@/D@w6**&_'D @/D@9*ճ&'?@/D@c @*c&Tj'4j@/D@"` *&6}'kW@/D@e*3&"'@!@/D@8*&5'@/D@`H +*&']@/D@_ *,&.I' @/D@ޟ˰*3&³'!-@/D@Ex*&'#@/D@] :*+&'v@/D@@W *Ν(&ć';@/D@ `*&'^>@/D@ *8I&E +'N@/D@YTz*&V'@/D@B*&Κ'[H@/D@?+l&Ҫ'3@/D@_ + &''@/D@V˰+^&= +'E@/D@ q+ +& w'@/D@ :+&ֳ'@/D@" *ߔ& d'@/D@%S`*䫗& 'YV@/D@(J+e&҉'w@/D@* o+$N&ו'@/D@-8+&*'u@/D@0P+& 'Q@/D@3?*d&οf'}@/D@5_;*B&'*M@/D@8c*& '@/D@;L/+*M'&͐'@/D@> +\&J'(#@/D@@j+w&>D'u@/D@C+|&'"@/D@FI?^W*i&ʘ'/@/D@I_+&'@/D@KQ*j&'w\@/D@N˰*&E'jB]@/D@QEEx*)&'%T6@/D@T@*m&i'10@/D@V9*&â'I@/D@Y @+x&D7'qQ@/D@\B@*z&ĝ'ݾ@/D@_`4P*[&'eT@/D@a*O&';G@/D@dQ*&'v@/D@g>˰*& ')@/D@iEx*Z&_'G@/D@l@*&-'4*e@/D@o{*&'C7@/D@r:j*Ox&Uo'k@/D@t*#&Ǖ'I@/D@wL*̍&' @/D@zx?*&v'%@/D@}7?*q&6'f @/D@_;*N&'p@/D@_mY+&"e'^u@/D@t!*&b$'=\@/D@3*<&'Y@/D@*Ǐe&˳'o@/D@e*W&8'h@/D@p #*m&'KN@/D@/ o*)&'F@/D@ *e&'@/D@Ex+e&k\'0@/D@lw6+,2&NA'i@/D@++9&'@/D@"+F'&5'@/D@Tz+H&:^(S@/D@h8+I`*';(c@/D@'+U'X(\(@/D@+R9'(M@/D@ q+JD&O(s@/D@d@+F'?'t@/D@#+@:K&r' -@/D@"+A&Y'&}@/D@ o+BP& +4'o@/D@`>-+B&'u@/D@ o+K{(&(:W@/D@ +W'@( +5@/D@ĝm+Uy'FG(@/D@\/++Pm'P(t@/D@`+J&6(^@/D@ڀJ+Fq&'<@/D@ϙ +|[+:Hp&#'q3@/D@X_+2_&-'Qn@/D@_ +4'g'*@/D@?+1*&'|_@/D@ڕ@%N+1r&T'+@/D@T +22&̃'?@/D@ @+6'h'@@/D@+8$&T'9@/D@8+0&<'@@/D@O+I|&(B;@/D@ +M&jT(2@/D@͟m+?&'4@/D@!+1)&A'@/D@K`+5d&'/@/D@ +@+AƜ&'v@/D@L+G`&A'3@/D@+Bm&?'݅@/D@F+AQ&= 's @/D@Ex+BN& '@/D@ğ/++:I&'A@/D@+2]u&M'N@/D@ B` +0y;&y'@/D@ ?^W+6&︡'Ȟ@/D@H ++7&mh'fV@/D@~+2& '@/D@=Ex+,e&'ܫO@/D@/++.&e'~l@/D@`+8l#&'@/D@z@+C''@/D@8B+;=&}'t@/D@!+C"&'@/D@$˰+I&(@/D@'uc+>&'`@/D@*4@W +6R&n'@/D@,j+6O&'[@/D@/Tz+5D_&햛'@/D@2p #+2i&^r'^X@/D@5/_ +6)&<'?@/D@7 +,u&,'ܿ@/D@: :+ &mi'͹t@/D@=k+,&/'G@/D@@*J+:u&%'ʈC@/D@B?^W+ *&`K'"@/D@E+r&D'5@/D@Hf + Z~&U'@@/D@K%c+&FC'e@/D@M@W +&z'o@/D@P"+,&'@8@/D@Sae+ _&ܑ|'G@/D@V _+4|&'@/D@Xy+:5&}'Y8@/D@[Ex+/i&ò'@/D@^\!+$Uc&'X@/D@a@ +Α&'ȶ|@/D@cTz+&?'@/D@f #+&ld'B@/D@iW?+w&ǎj'G@/D@lc|*?"&<'p@/D@nԟ/+*(&'a@/D@q@ *ٝ+& 'E@/D@tQ*}y&FE';@/D@w #* +&,'@/D@y?*Ƈ&X'~J@/D@| q*l+&'&@/D@L!*ɳ&'k@/D@ @*& +'@/D@ o+&&'^@/D@+&͔'=@/D@G1*r&'I?@/D@m*u&r'n@/D@@W +s&і3'Lk@/D@"+.9&7' @/D@A +|[+(_i&h'ׄ^@/D@H ++&n'@/D@˰+U&չ 'ʫP@/D@}@%N+*L&#'v@/D@;+(N&ܧ'@/D@` +!q&F'/@/D@B+N&'ǔ@/D@wQ+%!&~8'>@/D@6 +.&'߹s@/D@/++*o&'(q@/D@ @++K&6'@/D@q o+ &j"'@/D@0?+f&'j@/D@ +d&p'@/D@@%N*X&*'@/D@k*Z&j'@/D@*` */&'{@/D@8*O&'F@/D@Ƨ_ *&&)'A@/D@e q*ʢC&8U'@/D@$@W * &'Uk@/D@ڲ*`& '%@/D@ѡ?^W*?P&j9&j@/D@_ o*z?&O&6@/D@?)^K&; &˵@/D@ܟ/+)&'R&n,d@/D@ܛ @)T&&&r@/D@Y +|[)e&%0&mO@/D@)ʴl&/6&&@/D@_;)&1}&@/D@@)\&.3_&sN@/D@S@ )5&,H&"_@/D@ o*&>}&@/D@H +* &VJg&͘@@/D@*Z&&' &@/D@L@*&k'=.@/D@ @ *:z&p'f@@/D@ o*&`'w@/D@H +* &5')@/D@F+&'6@/D@@+&ӱ'h@/D@ @+k&'"@/D@ +|[+&'Ǚ{@/D@ ?+%&և'i@/D@ ?+-d&y'!@/D@/++3}&ו'忙@/D@z"+;)B&='@/D@9?^W+9&G'@/D@Q+2%&'ݠ@/D@ q+:è&{'@/D@t +=p&'|@/D@!2J+@&'@/D@#>-+?&&'5Y@/D@&1+A&Q'@/D@)m_mY+7&ܶa'@/D@,+`+)l&,'@/D@.Tz+BE&W'iN@/D@1H ++?^&c)'@/D@4f_;+5&'`@/D@7$/++:& +'@/D@9"+/ &H')@/D@<L+-I&7'<@/D@?__ +*v&֥)'ڒ@/D@Bm+!\u&̨q'Ί@/D@Dۿ+c&hK'@/D@G*Ǣ!&'@/D@JX?*J&&'$"@/D@M_;*K̕&gW'nt@/D@Oԟ/+*&'@@/D@Rڲ*^&z 'gF@/D@UPB+ ^&H's@/D@Xy+$&4'ҩ@/D@Z_mY+-+N4&f<(@/D@{ +A&W'@/D@~t@+@&i'#@/D@2j+:&2-'"@/D@B+"U&NB'@/D@y*E&'@/D@m D+ +;|&5B'@/D@+ @+9&}'@/D@?^W+Qe&t`(96@/D@?+Y:s&T( @/D@e@%N+T&J((Mf@/D@#@ +M)&(/@/D@?^W+L&ߛ( v@/D@?+J-&۝(d@/D@]@%N+H#&+(@/D@@ +X&ݻ( +ũ@/D@?^W+f&s(@/D@?+m:&z(w@/D@U@%N+u &(Ғ@/|D@ @+&y(%@/{D@L+z!C&( I@/D@y++&(&3j@/|D@M :+T&((@/wD@ +"+k\&(%$@/{D@8+y:&c(@/|D@ +l$&(@/{D@Dw6+iDJ&^>(Jm@/{D@+q&١(@/xD@+>&d($'@/wD@~_;+|"&(!P@/wD@<@W +u%&z(@/wD@+ps&鍖(s@/wD@и+k]&O|(u@/xD@u q+v&t(̆@/wD@3+v&( +@/wD@e+rgH&L(#a@/tD@ۯ_ +bO&Tg(k@/tD@m@%N+aC&(+S@/tD@*j+]&ݴ( @/tD@8+\&Vt( 7x@/tD@榟˰+`v&W(@/tD@d!+z&:( B@/tD@"@+&((' @/tD@H ++z&;(#@/tD@ q+eu&.|(#t"@/pD@[`+cu&ݭ(@/pD@`4P+Z*f&؈w( B@/pD@y+h& +(s@/oD@@+qrI&(@/pD@R+lxN&(W<@/pD@_+P&v($>@/pD@ +p&0T( @/lD@+y݇&t(@/lD@ +I +|[+jb\&ޯ(@/pD@ ?+^&s( @/kD@@+hz&ޒN(L@/lD@+{O&( @/lD@@?+~&(##@/lD@c|+fh&(vW@/lD@`+&U(%x@/gD@y?^W+~'(";@/hD@ 6+p6&(&@/lD@"/++}&5 ('@/lD@%@+&p($7@/hD@(o+)&.|(+%S@/gD@+-c+b!&()s]@/cD@-j+iw&U(v@/dD@0 #+Z:A&g( g@/hD@3f?+`9&/(Ԡ@/gD@6#+_&Un( +@/dD@8`4P+T;m&}(@/dD@;1+m&1(@/cD@>\!+m&ug($u@/cD@A+U&H()N@/dD@Cנ'+&z(&@@/dD@F@%N+u[&ԁ(-c@/cD@IRڲ+p&\1(0!@/_D@L?+|'(!H@/_D@NͿEx+l2i&2-(*@/`D@Q@ +h0&ֳ(@/`D@TH>-+P9&ʣ(p$@/_D@W?+K&(m@/_D@Yÿ+\P&( @/_D@\?^W+kt&8(7@/`D@_> +&>(&R@/\D@a +!&!(-]@/[D@de+&((m@/[D@gw1+|\'(!@/[D@j4!+r3f&ه(-@/[D@lTz+V&(+c@/[D@o_ +!&(/w5@/[D@rlw6+s&ߓ(@/XD@u*+\\s&λ( @/XD@wQ+\5&D7( @/XD@z@+\6&( @/XD@}b@+|&U(!@/XD@'+C&ᶕ()L*@/XD@ :+u&(@/XD@` +r&(@/XD@W o+Z& +(+}@/TD@ :+L&(-9@/TD@` +%&() @/XD@ o++&ߪ(%V@/TD@M :+}&D("F@/PD@ +@+qЮ&fq(@/TD@Ǡ'+`g&=(@/SD@@+TN)&+(@/OD@B+A& '@/PD@_ +&E(#<@/PD@/++&(/a@/PD@yTz+&݌\()@/PD@7y+&9((@/PD@`+i&ws(9=@/PD@e+/&N(2@/PD@n+u&ߛ(*@@/LD@,+&X(.l@/KD@?^W+&Ȟ(6w@/OD@+&[_(:D@/LD@c`+}&6z(8w@/HD@ >-+|m&(!@/LD@c|+g'(,n@/LD@ě @+q'iT(.L@/GD@X?+1&+(%ؑ@/GD@_mY+&4(,fL@/HD@ҀJ+ &0(4sB@/HD@Ϗ'+tY&(6W|@/GD@Lw6+0a&(+ @/GD@ Tz+&w()@/HD@1+'~(5@/CD@ڃ9+&Um(;ک@/CD@AL+&*(A4U@/DD@ +~&᫃(2@/DD@@ +&w(1x@/CD@x?+&1(${@/CD@5_mY+ff&0(t@/DD@` +q&Ү(@D@ D+r<'pUm(?@CH@@ +n.'m +i( @CH@`4P+'sgB(#0@CH@Q+'t0T(%@CH@ }m+S1's((@CH@+'t()@CH@y+'r5(*=[@CH@H ++K't7(--@CH@v_;+1!'p()4@CH@$!+q/'dG(\'@CH@*rڲ+e'^f(#@CH@/B+d'^k(ZB@CH@5o?+c'\l()@CH@:c+a{-'Z˲(N@CH@@k+x?2'e(@CH@E+['m<7(+a@CH@Kh?+m%'t7(6NC@CH@P+t'rlb(5@CH@Vdw6+'p-(4;@CH@[ @+"'k=>(,i@CH@aa`4P+'cD(#Gf@CH@f o+~r'c2(#)@CH@l^c|+'epG(&@@CH@q`+['eE(' u@CH@wZ+,'cm($@CH@|B+'e_((è@CH@W_ +t'h(/>@CH@տEx+7'm(22@CH@T +S'fFC(,m7@CH@ҀJ+g'U%x(K@CH@P8+z+'\( E@CH@?+'fI(.2@CH@MEx+'fc(1J^@CH@ +,r'``().@CH@JJ+o'S>(@CH@B+id'RH(}@CH@G_ +{A~'Y p( @CH@ q+ր'^>(*R@CH@D@W +'ah(2@CH@¿ڲ+'h(<$@CH@A?^W+'ic)(@@CH@Կ o+W'b7(4*@CH@>?+{v'T( j@CH@߼w6+w'Qx((L@CH@;@ +'W((Y@CH@ o+'\(1;@CH@8?+#'X<(-t@CH@ +B'S(',@CH@5_mY+'X*(0q@CH@+ '_ X('_(?@CH@ B+C*'c؛(Et@CH@/Q+'`j(Cw@CH@ +'W (4;@CH@,w6+ZV'Qt(-@n@CH@!@ +2'S1(/@CH@')Tz+p['W(8@CH@,+ 'Y?(;@CH@2'y+PR'T(6)^@CH@7Ex+b'P(/[@CH@=$`+'Ka('П@CH@Bj+f'L@(,@CH@H!e+'K!(*'@CH@M_+&'N(/@CH@S1+(L'S4(8@CH@Xm+N'U(>ӗ@CH@^`+?'Xu(Ct@CH@cj+o'S<(;p@CH@i o+@'T d(==@CH@n_+}'X(D@CH@ty+2'\(P@CH@y q+N'a,;(Wo'@CH@!+'^(SR@CH@@ +2'^&(Ss@CH@+.j'_(WE@CH@>-+O;']h(TK@CH@Q+'Zx(Pc@CH@?+p'Y(N@CH@ :+P'V(J@CH@+'Y=>(OS@CH@ +J+'YS(Q@CH@`4P+ 'W(N#@CH@H ++'Y(T (@CH@+'`8(`@CH@Ex+'bg(ee@CH@Ƅ!+'`m(e@CH@`+['`'(cn@CH@т+vF'ZLi(XP@CH@B+'W (T@CH@+ 'ZK(Yd@CH@˰+'\r(]@CH@}c+\'X(Ys@CH@`+Y'Y9([SG@CH@{@ +'YZ(Z@CH@+'S(P@CH@xB+,'TA(T@CH@+Y'TQU(T_+@CH@v +'T= +(UA$@CH@ m+w'T%(S˘@CH@t/++I'O(M@CH@+/'P,(O@CH@r` +U'Pg(PD@CH@#?^W+'S$(V@CH@)p?+M'P(Q@CH@.y+?,'Iu(G@CH@4n +Vo'Pt(T@CH@9 :+'R (X'@CH@?l+''N"(R@CH@Dj+'D(A=@CH@JiTz+L'K d(M@CH@O8+'M܁(Rĺ@CH@Ug+ұ'H؜(Jr@CH@Z+U.'E(E@CH@`e q+'JT(OU@CH@e@+|'M(W@CH@kc+>'F_(IF^@CH@p"+'H!(M,@CH@vaTz+.j'Lf (WE@CH@{8+'N(XQ @CH@_+G'Kv:(W@CH@+5'H%(Vq@CH@] q+M'Nw(^@CH@ :+'Rt(d@CH@\+'Oz(c72@CH@j+oD'HQ(W@CH@Z+'I C(U @CH@L+'H~(V@CH@X?+†'G.(Us@CH@?+'G.}(U_@CH@V_;+7'MU(aN[@CH@c+b'LWG(c @CH@T!+ 'I(]K@CH@ӟ`+'Ja(_l@CH@Rڲ+H'M(h !@CH@Tz+ 'LH(e7@CH@PB+!'K}(d@CH@+'Fel(Z@CH@Oy+xm'?4o(Jז@CH@?+''H(]@CH@K`+|'G3(_W@CH@"+'Fv(]@CH@I+f'H(`q@CH@ +L+'C(Y@CH@H?+.8'C=(X@CH@Q+'Ej(^@CH@F˰+7'Fi(aN[@CH@ ſEx+'H+6(d@CH@&E :+'AB(Y@CH@+ +'=O(O@CH@1C`+̾'B(YW@CH@6€J+7'E~(aN[@CH@+R'@6(V,V@CH@WEx+g'A3i(X@CH@]= :+j'E(a|@CH@b +'F&(d@CH@h;`+fL'DH(cM@CH@m+'DE(b6@CH@s9Tz+'@&([J@CH@xL+'?؝(Z@CH@~8_+" +'C(as@@CH@'+'A(_@CH@6+'>(Vg@CH@ +'8Z&(M@CH@5_mY+'<(Xl@CH@/++TI'A(b>@CH@3+w'B}(e8@CH@ @+'D(jYl@CH@2J+d'E:(n+@CH@ o+'E(ng@CH@0B+Y%'G9(r]@CH@?+f'EȠ(qrm@CH@/'+'EH(pJ@CH@Ů+'C"(lU@CH@.?+'B}(i[@CH@Эc+\'Cl(j9@CH@,w6+6'C(k\@CH@۬ +'A*0(g6@CH@+`+R'9 (V,V@CH@檿ڲ+a'7(Q!@CH@*+('6'(P)@CH@`4P+f'8B(W.@CH@(>-+':(Y7@CH@+'8(Tq@CH@'_ +'4(M@CH@ +>'0|(Dc@CH@ &c|+j'2(J#@CH@_mY+u~':a(^@CH@$w6+'=o(e@CH@ +'@R(lg(@CH@##+D'AM<(nk@CH@(ڲ+'=B`(eV@CH@."+F':)*(]@CH@3 +|[+J'9p([@@CH@9 8+@ '7J(Y@CH@>?+5'7([%)@CH@D'+b'9(_@CH@I1+н'5Fy(V;@CH@O_;+'8L(\[@CH@TEx+ՙ'<(f0 @CH@Z D+@P'>(o|@CH@_!+ՙ':(f0 @CH@e+M'3(US@CH@j`+'6(\@CH@pڲ+':(g$@CH@u+@';d(l@CH@{ +|[+7'7L(aN[@CH@8+q'6u(^k@CH@_+f'5(_<@CH@ o+<'9;3(h@CH@y+5'<(qC@CH@+'>(w0@CH@c|+'>(y@CH@_mY+'=(w0@CH@w6+';(t==@CH@@W + }';Z(t@CH@`+d':W(r@CH@j+0'=(wH@CH@J+'9v(oV@CH@‘Tz+E'7 (kw@CH@`4P+l#'64(l@CH@͐>-+ +'5k(j4@CH@?+ r'4\3(g@CH@؏'+'8L(rd@CH@y+õ':E(z@CH@+0%':f({@CH@c|+ģo'93({z@CH@_mY+ɞ'<( @CH@ @+.'3(nO@CH@`+'/^(cI@CH@ +;'10(j&@CH@@ +'4gE(qH@CH@ + +ڲ+V':0(@CH@+˞w':h(P@CH@ e+'.(f ;@CH@L+e',5(dN@CH@ +Ϋ'5ǚ({@CH@%+(Z'7(~@CH@+Q+i'3IX(q|@CH@0+F'%(U%x@CH@6_;+hs'$m(U@CH@; q+J'0p(rK-@CH@A_mY+ʅp'5HR(@CH@F@+.'-i(p@CH@L@W +G '% ([<8@CH@Q+?A'"@(_ I@CH@W@ +B'/(w_@CH@\ڲ+Ե'7o("@CH@b@+ɢu'1( @CH@ge+'2A(0@CH@mL+uD'5(UK@CH@r #+O'1K(@CH@xH ++ף')4(pp,@CH@}'+'*e(u@CH@y+Bp'3c+(|p@CH@~˰+k'8 (@CH@ +'=(M@CH@}c+ U'=:(K@CH@ :+f'8L(@CH@|!+''5!(V@CH@+( '3($(B@CH@{+d',,(@CH@j+''".(jp{@CH@zJ+y'$(r!@CH@+ j'0`(m@CH@y +|[+{'5h(8@CH@B+IU'5C(M@CH@x+='7(@CH@+|'22(@CH@wQ+`'0((K@CH@1+-'0(4@CH@v+6',(@CH@c|+]'(+(`@CH@uc+Ć'#({@CH@ :+='c(m@CH@t!+'ט(SXM@CH@9+'6(F?@CH@s+2'(R,@CH@j+'(ty1@CH@ rJ+<')0(;@CH@+m+'.(m@CH@q +|[+ +!'1<(@CH@B+}'1A(@CH@"p+'1 (@CH@'+'-؝(@CH@-oQ+敕'+(@CH@21+'0(@CH@8n+'2(J@CH@=c|+'1&(g@CH@Cmc+D]'-z(Z@CH@H :+X')[(@CH@Nl!+I')0(9@CH@S+"''p(^@CH@Yk+k''0#(@CH@^j+u'd3( @CH@djJ+l#'h(l@CH@i+Z'(f@CH@oi +|[+'(@CH@tB+-' j(+@CH@zh+ެ'"Mr( @CH@+'#D(+@CH@gQ+'!$t(0@CH@1+\'!(.@CH@f+='&I(՘@CH@c|+''e(7@CH@ec++'%J(&Z@CH@ :+q'"()@CH@d!+ۿ]'9\(o@CH@9+/'E( +@CH@c`+pi'|.(H4@CH@"+4'(F@CH@b` +Qg?&4n(@CH@Tz+)EF&'ت@CH@a`4P+pY&(@CH@8+1n' +wC([ @CH@`_+tg'(|@CH@+'u(@CH@__ +ތV'I%(nL@CH@+>':(D@CH@^?+JP'(@CH@ݿEx+'(^ @CH@]@%N+ߘ'}([@CH@ܿw6+|'(z8R@CH@\@W +'1(M@CH@۟`+]&Ԃ( ~@CH@ [ @+P}&ҽY(n@CH@ڠ+o.&xD(@P@CH@Z+ù?'(z@CH@٠e+o'A([@CH@XB+'d(k@CH@$؀+s'!( @CH@*X+1_' I(f@CH@/Q+I9'"n(v@CH@5V,m'#](_@CH@:_;,5'"gF(X@CH@@U q+/' ~( +@CH@E@%N,'#k_( @CH@KTw6,['#(_-@CH@P@W +' (w@CH@VS`,|'#;i(?@CH@[ @,>C'% D(#@CH@aRJ,Ex'$'(\@CH@f,I'$ (@CH@lQ`4P,^~'$ &(@CH@q8,:w'$+(@CH@wP_,'#Fz(qj@CH@| o,ו'"2( @CH@O?,P'(H@CH@Ο˰+'H(@CH@N ,'!-+'W(@CH@ !+N1'z(@CH@H ++'(^@CH@+Ŝ 'Ԇ(|@CH@ _+HF'l(@CH@?+'s^(@CH@"+Pm'X({'@CH@,Tx'e9(҅@CH@^?,'D(@CH@c|,'T(@CH@ݠe,0>'>|(@CH@@%N,'k(H@CH@!\B,n'(e@CH@$/+,L'(@CH@&`,k'>(7@CH@),o'>|(@CH@,[`,^'(d@CH@/`, z'(A@CH@11,'(<@CH@4,`L'(a@CH@7Z?,m'Z(@CH@:,*'(0@CH@<٠e,>v'(E@CH@?@%N,i'˵(} @CH@BX8,Z'uj(v@CH@E/+,'Z((/@CH@G@W ,a'(@CH@J,ʕ'p(l@CH@MW,e'(@CH@Py++'h(O=@CH@Rֿڲ,''(Qq@CH@U_;,MC'/(L@CH@XVc|,' s(hY@CH@[ o,'(S@CH@]_mY,G'(a@CH@`B,;'(@CH@cT/+,U'z!(@CH@f@W ,'-(@CH@h,'H(`@CH@k,&'|(@CH@nSy,'(C@CH@qڲ,'+(@CH@s_;,,r',>(.@CH@vTz,'(x@CH@yQc,'<'(M@CH@| D,'(}4@CH@~>-,'(@CH@`,'G(!@CH@P+B'(^@CH@`+Y3'6J(b @CH@y,4'(m@CH@ڲ, '7(*>@CH@N_;+'_(@CH@c|,'A'(AM@CH@c,]z'%( @CH@ D,_G'k(Z@CH@L>-+~'0(e@CH@ @W +('j(@CH@,sJ'](J@CH@,'("@CH@K1,'۲(\@CH@ ++a' +(q@CH@?,<'2e(@CH@ o,'Q(@CH@I_mY+iB'K(ҹ@CH@8+?'(V@CH@!+ ]'(@CH@,'-(~@CH@G`+{' (F@CH@y+0d'L(@CH@Ơ+'R(Q@CH@Æ?+'2(@CH@E o+LZ' B(;@CH@@%N+k' (@CH@8+q[' (@CH@΄`+Pu'B(@CH@C+4'(@CH@+h'U(ea@CH@1+'С(S @CH@قJ+'(W@CH@A+b' (T@CH@e+~'ӳ(@CH@ D,]'m(@CH@䀟/++'?(O@CH@@H ++=Z' (@CH@`+R'(rJ@CH@y+b'u(X@CH@~+'!(r@CH@> +"' (@CH@e+t|'('@CH@ D+&!(y@CH@|/++'c(>@CH@<H ++{' (@CH@`+,'(@CH@y+P'  (H@CH@z+U'>(@CH@9,'D:(@CH@ +c,'D(@CH@ B,b'o( @CH@x!,k'j([@CH@8,k'Z](@CH@`,'e(˧@CH@",;'IZ(#a@CH@v_;,/'(<@CH@5 o,@'l('@CH@ @%N+' |(a@CH@#/++' Kg(:@CH@&tH ++f ' h(@CH@)3`,'(C@CH@+1,'-,Z'A(@CH@9H +,'H(8@CH@(>@CH@Rjڲ,'(X @CH@U*?,>v'q(E@CH@We,'m(Zi@CH@ZB,k'p(`@CH@]h`,' (@CH@`',' oE(@CH@by,^'~p(o6@CH@eJ,J'(G@CH@heTz,' N()@CH@k% D,w' &(ox@CH@m!,F' (@CH@p,' 6(c@CH@sc?,Y{'=(hL@CH@v",' 7(F@CH@xTz,%' oE(@CH@{@%N,$'P(I@CH@~`/+,Az'A( @CH@,7'}(F@CH@?,' y(9@CH@,Y{' =w(hL@CH@]Tz,?'(@CH@@%N,'%(:@CH@!,Ò' 6(7@CH@,g'J( @CH@[y,p'-(@CH@J,{'"(je@CH@ o,)'j(*@CH@B, +>'(@CH@X`, +'(@CH@`, + '(@CH@",h'(q@CH@ ,CG'("@CH@Uc,Z'(\@CH@>-,' a(@CH@,' m(@CH@?,O' XP(˚@CH@RJ,|K' +(@CH@ o,.' +n(Z@CH@B,4' +(m@CH@@W ,v' Z(Ԟ@CH@O,' (@CH@ڲ,,' |/(@CH@c|,3' (7@CH@ȍ@%N,I' +(į@CH@L`, +' +Ľ(s@CH@ `,VE' _(@CH@",&' 8(o)@CH@ӊ ,{Q' ("@CH@I@%N,8' (Ʈ@CH@!, +'(%+@CH@ǿ,e' h(N@CH@ކ",*' ;5(0@CH@F ,8' (Ʈ@CH@@%N,^L' O(E@CH@!,w' Q(@CH@郟`,E' D(N@CH@Bڲ,i' I(@CH@,[' (#@CH@ D,:' (@CH@@W ,' {(t@CH@?,k' (7@CH@,iM' ;( @CH@ o,' te(l@CH@|8,!?' O(@CH@<,' 6(@@CH@y,l' f (W@CH@?,J|' ),(,#@CH@ +y_mY,Y' ^(Q@CH@ 8!,rO' y(p@CH@`,-' N(@CH@ڲ,c' (@CH@uTz, <' t(ݽ@CH@4B,' (f@CH@H +,' Y(@CH@y,y' ( @CH@ r?,iM' ( @CH@#1_mY,^L' @(E@CH@%`,b' @(@CH@(,' o(@CH@+n,-' r(@CH@.-e,% ' (l@CH@0>-, ' }(L@CH@3,' Q( @CH@6jڲ, ' @(0@CH@9)Tz,T' ˁ(s@CH@;8,NH' (R@CH@>,N' (@CH@Ag1,o' 9](@CH@D&c|,' `(J7@CH@FB,\' (h$@CH@I,3B' (ƻ@CH@Lc1,m' (@CH@O!,' (|@CH@QB,`' t(3@CH@T,' 4=(N@CH@W_1,/v' Ժ( @CH@Zc|,Z' v(@@CH@\B,UK' (9@CH@_,Ex' `(\@CH@b[1,ɐ' @U(hf@CH@eTz,' +(C@CH@g8,fI' (1@CH@j,Y' p(]@CH@mVڲ,e' l(@CH@p o,' t(h@CH@rԟ/+,(s' +(@CH@u`,7' 9(@CH@xRJ,e' (@CH@{c,tO' (P@CH@}`,' 8(@CH@?,`' (q@CH@N?,o' (@CH@ D,/' H(Q@CH@,' ,(L@CH@",' 'T(:@CH@I o,' ^(z@CH@/+,9' j(@CH@ǀ,#' (@CH@_;,(' Z(3@CH@E@%N,U' U (N@CH@H +,' (@CH@1,#' N(@CH@Tz,.?'(0@CH@@>-,' O(@CH@,' (I@CH@_;,ő' (@CH@}@%N,S' y(@CH@<,3t' (M@CH@",' x(@CH@e, ' 0$(l@CH@x!,' g(}@CH@7?,' n(h@CH@ ,A' (@CH@8,' ( @CH@s`,' (ۤ@CH@2_;,i' I(@CH@@%N,' w(F@CH@ʰ,' r$(@CH@nڲ,' XP(@CH@-c,!' ( @CH@@W , +8' <(@CH@ի1,`' @U(q@CH@i o,' +((@CH@(!,1' +P( @CH@?,' +n(h@CH@Tz,' +(F@CH@d/+,' +&(@CH@#`,' (QW@CH@,' (c@CH@>-,' H(@CH@_`,' H(/@CH@ +'(@CH@>-+='*(Z@CH@+'(@CH@Z +'=( @CH@>-+;P'ul(@CH@׀+Ν&`J(<@CH@ +ò &*.(z}~@CH@T>-+6&(@CH@`+3'a(h@CH@ +'O(ު@CH@ /++'r(B@CH@O?+F'`(A@CH@ Tz+`'lg(=@CH@!+,'!.(@CH@y+^'d(@CH@I o+'5x(@CH@@W +$'((@CH@"+'A($@CH@"c,-'(X\@CH@%D,'m8(*1@CH@(,Q'(h@CH@* D,('.(@CH@-,I'(}A@CH@0>?,'G($@CH@2>-,8 '(@CH@5`,'(@CH@8yTz+(h'N(8@CH@;8`+,'<(x@CH@="+')(@CH@@_mY+'(r@CH@Cs,]'9)(@CH@F2_;,]'N(O0@CH@H8+0'(H@CH@K`+3i'(&( l@CH@NmTz+{w' (:@CH@Q,@W ,S'(AZ@CH@Sڲ,'@(@CH@V@%N,'=( +@CH@Yg`, +'V(s@CH@\& ,9'(h@CH@^!+ы'R(O@CH@a1+و'(/@CH@da_mY,Fr'c-(16@CH@g,-'(X\@CH@i?,'>I(l@CH@l/+,d'(@CH@o[1,_'X(@CH@rc,Vw'lg(e@CH@t,n'(c@CH@w?+:'-( @CH@zT/++3'^(!G@CH@}"+'(}@CH@@%N+%'C(ٱ@CH@`+'(Z@CH@Nc|+E:'(@CH@ `+s' (}[@CH@ʠ+G'C(@CH@B+'Q(@CH@G?+'J(V]@CH@e+S';6(H@CH@+'0$( @CH@?+n'(@CH@@!+nl'XQ(P@CH@ڲ+P'(4@CH@B+>'1((2@CH@{`+'(@CH@9e+'g(@CH@+'(%@CH@ +N't(X@CH@t`+'( ++@CH@2J+u'(~@CH@>-+'}(@CH@1+q' ( @CH@m@%N+b?'Y(*f@CH@+`+'a(@CH@e+B6'`(7@CH@+'(@CH@fc|+X'(@CH@$H ++',(y@CH@_;+' (@CH@̠!+'(@CH@^+W';6(5@CH@>-+bq'p(@CH@1+'(@CH@י D+ ]'nt(@CH@W?+U'jZ(@CH@_mY+'(dM@CH@`+Mi'@V(@CH@c+#'(1^@CH@O`+Y'({@CH@  o+'(Z@CH@˿+'o(@CH@Tz+I'g(f@CH@H+݇'(@CH@c|+z'M?(@CH@+3'i(!G@CH@ +Xj'$(@CH@@H ++'G(#@CH@ +'B.(@CH@@W +'_(@CH@z?+W'`(5@CH@8@W +B'x(@CH@?+&,'(,@CH@ @W +'(@CH@r?+E' F(}@{CH@0H ++ck'(T@|CH@ + ' ((@CH@H ++k&?~(&%@{CH@i+#Z&y(@|CH@(+n'k(@CH@c|+g8'(@|CH@!+c'z(e@wCH@$a o+Z';(}@{CH@'+)'#(@|CH@)ݠe+'o(@xCH@,+X'fA(z@wCH@/Y_mY+.[&,(@wCH@2?+)&l( @xCH@4 D+*&m(@xCH@71+5&z(6@wCH@:P8+b&9(r@wCH@=ڲ+&(H@wCH@?̟/++V`&8(@xCH@BJ+ z&T(@tCH@EH@W +q&.G({@tCH@H +&(e@tCH@J+&(DG@tCH@M o+z&](@tCH@P?+o&(@pCH@R@%N+V.&/M(t@tCH@Uy+&y(*@tCH@Xx8+&@(Tk@pCH@[6+&ߒ( +@pCH@]`+&I (#@pCH@` +G/'S(V@pCH@co+'W(@pCH@f-e+@'(,@pCH@h`+'&(4@kCH@kB+'C4(@kCH@nfڲ+r&L((@pCH@q$!+&YQ(@lCH@s +'|d(׿@lCH@v+'YW(H@kCH@y]c+Je'"i(A@gCH@|y+F'(@lCH@~8+1-'N(@lCH@J+'q(A@gCH@TH ++ W'8(W@gCH@ o+'({i@hCH@`+yn'(@gCH@B+'P(Q@gCH@J+d4'(@@hCH@@W +pa&9(R*@gCH@Tz+F&C(@dCH@`+&x(@dCH@@B+t&%(!@dCH@J+&)[({@dCH@H ++& ($@dCH@ye+]1'f(@dCH@7?+'6K(=A@dCH@>-+'J(׿@`CH@?+N1'T7(@_CH@o+ϴ'/(@`CH@-@%N+ȱ'(M>@`CH@ڲ+P'(H@`CH@@W +'(Ǜ@`CH@e o+'-(]|@_CH@#?+$'X(3@`CH@>-+N1'ul(@\CH@ + 'x((Y@[CH@[`+L's(@[CH@B+'jZ(@\CH@րJ+'5(@\CH@˓+V'n (7@[CH@Q_mY+'(@[CH@ڲ+&(>@XCH@H ++g&4($@XCH@։c+'Ln(@XCH@F"+K'(@XCH@@W +ɫ'5(@XCH@e+q'&(g@XCH@1+8'k(R@XCH@<`+K'(@TCH@e+Q'~(?@TCH@1+'([(@TCH@t@W +}'a!(@TCH@1e+E'Vx(@SCH@"+Nd']([!@TCH@@W +@' (K +@TCH@ic+a/'[(@OCH@&ڲ++'|d(@PCH@+,&(@PCH@@%N+'b(k@PCH@^J+'y(*@OCH@+'i(q@OCH@B+G's(Ǩ@PCH@ +?+z'ul(D:@LCH@ S`+'5(*@KCH@/++'5(*@KCH@ o+K'|(@LCH@1+'6(>@KCH@HH ++}'h(iF@HCH@@%N+걟'](4=@LCH@€J+P&'H(@KCH@ `+f(')a(`@HCH@#<>-+$'!(~@HCH@%Tz+'͎(<@HCH@(1++'(m@HCH@+tH ++'{(@HCH@.1@%N+'(@DCH@0?+' (@DCH@3`+ث'v(8@HCH@6h!+l'|(@CCH@9%c+e'](@@CH@;J+W['(O@DCH@>`+Ѩ'(l@CCH@A\/++''(1@@CH@De+©'8(rW@@CH@F֠+'Z)(m@?CH@I`+'J(k@[CH@Nc+'(BAC(@S/++p'Z)( +AC(@X_+m'(AC(@]>ڲ+('(UAC(@bTz+'"(AC(@fB+>"&5(*AC(@kH ++A&](MAC(@p`+1&$(HAC(@uJ+&:*(QAC(@zye+&(QAC(@X8+1&x(HAC(@8+0& A(w)AC(@?+z&(AC(@J+&>x(OAC(@ o+H&o(܃AC(@B+& ([pAC(@@W +_&(+AC(@s`+ &͉(1AC(@R"+C&(AC(@2?+i^&qM(AC(@c+&E(tAC(@8+z&(AC(@@W +&(AC(@`+&D5( +AC(@Ï1+&?(rAC(@n_;+&(kAC(@MTz+&(AC(@-@%N+!&(AC(@ /++@&w(AC(@H ++a&:(AC(@˟`+&(KAC(@y+CM&v(rAC(@ꊠ+&<(AC(@j +&(\AC(@Ie+ B&v(P*AC(@) D+&9(AC(@>-+?&z(&AC(@@W +T&(imAC(@+cV&S(AC(@ `+_&(̡AC(@1+&>(MAC(@f+֡&}(AC(@F?+"&.G(AC(@ %Tz+N&I(yAC(@%c+&y(!AC(@)@%N+&/(KAC(@.8+&a( LAC(@3/++&v(AC(@8@W +&m(;jAC(@=d+&((AC(@BC+ B&.(P*AC(@G#+gU&-(AC(@L?+&(AC(@P1+&'(kAC(@U¿ڲ+&(AC(@Z+;&G(9AC(@__;+&(YcAC(@db?+8~&(iAC(@iA+&(AC(@n!Tz+d&M("AC(@s o+&(6AC(@we+&߽$(AC(@|c+ࡐ&ߛ(ÏAC(@_mY+U&ݞ(#AC(@@%N+&ݦ/(JAC(@a@%N+&&;2(W"AC(@A D+&އ<(AC(@! D+X&(AC(@B+&(,AC(@B+d&ڟl(96AC(@B+]N&!( AC(@B+h&J(DAC(@B+h&ڌ(DAC(@`B+k&ٕ(BAC(@@B+7&(KAC(@! D+B&9(n>AC(@ D+Y&إ(AC(@@%N+&](?AC(@@%N+ވ&^(kAC(@ϡ_mY+ް^&([AC(@ԁc+&(0AC(@ae+f&(AC(@A o+^&7(e-AC(@!Tz+3&ҹ(}AC(@+2&Ӏ(|IAC(@?+~&(yAC(@_;+͔&s(P_AC(@+V&Ԇ(GAC(@ڲ+<&g(;AC(@c1+LD&O(AC(@C?+)&r(>.AC(@ +#`+)&ЛS(>.AC(@`+֣& (^iA +C(@+ٔ&,(@UA +C(@@W +ƒ&ս( AC(@!+6&C(bAC(@">-+ک&(A +C(@'e D+e&h~(~A +C(@,E_mY+ j&Ӛ(mA +C(@1% o+ٴ&Ӣ(UA C(@6 +W&(A +C(@:_;+Lv&E(7A +C(@?ƿڲ+ٸ&$(WdA C(@Dy+.&= +(pA C(@I+[&N(wA C(@Ng+&Ӣ(=AC(@SH`+& +(SAC(@X(>-+/&ލ(AC(@] @%N+T&Ѩ(fAC(@ae+ׂ&V (`AC(@f +3&(AC(@kJ+&(AC(@p1+&|(AC(@uk+յ&(:AC(@zL+W&Ǚ(-AC(@,!+&Ѕ0(^AC(@ B+Վ&φ(AC(@c+I&i( AC(@ +ԎK&1( &AC(@+ e&D7(YAC(@?++&(AC(@o+&.(PAC(@P`+)&ͅ(AC(@0B+]&G(BAC(@e+T&+(AAC(@ +Ӡ&ˈ(pAC(@ҿڲ+4j&;2(+AC(@+uD&ʫP(UKAC(@H ++2&h(AC(@t>-+8&(.AC(@U_mY+҇z&Ȯ/(AC(@6 + &%(AC(@ڲ+҃&(AC(@+&v(rAC(@@W +X&3(!AC(@8+&xG(jAC(@噠e+!&b$(E4AC(@z_;+14&8( AC(@[y+&ľ(-AC(@;+S&(}AC(@>-+&5 (lAC(@c+Ri&F(gAC(@?+}&×(AC(@y+&ù (ϵAC(@ +`&Åe(AC(@>-+Z&d1(֠AC(@ac+s;&O}(5DAC(@B_;+ˌs&•(EhAC(@ #?+r&Û(|AC(@%H ++ΈB&c(.?AC(@)B+Υ&v(@AC(@.Tz+R7&Ðw( AC(@3ڲ+r&?L( iAC(@8`+O&‘( AC(@=h/++&О(vAC(@BIc+&¨ (ϵAC(@G*J+͌&oB(AC(@L `+̷}&7(AC(@P`+&:(AC(@U@%N+R&](;AC(@Z?+ˁ&(>}AC(@_?+ː &v(GA C(@dp@W +Y&B(A C(@iQ@%N+sm&(AC(@n2?+ɿH& +(BAC(@s?+L&= ()A"C(@w`++^&(X(coA"C(@|_mY+O&(5QAC(@_;++^&(coA"C(@+K&P(A"C(@x!+zo&:(9A"C(@Ye+R&a(ݥA$C(@:ڲ+&u(A$C(@+&,(A"C(@8+e5&1((A"C(@c|+O&4(3A$C(@y+&d(A$C(@@W +&R\( A&C(@c+x&[,(~jA&C(@b+p&(~A$C(@C+&g(}5A$C(@$8+y&(}1?A&C(@ +Ɖ&(~!A&C(@?+S&T(}A&C(@!+&9&(~}JA(C(@ԩ o+Ƃ&(~A&C(@ي"+dž&>F(cA&C(@lH ++Z&(}A(C(@M_mY+,&& ~(}'A(C(@.+Wb&.(}~A(C(@+^e&(1%A(C(@ D+A&(}A'C(@_;+&T(~نA'C(@`+Ċ7& ({2A*C(@B+&ח({A*C(@v?+&:(zA*C(@ +W`+b&jX(z A*C(@88+&(yHA*C(@?+&(yA*C(@+&`(yvA*C(@8+Êi&n(zJA,C(@"?+M)&v(y^A,C(@'`+j.&(xA,C(@,B+f&(wA,C(@1b_;+E&.~(x*A,C(@6C+h&(wA,C(@;% D+3&(wKA,C(@@J+&c(vA,C(@D+&j(vA,C(@I@%N+&(wA.C(@Nڲ+&j(v&A.C(@SH ++l&!,(vA.C(@Xme+&T(wA.C(@]O1+&b(uiA.C(@b0!+J&](sA/C(@g+&¯(r?A0C(@k+&٣(vtzA.C(@p8+J%&y(v!wA.C(@u_;+T&Z(wvA0C(@z+ K&n(uuA0C(@y_mY+&o(uA/C(@Z"+&(uA2C(@<!+X&\3(t|A2C(@c|+_&(tA0C(@+ |&?(qA/C(@B+&0(n5A2C(@ +X&h(gRA2C(@H ++&\(^UnA2C(@ o+ &~:(N#A2C(@g?+[&(QA2C(@H8+{&(c-A4C(@*J+w&O(j^ A4C(@ H ++5&(nY8A2C(@e+&G(qHA2C(@?+&aS(pKHA4C(@Ȱ8+1&(qi4A4C(@͒J+C(@3+V&<:(ieA>C(@ o+ &>{(jKA<C(@`+5&(hA<C(@c+&(hg\A<C(@`+'&(g)(A>C(@_mY+њ&[(h_A=C(@?+&(hA>C(@a@%N+&E +(g-A>C(@Cy+&x(gRA>C(@% D+&R](hڧA>C(@1+&[-(gA=C(@B+_&V (gIpA@C(@1+&S(f+A>C(@8+e&(e)A=C(@Ǝ"+iQ&؝(f4A@C(@p8+ &^ (cqA@C(@R"+p&a(dgA@C(@48+f&(cA@C(@"+3&(d+A@C(@8+&2(dA@C(@"+c&4(cA@C(@8+"&(dA@C(@"+]&(eA@C(@8+/&X(e[ABC(@c1+ҕ& (bU9ABC(@DB+ :&(bA@C(@'1+(&(b+ABC(@ D+ǔ&(cABC(@ +y+j&E(a|ABC(@@%N+f&<(aABC(@?+ &H(bABC(@_mY+˒&C(aABC(@s`+Y&#(bABC(@#Uc+f&(aACC(@(7`+[& +(`uABC(@-e+Q&ć(`gABC(@1+&(_ACC(@6Tz+Mx&L(`c)ADC(@;+Mx&(`c)ADC(@@ +&M (_0ADC(@E@W +&;(_ACC(@Jf_;+&yO(^ACC(@OH!+& &(^ADC(@T*+ϐ&ϙ(^zSADC(@Y >-+&V(_j!ACC(@]"+"&#(]ACC(@bB+\x&݉(\RAFC(@g?+0& (]\fAFC(@l_mY+&(\1ADC(@qw+!&ڪ(]*AFC(@vY o+u&F(\AFC(@{;+X&f +(\AFC(@ +&(ZAFC(@@W +&&-([ݡAFC(@J+ &(ZAEC(@ğ/++Uu&n([NAEC(@"+\&.([WAFC(@B+)&([AFC(@k?+&v<(ZzAHC(@Mc+&-(ZAHC(@/+Ns&(YAFC(@Tz+&6(ZGAFC(@H ++&w(YxFAHC(@_;+(&O(YjpAHC(@/++1&(YAHC(@"+&(Y:AHC(@} D+&(YAHC(@_`+g&D(XAHC(@Ae+ &~(W%AHC(@#+&(WAHC(@ +N&-(Wo'AHC(@`+&h(VqAHC(@ʠ+&&(V1AJC(@B+&U(WAJC(@?+1&;4(W%^AHC(@qc+ov&(VQ;AJC(@S+&Ѧ(U AJC(@6 +۾&A(U&AHC(@`+hs&'(UAJC(@ڲ+ +&h(TAJC(@B+&m(U\AJC(@ `+(&(TmAJC(@e+&(TLAJC(@+]&(Tv:AJC(@f?+z&8(S4AJC(@!H/++h&l(S%ALC(@&+1+&(RҐAJC(@+ @%N+D&(R9AJC(@/`+&FF(TaAKC(@4+&H(S8ALC(@9`+Ի&9(TCAJC(@>+&6(R,AJC(@CxB+64&^(SxALC(@H[`+.&f(RALC(@M= o+&C(RAKC(@R H ++y&%(RrALC(@WJ+'&(RALC(@[8+`&(PqAKC(@`?+&O(QALC(@ee+/2&Cg(R'ALC(@j+V&ϙ(RZAKC(@on_;+&o(PALC(@tP>-+&e(PLALC(@y3y+^&=u(OxANC(@~e+:e&F(OANC(@+p&(NAKC(@_;+&k(N wALC(@>-+&(MЃANC(@?+&P(OANC(@e+G&v(NpALC(@d+S&>G(O3ANC(@FJ+^&(MF*ANC(@(8+x &(MfrAKC(@ ?+&P(MЃANC(@ o+P5&Tj(N{%ANC(@H ++&8U(MtGANC(@+u&[(NɋANC(@B+\&S(LANC(@w+ق&I(LANC(@YTz+!&(KUANC(@<`+&(L'APC(@"+P&|(KIANC(@@%N+(& (KANC(@+b&X(LXANC(@ +&X(IcANC(@䨟/++!&(JhAPC(@y+))&(Jr!APC(@me+&(JANC(@P+f&G(H1ANC(@2J+˯&IX(HAPC(@B+&n=(HװAPC(@+&(HAPC(@+F`&($(H)APC(@ !+v&6(HANC(@"+v&(HANC(@_mY+F.&(IOAPC(@c+o&<(HdeAPC(@F_;+)\&B(I*APC(@$(8+;_&(IAAPC(@) `+&f(H_APC(@-Tz+;&q(GTAPC(@2`+&+(GAPC(@7"+7&V(GAPC(@<_mY+X&8U(FAPC(@Aw+?&5(G8APC(@FZ_;+&bZ(G&0AQC(@K-+&s(CyhAPC(@?+E&(D܁AQC(@Tz+o&R(DARC(@`+r&&(DAPC(@"+u&"3(C&eAQC(@ec+;&=u(C]ARC(@H+&>(BVAPC(@*J+&7(BVARC(@ D+&U(@RAQC(@`+&ć(AAQC(@?+R*&(AARC(@>-+&w(AARC(@`+5&P(AAQC(@yTz+`&(AKAPC(@\`+y&(A!ARC(@?1+&(AkAQC(@!c+o.&̆(@PAQC(@H ++&(APARC(@+C&(@VARC(@@%N+F&7(?ATC(@+&(@AQC(@_;+`&Z[(@{AQC(@pB+h^&&(=;ARC(@S+&c(=lARC(@6 +H&;(=kAQC(@/++&.(=)AQC(@?+۩&(>ATC(@Tz+&ɧ(>%ARC(@ `+za&(> JARC(@1+&4(>DAQC(@c+&q(<-AQC(@hH ++=&V(;0ATC(@Jڲ+K&(AQC(@0B+q&s(=/AQC(@5`+&(>-ATC(@:?+&-(=YoARC(@?|>-+&(;ÚARC(@D_`+F&c,(:ASC(@IA+&w(9~AQC(@N$!+D&y(;9AARC(@Sy+&F(;ATC(@W o++&f(;ATC(@\`+;&Y (:uAQC(@a"+&B(:NAQC(@fc+f&M=(9&ATC(@ktH ++H&~(9oATC(@pVڲ+z&(:7ARC(@u9@%N+&(90"ARC(@z+3&(8VATC(@~J+&tc(9AQC(@B+ &(9õAQC(@ß`+5&(94ATC(@?+!&(8|GATC(@8+&(9YARC(@k`+LS&(8ARC(@Nc|+k&(8_ASC(@0/++P &(7pASC(@?+P &E(7pATC(@Tz+ՠ&(6ARC(@`+WT&V(7zARC(@1+=&W(8,ATC(@e+.&(7ATC(@@W +&(6wAQC(@bڲ+6&jX(7PAQC(@E_mY+A&jX(6ATC(@(+ &N(7-ATC(@ ++6&!(7PARC(@ D+LS&r(8AQC(@Ͽ+&D(6+ASC(@_;+l&(6ATC(@B+7L&(4ARC(@w+F&(3ARC(@Z +u&(3ATC(@<>-+i&~(3AQC(@?+1&(3qAQC(@Tz+&(1ATC(@!+&(2ATC(@y+&Es(1[ARC(@ e+>,&X(2;ARC(@@W +v&@(1ASC(@n"+G&-C(1AQC(@Q_mY+4&(30ARC(@ 4+I&Y(3ATC(@%+n&q(3?ATC(@)@%N+&(50WAQC(@.ۿ+,|&(4AQC(@3_;+&(3ATC(@8B+Wd&,(2[bARC(@=+&}(0ARC(@Bf +n&Cf(/ ATC(@GH>-+&(0xAQC(@L+?+;&(1-AQC(@Q Tz+l&ҫ(2 ARC(@U`+I&P(1qARC(@Z1+5&=(20ATC(@_e+&X(1դAQC(@dH ++&r(/=AQC(@izڲ+F}&gy(/cARC(@n]@%N+<&(/\uARC(@s?+z&q(.,ATC(@x"J+&<(/MAQC(@}B+V&(/AAQC(@`+ &u(/hARC(@ +A&_(/@TARC(@>-+<&(.bAQC(@?+ &(-tAQC(@qTz+!&R((,ARC(@T`+P&(-HARC(@71+v&(,AQC(@c+&(,AQC(@H ++F&a(-ZARC(@ޠ+4%&U(-ARC(@@%N+&Û(.AQC(@+&j#(-APC(@?+1&F(,HARC(@h8+gN& (-QARC(@K`+&q(-+ARC(@.c|+&(,y4AQC(@!+ڡ&J(+UIAPC(@1+)&(,*ARC(@ՠe+&u(+rAQC(@޸H ++c&o(+APC(@㚠+& (+\4ARC(@}@%N+ &'(+AQC(@_+8&e(+APC(@B?+~&s(*߰APC(@$>-+&H()ARC(@`+`&•((|APC(@t8+ǐ&†((ANC(@ +Z&((ATC(@W+&ʼn((zASC(@ȿڲ+U&İ<('{NAPC(@ +:+0&@('KAPC(@ @%N+w&a('APC(@!+R&('d?APC(@ o+3&|((bAPC(@1+H&c()SAPC(@p?+&º{('APC(@+&((APC(@Rڲ+.q&ĀE('APC(@+`&((*APC(@ 5@%N+D&('APC(@"!+ &('APC(@% o+O&(&˚APC(@'B+&E(';APC(@)?+1&j(&?APC(@,k+x&5('APC(@.ܿڲ+&~(&APC(@1N+ާ&9(&;APC(@3@%N+&Ėh(&B,ALC(@60`+&C(%AKC(@8`+F@&NB(%xAPC(@;8+=&ɒ(%n APC(@= +'D&{Z(%PAPC(@?_mY+(&Ȫ~(%!{APC(@Bf+g&Ɓ($\APC(@DTz+ &VA(#mAKC(@GHB+&@(#ALC(@I?+~&Q(#APC(@L++~ &F(# APC(@Nڲ+Y5&ć(#lKAPC(@Q+&E>(#BTALC(@Sy+&F(#BTALC(@U`+}&("\4APC(@Xa`+}4!&(" APC(@Z8+|&ɴ (!ALC(@]D+&U(#EALC(@_@%N+}ߠ&("zAPC(@b&!+y&]8(# AKC(@d`+}&̤("EALC(@g8+~H&ͮc("APC(@iz +}& ("=ALC(@k@%N+|&ʠ?(!Y}AKC(@n\!+}&ܵ("lAPC(@p o+}s&LJ ("5wALC(@s>8+|<&(!ALC(@u +{&))(!"ALC(@x!@%N+|&?L(!DAKC(@z!+|&¨ (!QAPC(@} o+y&( ALC(@t8+xu&Š(R6ALC(@ +x=&b(ĢALC(@W@%N+y'&*(uAKC(@!+z>&( (2AKC(@9`+{&V(!5ALC(@8+z&̤( ALC(@+x= &{Z(bAHC(@y+y &L(d3ALC(@`+y|&(iEALC(@o+xzH&aR(AKC(@ڲ+v[&(RAKC(@QTz+r 5&(AHC(@1+l&(^ALC(@4?+qi&( AKC(@_mY+r|-&(0AHC(@!+s& q(ޝALC(@ o+u&Ļ(ALC(@8+s&(AHC(@j+p{&(&AHC(@y+n>&(z?+fg&c(aA@C(@G@%N+g&6|(sA@C(@J ?+f~&(A@C(@L@%N+dK&B(A@C(@O?+cWz&w(A@C(@Qs@%N+a:S&(%TA@C(@S?+_U&T(*tA<C(@VUy+c&Dl(6A<C(@X +eC&(^A@C(@[7y+d&(gA@C(@] +ee&d(RA@C(@`y+c&W|(^A<C(@b+ax&u(A<C(@d1+c &(O>A@C(@gl+c&1(6A<C(@i8+c% +&Ðw(_bA<C(@lMTz+b&(EA<C(@nڲ+dH&1\((A<C(@q/ o+cvv&Ě(A@C(@sڲ+`r&H(A<C(@v`+b7&s(ǩA<C(@x+a&6(A<C(@z+a&el(\A8C(@}d`+bN&B(A<C(@_mY+c&1((A<C(@F?+cA$&(q_A<C(@@%N+c &$(MA<C(@( +`&0(A7C(@B+`4 &/(}vA<C(@ ++a&R(kA<C(@z8+`e &iQ(A8C(@ o+cM&/(yA8C(@\+^Z&Åe(A8C(@̀+]&( A<C(@>!+\\s&2( A<C(@_mY+ZE& +( A8C(@ ?+Y_&d( J{A8C(@y+XJ&>( +ƖA8C(@+\&W( ;A8C(@r8+] c&U( vA8C(@ o+^G)&{[(BA8C(@T+^&(6A8C(@ŀ+]#T&n( @A8C(@6`+]&( @A4C(@y+\&( )A4C(@+\-& =( A8C(@8+\>& ( A8C(@ o+Z=&2( ݗA8C(@j+]y&%( A4C(@_mY+]&(A4C(@L?+[!&X( {A8C(@y+Y, &‘( +wA4C(@-Tz+V}&( A4C(@ƞڲ+WD&A( ŷA4C(@+Z&|( A4C(@ˀ`+Z&( A4C(@y+Z&#( A4C(@b+Y ++&( +A4C(@ҿڲ+Y:&( v=A/C(@ڲ+[,^&|( E[A0C(@w+\ʳ&( NA4C(@`+\X &"( 3A4C(@Yy+[( &ǯ( BA/C(@Tz+Xh&p( +aA0C(@:+VE&܁( VA0C(@_mY+Uo&Z((A0C(@ +V&( NA0C(@8+Y&( +A/C(@`+XJ&Ը( +ƖA0C(@n`+Yc&>( 6A0C(@y+W&2?+M&(?A(C(@@8+Lr&œ(4A(C(@C+L7:&(A(C(@E +KO&!(A'C(@Gڲ+M9&r(XDA'C(@Je_mY+MyS&(A(C(@L+M~^&(A$C(@OF!+N(&s(ZA$C(@Qy+M&(pA(C(@T' o+Mx&8 (A(C(@V`+M&x|(A$C(@Y8+N&(A$C(@[y+M=&(ZA$C(@]+Mm&˛(yxA$C(@`Z+L&N( gA$C(@by+M]&Ӛ(oSA$C(@e; o+J&7(A$C(@g?+GGV&'AC(@jڲ+IY&(A C(@qn`+Kd&,<(, A C(@s8+KC&7(A$C(@vO+K +&)(wA$C(@x+J&(AC(@{0!+J6-&Z&(jZAC(@}B+KQ&([A C(@€+KpY&V(3lA C(@‚+K\,&o(&AC(@„!+Kg&d0(-A C(@‡c1+H&"(AC(@‰_mY+H@&R()aAC(@ŒCTz+H&֡y(sA C(@Ž`+Hz&([/A C(@‘$8+H&ʬ( AC(@“@%N+HΜ&Ӹ9(;AC(@– o+H&(AC(@˜v?+G m&ΰ'AC(@š+F&I'AC(@Wy+F6&'AC(@Ÿǀ+F-&'mAC(@¢8+D&>F'AC(@¤`+C&<'AC(@§8+@&'+AC(@©@%N+?&XN'AC(@«`+BE&X'iNAC(@®j+D&u'sAC(@°!+D&܂'SAC(@³J8+DJ&-A'@AC(@µ@%N+Cd8&ó'AC(@¸+`+D(&v9'AC(@º+D&ڱ'xAC(@½ `+E4&׮'lAC(@¿|ڲ+E#&P'AC(@y+F<&#'qAC(@]+E9&9'`IAC(@Tz+D&'AC(@> +B&ǃX'9AC(@ˮ!+Ckm& <'#AC(@8+@E&Ӣ'AC(@Џ@%N+B__&j'AC(@+Bu&'AC(@oTz+BB&ۮ'AC(@ +@&z'!AC(@P!+@#<&'AC(@ڲ+?I&޷2'AC(@1y+>&E'AC(@_mY+?&W{'CAC(@`+B__&ͣQ'AC(@+@K&n'#PAC(@?+ArM&'AC(@b!+@&|'AC(@ҿڲ+Aؠ&֖g'AC(@C1+CX&' AC(@@%N+C&'AC(@#+As&!]'dAC(@ o+@-S&'AC(@+>&ڧ' [AC(@t?+?&]7'>AC(@!+=&' AC(@Tڲ+>r&'BAC(@B+>W&^'5A C(@5y+>ȣ&B'4A C(@_mY+>KB&'AC(@ `+>&z'LA C(@  o+?҈&t'\A C(@+??&'4A C(@f +>'&'joA C(@`+>\&'4A C(@F!+>&']AC(@+=B&>'A C(@&8+<ǖ&ۚL'PA C(@1+:%&~l'DAC(@!y+:-&ŋ'N&AC(@#w@%N+;&4'A C(@%+>7&5 +'N[A C(@(W`+=K'' +AC(@* o+<)''fAC(@-7Tz+;o''[AC(@/+;+k'e:'AC(@2+;:''AC(@4 +<&'pAC(@6?+;&@'AC(@9h`+:Ɖ&t'AC(@;`+;m&'AC(@>H!+DAC(@l8+76J' m'AC(@o8+7' a'qAC(@qx8+7>' f'AC(@sڲ+68' '>DAC(@vXڲ+7'vr'E"AC(@xȠ+6<''CAC(@{8+64R';'8AC(@}!+7'''p{AC(@À`+7|'eo'QAC(@Â?+6W''eAC(@Ä?+5'rX'nAC(@Çh +4' +P'皚AC(@É+6''AC(@ÌGTz+5''w AC(@Î o+5''AC(@Ñ'`+5b'_'AC(@Ó+4'7'>AC(@Ö_mY+2'!'AC(@Øw@%N+3['"%'@AC(@Ú1+3'#L'%AC(@ÝV8+2@'$'AC(@ßƿڲ+0'$s)'AC(@â6!+.'#:'fqAC(@ä`+.'#c'޾AC(@ç +-܉'"'ފAC(@é+02'!R'wAC(@ë o+0'D'AC(@îe`+1ޣ'A'UAC(@ð_mY+0'R'EAC(@óEy+1+''ǘAC(@õ8+2"^' 'AC(@ø$+1l'n'AC(@ú`+3 ''HAC(@ý +1L' O'vAC(@ÿsTz+0sw'!9'zAC(@`+1'%'O-AC(@P+/(aCA H@ʪ+/(`ՃA @@+/S)(`jrA H@k+.(_A @+.(_^A D@ +.(_kzA H@+.F(_A @+-(^A @U +-(^3UA @ +-?(]NA @@@+,(]9|A @}@+,`(\A @ +,((\\A @K +,](\+A @++([9A|@%++r([sMA @ ++!([ A @+*(ZA|@g+*r6(Z+A @ۀ+* \(YkA|@B+)(YF*A @" +)x(XAt@'*+((XN(A|@++(!A(W4A|@0+'W(V2Ax@4`+'y(UAx@8 +'B(VAx@=m+'UR(V/A|@A+&(UAx@Fa`+&n(U3A@J +&u(U&Ax@OU+&Z|(TA@Sɀ+&(TAx@XJ +%(T?A@\+%(SA@a>+%9(S}HAx@e+$"(SsA@j?+$.6(R&A@n@+#w(Q=A@s@+#U(QA@w@+#r(Q6A@|N+#[(QA@Āπ+#(PA@ą\+"3(PPA@ĉ݀+"n(OA@Ďj+"#v(OA@Ē@+!.(OcA@ėx+!(N0A@Ĝ@+!O(NzrA@Ġ+! +#(N!tA@ĥ!+ Z(M"A@ĩ+ (LA@Į;+Z(KhA@IJ@+=(K29A@ķc+(JAH@Ļ+(KA@~@+(K)A@+a(JhAH@ɲ+K(J(AH@@ +(J +3A@`+(I5AH@t+(Hx8AH@+(GXA@@++(EAH@C +)(ETAH@`+(FTKAH@w+J(F"AH@+(FKA@+q_(EAH@_+:(EjA@+(DAD@+(E vA@ +;@+(E'AH@@+(D|A@@+>(CA@0@+(CyWA@@+w(C(A@!~`+ӛ(BVA@&%`+2[(A"A@* + (AUAx@/@+A(AA@44+*d(A}Ax@8+_/(@yA@=+{B(?VA|@B5+(?^IA@F+(?A|@K`+(?Ax@PQ@+ (>A|@U +~(+c (;`Ax@ň +(:A@ō+!(: A@Œ`+ (:uA@ŗM+u(:%A@Ŝ+ +(:QA@Š@+P/(:`*,'A6|@ *'CA8@*'BVA8@*E'$A8@$N`*x'AA9@* *V'nA8@/* D'AA8@5`*.'A9@;^ *q'}HA8@A+*;'A9@F@*'A9@L*h<')BA9@R`* 'OA9@Xb*'!A9@^/*'{A9@c *'A9@i׀* '~A;L@o*9-']A9@u`*9'A;L@{Y*,'A;P@ʁ'`*'pA9@ʇ*'2A;L@ʌ *YG'eA;L@ʒ*'A;L@ʘ*P'A<@ʞx *%6'mA;L@ʤR`*'A;H@ʪ9*{'A<@ʰ*0o'3A;H@ʵ@*m'詁A<@ʻ`*D'NA<@ɀ*;'R7A<@ǰ*['۠A<@͗*/|'.A<@ * 'wA<@s*7'A>|@Z *h'A<@N@*';A>@5`*̨'A<@)`*x+'pA>@@* ('3A>|@`*'㈯A>@`*Y'A>@@*7'ZA>|@`*'.6A>@@*`.'A>|@* 'WA@@ *'PA>@&*?'QA@@,נ*'[A@@2؀*'ߩA@@8@*w'QoA@@>*f';A@@D*9'oA@@J۠*uO'A@@P * ,'݁AA@V*yV'EA@@\*'.AA@b*-'A@@i*'ۺ?AA@o*k*'jsAA@u!@*"' AA@{.*`'ږ=AA@ˁ<*d&'AA@ˇV*i'ٳACL@ˍd`*';AA@˓~*B'ا%ACP@˙`*"'DAA@˟*r' ACP@˥@*'׿ACL@˫*='YACP@˱*'ACH@˸*'ցACP@˾**3'ACL@R*'lIAD@l*''ԭACP@Г*'AD@֮ *'ACP@@*q'AD@*8'WRAD@#*'ҐAD@K*$'AD@r *' AD@@*1'AF@`*!'љAD@`*y4'>AF@(*+8')AD@\*'gAF|@*8'ϤAF@ Ġ*B'iAF|@&*'ͱAF@-,*'ͥAF@3`*'͇AF@9*v'cAH@?ՠ*g'QAF@F*6'AH@LJ`*ڍ'̜AF|@R@*['AH@X*':AH@_ *i'AH@eM*':qAH@k`*S'a9AI@q@*'IAH@x *K'VuAH@~j*\'lAI@̄`*,'/NAKP@@*'AI@4*'ĬTAKL@Џ *Z'JAKP@*'OAKP@D *+'ÝAKP@@*'AAL@*E'AKP@m*'gAL@ǀ*i'.AKP@.*%'xDAL@*'2AL@ */'<3AL@d`*'AL@ˠ*g''AL@?*|n'WAN@#*'gyAL@*@*L'~AL@0@*'AN@6@*x'#)AN@=j@*C'tAN@C`*'w AN@JR*'AN@Pƀ*$L'WlAN@W:*<'-AN@]`*' AP@d/`*]'DNAN@j@*' AP@q1 *o''AP@w@*'LAN@~& *W' AP@̈́*'AP@͋4*'DAQ@͑`*`'AP@͘6@*#'AP@͞*n'6OAQ@ͥQ*'ٚAQ@ͫҀ*E'cAP@Ͳ`@*ە'۠AQ@͸*s'{tAQ@Ϳ{*j'KAQ@ @*&%'cAQ@̣*'o7ASP@1`*pQ' +AQ@*-'/ASP@Y*'*AQ@*B'ASP@펀*l'0ASP@)*,' 9ASP@`*'FASL@]*s '~ASL@ *^u'dlAT@* 2'"ASP@F*Y'xAT@`*R' ASP@"*'}#AT@)0*b'ٿAT@/@*:'AT@6~*J'AT@=2*2'bAV@C**'W@AT@J*'AV@Q5@*S'jAT@W@*' AV@^`*'AV@eQ`*67'ʃAV@l*B7'AV@r*m'AV@ym*Ih'AV@΀.*'AX @Ά*\'CAV@΍*' AX@ΔW*o'ˠAV@Λ*H'( +AX@Ρ`*'pAX@Ψ@*'AX@ίh *'(dAY@ζ)*k'AX@μ*ܘ'AX@÷*)F':AY@ʅ@*.'ϗAY@R*R'IAY@*2'AX @`*X'ׯA[P@*'AY@*'?AY@W`*'(AY@2*'tA[T@ *|G'#A[P@ *y'AY@*y_'VA[P@@*{;'9A[T@i*~'_A[L@#D *~'-A[P@*+`*~/'A\@1*}l'1=A[T@7@*}X'$zA\@>*},G'A[P@E*|h'A\@L*{u' KA\@S}*{"'A\@Ze*z 'A\@aY@*x''KA^@h@*w;A':gA\@o4*tM'ZA^@v*p7'A\@}*o'ZA^@τ *q#'ԑA^@ϊ@*s'EA^@ϑ`*taZ'gDA^@Ϙ*tj'mEA^@ϟ*tV='`'A` @ϦՀ*s}'A^@ϭր*sU'A` @ϴ`*r'A`@ϻˀ*r'PRA^@̀*r'3)A` @`*r4#'A`@ *q3'Aa@*pS'A`@*ot'@A`@*n~'Aa@`*m'(Aa@`*lpT'R!A` @*jw'Aa@ +`*fj'wtAa@*bA`'ͮAcX@*`1'|Aa@ `*b0j'Aa@2*d'AcX@*f'AcP@F*g!'Aa@ *f"'AcX@a`*fyZ'AcP@ *fg'CuAcP@$@*e'$Ad@(*d/'AcP@+@*df'-!Ad@/0*c'AcP@2 *b'FIAd@6W*b'AAd@9*b'Ad@=@*aob'GIAd@A*`1'>Ad@D*_{'8Af@H@*^ہ'Ad@K*]}'Af@Ot*]k'Af@S*\';ZAf@V*[R'4Af@ZC*Zl('WAf@] *X['ƠAf@aw *W'Af@e*S"'*Ah @h*Nġ'TAf@lR *Lo'Ah @o*N՜'_Ah @s *R'+Ah @w3*T1'Ah @z *T'Ah @~{*T2!')Ai@Ђ`*S'kAh@Ѕ`*S'tAi@Љi@*S+'gAi@Ѝ *S' Ai@А*R['Ai@Д]*QM'5PAi@И*Q'Ai@Л*P? 'GAi@ПX*OI'AkP@Т*O<'Ai@Ц *N'FAkX@ЪZ`*N'AkP@Ю*M{'CAkX@б*L'AkP@еb@*K.' AkP@й*J.'Al@м *J'1AkH@v*JZa'Al@**I'!DAl@@*I+['Al@˒*H'QAl@E*G'Al@`*F'~s.Al@ֳ*F;'} An@g *E('|Al@!@*DA'|An@`*C%'zbAn@ *B.'ysnAl@O*A+'wB;Ap @ *>V 'sqAnx@à*:# 'nAVAn@}*5.L'gWAn@>@*4J'f6Ap @*8l'lAp @@*;'pAp @*=Y'r]xAp @@@*='rAp @ *=='r:Ap @@*I`*'>CA@BP@*9'=A@FW@*':mA@J^@*T'6.A@Nk*'-A@Rr`*=')MA@V*-5'.NWA@Z* '5DA@^*'8%8A@b*S'8A@f */'8At@j€**'8A@n*'7[A@r*G'7fbA|@v@*'6pAt@{ *G'6:Ax@* '5Ax@҃2* l'5&Ax@҇F@* P'4Ax@ҋZ* $'42Ax@ҏt * k'3RAD@ғ@* a'3=AD@җ* 3'2AH@қ€* 13'2*~A@@ҟܠ* +I'14AD@ң* +|'1CAH@Ҩ`* '0A@Ҭ1* z'/AD@ҰR * '/vnA@Ҵr*~'/PA@Ҹ *W'.A@Ҽ* '-A@@*mw'-XA@@*?',ϭA@*&',ScA@B*1'+A@i*6'+A@Ր*'*UA@ٷ*x_')A@ހ*-'(A@ *'(A@2*X7'(A@` *F''eyA@*t'&DlA@*'$A@ )]'!EA@)I'XGA@I@)'XAt@v)%W'A@`)'At@ @)Q' A|@)'!@TAt@E)`'!RAx@y)2'" A|@)ċ'!xA@@ `)'!UA|@%!)R' ةAD@)[)s' S|AH@-)'A@@1)@'nAH@6 + )' dAD@:J)M'A@>)'XAD@Bŀ)/'A@G)I'WA@KF)')A@O )'xA@S ),';A@X)6'A@\U)c'}OA@`)c' A@d)4['DA@i*)w'gA@mq)X'A@q`)'-A@v)j'vA@zL)'A@~ )L'aA@ӂ)c'@A@Ӈ4)/'?A@Ӌ)2'pA|@ӏ)H'A@Ӕ))M'{A|@Әw )U' A@Ӝ)''A|@ӡ)'31At@ӥr)Q,'OA|@ө)''SLAH@Ӯ `)'>At@Ӳz)6^'jyAH@Ӷ`)₵'~Ax@ӻ()'AD@ӿ)')AH@@)c'A@=)߭,''&AH@̗)g'AD@@)*'%9A@X)]C' TA@ٹ`)' MA@)*' A@z)sI' rA@)ڰ' BA@B )@' 3A@)r' *A@)\' +A@w )'8' +VA@)x' zA@E)q' wRA@`)F' KA@ +`)e'A@)Խ''A@ )'YA@a)v<'UA@)ҳ' A@ B)K'OA|@$ )('ܵA@)#)Л3' Ax@-)')Ax@2 )ab'4A|@6@)Ηh'7Ax@:)'dAx@?m@)aQ'q{AH@C)V'Ax@H[ )P'AD@L`)˯'[AH@QO)7'`AH@U)O'zAD@ZJ`)ɥ' A@^Ġ) +'@AH@cE@){'O,A@g)&$A@lF`)&CA@p)(&A@uG)x&*A@yΠ)b)&A@~O )?&A@Ԃ )3E&"A@ԇ] )Ë&L7A@ԋ )&&bA@Ԑk )&WA@Ԕ)R&tdA@ԙ)&A@Ԟ )if&IxA@Ԣ`)K&iA@ԧ')6&A@ԫ )[&6A@԰H)& Ax@Դ`)M&OA@Թj )&PAx@Խ)9&&A|@‹@)X&-A@)"&~AH@ f`)k&A@%M)z&A@*. )&A@/)@/&{A@3)-&%A@8)nA&nhA@=)"&6A@B)rE&+A@G`) &yA@L`)w&VA@Ql)&lA@VZ@)&|A@[G).&FA@`5@)&A@e")F&A@j);&`A|@o +)i&2A@s@)Q&v*Ax@x )&A|@})&XAx@ւ)v&nA@և )7&2AH@֌`)ɸ& +AH@֑ )[?&Ax@֖)a&RA@֛ )o1&|AH@֠`)&Y[AH@֥)&A@֪)*&KaA@֯`)&A@ִ)K&-A@ֹ)X&GA@־`)t&A@`)&JA@ɀ)t&vA@Ѐ)&cA@נ)F&A@ޠ):&A1A@ )v&cA@)&VA@)Y&^A@))&KA|@")H&õA@/)&8 A@C`)oT&8A|@P)&!EA@d)&A@ +x),!&Ax@)&AH@)~ވ&A@)~&@AH@)}&AL@׹Ϡ)e&AD@׿ +)d6&AL@J)dN&A@Ʌ)cm&PAL@)c<(&n.A@`)bl&A@M)aޢ&|A@ގ )a&A@)`@&eGA@)_ V&7A@] )^Ku&DA@@)].&yA@)]1u&KA@8)\&(A@@)\&ЭA@`)[t&sA@)Z&A@n)Y=&mA|@@)X3&A@ )W& A|@#])WP&A@()V&hA@.)Vc&5A|@3_)U&AH@8)T)&?vA@>)S&&KAH@Ch`)SD &5AL@H )R&AH@N)Q>&aoAH@Sw@)Qd&AL@X)P`&\A@^8)OX&A@c`)N٠&bRA@h )N&JA@nZ)Nt&!A@s)N&?A@y")Ms&|A@~)LW&A@؃)L&&CA@؉^`)K~&)E=&|wA@ؿ@)Dc&| +Ax@,)Di&{h`AL@ʠ)C&zA@)Bv&yEAL@Օ@)A&xPyAH@)As&w,AH@)AU&wx&AL@ +)@b&v}A@)?&uAL@)?6&tA@`)>&sA@ )=]&rlA@@)<|&qCWA@);&ocA@ ):&nA@@)9&n$A@`):>C&nd,A@1):=&nbA@")9&n4A@(F)9&mwA@- )91&lSA@3a)8n&lA@8@)7Z&k/A@>)6;&j7Ax@D)6,&i.A@I)5&hKA|@O8)5k&h7A@T)4 &gkAL@Zf)44&fA|@` )3%&eAL@e )3&e#A@k5)2Z&dJA@p@)1 &cYAL@vj)0{&bUAH@| @)/K$&``.A@ف)-&^_A@هL),&]dA@ٌ`)-#&]NA@ْ )-&]A@٘5`)+&[wA@ٝ܀)(i'&WA@٣}@)#Ӝ&QA@٩*)#r&Qq6A@ٮ)'k&VLA@ٴ))&YCA@ٺ&)*+R&Y A@ٿ ))]&YkA@Ł))$&XA@5)(*&WiA|@@)(It&WhBA@֗ )(&WA|@K )'&V{A@ )'&UA@)&`>&TA|@m`)%&T"WAL@')%Bk&S7AP@@)$&RAL@)#&QAH@V)#&PAL@ +@)"k&OEAL@)!D&O4A@) D&NA@S)U&KA@!@)&JOqA@&`)2&J~YA@,)&K^A@2i)&KA@81)&KjA@= )&JnA@C@) &JgA@I)&IA@OZ`)5&I:^A@U')&HA@Z);&GA@``)&GUA|@f)9?&FA@lk)&EDA@r?)&EG?A@x`)v&DAL@}@)5&DA|@ڃǠ)_&CFAL@ډ )N]&BAP@ڏ|)t&BOAL@ڕV)Pe&AAL@ڛ7)&A3A@ڡ)Q&@hAH@ڦ)&?̱A@ڬӀ)a&?5(A@ڲ)&>A@ڸ)^&=A@ھ)ӊ&=7A@i)T &&YAƄ@#(y&A|@) (i6&uAƄ@/(Ͳ&dAL@6'("&Aƀ@`(}1& +A@(\& +Aʹ@ @(& A@&(iW& 9-Aʹ@,(յ&A͸@3b(&SA΀@9@(R&Aʹ@@D@(Ӡ`&pA΀@F`(&A΄@M2(@&nAP@S(і"&"A΀@Z!`(l&AP@`(;&EAL@g@(ύ&ՠAP@m( +&eAL@t(/&A@z`(̀k&cA@݁@(`&A@݇ (<&A@ݎ(Y&$A@ݔ@(ʋ&4A@ݛ#(ɉ&A@ݡ(ر%ͯA@ݨ8`(ό%AѴ@ݮ( %bkA@ݵM`( }%XAѴ@ݻ(Ħ +%AѴ@h(o%AѸ@(N%AҀ@ϐ(F%:A҄@%(O%FxA҄@ܹ(ú)%AҀ@M (%A҄@(r%AP@($%BAL@(m%AP@(b%@AP@W(%A@ +(B%A@(%,A@:(Q%8A@`(e%mA@%(_%A@,)('O%'A@2@(%A@9x(-%pA@@& (s%~Aմ@F(%oAո@M(2% Aմ@T/ (%[Aմ@Z@(T%vAք@a`(Z+%Aք@hK`(%Aր@n(ժ%迒Aք@u(z%J>Aք@|n (%mAP@ރ((u%&AP@މ (4%AP@ސ(3(%`3AP@ޗ^(%A@ޞ`(/%-A@ޤ@(%UA@ޫ@(%⌋A @޲h(]`%3A@޹/(X%A@޿((%3A@ƾ@(d%8mA@ͅ(l%ގA@S`(%Aٸ@!(|%nAٴ@(fa%ܬAٸ@(%Aڀ@([T%V.Aٸ@d('%ڡyAڄ@8(C%`Aڄ@@(%>/AP@ +@(!"%|TAڀ@(s%ײAT@`(%AP@}@(%hA@&W(%վAP@-8(t2%A @4(%_A@:(]%ӫjA@A('%'A@H(,%$A @O(%}A@V(3%OAݸ@] (%?A@dl(#%ωAݴ@kZ(%'Aݸ@rH@(F%.nAݸ@y5(%͉Aݴ@߀*($%Aބ@߇@(w%}Aވ@ߎ@(%|2Aހ@ߕ`(]%wAބ@ߜ(e%3AT@ߢ`(]%mAL@ߩ(ú%ȨAT@߰(F%AP@߷`(ԕ%vA@߾(X4%LAT@(%(A@@(O%ŃA@ (ܢ%rA@`(_]%QA@(6%êA@ (c%A@(~%nA@ (_%DA@.(%A@ (^x%xA@'(ї%ĘA@ (;%A@ <(u%;vA@ (ǃ%(VA@P (% A@`(%AP@j(.%AX@(%VAP@"`(!%A@&(C%pAX@)@(|%A @-6(a%A @0@(%7!A@4Z(<%WA @7(т%λA@; (%8A@?(J %!UA@B(!%A@FC(d%A@Iڀ(%Z_A@Mt(f$%A@Q `(3%&A@T`(w%PA@X?(r%A@[(8%yAX@_v(-5%ݴA@c@(%DAX@f`(B%vAH@jQ(B%&A @m@(i%AX@q(R%A @u0@(R%q A @x( +o%(A@|t@(7%JA@('%A@(% A@b(Hw%1A@@(%A@ (v%A@T (v%nA@(S%YAx@( %ogA@O( +% +JA@ (5,%uA@द(A%-AX@P(l?%FA@(%AX@௫ (.%AP@[((% +A@(%AX@ູ`(~%A @i(}%c A @(|%A@(|"0%]A @Ɂ({T%٭A@5`(z%Z6A@`(y~%eA@Ԡ(x!%Y A@V(x"%ΠA@(w])%PA@(vE% A@(u%5A@<(tɱ% +A@ (t %0UA@@(sJn%A@m(r%3AP@*(q%AP@ (p%8 AX@(p=%.A @i (ov%AA @)(n%A @ (mҏ%4A @ (m%A @n@(lK%:A@2(ky%bA@(ja%6A@(i%A@(iz%/A@#J`(hi%sA@'(g1%IA@*`(fF%-A@.(f3F%TA@2o(ec%A@6<(d %HAP@:(cڞ%ӘA@=@(c-V%dAP@A(bv%AX@Er (a%wA @I?`(a%AP@M(`O%A @P(_%A@T (^ %fA @X(]%iA@\[(]W%A@`/@(\%5A@d ([%A@g([>~%PA@k(Z%A@o(Y(%cMA@se(Y %A@w? (XT[%smA@{@(Ww%kA@~`(V%A@Р(VJ%% AP@ᆭ(UG%uAP@ኋ@(T}%=AX@h(T"1%AP@I(SZ%DtA @)(RH%aA @ +(R%oA @(Ql%A@р(Pz%A@᥵@(P %*CA@ᩙ(Of%A@(N%M,A@f(Nx%WA@M(MC%^A@4(LO%A@(K;%~A@(KBh%A@(J% A@@(Iؖ%.tAP@`(I72%*A@з(H%Z(AP@Ԩ (G%A @ؕ(G?]% lA`@܆ (F%~+A @v(Eg%}SA @j@(ET3%|A@Z(D%{7A @N(D%zGA@B`(CbI%zgA@9@(BC%yXA@0 (B*%xA@'(A%wA@(@%v A@ (@N%v&A@(?%uNA@ `(>6%tSxAX@(>%sVA@(=%r5AP@ (<%qAX@(<]%qAX@(;%phAP@#@(;;S%oB@'(:%nNB@+`(:%nB@0 (9b%mJBx@4(8%%lrBt@8(7s%ksBx@<(6:%i_B@@@(4%f#Bx@D (1%c>7B@H! (1 %cWB@L+@(3%e5BD@P5`(4%fBD@T?(3܃%f8BD@XI(3j%eBD@\W(2%dB@`d@(259%d*B@dq(1%cbB@h@(1# %b9B@l(0%b +B@p(0%aLB@t(/l%`9B|@x`(. +%_B@|(.N%_%Bt@(-o%^deB|@(-+%]SB@(,+%\uB@0(+ %\'B@G(+`&%[\YB@^(*ǀ%ZB@x(*4%YBH@❒()%Y B@@⡰ ((%XB@̀(( #%WB@('{c%V`B@ ('p%UB@%(&Ķ%UvB@F(&\%TB@f(%ٰ%TIB@⾊`(%P)%SB|@® ($u%RBx@($H[%RH"Bt@(#O%QB|@@(#1%PBt@@`("%P#8B@g@(!E%OXB@ۑ`(!ET%Nm8BD@߸`( J%M,B@(%L8YBD@(X%KB@:((E%KBD@g@(ʳ%K@B@(A%JsB@@(%IB@(h%HfB@# (C%HB@W(޷%GyB|@ (`%FB@ ( %FcBt@(%E^B|@%(7%DEB@Y(_%CB|@(C%CKB@"(%C>BH@'(0%B|B@+<(L%B?BH@/v(D%AB@@3( %@B@7(I,%@]B@<.@(ӕ%?%B@@k(Y%?*TB@D (׷%>B@H(Qs%=B@M-@(Ͱ%=0=B@Qm(M%%9B@f@(%9C~B@k (?%8mB@oX (%8B@s@([O%7B D@w(%6B H@|9(%6mB @〇@( %5нB @Ԁ( %5,jB @!( %4B @r( (%4 +pB +@( 4Q%3v*B +@( o%2B +@g`( +%1B +x@㞸( +6%0B +@( %0?B +@b( PG%/B +|@㫹( *%/B +@(Ϙ%/3B +@g(i%.#B +@(%.NB D@(~%-nB H@v@(%,:B H@Ӏ(%)^B @-(%'B H@΋(M%(bB @(%)ǘB @L@(˄%)BB @۬(%)B @ `(#%)"B @q@(&%(xB |@(R%(B x@8(۝%'B x@(d%&B @(%&WB |@m(e%%mB H@Ԡ(*`%%TB @>(%$B H@ (Z9%$JB H@  ' %#B @@'/%#B @'(%"B @['%!~B @'b%!B@"<'%!B@&@'#% ?B@+'%B@/';%gBx@4`';y%bB|@8|@'c%TZB@<@'%ÈB@Aj@'X%AB@E`'%ʯB@J[`'8%MB@@Nՠ']%BH@SO'\%BH@W ' %FYBH@\G`'%RB@`'4%^B@eE'%RB@i 'V%wB@nF'%B@r`'c%+Bx@wK'/%B@{'Lk%NB|@U'%B@٠'间%B|@`'(%WB@'!%BH@q' %1\B@'I%˳BD@䛉`';%YNB@'}q%ߤBH@䤡'%daB@.'"%hB@䭿'8%lB@O'x%B@@'Ṍ%vB@p'%B@';;%Bx@Ę'~% QB|@, '޽R%Bt@@'%B@Z@':% B@'n% BH@ۋ'۱c% }B@%'% #BH@ ';% vB@]@'ٌ% :BD@'p% +B@ '2% +]B@8'v% B@`'ִ% hB@z'w%B@'J\%Bx@ `'ԓ% B@e`'ܦ%tB@ @')%%B|@ 'r%B@W 'Ѻp%9B@ @'%B@%`'S%SBD@*R'ϤC%BH@/ '%z B@3@'P% +@BD@8W'͏%4B@=`'̻%B@A'%~B@Fi'O%B@K@'ʦ%iB@O'%7Bx@T'i%B|@Y5'ڌ$B|@]'ƌ $#B@b'A$jB@gZ'-$B@l'+$GB@p'`0$BH@u'j$B@zC'$ BD@ 'g$[B@僾'¾F$ExB@ '#=$B@?'$B@`'$B@@'Hi$>B|@囈'$NBx@K'$wB|@'Jw$B|@'w$B@宝'$փB@h'i\$*BH@2@''$nFBH@`'9J$}BD@Ơ''$BH@Ɣ '$B@a'=($B@2@'$SHB@'2$!B@Ӏ'}q$B@ާ`'$wB|@x'Q$]B@O'5$NB@"'t$Bx@'$ +B@'!$BB@@'>$nBL@@'%$䘁B@_' +$B@ +9'$;BH@@' +$|6B@'O$sB@`'$B@'$ B@"'$_B|@'w`'$ޭB@,[ 'l$Bx@1?'$BB|@6&'J$܈B@; '$հB@?@'3j$#B@D@':$d!B@Iŀ'3$ٗKBH@N'h$ BD@S@'v$/B@X'b4$ׇB@]x 'j$גB@bh'Hd$8B@gY`'$cB@lJ ''$ԭB@q='$Bx@v.'$PB@{%'f$ҚB@'$wB@'[$0B@ +'$S%BH@'B @'$B x@'$"B |@'r$DZ6B |@'H$ÍB @ ''$QB @'$KB!L@'$fB @,`'$B!@6'$ăB!L@D '$B!@Q'$HvB!@b`' +/$œeB"@s'$ B"@')$KB"@`'$B"@ '$B"x@ @'V${NB"@ '$ڱB"|@ 'g$2oB"@'U$B#L@!'$B"@&9'$QxB#@+S`',$kB#L@0p')$gB#@5@'p${pB#@:'5$B#@?`'!$@*B$@D '?$;B$@J'ƌ$aB$x@O4'LI$kB$@TX'B$B$|@Y'W$2B$@^'$B$x@c'[$IB%H@h'e$XB$@n@'r$B%H@sL'$+VB%@xz@':$B%@}'$7B%@@'$o B%@'+$B&@6'$DB&@j'Am$B&|@痛 ' $B&@`'T$B&@ '$B&x@=@'b$KnB&@t`'K$B&@籮'Y$7|B'H@'{$B'H@&'$B'@`'4$B'D@ƞ@'B$B'@'Q$^jB(@'$@B(@``'u$EB(@ۡ'$B(@'$,B(|@,'$+B(@o'}$B(|@'C$uB(@@'E$B)L@H`'W$GB(@' +$B)H@@'#$J3B)@ -'~R$aB)@{ '}zn$9B)@'|$B*@`'{$'B)@ m@'z$B*|@%'zA$]B*@+'yG$B*|@0i'xo $dB*@5'w$mZB*@;@'v$B*@@n`'u$jB*@EȠ'u/=$B+H@K"'tfz$jB+H@P's$B+@U'r$^B+@[;'q$UB+@`@'q$M!B,@e'pT$ϸB,@k]'o$PB,@p'nf$jB,|@v%'m0$IB,@{'m#$B,@'lWz$B9B,@Z'k$B,@'j/$AeB-H@/`'i$oB-L@薙'i9$CCB-L@@'hvp$ƮB-@t'g$KB-@'f$B.@V@'f0$RcB.@'ei$ҙB.@:'d6$[B.x@輮'cC$SB.@"'c'$a*B.|@Ǚ'bkB$|B.@'ap$bB.@ҋ@'`5$UB/H@'`$nB/H@'_Z $B/L@'^M$tB/@{']_$B/@`']A$qB/@y '\gl$B0@'[$|B0@}'Z$B0@'YU:$B0@ 'W$w$s̉B6@`'=͸$rB6@'=1$r*UB7L@l'<4$qbB7H@&`';$pB7L@';T$otB7@ ':$nEB7@b`':$n(B8@# '9w$$meLB8@'8_$lZB8@#'82$kB8@)k'7/$jB8|@/2'7$j>pB8@4 '6`$iqB8@:@'5<$huB8@@'5 +$gB9L@FU'4a $fB9H@L#'3h$f1)B9@Q '3T$e`B9@W'2$dTB9@]'2-$dB:@c`@'1e$cRlB:@i1'1$b`B:@o'0q$aـB:@t '/$aNB:@z`'/E$`YB:@ꀊ'.$_B:@a'.|$^B:@<'-]$^B;L@', $]YB;@',ba$\B;L@'+}$[%B<@ꣲ@'+*h$[B;@꩓'*w$Z2B<@w ')g$YwB<@W')s$X_B<@?'($XFB<@#'(ko$WB<@ +@''z$VB<@''N\$V&B=L@'&$UmB<@@'&*0$TB=@޳'%$SB=P@`'%E$SHB=@ '$$RB>@'#$QxB>@s'#C$PB>@g'"T$P3B>|@['"-$OB>@O'!$O,B>@F'!;$N`B>@A ' |$MBB?H@8' 0$M B>@ 2'$LeB?H@&0`''s$KB?@,.'$K +B?@2+'A$J_ B?@8,`'.$I&B@@>-@'$HkB@@D1 'lg$H8B@|@J5 '$GB@@P<`'s$FB@@V@`'$FUB@@\J'm$EoBAH@bR'$EB@@h_'nC$Dd,BA@nj'q$CBAP@tw'a$C BA@z '$BgBA@뀖']$$ABB@놦'\$ABB@댺'a$@}=BB@'$?BB@'c$?87BB@'$>BB@@'`$=BCH@.'$=QrBCP@I 'jy$$ BSP@r`&ه$ 8BSL@ &P$ + +BSP@&$ +OBS@H@&d$ ;BS@ &֬$ dABT@&$BT@. &?>$zeBT@! &Ԉg$`BT@(y`&$BT@/ &$BT@5&f$BT@#1BX@&@#{BX@ &V#BYP@Џ&#MBYP@]`&%#QBY@+&#BY@&ߛ#BY@ɠ&;>#dBZ@&#<:BZ@q&w#jBZ@E&O#[BZ@@&#zBZ@ &#vB[P@@&]x#{B[P@&I#VB[P@"`&&#B[@)h@&#B[@0I &j#B\@7*&A#!B\@>&d#SB\@D@&#댝B\@Kـ&k#YB\@R&#B\@Y@&1#5B\@`&I#oB]@g`&M#窠B]P@nn &b#B]@u_&Ƕ#ZB^@|O&-/#XB^@@&#䔏B^ @5&^#B^@,@&`D# +B^@#&;#=B^@&"#toB^@`&Z#B_P@&]#B_T@ &b#6B_@ &#ޅ$B_@ `&F #LB`@ @&o# [B`@`&#PB`@&#۔*B`@&#B`@$ &fJ#B`@.&Ԃ#aBaT@9@&C #اBaP@F&#yBa@`& #4]Ba@2&Q#|Bb@@&#Bb @ E`&r# Bb@`&e#WBb@Y&V^#ӡBb@&#BcP@r&;}#7Bb@&F#сBcH@ &#Bc@$&#fBc@'`&#cBc@+<&}#εBd@.&#$Bd@2`&hD#RCBd@5&x#̡Bd@9&W#Bd@=&Q#I]BeH@@@&I#ʛBeX@DF&#BeP@G`&:#@Be@Ku&#ȔGBf @O@&-#Bf@R&#={Bf @V@&"y#ƒBf@Yܠ&#Bf@]x@&#=)Bf@a&q#ēBf@d &#KBgP@hN&#C1BgX@k`&#šBg@o&#VBh @s.`&#HBh @v&#Bh@zp&K#Bh@~&wx#Q=Bh@&k#Bh@[&7v#BiP@@&#ڶBiX@&*#_fBiP@M@&# Bi@&#Bj @@& >#Bj @F&(#NHBj @&_#FBj@𢜠&$# Bj@H@&#nBj@&Y#Bj@ &a#2hBkP@P &$#9Bk@&,B#5Bk@&#_cBk@^`&9#Bl @&/#*zBl@ &H#rBl@t&Ϋ#Bl@(`&V#YBl@ݠ&8#BmP@Ғ&i#*OBmP@H &#BmP@&|#Bn @ݷ&#dBm@p&D#kBn @* &#83Bn@@&#*Bn@&2# Bn@[&V#xBn@&Jo#eBoX@@&ֵ#PCBoP@ &dF#Bo@T&R#+Bo@&#KBp @&#Bp @ + &#wBp@Y@&,#Bp@&g#WBp@&K#rBp@&#6BqX@k@&i#)BqP@!2 &#Bq@$&6#Br @( &#Br @,&b5#r Br @0U&~#sBr@4!&}#ZBr@7 &|#ZBr@;&{=#DBr@? &{ ;#wBsP@CU&zF3#,Bs@G$&yq#Bs@J&x#Bt @N&w##Bt @R&v# EBt @Vi &v +G#w7Bt@Z;@&u#cBt@^&t;#OPBuP@a&s#BuX@e &r#dVBuP@i&q#2Bu@mi&q+L#Y&Bu@qA&pc#لBv @u&o5#XtBv@x&n͘#ՀBv@|&mb#QBv@񀫠&m0#TBv@&lc#J%BwP@f &k#ǚBwP@C&j#CBwX@$&i#Bx @&i/#=TBw@&he)#Bx@ŀ&g#<Bx @ &fڅ# Bx@&fo#EeBx@p&e\#FBx@V&d#LByP@;@&cѬ#ByP@"@&c#MOBy@ +&bC!#Bz @@&a#SBz @@&`I#NBz@`&_#W Bz@Ʊ&_="#qBz@ʞ&^x#gWB{P@Ί&]#Bz@y&]#rKB{@h`&\FR#B{@W`&[_#B{@H&Zu# B|(@8&Z}#;B| @*&YW#UB|@@&X|#B|@&W#"B|@@&W#]B}P@&VcV#5VB}X@&U#UB}@&Te#3tB}@&S9#CB~ @ۀ&SG#86B~ @ &RN#ώB~@ `&QY#^MB~@ &Q=#&B~@&P#}+B~@&O#oB@ &OV#UBX@!&N#AB@%Ā&MF#B@)Ơ&M Q#GBD@-@&LF#B@1&K#Bx@5Π&I;#Bt@9`&HR#Bx@=`&I=#gB@Aޠ&IF#LB@E&H[t#:B@I &G#]XB@M@&F#}GBD@R&D#{B@V &D=#{05Bx@Z`&D#{RB|@^$&DZ#{U5Bt@b2&C#z$B@f@@&C-#yUB@jO@&B#xB@n_&Ab#x$TB@rq&A8W#wRZBD@v&@#vB@z &?#uBt@~&?I#tBx@@&>#tB@Ԡ&>#s50B@&=^/#rdB@`&&5#hB@a&5C#hBH@Ą&4#g=Bx@Ȩ`&4 O#fv'Bt@&3qb#eB@ &2V#ddB@ &2;#d#BB@B&1L#c_B@k &1 #b B@&0r4#aB@忀&/#a5Bx@&/C#`VBH@&.#_LB@D`&.4#^ԽB@q&-Y#^B@&, #]UB@@&,V'#\&#y#Q4B@BP&#LA#QrB@F&"#PPB@J &"2#OB@O@&!#NBD@ST`&!#N9jBD@W@& #MB|@[݀& #L}B@`#&}#L&UB@di&#KvB@h&l#JB@l`&#J^B@qB&[#IkYB@u &d#HBD@y&M[#HBx@~#&#GdBx@q&@#F%B@`&#F B@ `&5#EcAB@^&#D B@󓮀&+#DB@&#CdBH@R&#t#BBD@󠦠&B#BBx@&7#AoB@Q`&9#@>B@`&8#@"B@@&#?|B@W&k#>דB@`&o#>3B@ @&#=uB|@f&X#<>BH@&3# &!#9B@ݞ&#9$B@&(#8!BH@d&#7&B|@`&0 #7GBt@-&#6B@@&8#6 B@ & #5lB@b& B#4+B@`& ^#44B@5& Pe#3BD@ & w#3BH@ & `i#2fBx@x& +z#1iB@@& +p#14B@U@& #0B@& #0B@$6`& #/k+B@(&#.@B@-& (#.=Bx@1&#-lB|@6`&5#-Bx@:w&##,|VB@>&M #+B@Ce&I#+SB@G`&e#*B@LX&Q#*+BD@P&#)2BH@UN& #)0Bx@Y&H#(tB@^I@&(`#'B@bƠ&#'PB@gG@&GL#&B@k&#&33B@pH`&g#%B@tʠ&#%BH@yN&#$B|@}&E##B@Y`%W##kwB@ޠ%{#"޷B@g@%#"R]B@%#!rB@x%#!:B@%# BH@`%:}# %oBt@@%b(#B|@@%N#B@6%?#B@`%>#B@V@% +L#w;B@%5#2BH@z%a#gBD@%#eB|@Ƣ`%#YB|@9`%2#SB@Π%#MB@g@%JY#/B@%zy#D$B@ݘ%#B@2%#;BH@Π%#B|@l%C#5B@ `%w# B@`%#1B@G`%!#B@%P#/B@@%Q#BH@,`%燀#-BD@ @%.#B|@u%#-dB@ %1 #B@ %kc#0?B@j%[#%B@#`%?#4B@'%#BD@,g%\#:BH@1%c#SBx@5%q#B3B@:n`%=#ƍB@?`%U#K5B@C%ݕ# aB@H~%W# UB@M0%# zBH@Q%V# ` B|@V%ڐ# Bx@[N%ٱO# RB@`%ؑ# +B@d%טe# "B@it%3# B@n-@%Ԋ# }B@r %4q# RB|@w@%##IBD@|`%#-B@ %^#B@ %XW#BB@@%Ң#B@\%O#YB@%6#BD@%Ё#qB|@%Z#NB|@j%'#VBx@1%`[#B@%ͫ#B@%2#0 B@%N7#kBH@T%ˠ#RLBD@`%#`BL@%Br#r5B@ȹ@%ɓR# B@͆%T#!B@W@%6>#"B@'%lj"hB@%F"&B@`%2a"B|@@%ņ"2B|@t%>"Bx@K %0J"B@"@%Æ"EB@@%"oXB@Ӏ%7J"BH@ %*"}B@%&"nBx@ c%@9"B|@A %"@B@ @%"mB@`%Pw"1B@%"yB@$ %"BD@)`%c"#BH@.@%j"Q+B|@3m%"B@8S@%{ "B@=;%["B@B"%:"5B@G %'"I'BH@K`%"zSBH@P%Y1"ꯛBH@U %"B@Z%"B@_%"UB@d%"猲B@i@%IT"BB@n}%"BH@sq`%"6B|@xe %x"pBx@}Z%"bB@P %C"1B@H%6"!B@?%"^kB@: %y"BL@4`%"@BH@0@%I"B|@-%{"UB@+ %"ݕXB@*@%"zB@*%"#B@- %^"YBH@/`%ɾ"ڛBH@1%5"4BH@7 %"!5B@<%"dB@C%z"ק^B@L`%M"B@U%X"4pB@_@%ɛ"|BH@i%9%"BL@w%" KB@`%#"S_B@%"ҜB@%2"B@@%o"2B@Š%"~FBL@%U"BD@ @%["6B@%=i"cB@@%"ͰrB@1%&"xB@I%"KB@#b@%"˚~B@(~ %$"B|@-%" %1"BL@y%k"Bx@÷%8;"R7B@%"=B@5%A"B@v`%"zB@ط%NX")B@%"B[B@>%X"Bx@`%"B@%g "oB@%"oB@[@%w"=B@%B",BH@%" BL@;%E"sBx@ @%"B@`%%"DB@'`%"B@y%:"BL@"% "BH@(@%Q"BH@-s%!"X{B@2@%h!"¹B@8 `%d"-LB@=w%"B@B@%" +B@H*%a"xBH@M%,"B@R%"UB@XA%J?"oB@]% +"5B@c@%j5"B@hb%"B@m%"B@s+`%"B@x %ZA"lB@}%~}2"|B@]%}y"RB@@%|"\B@/%{"8B@%{ "B@`%z5""JB@q %y`"B@%x_"B@R%wV"AB@@%vA">B@4%vQ"uB@%u3"B@%t_k"fB@Ė@%s":B@%r"YB@χ%q"B@`%q"M8B@y %pH>"B@%oxr"BB@j%n9"8B@@%m":.B@l%m "B@%l<"0B@m%ko="B@ %jR"-B@n%iݗ"B@ %ii"+B@`%hK"fB@ %g"+2B@%fu",B@""%eB"+B@'@%e."B@-4%dh^".QB@2%c@")B@8U%b޵"2_B@=@%b"B@Cw%aW"7B@I%`"WB@N`%_"?>B@T9 %_""B@Y%^O"GB@_Z%]"B@d`%\q"N]B@j %\ +"ӳB@p,%[P +"\/B@u͠%Z+"B@{n`%Yu"iB@ %Y"B@%X^"yB@P%W)"B@`%Vz"B@ %V."?B@B%Ua("B@%T"bB@`%S",B@5 %S5J",XB@%R"TB@%QN"UQB@7`%Q1"VB@ %P}"o2B@ʘ%O"B@I%O"HB@`%Nb"+B@۫ %MM"B@[%L2".4B@%LGO"B@`%K"N~B@~ %J"B@>%J?["p:B@%I{"NB@`%H"B@ q %H4"!B@1%G"fB@%Fq"~>B@`%F-v"}B@ t %Er"|B@&5%D="{XB@,%D0 "{B@1ƀ%C"zFDB@7@%B"ynB@=X%B5"xB@C%A"wB@H%@B"vJB@N@%@?"vB@T %?"u?iB@Z[%>"tkB@`,%>L,"sB@e`%=R"rB@k %<"q_B@q%<]"qB@wo%;"pPRB@}P%;J"oB@!@%:|3"nuB@%9A"mB@%97B"mB@%8"lGB@`%7"k}B@u %7["jB@U%6+"iB@6%6"imB@`%5"hUlB@@%4"gB@%4It"fkB@%3&"eB@ɪ%3"e2B@ϛ`%2u"dn +B@| %1S"cB@l%1C"bcB@]%0"b"9B@N%0o"a]B@/@%/w"`KB@ %."_jB@ %.CW"_B@%-N"^JB@`%-;"]B@ + %,"\ЩB@%+"\GB@%+]"[YJB@%*ʄ"ZB@"`%*6"YB@( %)"Y#XB@.%)5"XgB@4%(~"WB@:ـ%'"V'B@@@%'W"V2B@F %&Ǥ"UzkB@L%&9"TB@R%%"TB@X%%"SVB@^@%$"RB@d %#"QB@k%#q$"Q4B@q %""PB@w1%"V"O(B@}2@%!"OB@C %!;"Na'B@c% "MB@t% "LB@%Yt"KB@@%,"JuB@ %>"JSB@%t"JB@%oU"ICB@%"HB@`%h6"H3xB@; %%"GB@\%ZG"FB@|%Ә"F-B@ҝ%M`"EB@ؾ`%"D(B@@%C{"D-jB@%"CB@0%:"BڠB@a%"B2B@%3"AB@@%"@WB@ %."@;B@ +%"?B@E%*%">DB@v%">HrB@`%#_"=B@" %"B@%"-B@%/"- +.B@^%",p&B@ү`%E$"+ݞB@@%M"+KB@q %`"*7B@%"*'B@2%|")B@% +")8B@%"(pyB@U`%%"'݆B@ %"'K0B@ '%@"& B@%"&$B@%X"%B@i%"$B@%`%{G"$tB@,;@%"#6B@2 $C"#^B@9$f""AB@?$5""CB@E$"!B@L$ԩ"!+B@R`$" B@Yq@$#" B@_ $J"B@fc$r"B@l$"wB@sT$k"B@yՀ${"d%B@V`$"B@@$?"QB@h $i"ȳB@$e"B,B@i$"$B@$":-B@{$*"B@ `$Z"/B@@$"B@ $0"%B@$6"B@?$R"]B@$LZ"CB@q$v<";B@$i"B@`$"B@4@$D"B@ $I"8B@f$z"B@$"B@$" B@ +8$Q"HB@ـ$F<"tB@z`$["DB@+@$z"B@$ $1" B@+m$"m)B@2$"AB@8$t" B@?o$o" 'B@F $" yB@L`$܏ " (YB@Sr@$c" B@Z# $" B @ӓ@$&"B@d $m"yjB@5$̴"B@$:"%B@$U""[B @$ʭ"B@x$2"IB@Y$S"cB@ +*$ȥ"iB @ `$!tB@@$If!EB@ $Ɯ!9/B@% $m!\B @,$C!B@3_$Ė!B@:@$!B@A!$?!B @H$˜0!B@N$!?B@UԀ$Jo!iB @\`$!B@c@$!B@j@$U*!B @q $E!B@xy$ !?B@j$d!lB @Z$!$!ֆB ABF@$!pB AE$v!B AIw $!YBAM$T!ӟB AP $!B AT@$6!0B AW $4!{$B A[y$!B A_$!!BAb$!\B AfK$s2!ΧB Ai$!fB Am$[!AcB Aq,`$!̏JBAt$E=!ݿB Axm`$!,B A| $0!{B A`$!ȭB AV$!B A`$!^B A$n!ǮBAH@$|C!tB A$Q!`gB A@$x +!Ÿ^B AA$! B A@$jw!_QB A$!òB A; $^ +!BA$ڿ!_B A $Y!B AD$ !@B A $TX!kB A$!B AV $O!!CAC $S!CAG$RY^!CAK $Q`!*{CAO$P!CAS@$P5!ABCAW$O!VCA[@$NN!YCA_$NG!CAc`$Md!sCAh$L!FCAl$K!=CAp0$KN^!CAt@$J!CAxQ$I7!;CA|i$I=k!&CAz $H !ZCA$G߸!֮CA@$G1!~FCA$F!~yCA@$Eײ!}= CA$E*!|^CA`$D|M!{cCA$C!z3CA>$Ct!yMCAW$Bo!xCAw$A!xBCA $A!w-CA$@x!v]BCA@$?s!uCA$?6h!tCA@$>!sqCA:$=!sCA[`$=F!rE"CAʃ$<!qqCAΤ$;!pCA$;Y7!o[CA$:j!nCA $:!n.CAF$9r0!m^CAo@$8н!lNCA$8/!k\CA`$7!j4CA$6!j(CA!`$6Pq!i\CAR$5!hfCA$5u!gCA $4u!fCA$3؏!f3CA @$3;!ekkCA D$2!dCA}@$2t!cܽCA$1i!ctCA`$0!bPCA$04!akCA"W$/}!`CA& $/!`JCA*Ƞ$.j!_@%CA/@$-)!^}CA39$-:!]CA7z`$,!\@CA;$, j!\:!CA?$+w![zCAD4$*!ZCAHt$*M!YlCAL $)!Y?CAP$)%!X3CAU>@$(s!WűC AY~$'!W CA]`$'m!VN(C Ab$&t!UCAfP$&G]!T9C Aj $%!TsC An$%"!S_C As*@$$!R,C Awr$$!QC A{`$#w!Q=OC +A $"c!PC A\$"XA!O C +A $!s!OC +A$!8_!N\C AF@$ !MUC +A$ "!LuC A`$c!LJC +A?$!KC +A$~!JmC A$!J=dC +AA$v!IC A@$!HC A$d!H.C +AK`$ۅ!GbC A$R}!FC A$~!F:C AU $#!ELwC Aɵ$v!D{xC A@$ !CXC An$!CfkC A`$.!BC A0$v!B#&C Aߐ$'Y!Az C A $!@єC AY$ v!@)C A@$O!?C A"$!>ڨC A${!>3C A$!=C A\$j!CAd $rv!.CAiJ$!.LCAm`$!-yCArL$!,PCAv̀$g!,H2CA{U $!+CA$!+jCA^`$7!*CA$!!)CAg$L!)WCA $հ!(CA$[!(#CA `$ߪ!'CA$t!&CA"$!&}TCA $v!%CA;$6h!%d\CA`$!$cCA]$U!$DCA#˩!#CA #!#'CA#!"CAȯ`#1q!" )CA@#T!!}CAؠ#x! "CAq #R! dCA #!CAߢ`#!MCAC#!CA۠#8W!8CA|@#`!CA#R!%SCA#a!gCAV #!CA# +3!CA@#6\!CA ?#ct!}CA #!bCA #?!p(CA)#!OCA`#!eCA {#N !CA%##@![CA)@#밲!|CA.|#!SCA3%#O!2CA7#H!MfCA<#}U!CAA7@#!ICAE#!CAJ#!>!HzCAOI #Y*!mCAS# !HfCAX`#Ȓ! CA]k#c!GCAb#9!ȷCAf@#r!IgCAk#O!˸CApE# !ObCAu #*;!XCAy#i\!WCA~`#ݨ]! eCA8#b! `CA#&! CA@#f! jCAy#ڧ! iCA:#! vpCA #*! +CA#k! +iCA`#ת! +CAU #! @CA#/! aCA`#p!3CA#Ը[!$CAw#!jCA@@#L!;8CA#ҘZ!CAـ#=!SZCAϪ #+n![CAz#u%!iCAK`#Ͽ^!ZCA# ! CA#S6! KCA`#͞p!CA#!&CAn#;!}CAG@#ˉ!CCA#؈!CCA#'!aCA #wc!?CA #Ǽ!CA#!CAk #i ?CAK#ƻ `CA,`# N CA" #a# KCA&#ĵO ZCA+`# wCA0#\  +CA5#² 6CA:@# + _CA?h#a 4CADQ#v CAI:@#< WCAN*#h| CAS#z *CAX # VwCA\#v2 CAa݀#ь CAf #-6 ݶCAk# CAp`# :?CAu #B iCAz#5 CA`#) rCA#[ CAz# +CA{`# ^)C At#x UCAl#= CAm`#:* C Af# /dCAf#g eC Ag@#_ $C Ah# #C Ah# C Ai@#rR !C Ar#[ r`C!Ar#Z C A{@#¾ EC!Aτ#) 5uC!AԌ# qC!Aٕ@# ޮC!Aޞ#` C!A㦠#ɿ +2C!A@#2. i0C"A#% ۥNC"AР#> C!A@#j "CC"A#ѫ ^LC"A +#< ؟C#A@#J C"A 4# -C#AD#Q tC"A]`# սC#Av#k C#A #q JC#A%`#G ӏC#A*# эC$A/#" C#A5`# _C$A:# НC#A?:#Le ϽC$AD[`# ǺC$AI # I %|C%AN#H ͻ=C$ASŀ#F4 &C$AX # wC%A^#2 C%Ac?# EC%Ahh #~ c0C%Am# ɲC%Ar# + C%Aw@# RC&A}# ǣC%AC#o zC&At@# GC&A#` ŚoC&Aՠ#$ CC&A`#T BC'A?#Ξ ×C&Aw#I C'A`# CC&A #@p )C'A#q 4C'AZ#8 HC(A # C'A#3/ C'A # SAC(AM@#/G 'C(AЍ# C(AΠ#, bSC(A`# 4C(AP#+ iC(A# u&C)A`#,+ "C(A" # /bC)Aj#. C)A#j TC)A@#4d MLC*AL#F nC)A +# C6A ؂#U C6A 3`#T .C6A #T9 C7A #SV AIC7A U#RN C6A #Q6 UAC7A @#Q- C8A +#Pw4 kC7A +@#O tC7A + #O SC8A +@#NV C8A +#Ml &C8A +C#L 'C8A +##L85 UC8A +(@#Ks @JC9A +.#JJ C8A +4V#J!` ] +C9A +:#Iq C9A +?`#HS |^C9A +E #Hp )C9A +K#GbM 6%C:A +QJ#F ~XC9A +W`#F }}EC:A +\ #E^ |C:A +b#D {ƂC:A +h#DJ zC:A +nf#C\ z_C;A +t7@#B y4pC:A +z#B xYC;A +#A\" w+C;A +#@ vkC;A +`#@ unC;A +s #?d tC;A +S#> t%C<A +,#>@ sOC;A + #=p. r{C<A +@#< qC<A +#<&A pC<A +#; pC=A +#:A o0C<A +`#:; n`C=A +b #9I mC<A +J#8& l0C=A +;#8T kUC>A +$#7 k#1C=A + @#7 jUC=A +#6r iC>A +#5Ӌ hC>A +ߠ#54 gC>A +`#4j g&C>A + #3 f\C>A #3[- elC>A #2[ d#C?A #2 cC?A `#1y c*C?A  #0 bhC?A #0L a.C?A %#/ `C?A +#/ `%C@A 1@#. __iC@A 7 #- ^C@A =#-8 ]wC@A C#, \C@A I#+ \C@A O@#+y [}bCAA U#* ZCAA [#*a ZC@A a#)\ YXCAA g#)9 XCBA m@#(y WSCAA s#(X W"CBA y#'} VgCAA #& UCBA #&\6 TCBA @#% T6CCA %#%9 S}RCBA =#$z RrCCA N#$w R CBA g## QTCCA @#" PCCA #"l OICDA #! O1CCA #!QH N|CDA # 7 MCCA `# 7 MCDA 5 # L`CDA ]# C KjCEA ~#> JxCDA ᧀ# + JKCEA `# I{# @)CGA D# ?wCGA J#L >܉CHA Q.@#1 >3rCGA Wo # =uCHA ]#m dCKA /# + + 1CKA Շ# +M 1QCKA # 0lCLA A# \3 /-CKA `# /8qCLA  #ld .8CLA d# ._CLA #} -mCMA -#T ,-CLA #y ,?RCMA `# +CMA h@# +CMA  #/ *yCMA "B# )"CNA (#D )M|CMA /# (KCNA 5#b (+CNA ;`#w 'CNA Bn@#| '6CNA H# +N &sCOA O_#$ %vCOA U#& %PCNA \I# $COA bʀ#E $0CPA iC`" #"COA o@"z #9CPA v=" "COA |" !sCPA >"0w !fCPA Ǡ"T ٧CQA H"y MuCPA `" CQA R@"a 6CPA " CQA l";  &CRA ":$ CQA }"b  CQA " CRA ğ`" CRA 0@" qGCRA " lCRA Z"9 aCSA "e CRA "( SCSA "} CSA "d GJCSA V`" v CTA @"Q >CSA " NCTA 1" 6cCTA" CTAr" 0 +CTA!"O= CUA'" +CTA.e`"v CUA5@" (CUA; "&  CUABh"^ 'CVAI"? CUAO"% (iCVAVr" pCVA]#"C *CV AcԀ"~ CVAj`"߹ /CWAq>@" CVAw "2 4CWA~"p VCWAh"ܭC ;CWA)" CXA"(@ BCWA"iM ȃCX Ad"٪, N1CXA%`" +CXA@"1 +\CXA "to CYAx"ַ k@CYA@") CYA "< xCY A"Ԁ CYA֛" CYAl"| CZA=`"Z CZA`"Ѣ *CZ A@"; DCZA "4g @ACZA"~J ˴C[Ab"ȯ WzC[ A :" C[A"_^ pyC_AO"b C_ AO"w̕C`AH" C_AI"(C` AJ"LEC`AK"NyC` AL";#C`AU`"P)CaAV`"C` A_@"Q5@CaAh@"fQCa Ay "w뗢CbA "mgyCa AI"{CbA"+-Ca AZ"alCc A +"CbAk`"OˏCb A"BCc A`"9ACc A"x)pCcA@"Cc A )"@cCc A#@"6&Cd A'J" +UACdA* "pXCd A.k"aʺCd A1 "<QCd A5"CyCeA9%" 3݁Ce A<"uܿCe A@N"{Ce AC"HX=Ce AGz"d}CfAK`"پCe AN"Cf ARD`"B%Cg AU"_ׄCf AYu@"J CfA]"9W Cg A`@"PCg AdJ"ԕCg Ag@"۴Ch Ak""ACgAo( "bZihCh ArȠ"nѱ1Ch Avi "BCh Az " +BCh A} "%όRCi AR"֛Ci A" +'!yCiA"}lCi A@"W̸Ci A"dH{Cj A"سRCj A9"MʠCj A"uCj A`"9>CjA6"mȎCk A`"&HCj A"|/Ck A<`"ƁPCl A"Ck A`"$Ck AE"|vCl A`"Cl A"pClA[@"*tCm A "g@Cl A@"#FCm At"_zACm A)@"ѲCm A"X)Cn Aٖ@"ՖCm AN"Rr+Cn A@" 1Cn A"L/yCo A|@"Cn A8"J@Co A@"ƕCn A"4\ܞCpAn "6Co A*"3r-Co A ""Cp A"QrCp Al "֞ECp A +,"Y5OCp A "Cq A"`Cp Av "XFCq A:"iHCq A "Cr A Ǡ"t Cq A$ "Cr A(X"#GCr A,! "Cr A/"Cs A3 "owCr A7"_Cs A;O "%DCs A?"tCs AB "7|Ct AF"'|ZCs AJ "K8Cu Al"5zCv Ap@"Cv At"RCv Ax@"EcCw A|c"oeCv A@@"Cw A"RFCw A@"~@FCw A"}a{)Cx A@"|Cw A"{N +oCx(Aw`"zxHCx AW"yz/Cx A<`"y dCy A "x88Cy A`"w_QCy A"vCy A`"u)Cy(A"s+YCz Ap"rVC{ AY"q0Cz AE"p \C{ A2"opC{ A"o C{ A "n7uC{(A"mgW8C| A "l[kC{ Aؠ"kkC| A "jbNC| A彠"j+nC} A@"i^N[C|(A"hSC} A@"g UC} A"fC~ A@"f0RJC} A|"ef:C~(Au`"dPC~ Am"cՏ[C~ A f`"c PC~ A b"bETC A["azNvC~(A\"`CAX"_RC AU"_0oC A!U"^mZCA%V "]CA)V"\aCA-W "\$gCA1["[Y5b CA5`@"ZٕCA9d"Ye^UCA=i@"YnCAAm"Xg +bCAEv`"WE6CAI~"VCAM`"V.CAQ"UpCAU"T#CAY"SXCA]"SF7CAa "RCAeΠ"Q[KCAi "QhaCAm"Pe_CAr@"O9CAv"NxvCAz%@"NA&CA~5"MWCAN`"L4CAb"L$CAw"Kr5CA"JÏCA"JQCA "I^sCA٠"H2o|CA "GMCA"GOCA/@"F|~>CAK"E;}_CAl`"ED|CA"D{CA`"C%zCA"C=VyCA"Bky VCA "Ax4aCA3"A?w[CAX "@QvCAЀ"?uCAԥ@"?E&tcCA">dsCA`"=Fs&CA"=OrQCAK"<q|CAt"<8p=CA";_Vo0CA ":Eo0CA":mn2vCA.@"9tImaCAZ"8ўlnCA`"8/kCA"7jKCA +"6%j%MCA%"6LiWCAY"5hECA "5 jg?CAƠ"4nf CA@"3ff)wCA$3"32e_CA(p`"2dCA,"1c)CA0"1\cGCA5"0 b>CA9^"0%axCA= "/z`CAA".j_TCAF@".X _)CAJX"-^eCAN`"-'Q]CAR",{\CAW""+#\CA[g "+aS[]CA_"*ZuCAc@"*57YݶCAh8")YCAl`") )X`5CAp"(vW_CAu"'VC \ No newline at end of file diff --git a/tests/data/cache/astropy/download/url/2c303169e6bbbb2b9c683391733d2931/url b/tests/data/cache/astropy/download/url/2c303169e6bbbb2b9c683391733d2931/url new file mode 100644 index 000000000..8c1cb9c91 --- /dev/null +++ b/tests/data/cache/astropy/download/url/2c303169e6bbbb2b9c683391733d2931/url @@ -0,0 +1 @@ +https://archive.stsci.edu/hlsps/reference-atlases/cdbs/calspec/hd111980_stis_006.fits \ No newline at end of file diff --git a/tests/data/reduc_20170530_134_wcs/reduc_20170530_134_gaia.ecsv b/tests/data/reduc_20170530_134_wcs/reduc_20170530_134_gaia.ecsv new file mode 100644 index 000000000..d3848e1ac --- /dev/null +++ b/tests/data/reduc_20170530_134_wcs/reduc_20170530_134_gaia.ecsv @@ -0,0 +1,180 @@ +# %ECSV 1.0 +# --- +# datatype: +# - name: ra +# unit: deg +# datatype: float64 +# description: Right ascension +# meta: !!omap +# - {ucd: pos.eq.ra;meta.main} +# - {utype: Char.SpatialAxis.Coverage.Location.Coord.Position2D.Value2.C1} +# - name: dec +# unit: deg +# datatype: float64 +# description: Declination +# meta: !!omap +# - {ucd: pos.eq.dec;meta.main} +# - {utype: Char.SpatialAxis.Coverage.Location.Coord.Position2D.Value2.C2} +# - name: pmra +# unit: mas / yr +# datatype: float64 +# description: Proper motion in right ascension direction +# meta: !!omap +# - {ucd: pos.pm;pos.eq.ra} +# - name: pmdec +# unit: mas / yr +# datatype: float64 +# description: Proper motion in declination direction +# meta: !!omap +# - {ucd: pos.pm;pos.eq.dec} +# - name: ref_epoch +# unit: yr +# datatype: float64 +# description: Reference epoch +# meta: !!omap +# - {ucd: meta.ref;time.epoch} +# - name: parallax +# unit: mas +# datatype: float64 +# description: Parallax +# meta: !!omap +# - {ucd: pos.parallax} +# - name: phot_g_mean_mag +# unit: mag +# datatype: float32 +# description: G-band mean magnitude +# meta: !!omap +# - {ucd: phot.mag;stat.mean;em.opt} +# - {name: dist, datatype: float64} +# schema: astropy-2.0 +ra dec pmra pmdec ref_epoch parallax phot_g_mean_mag dist +193.31387874127503 -18.52522966943086 314.6217104148161 -802.7940081262793 2015.5 10.952603073572996 11.850179 0.003194503077334316 +193.31408002656195 -18.525652464350433 299.48903077653887 -796.0918271978387 2015.5 12.925448038432572 8.209325 0.0036572194992613833 +193.3277945272934 -18.51814688394671 -5.160688804105089 -1.14750264511897 2015.5 1.0688747619611119 19.440645 0.014856773289668808 +193.3204468220089 -18.50884073371206 -10.682364603936644 3.2097113709856444 2015.5 -0.0694777743150532 17.879246 0.015256268583383152 +193.3040125259853 -18.50927392586909 -11.427188237352146 0.5699115873427919 2015.5 0.10802389415888732 20.819374 0.01536534889835026 +193.3157394183568 -18.537629646356873 5.8144923359535134 -11.052391369410625 2015.5 1.7119929585735418 19.119549 0.015664910778359787 +193.29617831112887 -18.528615059374513 -31.696126246519107 -4.70913052839484 2015.5 1.720546752840018 19.287481 0.016943230165895606 +193.32737740917463 -18.532134915027743 -12.082740620346542 -0.7558372784127914 2015.5 0.43928834587071036 19.431416 0.017061152151825246 +193.3097396900157 -18.501509382686073 -19.168150326342403 9.221302373174847 2015.5 1.431036176223781 20.081364 0.020910630442809715 +193.31539418930976 -18.497549321035812 -2.6199018306752353 -2.3145552734671337 2015.5 0.41014208072796726 18.762243 0.024806798409123216 +193.3032847361622 -18.499023939385406 24.649227785555613 -20.481895967993694 2015.5 3.8916123975959076 18.201487 0.02487132967479237 +193.30858653779057 -18.54797389015663 -6.595876065039609 0.28142358292914493 2015.5 0.9895469503815828 20.598286 0.026044684383603103 +193.30970726860335 -18.496122689087873 -9.515909114958472 -18.071671618565425 2015.5 0.6321948998346161 17.669962 0.026261103390160648 +193.28932201859828 -18.536556572024647 -2.0109487629633476 -1.5103820905474827 2015.5 1.2768604475432879 20.57137 0.026417449258433354 +193.34019980738998 -18.517446113856916 -9.872288371001845 -0.7764269730320621 2015.5 0.2978591332523562 16.403965 0.026483518523732052 +193.30515802414263 -18.547835692288228 0.051216598504189026 -3.762493890154479 2015.5 -0.45839166775664525 19.045279 0.026595648310797384 +193.3223765417061 -18.547747801687624 "" "" 2015.5 "" 20.08203 0.027110588433522372 +193.2912522639206 -18.540765296724448 -7.201886333740895 -8.337250629410883 2015.5 1.301048795195839 15.39927 0.027537552190521387 +193.2968959184522 -18.49684165208324 -8.903935163024627 -6.3889874365702015 2015.5 -0.1447436783319508 19.167841 0.029492917659330115 +193.3422578627708 -18.532670090311566 -14.12998057808509 -6.5866462780425055 2015.5 0.5629848034343903 20.495178 0.029882797357607346 +193.34150680485675 -18.538590395559364 -19.655325533213052 -13.655913900666137 2015.5 2.6064756538197633 20.438272 0.031816470871387406 +193.34850074415692 -18.523685148937787 -1.6949458762500034 -10.70348640867291 2015.5 0.10321164991768625 19.081028 0.03395018114998625 +193.2760239774249 -18.51841354894035 -4.804930918057392 -3.9781042330896703 2015.5 -0.2904115355408065 19.073843 0.03501219315746438 +193.28158431842976 -18.50255387370315 -18.366004582612995 7.671362827510471 2015.5 -0.6267297869547805 19.606089 0.03548554782449654 +193.30042865592898 -18.48844424919503 -0.9840456976868367 -6.21908767222436 2015.5 0.544974839605643 18.035854 0.03573971959352718 +193.29610740357413 -18.555687172577745 -24.425084211028608 -3.303634021118067 2015.5 -1.7476770541361897 20.20495 0.03698544489856827 +193.30526231006476 -18.485628188903462 "" "" 2015.5 "" 21.384804 0.0372774383993838 +193.3125778926402 -18.48249728710623 -8.694595847243399 1.385804527181762 2015.5 1.0301235642606748 19.302637 0.039729990869435364 +193.34675284640363 -18.496980313980707 -3.0900555825713782 2.2850099710650755 2015.5 0.45613185443777127 16.694885 0.040967831959646935 +193.2717375844366 -18.50445002084672 -19.57249524325576 -0.3548836171101366 2015.5 0.7950063399211105 17.203684 0.04274213112411268 +193.3569047764256 -18.532881104634455 -6.422258536058061 -1.453111133839209 2015.5 -0.2663779384228213 18.698923 0.04322013548249458 +193.2833157042159 -18.48858836641649 0.3060973626544119 -3.1044536189374132 2015.5 0.4378343134876523 20.287819 0.04369823208866542 +193.3341752926928 -18.48251119808841 0.5918590632584885 -21.190231203705697 2015.5 2.392970657314053 19.490725 0.04462038857446248 +193.34258452145735 -18.48729218239866 6.877210302811914 -14.55832976577129 2015.5 1.7490732964229587 17.355742 0.04496686788671832 +193.2686399734325 -18.505424390305336 -9.623707637718237 -1.8451185081669865 2015.5 0.9372076642842796 19.048332 0.04505729677837554 +193.32298678488038 -18.567674671255205 -22.85430541406342 -8.832210093309333 2015.5 0.10000654073020168 20.750092 0.04647656973362755 +193.34304543584827 -18.4851732399555 -19.806709408565446 3.546394341822805 2015.5 3.211855506995056 16.59929 0.04689893131240749 +193.34279583580093 -18.484793595387043 -23.583022954090946 4.959201549954996 2015.5 4.077412845117796 18.917725 0.047055674370844146 +193.2618691150194 -18.52473016475954 -9.754860055965692 -8.42317301181425 2015.5 0.15646640968258646 15.913697 0.04828972149714924 +193.35271768338865 -18.552229702512157 -0.49539382554123734 -3.314737796846325 2015.5 1.1260708933804089 20.068752 0.04834920446629307 +193.35321594820257 -18.492654701003378 -3.8319273114758325 -4.9038525825038874 2015.5 0.31598306328150066 17.041807 0.04846200178059192 +193.27163849353528 -18.49312532299253 -8.193279947653968 -7.961657658560421 2015.5 0.37332829768651604 19.686077 0.048633227076299336 +193.29477631334734 -18.568161983256594 -15.817072760619082 2.3055226084191625 2015.5 1.4175494765638903 20.0301 0.048986830411314575 +193.3514851556911 -18.555136634884562 -12.306382207978471 -5.520114916197348 2015.5 0.5872520384019237 19.990967 0.04932806922476461 +193.3591631639113 -18.545189257151016 -5.140904622415734 0.37990909082765933 2015.5 0.5620991680378893 19.772348 0.04965447088505243 +193.2637826053216 -18.54075935897978 0.5860331940430004 -0.16723092858737693 2015.5 -0.9974952174488456 19.595648 0.04997173967846638 +193.26209749749935 -18.538260978549157 2.6294058676578427 -5.446665774274372 2015.5 1.567546532121662 20.90238 0.050613214960639946 +193.31306860517319 -18.57677594250233 -9.150754811865975 -5.447445203427211 2015.5 -0.8637274969543044 20.36047 0.05454987358261117 +193.29481509868873 -18.469547038814103 "" "" 2015.5 "" 20.613518 0.05535146946955866 +193.2980674560779 -18.575823399508252 -13.412138363360619 -11.6064805381313 2015.5 1.39023120984776 17.04831 0.055369424961944476 +193.28609113393253 -18.571914706728922 "" "" 2015.5 "" 20.445902 0.05573722593642022 +193.283774679821 -18.570995167416843 -7.529259203061585 5.8047784692052815 2015.5 1.092669503312204 20.265375 0.05596297825987852 +193.30205850701685 -18.577646395683804 -7.907447889070238 -9.50318616332535 2015.5 0.7354816189217039 16.601625 0.05633505876680276 +193.25436458859113 -18.53369384027024 -11.416100478607238 -5.150776118074804 2015.5 -1.9241383998470587 20.572058 0.05651462913087596 +193.25371212996365 -18.51386611119541 4.528639709865158 -4.1788382545531135 2015.5 -0.18362838495214068 19.69459 0.05658211724128889 +193.34065319027115 -18.57262420284615 "" "" 2015.5 "" 20.581701 0.056927592225123363 +193.30276134556442 -18.466070484379408 -9.44321532264481 -1.9418241550984645 2015.5 0.30382808228549923 17.73599 0.056946549748764404 +193.33873018898043 -18.47060145504552 -6.374149326725131 -0.7835088899204141 2015.5 0.1004016261450385 20.182205 0.057212143163595866 +193.25467147893045 -18.50560184137736 -15.702984745165136 1.279477693828889 2015.5 1.3371201105743395 20.17862 0.05750816277500755 +193.3342384784335 -18.46836257170362 -15.32865745479114 -0.8710087778766653 2015.5 0.29256838655871165 19.4277 0.05759762671783454 +193.34222817236105 -18.573074187545593 2.8452049082725384 6.676492075064564 2015.5 1.5769169219410797 18.820784 0.05803100566646977 +193.27126246628632 -18.47946128757159 "" "" 2015.5 "" 21.113806 0.058096718840600275 +193.25261284519547 -18.50900318480033 -5.155072036948111 -4.542833831673805 2015.5 0.8886920949483617 20.344685 0.058517892575201014 +193.33544940357737 -18.57706659483904 -0.6860107178277368 -3.2704890395934614 2015.5 0.9253762319834703 17.72585 0.058918260765823675 +193.24973844760063 -18.529800194628383 -30.34130309536305 -3.1075262633766885 2015.5 6.294050243038902 20.516384 0.06020435477223766 +193.29785518540132 -18.46264197881629 -0.34828176087469 -4.673549189975991 2015.5 0.8477690569142541 20.485212 0.06123189606235932 +193.375111034307 -18.505483410845102 -8.667074894504264 -2.694940586990444 2015.5 0.7332990091094694 16.846233 0.06147778895105242 +193.28621533637823 -18.46591655374091 17.443905989507584 -16.505656189372605 2015.5 -0.5736526229568147 20.450089 0.06166927058633878 +193.24960760345002 -18.507243771917214 "" "" 2015.5 "" 20.104843 0.06170102590328457 +193.28988151047383 -18.46382527402963 -1.9073374332883801 -1.5827137390309807 2015.5 -0.8043879192178933 20.12438 0.062291602655783214 +193.2469988845399 -18.51515447029254 -6.161133802988571 0.7878531458191129 2015.5 0.2651593008351387 17.734467 0.06272640130412929 +193.35493042703303 -18.570998906783192 "" "" 2015.5 "" 20.8295 0.06308320125724055 +193.29368547688426 -18.461015438748337 -13.947906479028818 5.4653806166192 2015.5 0.915546282384468 19.056154 0.06382025269891257 +193.37937014908488 -18.513228305237387 -3.831219046440603 -0.5032772748107259 2015.5 0.8688091376652296 16.348978 0.06382856019230403 +193.2512016656803 -18.495980555655017 -21.805006594952072 -12.225023056278541 2015.5 2.115739429912935 16.847715 0.06397623537806946 +193.37658568389594 -18.501420198791124 -5.226799142241804 -11.236494624169072 2015.5 0.6953628927772167 15.534013 0.06402788079422662 +193.30849509913517 -18.587381767844917 -28.799370957427232 -0.8154468233607778 2015.5 3.4178796268780407 20.111591 0.06527825191023817 +193.37499837687892 -18.494010798154143 -14.159337535984113 2.6009045873191265 2015.5 0.31274536409548503 18.89604 0.06544411294049797 +193.32809408938647 -18.45835016260978 -34.08463716026513 -24.167733022930076 2015.5 0.77142691664275 20.232376 0.06551793284735445 +193.3096284156054 -18.5880834015776 -25.891579504080926 -4.196176757475371 2015.5 1.7894205118036695 20.0816 0.06592193733570205 +193.34522515843062 -18.580784661518887 3.594764212604222 -9.878614270933955 2015.5 1.3197229921128455 20.332003 0.06616735016257408 +193.26991463672894 -18.469899492300957 -20.08120431870621 5.635056742369507 2015.5 0.5926951076747647 17.821411 0.06623247405205199 +193.28101694260533 -18.462630973288196 -3.1888703432485626 2.1081366218847117 2015.5 0.040028465766947026 17.129591 0.06675446694159952 +193.30138393500658 -18.456253814724647 -11.284005821463047 -5.461925195340669 2015.5 -1.1918735472069983 15.436011 0.06684478609385924 +193.30162429555799 -18.45616285515967 "" "" 2015.5 "" 17.693565 0.06689829805953086 +193.36981780814375 -18.482107926832665 -26.276296993679672 -6.300519282382787 2015.5 -0.020274356980310444 18.006039 0.06738312599631312 +193.26114429157016 -18.56863216007125 -9.73605309971682 -3.5491817322255126 2015.5 0.12007337022076488 18.691391 0.06741819731841249 +193.344042613359 -18.582770727950066 -0.5175584180357036 -4.101695889465862 2015.5 -0.16573890237061104 20.267782 0.06743019281457185 +193.2472418271921 -18.54901489098607 -4.513881481753824 -3.7662245531134024 2015.5 0.54740893136138 18.91358 0.06762207079097611 +193.36626131364773 -18.476173935961125 -8.333138871412189 8.171234216263926 2015.5 1.1527188296928303 18.383675 0.06854279492863287 +193.34440237896092 -18.58387975850099 -4.142844410482176 -2.989704585005237 2015.5 0.1048097386670374 20.59729 0.06857631736133162 +193.35549745512537 -18.579451774202692 -3.4190461629226556 -13.781916544970036 2015.5 -0.20369669806691604 17.47182 0.07013337588095457 +193.38776703543675 -18.528123059158876 -8.82377931273977 -0.809102492977574 2015.5 0.7490962409236632 19.99619 0.0713939656181207 +193.30158617011193 -18.593426343253103 -21.65528734437662 12.92639251127718 2015.5 1.9846991821343603 15.727292 0.07197864423362826 +193.23822281914894 -18.507754254579254 -6.750761179795323 -2.5928290844030495 2015.5 -1.7908303649137223 20.859224 0.07211673140170481 +193.25785512751654 -18.470879182106952 "" "" 2015.5 "" 21.156693 0.07310718420607737 +193.36738415662515 -18.47060502096567 -10.761214240600998 1.600032433416448 2015.5 0.6134282356903833 16.520748 0.07315322725846632 +193.23590076531767 -18.514110048704758 -3.0417370645502713 -34.31821410738064 2015.5 2.4249011649068946 18.112406 0.07330088693070919 +193.38743253613785 -18.502823510580765 "" "" 2015.5 "" 21.234129 0.07344753918765257 +193.3352327092996 -18.451930356556993 -9.664531425290205 0.7920909938626207 2015.5 -0.017911985632117426 18.785091 0.0734651510525724 +193.30239416609896 -18.59543665934755 -8.803103293228064 -2.8686956325166038 2015.5 -0.16924535671699395 19.039885 0.07386227723775582 +193.293191532436 -18.59383137163806 -9.23463458031917 3.4400547139186957 2015.5 0.437154672477869 17.129267 0.07396095689270266 +193.37856063775897 -18.561946558783088 -9.772939207489415 -5.034248292150143 2015.5 0.0435123192778215 19.555023 0.07398119886520084 +193.37433302035652 -18.4765080403008 -19.939487789276754 -6.716930766952941 2015.5 1.07471699208673 19.420132 0.07418379633694194 +193.38375695586316 -18.490830480505036 -5.961246545338723 1.6414756005751654 2015.5 0.7654989078390342 20.352316 0.0743132342895139 +193.26335137259463 -18.46452325209116 -0.1908388761602607 -0.7869383222076025 2015.5 4.248256677931948 18.283983 0.07431383395696717 +193.2446818940562 -18.55960935467553 -1.8259120118508299 -5.415296855498066 2015.5 2.327088350577277 18.95821 0.07456291200536323 +193.3834332660322 -18.555491497270783 -10.725587657106095 1.6936358838037404 2015.5 0.49652811092113025 19.699902 0.07483505076451395 +193.26585457635323 -18.583356768952168 2.3072808314013526 -6.732274562401316 2015.5 1.3190399740554706 19.950048 0.07557511813718185 +193.36582353406882 -18.57921214466769 -18.58758787589614 -7.615454882707199 2015.5 1.6924212280780095 20.661837 0.07603305415529674 +193.3688835706723 -18.46746006472781 -5.7111505651657195 -3.0246890029142306 2015.5 0.495592301311842 19.389353 0.07639020547448523 +193.30665558276095 -18.598516562998206 "" "" 2015.5 "" 20.945768 0.07650647702477237 +193.23225740726016 -18.516043751429343 -26.374100025071275 6.555866792701145 2015.5 0.7243670794431314 18.013857 0.07655448733016727 +193.37653698342294 -18.569318926718957 0.6923834115575546 -1.586481566637147 2015.5 0.700506934145352 18.444387 0.0766632162322302 +193.2756085635824 -18.590631100664567 28.947070945170385 0.8876871442011489 2015.5 3.130041880077366 14.860598 0.07692515354578484 +193.30665417587446 -18.59912680263045 "" "" 2015.5 "" 21.056816 0.0771150988093329 +193.3055767219674 -18.59920574421312 0.07439785230487614 -0.19018106873930551 2015.5 -0.07072094853772486 18.32928 0.07727673021266655 +193.37196190904143 -18.57591454001483 "" "" 2015.5 "" 20.857197 0.07769075260536432 +193.3946295038761 -18.5192269563226 -1.924764446585279 -1.4540518250901335 2015.5 0.19506612065574874 18.271738 0.07771691826647817 +193.36901330067244 -18.579279301406782 -17.272164245842397 -14.827587841290185 2015.5 0.7161140420299488 16.9933 0.07811698518989549 +193.25637401253093 -18.465081904173267 -32.907144790357684 -21.470481648218463 2015.5 2.3864712321203156 17.34522 0.07824245788216501 +193.3181928064275 -18.44404585181748 -7.783309717287271 -4.47623780579611 2015.5 0.8962538646133067 19.137789 0.07835272871334766 +193.24058884395225 -18.483362203481086 -1.9070370655365945 -8.08575324871106 2015.5 0.590797755483222 17.736132 0.07867987721903368 +193.27476446297698 -18.592240440320758 -3.2565233792382755 -13.297345090038661 2015.5 0.43123534773967526 17.336054 0.07872222008736775 +193.23001246193613 -18.529178742640546 -3.002400192394866 2.255418217988204 2015.5 -0.1033811580843624 20.16529 0.07873753711760782 +193.33743246447423 -18.44505620618127 -55.706141698607 -6.191137634338219 2015.5 2.496840558748934 19.590519 0.08064904187481035 +193.31322158138576 -18.44091880091281 0.18174750032041165 -3.26959977306105 2015.5 2.3060617984903686 20.844696 0.08130956276854712 +193.23710737382063 -18.560939973450257 -1.5646251500176827 -8.511980955639956 2015.5 0.24152735423363764 17.793322 0.08148022725943328 +193.39145532275825 -18.559288538955506 "" "" 2015.5 "" 20.340668 0.08333519002760909 +193.39229056976905 -18.486686577393655 -12.554875369825231 6.313919829469455 2015.5 0.46760227460443793 20.865679 0.08340011389002859 diff --git a/tests/test_extractor.py b/tests/test_extractor.py index 8f4b457eb..fb9aaecbe 100644 --- a/tests/test_extractor.py +++ b/tests/test_extractor.py @@ -34,7 +34,7 @@ def test_extractor_ctio(): load_config("ctio.ini") parameters.VERBOSE = True parameters.DEBUG = False - parameters.CCD_REBIN = 2 # rebin=1 to build tests/data spectrum + parameters.CCD_REBIN = 1 # rebin=1 to build tests/data spectrum apply_rebinning_to_parameters() for file_name in file_names: diff --git a/tests/test_fullchain.py b/tests/test_fullchain.py index ac9d3b586..f11dab5e0 100644 --- a/tests/test_fullchain.py +++ b/tests/test_fullchain.py @@ -6,7 +6,7 @@ from spectractor import parameters # noqa: E402 from spectractor.extractor.images import Image # noqa: E402 from spectractor.extractor.spectrum import Spectrum # noqa: E402 -from spectractor.extractor.extractor import Spectractor # noqa: E402 +from spectractor.extractor.extractor import SpectractorRun, SpectractorInit # noqa: E402 from spectractor.logbook import LogBook # noqa: E402 from spectractor.config import load_config, apply_rebinning_to_parameters # noqa: E402 from spectractor.simulation.image_simulation import ImageSim # noqa: E402 @@ -26,9 +26,16 @@ PSF_POLY_ORDER = 2 PSF_POLY_PARAMS_TRUTH = [1, 0, 0, 0, 0, 0, - 3, 1, 1, + 3, 0, 0, 3, 0, 0, 1e6] * N_DIFF_ORDERS + +PSF_POLY_PARAMS_AUXTEL_TRUTH = [1, 0, 0, + 0, 0, 0, + 8, 0, 0, + 3, 0, 0, + 1e6] * N_DIFF_ORDERS + A1_T = 1 A2_T = 1 A3_T = 0 @@ -48,7 +55,7 @@ def plot_residuals(spectrum, lambdas_truth, amplitude_truth): Parameters ---------- - spectrum + spectrum: Spectrum lambdas_truth amplitude_truth @@ -58,8 +65,8 @@ def plot_residuals(spectrum, lambdas_truth, amplitude_truth): >>> from spectractor.extractor.spectrum import Spectrum >>> image = Image("./tests/data/sim_20170530_134.fits") >>> spectrum = Spectrum("./tests/data/sim_20170530_134_spectrum.fits") - >>> lambdas_truth = np.fromstring(image.header['LBDAS_T'][1:-1], sep=' ') - >>> amplitude_truth = np.fromstring(image.header['AMPLIS_T'][1:-1], sep=' ', dtype=float)[:lambdas_truth.size] + >>> lambdas_truth = np.fromstring(image.header['LBDAS_T'][1:-1], sep=',') + >>> amplitude_truth = np.fromstring(image.header['AMPLIS_T'][1:-1], sep=',', dtype=float)[:lambdas_truth.size] >>> plot_residuals(spectrum, lambdas_truth, amplitude_truth) #doctest: +ELLIPSIS array([... """ @@ -94,32 +101,50 @@ def plot_residuals(spectrum, lambdas_truth, amplitude_truth): def make_image(): spectrum_filename = "./tests/data/reduc_20170530_134_spectrum.fits" image_filename = "./tests/data/reduc_20170530_134.fits" - ImageSim(image_filename, spectrum_filename, "./tests/data/", A1=A1_T, A2=A2_T, A3=A3_T, - psf_poly_params=PSF_POLY_PARAMS_TRUTH, with_stars=False, with_rotation=True, with_noise=False) + sim = ImageSim(image_filename, spectrum_filename, "./tests/data/sim_20170530_134.fits", A1=A1_T, A2=A2_T, A3=A3_T, + psf_poly_params=PSF_POLY_PARAMS_TRUTH, with_starfield=True, with_rotation=True, with_noise=False, + with_flat=True) + return sim + + +def make_auxtel_image(): + spectrum_filename = "./tests/data/test_auxtel_spectrum.fits" + image_filename = "./tests/data/exposure_2023092800266_dmpostisrccd.fits" + sim = ImageSim(image_filename, spectrum_filename, "./tests/data/", A1=A1_T, A2=A2_T, A3=A3_T, + psf_poly_params=PSF_POLY_PARAMS_AUXTEL_TRUTH, with_starfield=False, with_rotation=True, + with_noise=False, with_flat=False) + return sim + + +def make_stardice_image(): + spectrum_filename = "./tests/data/IMG_0019584_spectrum.fits" + image_filename = "./tests/data/IMG_0019584.fits" + ImageSim(image_filename, spectrum_filename, "./tests/data/IMG_0019584_sim.fits", A1=A1_T, A2=A2_T, A3=A3_T, + psf_poly_params=PSF_POLY_PARAMS_TRUTH, with_starfield=False, with_rotation=True, with_noise=False, with_flat=False) @unittest.skipIf(uvspec_available() is False, 'Skipping to avoid libradtran dependency') @astropy.config.set_temp_cache(os.path.join(os.path.abspath(os.path.dirname(__file__)), "data", "cache")) def test_ctio_fullchain(): parameters.VERBOSE = True - parameters.DEBUG = False + parameters.DEBUG = True parameters.SPECTRACTOR_ATMOSPHERE_SIM = "libradtran" - sim_image = "./tests/data/sim_20170530_134.fits" + sim_image_filename = "./tests/data/sim_20170530_134.fits" # load test and make image simulation - if not os.path.isfile(sim_image): - make_image() - image = Image(sim_image, config="./config/ctio.ini") - lambdas_truth = np.fromstring(image.header['LBDAS_T'][1:-1], sep=' ') - amplitude_truth = np.fromstring(image.header['AMPLIS_T'][1:-1], sep=' ', dtype=float) + # if not os.path.isfile(sim_image_filename): + sim = make_image() + image = Image(sim_image_filename, config="./config/ctio.ini") + lambdas_truth = np.fromstring(image.header['LBDAS_T'][1:-1], sep=',') + amplitude_truth = np.fromstring(image.header['AMPLIS_T'][1:-1], sep=',', dtype=float) parameters.AMPLITUDE_TRUTH = np.copy(amplitude_truth) parameters.LAMBDA_TRUTH = np.copy(lambdas_truth) # extractor - tag = os.path.basename(sim_image) + tag = os.path.basename(sim_image_filename) tag = tag.replace('sim_', 'reduc_') logbook = LogBook(logbook="./tests/data/ctiofulllogbook_jun2017_v5.csv") - disperser_label, target, xpos, ypos = logbook.search_for_image(tag) + disperser_label, target_label, xpos, ypos = logbook.search_for_image(tag) load_config("./config/ctio.ini") parameters.SPECTRACTOR_ATMOSPHERE_SIM = "libradtran" parameters.PSF_POLY_ORDER = PSF_POLY_ORDER @@ -130,8 +155,16 @@ def test_ctio_fullchain(): if parameters.CCD_REBIN > 1: for k in range(2 * (PSF_POLY_ORDER + 1), 3 * (PSF_POLY_ORDER +1)): PSF_POLY_PARAMS_TRUTH[k] /= parameters.CCD_REBIN - spectrum = Spectractor(sim_image, "./tests/data", guess=[xpos, ypos], target_label=target, - disperser_label=disperser_label, config="") # config already loaded, do not overwrite PSF_POLY_ORDER + + image = SpectractorInit(sim_image_filename, target_label=target_label, + disperser_label=disperser_label, config="") # config already loaded, do not overwrite PSF_POLY_ORDER + image.flat = sim.flat + image.starfield = sim.starfield + image.mask = np.zeros_like(image.data).astype(bool) + image.mask[680:685, 1255:1260] = True # test masking of some pixels like cosmic rays + parameters.SPECTRACTOR_SIMULATE_STARFIELD = False # here we want to test fit with an exact starfield simulation + spectrum, w = SpectractorRun(image, guess=[xpos, ypos], output_directory="./tests/data") + # tests residuals = plot_residuals(spectrum, lambdas_truth, amplitude_truth) @@ -168,7 +201,7 @@ def test_ctio_fullchain(): spectrum_file_name = "./tests/data/sim_20170530_134_spectrum.fits" assert os.path.isfile(spectrum_file_name) - atmgrid_filename = sim_image.replace('sim', 'reduc').replace('.fits', '_atmsim.fits') + atmgrid_filename = sim_image_filename.replace('sim', 'reduc').replace('.fits', '_atmsim.fits') assert os.path.isfile(atmgrid_filename) spectrum = Spectrum(spectrum_file_name) w = SpectrumFitWorkspace(spectrum, atmgrid_file_name=atmgrid_filename, fit_angstrom_exponent=False, @@ -188,9 +221,10 @@ def test_ctio_fullchain(): f"{np.abs(w.params.values[i] - spectrum.header[l]) / np.sqrt(w.params.cov[icov, icov]) < nsigma}") assert np.abs(w.params.values[i] - spectrum.header[l]) / np.sqrt(w.params.cov[icov, icov]) < nsigma k += 1 - assert np.abs(w.params.values[1]) / np.sqrt(w.params.cov[1, 1]) < 2 * nsigma # A2 - assert np.isclose(np.abs(w.params.values[8]), 0, atol=parameters.PIXSHIFT_PRIOR) # pixshift - assert np.isclose(np.abs(w.params.values[9]), 0, atol=1e-3) # B + A2id = w.params.get_index("A2") + assert np.abs(w.params.values[A2id] / w.params.err[A2id]) < 3 * nsigma # A2 + assert np.isclose(np.abs(w.params.values[w.params.get_index("alpha_pix [pix]")]), 0, atol=parameters.PIXSHIFT_PRIOR) # pixshift + assert np.isclose(np.abs(w.params.values[w.params.get_index("B")]), 0, atol=1e-3) # B parameters.DEBUG = False parameters.SPECTRACTOR_ATMOSPHERE_SIM = "libradtran" @@ -198,9 +232,138 @@ def test_ctio_fullchain(): verbose=True, plot=True, live_fit=False) run_spectrogram_minimisation(w, method="newton") nsigma = 2 + labels = ["A2_T", "VAOD_T", "OZONE_T", "PWV_T"] # "A1_T" fixed + indices = [1, 3, 5, 6] + A1, A2, A3, aerosols, angstrom_exponent, ozone, pwv, B, Astar, D, shift_x, shift_y, shift_t, pressure, *psf_poly_params = w.params.values + ipar = w.params.get_free_parameters() # non fixed param indices + cov_indices = [list(ipar).index(k) for k in indices] # non fixed param indices in cov matrix + assert w.costs[-1] / w.data.size < 1e-3 + k = 0 + for i, l in zip(indices, labels): + icov = cov_indices[k] + spectrum.my_logger.info(f"Test {l} best-fit {w.params.values[i]:.3f}+/-{np.sqrt(w.params.cov[icov, icov]):.3f} " + f"vs {spectrum.header[l]:.3f} at {nsigma}sigma level: " + f"{np.abs(w.params.values[i] - spectrum.header[l]) / np.sqrt(w.params.cov[icov, icov]) < nsigma}") + assert np.abs(w.params.values[i] - spectrum.header[l]) / np.sqrt(w.params.cov[icov, icov]) < nsigma + k += 1 + A2id = w.params.get_index("A2") + assert np.abs((A2 - 1) / w.params.err[A2id]) < 2 * nsigma # A2 + assert np.isclose(shift_y, 0, atol=parameters.PIXSHIFT_PRIOR) # shift_y + assert np.isclose(D, spectrum.header["D2CCD_T"], atol=0.1) # D2CCD + assert np.isclose(B, 1, atol=1e-3) # B + assert np.isclose(Astar, 1, atol=1e-2) # Astar + assert np.all(np.isclose(psf_poly_params[(PSF_POLY_ORDER + 1):len(PSF_POLY_PARAMS_TRUTH)//N_DIFF_ORDERS - 1], + np.array(PSF_POLY_PARAMS_TRUTH)[(PSF_POLY_ORDER + 1):len(PSF_POLY_PARAMS_TRUTH)//N_DIFF_ORDERS - 1], + rtol=0.01, atol=0.01)) + +@unittest.skipIf(uvspec_available() is False, 'Skipping to avoid libradtran dependency') +@astropy.config.set_temp_cache(os.path.join(os.path.abspath(os.path.dirname(__file__)), "data", "cache")) +def auxtel_fullchain(): + """ + + Returns + ------- + + Examples + -------- + >>> test_auxtel_fullchain() + """ + parameters.VERBOSE = True + parameters.DEBUG = True + parameters.SPECTRACTOR_ATMOSPHERE_SIM = "getObsAtmo" + sim_image_filename = "./tests/data/sim_2023092800266_dmpostisrccd.fits" + + # load test and make image simulation + # if not os.path.isfile(sim_image_filename): + sim = make_auxtel_image() + image = Image(sim_image_filename, config="./config/auxtel.ini") + lambdas_truth = np.fromstring(image.header['LBDAS_T'][1:-1], sep=',') + amplitude_truth = np.fromstring(image.header['AMPLIS_T'][1:-1], sep=',', dtype=float) + parameters.AMPLITUDE_TRUTH = np.copy(amplitude_truth) + parameters.LAMBDA_TRUTH = np.copy(lambdas_truth) + + # extractor + load_config("./config/auxtel.ini") + parameters.PSF_POLY_ORDER = PSF_POLY_ORDER + parameters.CCD_REBIN = 1 + # JN: > 1 not working well for now: I guess CTIO spectra are too narrow + # and under-sampled to extract unbiased rebinned spectrum, but pipeline is ok. + apply_rebinning_to_parameters() + if parameters.CCD_REBIN > 1: + for k in range(2 * (PSF_POLY_ORDER + 1), 3 * (PSF_POLY_ORDER +1)): + PSF_POLY_PARAMS_TRUTH[k] /= parameters.CCD_REBIN + + image = SpectractorInit(sim_image_filename, config="") # config already loaded, do not overwrite PSF_POLY_ORDER + xpos, ypos = np.array([image.header["TARGETX"], image.header["TARGETY"]]) / 2 + parameters.SPECTRACTOR_SIMULATE_STARFIELD = False # here we want to test fit with an exact starfield simulation + spectrum, w = SpectractorRun(image, guess=[xpos, ypos], output_directory="./tests/data") + + # tests + residuals = plot_residuals(spectrum, lambdas_truth, amplitude_truth) + + spectrum.my_logger.warning(f"\n\tQuantities to test with {parameters.CCD_REBIN=}:" + f"\n\t\tspectrum.header['X0_T']={spectrum.header['X0_T'] / parameters.CCD_REBIN:.5g} vs {spectrum.x0[0]:.5g}" + f"\n\t\tspectrum.header['Y0_T']={spectrum.header['Y0_T'] / parameters.CCD_REBIN:.5g} vs {spectrum.x0[1]:.5g}" + f"\n\t\tspectrum.header['ROT_T']={spectrum.header['ROT_T']:.5g} " + f"vs {spectrum.rotation_angle:.5g}" + f"\n\t\tspectrum.header['BKGD_LEV']={spectrum.header['BKGD_LEV'] * parameters.CCD_REBIN**2:.5g} " + f"vs {np.mean(spectrum.spectrogram_bgd):.5g}" + f"\n\t\tspectrum.header['D2CCD_T']={spectrum.header['D2CCD_T']:.5g} " + f"vs {spectrum.disperser.D:.5g}" + f"\n\t\tspectrum.header['A2_FIT']={spectrum.header['A2_FIT']:.5g} vs {A2_T:.5g}" + f"\n\t\tspectrum.header['CHI2_FIT']={spectrum.header['CHI2_FIT']:.4g}" + f"\n\t\tspectrum.chromatic_psf.poly_params=" + f"{spectrum.chromatic_psf.params.values[spectrum.chromatic_psf.Nx + 2 * (PSF_POLY_ORDER + 1):-1]}" + f" vs {PSF_POLY_PARAMS_TRUTH[2 * (PSF_POLY_ORDER + 1):len(PSF_POLY_PARAMS_TRUTH)//N_DIFF_ORDERS - 1]}" + f"\n\t\tresiduals wrt truth: mean={np.mean(residuals[100:-100]):.5g}, " + f"std={np.std(residuals[100:-100]):.5g}") + assert np.isclose(float(spectrum.header['X0_T'] / parameters.CCD_REBIN), spectrum.x0[0], atol=0.2 * parameters.CCD_REBIN) + assert np.isclose(float(spectrum.header['Y0_T'] / parameters.CCD_REBIN), spectrum.x0[1], atol=0.2 * parameters.CCD_REBIN) + assert np.isclose(float(spectrum.header['ROT_T']), spectrum.rotation_angle, atol=1e-3) + assert np.isclose(float(spectrum.header['BKGD_LEV'] * parameters.CCD_REBIN**2), np.mean(spectrum.spectrogram_bgd), rtol=1e-3) + assert np.isclose(float(spectrum.header['D2CCD_T']), spectrum.disperser.D, atol=0.1) + if parameters.CCD_REBIN == 1: + assert float(spectrum.header['CHI2_FIT']) < 1.5e-3 + else: + assert float(spectrum.header['CHI2_FIT']) < 1.5e-1 + assert np.all( + np.isclose(spectrum.chromatic_psf.params.values[spectrum.chromatic_psf.Nx + 2 * (PSF_POLY_ORDER + 1):-1], + np.array(PSF_POLY_PARAMS_TRUTH)[2 * (PSF_POLY_ORDER + 1):len(PSF_POLY_PARAMS_TRUTH)//N_DIFF_ORDERS - 1], rtol=0.01, atol=0.01)) + assert np.abs(np.mean(residuals[100:-100])) < 0.25 + assert np.std(residuals[100:-100]) < 3 + + spectrum_file_name = "./tests/data/sim_2023092800266_dmpostisrccd_spectrum.fits" + assert os.path.isfile(spectrum_file_name) + spectrum = Spectrum(spectrum_file_name) + parameters.SPECTRACTOR_ATMOSPHERE_SIM = "getObsAtmo" + w = SpectrumFitWorkspace(spectrum, fit_angstrom_exponent=False, verbose=True, plot=True, live_fit=False) + run_spectrum_minimisation(w, method="newton") + nsigma = 2 + labels = ["VAOD_T", "OZONE_T", "PWV_T"] + indices = [2, 4, 5] + ipar = w.params.get_free_parameters() # non fixed param indices + cov_indices = [list(ipar).index(k) for k in indices] # non fixed param indices in cov matrix + assert w.costs[-1] / w.data.size < 0.5 + k = 0 + for i, l in zip(indices, labels): + icov = cov_indices[k] + spectrum.my_logger.info(f"Test {l} best-fit {w.params.values[i]:.3f}+/-{np.sqrt(w.params.cov[icov, icov]):.3f} " + f"vs {spectrum.header[l]:.3f} at {nsigma}sigma level: " + f"{np.abs(w.params.values[i] - spectrum.header[l]) / np.sqrt(w.params.cov[icov, icov]) < nsigma}") + assert np.abs(w.params.values[i] - spectrum.header[l]) / np.sqrt(w.params.cov[icov, icov]) < nsigma + k += 1 + assert np.abs(w.params.values[1]) / np.sqrt(w.params.cov[1, 1]) < 2 * nsigma # A2 + assert np.isclose(np.abs(w.params.values[8]), 0, atol=parameters.PIXSHIFT_PRIOR) # pixshift + assert np.isclose(np.abs(w.params.values[9]), 0, atol=1e-3) # B + + parameters.DEBUG = False + parameters.SPECTRACTOR_ATMOSPHERE_SIM = "getObsAtmo" + w = SpectrogramFitWorkspace(spectrum, fit_angstrom_exponent=False, verbose=True, plot=True, live_fit=False) + run_spectrogram_minimisation(w, method="newton") + nsigma = 2 labels = ["A1_T", "A2_T", "VAOD_T", "OZONE_T", "PWV_T"] indices = [0, 1, 3, 5, 6] - A1, A2, A3, aerosols, angstrom_exponent, ozone, pwv, D, shift_x, shift_y, shift_t, B, *psf_poly_params = w.params.values + A1, A2, A3, aerosols, angstrom_exponent, ozone, pwv, B, Astar, D, shift_x, shift_y, shift_t, *psf_poly_params = w.params.values ipar = w.params.get_free_parameters() # non fixed param indices cov_indices = [list(ipar).index(k) for k in indices] # non fixed param indices in cov matrix assert w.costs[-1] / w.data.size < 1e-3 @@ -215,6 +378,138 @@ def test_ctio_fullchain(): assert np.isclose(shift_y, 0, atol=parameters.PIXSHIFT_PRIOR) # shift_y assert np.isclose(D, spectrum.header["D2CCD_T"], atol=0.1) # D2CCD assert np.isclose(B, 1, atol=1e-3) # B + assert np.isclose(Astar, 1, atol=1e-2) # Astar assert np.all(np.isclose(psf_poly_params[(PSF_POLY_ORDER + 1):len(PSF_POLY_PARAMS_TRUTH)//N_DIFF_ORDERS - 1], np.array(PSF_POLY_PARAMS_TRUTH)[(PSF_POLY_ORDER + 1):len(PSF_POLY_PARAMS_TRUTH)//N_DIFF_ORDERS - 1], rtol=0.01, atol=0.01)) + + + +@unittest.skipIf(uvspec_available() is False, 'Skipping to avoid libradtran dependency') +@astropy.config.set_temp_cache(os.path.join(os.path.abspath(os.path.dirname(__file__)), "data", "cache")) +def test_stardice_fullchain(): + """ + + Returns + ------- + + Examples + -------- + >>> test_stardice_fullchain() #doctest: +ELLIPSIS + OHP site... + """ + parameters.VERBOSE = True + parameters.DEBUG = True + parameters.SPECTRACTOR_ATMOSPHERE_SIM = "getObsAtmo" + sim_image = "./tests/data/IMG_0019584_sim.fits" + + # load test and make image simulation + #if not os.path.isfile(sim_image): + make_stardice_image() + image = Image(sim_image, config="./config/stardice.ini") + lambdas_truth = np.fromstring(image.header['LBDAS_T'][1:-1], sep=',') + amplitude_truth = np.fromstring(image.header['AMPLIS_T'][1:-1], sep=',', dtype=float)[:lambdas_truth.size] + parameters.AMPLITUDE_TRUTH = np.copy(amplitude_truth) + parameters.LAMBDA_TRUTH = np.copy(lambdas_truth) + + # extractor + load_config("./config/stardice.ini") + parameters.SPECTRACTOR_ATMOSPHERE_SIM = "getObsAtmo" + parameters.PSF_POLY_ORDER = PSF_POLY_ORDER + parameters.CCD_REBIN = 1 + if image.header['MOUNTTAU'] < 90: + parameters.OBS_CAMERA_ROTATION = 180 + elif image.header['MOUNTTAU'] >= 90: + parameters.OBS_CAMERA_ROTATION = 0 + + # JN: > 1 not working well for now: I guess CTIO spectra are too narrow + # and under-sampled to extract unbiased rebinned spectrum, but pipeline is ok. + apply_rebinning_to_parameters() + if parameters.CCD_REBIN > 1: + for k in range(2 * (PSF_POLY_ORDER + 1), 3 * (PSF_POLY_ORDER +1)): + PSF_POLY_PARAMS_TRUTH[k] /= parameters.CCD_REBIN + spectrum, w = SpectractorRun(image, "./tests/data", guess=(530, 610)) # config already loaded, do not overwrite PSF_POLY_ORDER + # tests + residuals = plot_residuals(spectrum, lambdas_truth, amplitude_truth) + + spectrum.my_logger.warning(f"\n\tQuantities to test with {parameters.CCD_REBIN=}:" + f"\n\t\tspectrum.header['X0_T']={spectrum.header['X0_T'] / parameters.CCD_REBIN:.5g} vs {spectrum.x0[0]:.5g}" + f"\n\t\tspectrum.header['Y0_T']={spectrum.header['Y0_T'] / parameters.CCD_REBIN:.5g} vs {spectrum.x0[1]:.5g}" + f"\n\t\tspectrum.header['ROT_T']={spectrum.header['ROT_T']:.5g} " + f"vs {spectrum.rotation_angle:.5g}" + f"\n\t\tspectrum.header['BKGD_LEV']={spectrum.header['BKGD_LEV'] * parameters.CCD_REBIN**2:.5g} " + f"vs {np.mean(spectrum.spectrogram_bgd):.5g}" + f"\n\t\tspectrum.header['D2CCD_T']={spectrum.header['D2CCD_T']:.5g} " + f"vs {spectrum.disperser.D:.5g}" + f"\n\t\tspectrum.header['A2_FIT']={spectrum.header['A2_FIT']:.5g} vs {A2_T:.5g}" + f"\n\t\tspectrum.header['CHI2_FIT']={spectrum.header['CHI2_FIT']:.4g}" + f"\n\t\tspectrum.chromatic_psf.poly_params=" + f"{spectrum.chromatic_psf.params.values[spectrum.chromatic_psf.Nx + 2 * (PSF_POLY_ORDER + 1):-1]}" + f" vs {PSF_POLY_PARAMS_TRUTH[2 * (PSF_POLY_ORDER + 1):len(PSF_POLY_PARAMS_TRUTH)//N_DIFF_ORDERS - 1]}" + f"\n\t\tresiduals wrt truth: mean={np.mean(residuals[20:-20]):.5g}, " + f"std={np.std(residuals[20:-20]):.5g}") + assert np.isclose(float(spectrum.header['X0_T'] / parameters.CCD_REBIN), spectrum.x0[0], atol=0.2 * parameters.CCD_REBIN) + assert np.isclose(float(spectrum.header['Y0_T'] / parameters.CCD_REBIN), spectrum.x0[1], atol=0.2 * parameters.CCD_REBIN) + assert np.isclose(float(spectrum.header['ROT_T']), spectrum.rotation_angle, atol=3e-3) + assert np.isclose(float(spectrum.header['BKGD_LEV'] * parameters.CCD_REBIN**2), np.mean(spectrum.spectrogram_bgd), rtol=1e-3) + assert np.isclose(float(spectrum.header['D2CCD_T']), spectrum.disperser.D, atol=0.2) + if parameters.CCD_REBIN == 1: + assert float(spectrum.header['CHI2_FIT']) < 3e-4 + else: + assert float(spectrum.header['CHI2_FIT']) < 3e-1 + assert np.all( + np.isclose(spectrum.chromatic_psf.params.values[spectrum.chromatic_psf.Nx + 2 * (PSF_POLY_ORDER + 1):-1], + np.array(PSF_POLY_PARAMS_TRUTH)[2 * (PSF_POLY_ORDER + 1):len(PSF_POLY_PARAMS_TRUTH)//N_DIFF_ORDERS - 1], rtol=0.05, atol=0.1)) + assert np.abs(np.mean(residuals[20:-20])) < 0.1 + assert np.std(residuals[20:-20]) < 1 + + spectrum_file_name = "./tests/data/IMG_0019584_sim_spectrum.fits" + assert os.path.isfile(spectrum_file_name) + spectrum = Spectrum(spectrum_file_name) + w = SpectrumFitWorkspace(spectrum, fit_angstrom_exponent=False, + verbose=True, plot=True, live_fit=False) + run_spectrum_minimisation(w, method="newton") + nsigma = 3 + labels = ["VAOD_T", "OZONE_T", "PWV_T"] + indices = [2, 4, 5] + ipar = w.params.get_free_parameters() # non fixed param indices + cov_indices = [list(ipar).index(k) for k in indices] # non fixed param indices in cov matrix + assert w.costs[-1] / w.data.size < 3 + k = 0 + for i, l in zip(indices, labels): + icov = cov_indices[k] + spectrum.my_logger.info(f"Test {l} best-fit {w.params.values[i]:.3f}+/-{np.sqrt(w.params.cov[icov, icov]):.3f} " + f"vs {spectrum.header[l]:.3f} at {nsigma}sigma level: " + f"{np.abs(w.params.values[i] - spectrum.header[l]) / np.sqrt(w.params.cov[icov, icov]) < nsigma}") + assert np.abs(w.params.values[i] - spectrum.header[l]) / np.sqrt(w.params.cov[icov, icov]) < nsigma + k += 1 + assert np.abs(w.params.values[1]) / np.sqrt(w.params.cov[1, 1]) < 2 * nsigma # A2 + assert np.isclose(np.abs(w.params.values[8]), 0, atol=parameters.PIXSHIFT_PRIOR) # pixshift + assert np.isclose(np.abs(w.params.values[9]), 0, atol=1e-3) # B + + parameters.DEBUG = False + parameters.SPECTRACTOR_ATMOSPHERE_SIM = "getObsAtmo" + w = SpectrogramFitWorkspace(spectrum, fit_angstrom_exponent=False, + verbose=True, plot=True, live_fit=False) + run_spectrogram_minimisation(w, method="newton") + nsigma = 3 + labels = ["A1_T", "A2_T", "VAOD_T", "OZONE_T", "PWV_T"] + indices = [0, 1, 3, 5, 6] + A1, A2, A3, aerosols, angstrom_exponent, ozone, pwv, B, Astar, D, shift_x, shift_y, shift_t, *psf_poly_params = w.params.values + ipar = w.params.get_free_parameters() # non fixed param indices + cov_indices = [list(ipar).index(k) for k in indices] # non fixed param indices in cov matrix + assert w.costs[-1] / w.data.size < 3 + k = 0 + for i, l in zip(indices, labels): + icov = cov_indices[k] + spectrum.my_logger.info(f"Test {l} best-fit {w.params.values[i]:.3f}+/-{np.sqrt(w.params.cov[icov, icov]):.3f} " + f"vs {spectrum.header[l]:.3f} at {nsigma}sigma level: " + f"{np.abs(w.params.values[i] - spectrum.header[l]) / np.sqrt(w.params.cov[icov, icov]) < nsigma}") + assert np.abs(w.params.values[i] - spectrum.header[l]) / np.sqrt(w.params.cov[icov, icov]) < nsigma + k += 1 + assert np.isclose(shift_y, 0, atol=parameters.PIXSHIFT_PRIOR) # shift_y + assert np.isclose(D, spectrum.header["D2CCD_T"], atol=0.2) # D2CCD + assert np.isclose(B, 1, atol=1e-3) # B + assert np.all(np.isclose(psf_poly_params[(PSF_POLY_ORDER + 1):len(PSF_POLY_PARAMS_TRUTH)//N_DIFF_ORDERS - 1], + np.array(PSF_POLY_PARAMS_TRUTH)[(PSF_POLY_ORDER + 1):len(PSF_POLY_PARAMS_TRUTH)//N_DIFF_ORDERS - 1], + rtol=0.1, atol=0.1)) diff --git a/tests/test_simulator.py b/tests/test_simulator.py index dad952b9a..8b05521d9 100644 --- a/tests/test_simulator.py +++ b/tests/test_simulator.py @@ -30,9 +30,9 @@ def test_atmosphere(): ozone_grid=[400, 400, 1], aerosol_grid=[0.0, 0.1, 2]) atmospheric_grid = a.compute() assert np.sum(atmospheric_grid) > 0 - assert np.all(np.isclose(a.atmgrid[0, a.index_atm_data:], parameters.LAMBDAS)) - assert not np.any(np.isclose(a.atmgrid[1, a.index_atm_data:], np.zeros_like(parameters.LAMBDAS), rtol=1e-6)) - assert a.atmgrid.shape == (3, a.index_atm_data + len(parameters.LAMBDAS)) + assert np.all(np.isclose(a.atmgrid[0, a.index_atm_data:], a.lambdas)) + assert not np.any(np.isclose(a.atmgrid[1, a.index_atm_data:], np.zeros_like(a.lambdas), rtol=1e-6)) + assert a.atmgrid.shape == (3, a.index_atm_data + len(a.lambdas)) a.save_file(a.image_filename.replace('.fits', '_atmsim.fits')) assert os.path.isfile('tests/data/reduc_20170605_028_atmsim.fits') a.load_file(a.image_filename.replace('.fits', '_atmsim.fits')) @@ -63,7 +63,7 @@ def test_simulator(): atmosphere = AtmosphereGrid(atmgrid_filename="./tests/data/reduc_20170530_134_atmsim.fits") spectrum_simulation = SpectrumSimulation(spectrum, atmosphere=atmosphere, fast_sim=True) spectrum_simulation.simulate(A1=1, A2=1, ozone=300, pwv=5, aerosols=0.05, angstrom_exponent=None, - reso=0., D=56, shift_x=0., B=0.) + reso=0., D=56, shift_x=0.) assert np.sum(spectrum_simulation.data) > 0 assert np.sum(spectrum_simulation.data) < 1e-10