def make_matrices():
    # Find all the relevant files
    #allfiles = [f for f in os.listdir("./") if f.startswith("RV") and f.endswith("-0.fits")]
    allfiles = [f for f in os.listdir("./") if f.startswith("RV") and '-0' in f and f.endswith("corrected.fits")]

    # Read in the measured RV data
    bjd, rv = np.loadtxt("psi1draa_100_120_mcomb1.dat", usecols=(0,1), unpack=True)
    bjd2, vbary_arr = np.loadtxt("psi1draa_100p_28_37_ASW.dat", usecols=(0,5), unpack=True)

    # Put all the data in one giant list
    alldata = []
    print "Reading all data"
    for i, fname in enumerate(allfiles):
        header = fits.getheader(fname)
        jd = header['jd']
        #vbary = GenericSearch.HelCorr(header, observatory="McDonald")
        idx = np.argmin(abs(bjd2 - jd))
        bjd2_i = bjd2[idx]
        vbary = vbary_arr[idx] / 1000.0
        idx = np.argmin(abs(bjd - jd))
        bjd_i = bjd[idx]
        vstar = rv[idx]/1e3
        print(fname, vbary, vstar)
        vel = vbary - vstar  #Closest... but still not great
        #vel = -vbary + vstar  #NO
        #vel = vbary + vstar  #NO
        #vel = -vbary - vstar  #NO
        #vel = vstar  #NO
        #vel = -vstar #NO
        #vel = vbary  #Surprisingly not bad...
        orders = HelperFunctions.ReadExtensionFits(fname)[:-2]
        for j in badorders[::-1]:
            orders.pop(j)
        if i == 0:
            template = []
            for j, order in enumerate(orders):
                order.x *= (1.0+vel/c)
                orders[j] = order.copy()
                template.append(order.copy())
                alldata.append([order])
            #template = [o.copy() for o in orders]
        else:
            vel = fit_rv_shift_old(template, orders)
            print('RV adjustment = {}'.format(vel))
            for j, order in enumerate(orders):
                order.x *= (1.0+vel/c)
                orders[j] = order.copy()
                if i == 0:
                    alldata.append([order])
                    #template.append(order.copy())
                else:
                    alldata[j].append(order)
                    #plt.plot(order.x, order.y/order.cont, 'g-', alpha=0.5)
            #plt.show()


    # Interpolate each order to a single wavelength grid
    print "Interpolating to wavelength grid"
    xgrids = []
    c_cycler = itertools.cycle(('r', 'g', 'b', 'k'))
    ls_cycler = itertools.cycle(('-', '--', ':', '-.'))
    for i, order in enumerate(alldata):
        print "Order ", i+1
        firstwaves = [d.x[0] for d in order]
        lastwaves = [d.x[-1] for d in order]
        size = np.mean([d.size() for d in order])
        xgrid = np.linspace(max(firstwaves), min(lastwaves), size)
        for j, data in enumerate(order):
            tmp = FittingUtilities.RebinData(data, xgrid)
            order[j] = tmp.y/tmp.cont

            #if i == 20:
            #    col = c_cycler.next()
            #    if j%4 == 0:
            #        ls = ls_cycler.next()
            #    plt.plot(xgrid, order[j], color=col, ls=ls, alpha=0.8, label=allfiles[j])
            #plt.plot(xgrid, order[j], 'k-', alpha=0.2)
        alldata[i] = np.array(order)
        xgrids.append(xgrid)
    #plt.legend(loc='best')
    #plt.show()

    return allfiles, xgrids, alldata
Esempio n. 2
0
            fitter.const_pars[j] for j in range(len(fitter.parnames))
            if fitter.fitting[j]
        ]
        full_model = fitter.GenerateModel(fitpars,
                                          separate_source=False,
                                          return_resolution=False,
                                          broaden=False,
                                          nofit=True)

        for i, order in enumerate(orders):
            left = np.searchsorted(full_model.x, order.x[0] - 5)
            right = np.searchsorted(full_model.x, order.x[-1] + 5)
            if min(full_model.y[left:right]) > 0.95:
                model = FittingUtilities.ReduceResolution(
                    full_model[left:right].copy(), resolution)
                model = FittingUtilities.RebinData(model, order.x)
                data = order.copy()
                data.cont = np.ones(data.size())

            else:
                print "\n\nGenerating model for order %i of %i\n" % (
                    i, len(orders))
                order.cont = FittingUtilities.Continuum(order.x,
                                                        order.y,
                                                        fitorder=3,
                                                        lowreject=1.5,
                                                        highreject=10)
                fitter.ImportData(order)
                fitter.resolution_fit_mode = "gauss"
                model = fitter.GenerateModel(
                    fitpars,
Esempio n. 3
0
    def MakeModel(self,
                  pressure=795.0,
                  temperature=283.0,
                  lowfreq=4000,
                  highfreq=4600,
                  angle=45.0,
                  humidity=50.0,
                  co2=368.5,
                  o3=3.9e-2,
                  n2o=0.32,
                  co=0.14,
                  ch4=1.8,
                  o2=2.1e5,
                  no=1.1e-19,
                  so2=1e-4,
                  no2=1e-4,
                  nh3=1e-4,
                  hno3=5.6e-4,
                  lat=30.6,
                  alt=2.1,
                  wavegrid=None,
                  resolution=None,
                  save=False,
                  libfile=None,
                  vac2air=True):
        """
        Here is the important function! All of the variables have default values,
          which you will want to override for any realistic use.

        :param pressure:       Pressure at telescope altitude (hPa)
        :param temperature:    Temperature at telescope altitude (Kelvin)
        :param lowfreq:        The starting wavenumber (cm^-1)
        :param highfreq:       The ending wavenumber (cm^-1)
        :param angle:          The zenith distance of the telescope (degrees). This is related to
                               the airmass (z) through z = sec(angle)
        :param humidity:       Percent relative humidity at the telescope altitude.
        :param co2:            Mixing ratio of this molecule (parts per million by volumne)
        :param o3:             Mixing ratio of this molecule (parts per million by volumne)
        :param n2o:            Mixing ratio of this molecule (parts per million by volumne)
        :param co:             Mixing ratio of this molecule (parts per million by volumne)
        :param ch4:            Mixing ratio of this molecule (parts per million by volumne)
        :param o2:             Mixing ratio of this molecule (parts per million by volumne)
        :param no:             Mixing ratio of this molecule (parts per million by volumne)
        :param so2:            Mixing ratio of this molecule (parts per million by volumne)
        :param no2:            Mixing ratio of this molecule (parts per million by volumne)
        :param nh3:            Mixing ratio of this molecule (parts per million by volumne)
        :param hno3:           Mixing ratio of this molecule (parts per million by volumne)
        :param lat:            The latitude of the observatory (degrees)
        :param alt:            The altitude of the observatory above sea level (km)
        :param wavegrid:       If given, the model will be resampled to this grid.
                               Should be a 1D np array
        :param resolution:     If given, it will reduce the resolution by convolving
                               with a gaussian of appropriate width. Should be a float
                               with R=lam/dlam
        :param save:           If true, the generated model is saved. The filename will be
                               printed to the screen.
        :param libfile:        Useful if generating a telluric library. The filename of the
                               saved file will be written to this filename. Should be a string
                               variable. Ignored if save==False
        :param vac2air:        If True (default), it converts the wavelengths from vacuum to air
        
        :return:               DataStructures.xypoint instance with the telluric model. The x-axis
                               is in nanometers and the y-axis is in fractional transmission.
        """

        self.FindWorkingDirectory()

        #Make the class variables local
        TelluricModelingDir = self.TelluricModelingDir
        debug = self.debug
        lock = self.lock
        layers = np.array(self.layers)
        ModelDir = self.ModelDir

        #Make a deep copy of atmosphere so that I don't repeatedly modify it
        Atmosphere = copy.deepcopy(self.Atmosphere)

        #Convert from relative humidity to concentration (ppm)
        h2o = humidity_to_ppmv(humidity, temperature, pressure)

        #Start by scaling the abundances from those at 'alt' km
        #  (linearly interpolate)
        keys = sorted(Atmosphere.keys())
        lower = max(0, np.searchsorted(keys, alt) - 1)
        upper = min(lower + 1, len(keys) - 1)
        if lower == upper:
            raise ZeroDivisionError(
                "Observatory altitude of %g results in the surrounding layers being the same!"
                % alt)
        scale_values = list(Atmosphere[lower])
        scale_values[2] = list(Atmosphere[lower][2])
        scale_values[0] = (Atmosphere[upper][0] - Atmosphere[lower][0]) / (
            keys[upper] - keys[lower]) * (alt -
                                          keys[lower]) + Atmosphere[lower][0]
        scale_values[1] = (Atmosphere[upper][1] - Atmosphere[lower][1]) / (
            keys[upper] - keys[lower]) * (alt -
                                          keys[lower]) + Atmosphere[lower][1]
        for mol in range(len(scale_values[2])):
            scale_values[2][mol] = (
                Atmosphere[upper][2][mol] -
                Atmosphere[lower][2][mol]) / (keys[upper] - keys[lower]) * (
                    alt - keys[lower]) + Atmosphere[lower][2][mol]

        #Do the actual scaling
        pressure_scalefactor = (scale_values[0] - pressure) * np.exp(
            -(layers - alt)**2 / (2.0 * 10.0**2))
        temperature_scalefactor = (scale_values[1] - temperature) * np.exp(
            -(layers - alt)**2 / (2.0 * 10.0**2))
        for i, layer in enumerate(layers):
            # Atmosphere[layer][0] -= pressure_scalefactor[i]
            Atmosphere[layer][0] *= pressure / scale_values[0]
            Atmosphere[layer][1] -= temperature_scalefactor[i]
            Atmosphere[layer][2][0] *= h2o / scale_values[2][0]
            Atmosphere[layer][2][1] *= co2 / scale_values[2][1]
            Atmosphere[layer][2][2] *= o3 / scale_values[2][2]
            Atmosphere[layer][2][3] *= n2o / scale_values[2][3]
            Atmosphere[layer][2][4] *= co / scale_values[2][4]
            Atmosphere[layer][2][5] *= ch4 / scale_values[2][5]
            Atmosphere[layer][2][6] *= o2 / scale_values[2][6]
            Atmosphere[layer][2][7] *= no / scale_values[2][7]
            Atmosphere[layer][2][8] *= so2 / scale_values[2][8]
            Atmosphere[layer][2][9] *= no2 / scale_values[2][9]
            Atmosphere[layer][2][10] *= nh3 / scale_values[2][10]
            Atmosphere[layer][2][11] *= hno3 / scale_values[2][11]

        #Now, Read in the ParameterFile and edit the necessary parameters
        parameters = MakeTape5.ReadParFile(parameterfile=TelluricModelingDir +
                                           "ParameterFile")
        parameters[48] = "%.1f" % lat
        parameters[49] = "%.1f" % alt
        parameters[51] = "%.5f" % angle
        parameters[17] = lowfreq
        freq, transmission = np.array([]), np.array([])

        #Need to run lblrtm several times if the wavelength range is too large.
        maxdiff = 1999.9
        if (highfreq - lowfreq > maxdiff):
            while lowfreq + maxdiff <= highfreq:
                parameters[18] = lowfreq + maxdiff

                MakeTape5.WriteTape5(parameters,
                                     output=TelluricModelingDir + "TAPE5",
                                     atmosphere=Atmosphere)

                #Run lblrtm
                cmd = "cd " + TelluricModelingDir + ";sh runlblrtm_v3.sh"
                try:
                    if self.print_lblrtm_output:
                        command = subprocess.check_call(cmd, shell=True)
                    if not self.print_lblrtm_output:
                        command = subprocess.check_call(
                            cmd,
                            shell=True,
                            stdout=subprocess.DEVNULL,
                            stderr=subprocess.DEVNULL)

                except subprocess.CalledProcessError:
                    raise subprocess.CalledProcessError(
                        "Error: Command '{}' failed in directory {}".format(
                            cmd, TelluricModelingDir))

                #Read in TAPE12, which is the output of LBLRTM
                freq, transmission = self.ReadTAPE12(TelluricModelingDir,
                                                     appendto=(freq,
                                                               transmission))
                lowfreq = lowfreq + 2000.00001
                parameters[17] = lowfreq

        parameters[18] = highfreq
        MakeTape5.WriteTape5(parameters,
                             output=TelluricModelingDir + "TAPE5",
                             atmosphere=Atmosphere)

        #Run lblrtm for the last time
        cmd = "cd " + TelluricModelingDir + ";sh runlblrtm_v3.sh"
        try:
            if self.print_lblrtm_output:
                command = subprocess.check_call(cmd, shell=True)
            if not self.print_lblrtm_output:
                command = subprocess.check_call(cmd,
                                                shell=True,
                                                stdout=subprocess.DEVNULL,
                                                stderr=subprocess.DEVNULL)

        except subprocess.CalledProcessError:
            raise subprocess.CalledProcessError(
                "Error: Command '{}' failed in directory {}".format(
                    cmd, TelluricModelingDir))

        #Read in TAPE12, which is the output of LBLRTM
        freq, transmission = self.ReadTAPE12(TelluricModelingDir,
                                             appendto=(freq, transmission))

        #Convert from frequency to wavelength units
        wavelength = units.cm.to(units.nm) / freq

        #Correct for index of refraction of air (use IAU standard conversion from
        #  Morton, D. C. 1991, ApJS, 77, 119
        if vac2air:
            wave_A = wavelength * units.nm.to(
                units.angstrom)  # Wavelength in angstroms
            n = 1.0 + 2.735182e-4 + 131.4182 / wave_A**2 + 2.76249e8 / wave_A**4
            wavelength /= n

        if save:
            #Output filename
            model_name = ModelDir + "transmission" + "-%.2f" % pressure + "-%.2f" % temperature + "-%.1f" % humidity + "-%.1f" % angle + "-%.2f" % (
                co2) + "-%.2f" % (o3 * 100) + "-%.2f" % ch4 + "-%.2f" % (co *
                                                                         10)
            logging.info(
                "All done! Output Transmission spectrum is located in the file below:\n\t\t{}"
                .format(model_name))

            np.savetxt(model_name,
                       np.transpose((wavelength[::-1], transmission[::-1])),
                       fmt="%.8g")
            if libfile != None:
                infile = open(libfile, "a")
                infile.write(model_name + "\n")
                infile.close()

        self.Cleanup()  #Un-lock the working directory

        if wavegrid != None:
            model = DataStructures.xypoint(x=wavelength[::-1],
                                           y=transmission[::-1])
            return FittingUtilities.RebinData(model, wavegrid)

        return DataStructures.xypoint(x=wavelength[::-1], y=transmission[::-1])