예제 #1
0
    def get_conv_factors(self, spcdb_dir):
        """
        Gets conversion factors used in budget computations

        Arguments:
           spcdb_dir : str
               Path to the species_database.yml file
        """
        # Read the species database
        path = os.path.join(spcdb_dir, "species_database.yml")
        spcdb = yaml_load_file(open(path))

        # Molecular weights [kg mol-1], as taken from the species database
        self.mw = {}
        self.mw["O3"] = spcdb["O3"]["MW_g"] * 1.0e-3
        self.mw["Ox"] = self.mw["O3"]
        self.mw["Air"] = constants.MW_AIR_g * 1.0e-3

        # kg/s --> Tg/d
        self.kg_s_to_tg_a_value = 86400.0 * self.d_per_a * 1e-9
예제 #2
0
파일: budget_aer.py 프로젝트: NW177/gcpy
    def __init__(self, devstr, devdir, plotsdir, year, overwrite):
        """
        Initializes the _GlobVars class.

        Args:
        -----
            devstr : str
                Label denoting the "Dev" version.
            devdir : str
                Directory where benchmark diagnostic files are found.
            plotsdir : str
                Directory where plots & tables will be created.
            year : int
                Year of the benchmark simulation.
            overwrite : bool
                Denotes whether to ovewrite existing budget tables.
        """        """
        Initializes the _GlobVars class.
        """
        # ------------------------------
        # Arguments from outside
        # ------------------------------
        self.devstr = devstr
        self.devdir = devdir
        self.plotsdir = plotsdir
        self.overwrite = overwrite
        
        # ------------------------------
        # Benchmark year
        # ------------------------------
        self.y0 = year
        self.y1 = self.y0 + 1
        self.y0_str = "{}".format(self.y0)
        self.y1_str = "{}".format(self.y1)

        # ------------------------------
        # Species info
        # ------------------------------

        # Directory where diagnostic files are found
        datadir = join(devstr, "OutputDir")

        # List of species (and subsets for the trop & strat)
        self.species_list = ["BCPI", "OCPI", "SO4", "DST1", "SALA", "SALC" ]

        # Read the species database
        try:
            path = join(datadir, "species_database.yml")
            spcdb = yaml_load_file(open(path))
        except FileNotFoundError:
            path = join(os.path.dirname(__file__), "species_database.yml")
            spcdb = yaml_load_file(open(path))

        # Molecular weights [g mol-1], as taken from the species database
        self.mw = {}
        for v in self.species_list:
            self.mw[v] = spcdb[v]["MW_g"]
        self.mw["Air"] = constants.MW_AIR * 1.0e3

        # Get the list of relevant AOD diagnostics from a YAML file
        path = join(os.path.dirname(__file__), "aod_species.yml")
        aod = yaml_load_file(open(path))
        self.aod_list = [v for v in aod.keys() if "Dust" in v or "Hyg" in v]

        # Descriptive names
        self.spc2name = {"BCPI": "Black Carbon",
                         "DST1": "Dust",
                         "OCPI": "Organic Carbon",
                         "SO4" : "Sulfate",
                         "SALA": "Sea Salt (accum)",
                         "SALC": "Sea Salt (coarse)"}

        # ------------------------------
        # Collection file lists
        # ------------------------------
        Aerosols = join(datadir, 
                        "*.Aerosols.{}*.nc4".format(self.y0_str))
        StateMet = join(datadir, 
                        "*.StateMet.{}*.nc4".format(self.y0_str))
        SpeciesConc = join(datadir, 
                           "*.SpeciesConc.{}*.nc4".format(self.y0_str))
        
        # ------------------------------        
        # Read data collections
        # ------------------------------

        # Diagnostics
        self.ds_aer = xr.open_mfdataset(Aerosols, data_vars=self.aod_list)
        self.ds_cnc = xr.open_mfdataset(SpeciesConc)
        self.ds_met = xr.open_mfdataset(StateMet)

        # Troposphere mask
        self.tropmask = get_troposphere_mask(self.ds_met)

        # Number of vertical levels
        self.N_LEVS  = self.ds_cnc.dims["lev"]

        # Set a flag to denote if this data is from GCHP
        self.is_gchp = "nf" in self.ds_cnc.dims.keys()

        # ------------------------------       
        # Months and days
        # ------------------------------
        self.N_MONTHS = 12
        self.N_MONTHS_FLOAT = self.N_MONTHS * 1.0
        
        # Days per month in the benchmark year
        self.d_per_mon = np.zeros(self.N_MONTHS)
        for t in range(self.N_MONTHS):
            self.d_per_mon[t] = monthrange(self.y0, t+1)[1] * 1.0
            
        # Days in the benchmark year
        self.d_per_yr = np.sum(self.d_per_mon)
            
        # Fraction of year occupied by each month
        self.frac_of_yr = np.zeros(self.N_MONTHS)
        for t in range(self.N_MONTHS):
            self.frac_of_yr[t] = self.d_per_mon[t] / self.d_per_yr

        # --------------------------------
        # Surface area
        # (kludgey but it works)
        # --------------------------------
        if self.is_gchp:   
            area = self.ds_met["Met_AREAM2"].values
            a = area.shape
            self.area_m2 = np.zeros([a[0], N_LEVS, a[1], a[2], a[3]])
            for t in range(self.N_MONTHS):
                for k in range(self.N_LEVS):
                    self.area_m2[t,k,:,:,:] = area[t,:,:,:]
            self.total_area_m2 = np.sum(self.area_m2[0,0,:,:,:])
        else:
            area = self.ds_met["AREA"].values
            a = area.shape
            self.area_m2 = np.zeros([a[0], self.N_LEVS, a[1], a[2]])
            for t in range(self.N_MONTHS):
                for k in range(self.N_LEVS):
                    self.area_m2[t,k,:,:] = area[t,:,:]
            self.total_area_m2 = np.sum(self.area_m2[0,0,:,:])


        # ------------------------------
        # Conversion factors
        # ------------------------------

        # v/v dry --> Tg
        self.vv_to_Tg = {}
        for spc in self.species_list:
            self.vv_to_Tg[spc] = self.ds_met["Met_AD"].values  \
                               * (self.mw[spc] / self.mw["Air"]) * 1e-9
예제 #3
0
    def __init__(self, devstr, devdir, devrstdir, year, dst, is_gchp,
                 overwrite, spcdb_dir):
        """
        Initializes the _GlobVars class.

        Args:
        -----
            devstr : str
                Label denoting the "Dev" version.
            devdir : str
                Directory where diagnostic files are found.
            devrstdir : str
                Directory where restart files are found.
            dst : str
                Directory where plots & tables will be created.
            year : int
                Year of the benchmark simulation.
            is_gchp : bool
                Denotes if this is GCHP (True) or GCC (False) data.
            overwrite : bool
                Denotes whether to ovewrite existing budget tables.
            spcdb_dir : str
                Directory where species_database.yml is stored.
        """
        # ------------------------------
        # Arguments from outside
        # ------------------------------
        self.devstr = devstr
        self.devdir = devdir
        self.devrstdir = devrstdir
        self.dst = dst
        self.is_gchp = is_gchp
        self.overwrite = overwrite

        # ------------------------------
        # Benchmark year
        # ------------------------------
        self.y0 = year
        self.y1 = self.y0 + 1
        self.y0_str = "{}".format(self.y0)
        self.y1_str = "{}".format(self.y1)

        # ------------------------------
        # Collection file lists
        # ------------------------------

        # Restarts
        if self.is_gchp:
            RstInit = join(self.devrstdir,
                           "initial_GEOSChem_rst.c48_TransportTracers.nc")
            RstFinal = join(
                self.devrstdir,
                "gcchem_internal_checkpoint.restart.{}*.nc4".format(
                    self.y1_str))
        else:
            RstInit = join(self.devrstdir,
                           "GEOSChem.Restart.{}*nc4".format(self.y0_str))
            RstFinal = join(self.devrstdir,
                            "GEOSChem.Restart.{}*.nc4".format(self.y1_str))

        # Diagnostics
        HemcoDiag = join(self.devdir,
                         "HEMCO_diagnostics.{}*.nc".format(self.y0_str))
        DryDep = join(self.devdir, "*.DryDep.{}*.nc4".format(self.y0_str))
        RadioNucl = join(self.devdir,
                         "*.RadioNuclide.{}*.nc4".format(self.y0_str))
        if is_gchp:
            StateMetAvg = join(self.devdir,
                               "*.StateMet_avg.{}*.nc4".format(self.y0_str))
            StateMetInst = join(self.devdir,
                                "*.StateMet_inst.{}*.nc4".format(self.y0_str))
        else:
            StateMet = join(self.devdir,
                            "*.StateMet.{}*.nc4".format(self.y0_str))
        SpeciesConc = join(self.devdir,
                           "*.SpeciesConc.{}*.nc4".format(self.y0_str))
        WetLossConv = join(self.devdir,
                           "*.WetLossConv.{}*.nc4".format(self.y0_str))
        WetLossLS = join(self.devdir,
                         "*.WetLossLS.{}*.nc4".format(self.y0_str))
        GCHPEmiss = join(self.devdir,
                         "GCHP.Emissions.{}*.nc4".format(self.y0_str))

        # ------------------------------
        # Read data collections
        # ------------------------------

        # Restarts
        skip_vars = constants.skip_these_vars
        self.ds_ini = xr.open_mfdataset(RstInit, drop_variables=skip_vars)
        self.ds_end = xr.open_mfdataset(RstFinal, drop_variables=skip_vars)

        # Change the restart datasets into format similar to GCC, and flip vertical axis
        if is_gchp:
            self.ds_ini = rename_and_flip_gchp_rst_vars(self.ds_ini)
            self.ds_end = rename_and_flip_gchp_rst_vars(self.ds_end)

        # Diagnostics
        self.ds_dcy = xr.open_mfdataset(RadioNucl, drop_variables=skip_vars)
        self.ds_dry = xr.open_mfdataset(DryDep, drop_variables=skip_vars)
        self.ds_cnc = xr.open_mfdataset(SpeciesConc, drop_variables=skip_vars)
        self.ds_wcv = xr.open_mfdataset(WetLossConv, drop_variables=skip_vars)
        self.ds_wls = xr.open_mfdataset(WetLossLS, drop_variables=skip_vars)

        # Met fields
        if is_gchp:
            self.ds_met = xr.open_mfdataset(StateMetAvg,
                                            drop_variables=skip_vars)
            # For now, don't read restarts for GCHP (bmy, 3/16/20)
            #ds_met_inst = xr.open_mfdataset(StateMetInst,
            #                                drop_variables=skip_vars)
            #
            # Add the initial met fields to the restart file collections
            #self.ds_ini = xr.merge([self.ds_ini, ds_met_inst.isel(time=0)])
            #self.ds_end = xr.merge([self.ds_end, ds_met_inst.isel(time=11)])
        else:
            self.ds_met = xr.open_mfdataset(StateMet, drop_variables=skip_vars)

        # Emissions
        if self.is_gchp:
            self.ds_hco = xr.open_mfdataset(GCHPEmiss,
                                            drop_variables=skip_vars)
        else:
            self.ds_hco = xr.open_mfdataset(HemcoDiag,
                                            drop_variables=skip_vars)

        # Area and troposphere mask
        # For gchp, get area in m2 from restart for use in calculating initial
        # and final mass from restart. Get area in cm2 from diagnostic
        # file for format compatibility with diagnostic output.
        if self.is_gchp:
            self.area_m2 = self.ds_ini["AREA"]
            self.area_cm2 = self.ds_met["Met_AREAM2"] * 1.0e4
        else:
            self.area_m2 = self.ds_met["AREA"].isel(time=0)
            self.area_cm2 = self.area_m2 * 1.0e4
        self.tropmask = get_troposphere_mask(self.ds_met)

        # ------------------------------
        # Months and days
        # ------------------------------
        self.N_MONTHS = 12
        self.N_MONTHS_FLOAT = self.N_MONTHS * 1.0

        # Days per month in the benchmark year
        self.d_per_mon = np.zeros(self.N_MONTHS)
        for t in range(self.N_MONTHS):
            self.d_per_mon[t] = monthrange(self.y0, t + 1)[1] * 1.0

        # Days in the benchmark year
        self.d_per_yr = np.sum(self.d_per_mon)

        # Fraction of year occupied by each month
        self.frac_of_yr = np.zeros(self.N_MONTHS)
        for t in range(self.N_MONTHS):
            self.frac_of_yr[t] = self.d_per_mon[t] / self.d_per_yr

        # ------------------------------
        # Species info
        # ------------------------------

        # List of species (and subsets for the trop & strat)
        self.species_list = ["Pb210", "Be7", "Be10"]

        # Read the species database
        path = join(spcdb_dir, "species_database.yml")
        spcdb = yaml_load_file(open(path))

        # Molecular weights [g mol-1], as taken from the species database
        self.mw = {}
        for v in self.species_list:
            self.mw[v] = spcdb[v]["MW_g"]
        self.mw["Air"] = constants.MW_AIR * 1.0e3

        # kg/s --> g/day
        self.kg_s_to_g_d_value = 86400.0 * 1000.0

        # ------------------------------
        # Conversion factors
        # ------------------------------
        self.kg_per_mol = {}
        self.vv_to_g = {}
        self.mcm2s_to_g_d = {}
        self.kg_s_to_g_d = {}

        for spc in self.species_list:

            # kg/s --> g/day (same for all species)
            self.kg_s_to_g_d[spc] = self.kg_s_to_g_d_value

            # kg/mole for each species
            self.kg_per_mol[spc] = constants.AVOGADRO / (self.mw[spc] * 1e-3)

            # v/v dry --> g
            self.vv_to_g[spc] = self.ds_met["Met_AD"].values  \
                              * (self.mw[spc] / self.mw["Air"]) * 1000.0

            # molec/cm2/s --> g/day
            self.mcm2s_to_g_d[spc] = self.area_cm2.values \
                                   / self.kg_per_mol[spc] \
                                   * self.kg_s_to_g_d[spc]
예제 #4
0
파일: budget_tt.py 프로젝트: NW177/gcpy
    def __init__(self, devstr, maindir, plotsdir, year, overwrite):
        """
        Initializes the _GlobVars class.

        Args:
        -----
            devstr : str
                Label denoting the "Dev" version.
            maindir : str
                Top-level benchmark run directory.
            plotsdir : str
                Directory where plots & tables will be created.
            year : int
                Year of the benchmark simulation.
            overwrite : bool
                Denotes whether to ovewrite existing budget tables.
        """
        # ------------------------------
        # Arguments from outside
        # ------------------------------
        self.devstr = devstr
        self.maindir = maindir
        self.plotsdir = plotsdir
        self.overwrite = overwrite
        
        # ------------------------------
        # Benchmark year
        # ------------------------------
        self.y0 = year
        self.y1 = self.y0 + 1
        self.y0_str = "{}".format(self.y0)
        self.y1_str = "{}".format(self.y1)

        # ------------------------------
        # Collection file lists
        # ------------------------------
        rstdir = join(self.maindir, self.devstr, "restarts")
        RstInit = join(rstdir, "GEOSChem.Restart.{}*nc4".format(self.y0_str))
        RstFinal = join(rstdir, "GEOSChem.Restart.{}*.nc4".format(self.y1_str))

        datadir = join(self.maindir, self.devstr, "OutputDir")
        HemcoDiag = join(datadir, 
                         "HEMCO_diagnostics.{}*.nc".format(self.y0_str))
        DryDep = join(datadir, 
                      "*.DryDep.{}*.nc4".format(self.y0_str))
        RadioNucl = join(datadir, 
                         "*.RadioNuclide.{}*.nc4".format(self.y0_str))
        StateMet = join(datadir, 
                        "*.StateMet.{}*.nc4".format(self.y0_str))
        SpeciesConc = join(datadir, 
                           "*.SpeciesConc.{}*.nc4".format(self.y0_str))
        WetLossConv = join(datadir, 
                           "*.WetLossConv.{}*.nc4".format(self.y0_str))
        WetLossLS = join(datadir, 
                         "*.WetLossLS.{}*.nc4".format(self.y0_str))
        GCHPEmiss =  join(datadir, 
                         "GCHP.Emissions.{}*.nc4".format(self.y0_str))
      
        # ------------------------------        
        # Read data collections
        # ------------------------------

        # Restarts
        self.ds_ini = xr.open_mfdataset(RstInit)
        self.ds_end = xr.open_mfdataset(RstFinal)

        # Diagnostics
        self.ds_dcy = xr.open_mfdataset(RadioNucl)
        self.ds_dry = xr.open_mfdataset(DryDep)
        self.ds_met = xr.open_mfdataset(StateMet)
        self.ds_cnc = xr.open_mfdataset(SpeciesConc)
        self.ds_wcv = xr.open_mfdataset(WetLossConv)
        self.ds_wls = xr.open_mfdataset(WetLossLS)

        # Set a flag if this data is from GCHP
        self.is_gchp = "nf" in self.ds_cnc.dims.keys()

        # Emissions
        if self.is_gchp:
            self.ds_hco = xr.open_mfdataset(GCHPEmiss)
        else:
            self.ds_hco = xr.open_mfdataset(HemcoDiag)
        
        # Area and troposphere mask
        if self.is_gchp:
            self.area_m2 = self.ds_met["Met_AREAM2"].isel(time=0)
        else:
            self.area_m2 = self.ds_met["AREA"].isel(time=0)
        self.area_cm2 = self.area_m2 * 1.0e4
        self.tropmask = get_troposphere_mask(self.ds_met)

        # ------------------------------       
        # Months and days
        # ------------------------------
        self.N_MONTHS = 12
        self.N_MONTHS_FLOAT = self.N_MONTHS * 1.0
        
        # Days per month in the benchmark year
        self.d_per_mon = np.zeros(self.N_MONTHS)
        for t in range(self.N_MONTHS):
            self.d_per_mon[t] = monthrange(self.y0, t+1)[1] * 1.0
            
        # Days in the benchmark year
        self.d_per_yr = np.sum(self.d_per_mon)
            
        # Fraction of year occupied by each month
        self.frac_of_yr = np.zeros(self.N_MONTHS)
        for t in range(self.N_MONTHS):
            self.frac_of_yr[t] = self.d_per_mon[t] / self.d_per_yr

        # ------------------------------
        # Species info
        # ------------------------------

        # List of species (and subsets for the trop & strat)
        self.species_list = ["Pb210", "Be7", "Be10" ]

        # Read the species database
        try:
            path = join(datadir, "species_database.yml")
            spcdb = yaml_load_file(open(path))
            tmp = spcdb["Pb210"]
        except KeyError or FileNotFoundError:
            path = join(os.path.dirname(__file__), "species_database.yml")
            spcdb = yaml_load_file(open(path))

        # Molecular weights [g mol-1], as taken from the species database
        self.mw = {}
        for v in self.species_list:
            self.mw[v] = spcdb[v]["MW_g"]
        self.mw["Air"] = constants.MW_AIR * 1.0e3

        # kg/s --> g/day
        self.kg_s_to_g_d_value= 86400.0 * 1000.0

        # ------------------------------
        # Conversion factors
        # ------------------------------
        self.kg_per_mol = {}
        self.vv_to_g = {}
        self.mcm2s_to_g_d  = {} 
        self.kg_s_to_g_d = {}

        for spc in self.species_list:

            # kg/s --> g/day (same for all species)
            self.kg_s_to_g_d[spc] = self.kg_s_to_g_d_value

            # kg/mole for each species
            self.kg_per_mol[spc] = constants.AVOGADRO / (self.mw[spc]  * 1e-3)

            # v/v dry --> g
            self.vv_to_g[spc] = self.ds_met["Met_AD"].values  \
                              * (self.mw[spc] / self.mw["Air"]) * 1000.0
          # molec/cm2/s --> g/day
            self.mcm2s_to_g_d[spc] = self.area_cm2.values \
                                   / self.kg_per_mol[spc] \
                                   * self.kg_s_to_g_d[spc]
예제 #5
0
    def __init__(self, devstr, devdir, devrstdir, year, dst, is_gchp,
                 overwrite, spcdb_dir):
        """
        Initializes the _GlobVars class.

        Args:
            devstr: str
                Label denoting the "Dev" version.
            devdir: str
                Directory where diagnostic files are found.
            devrstdir: str
                Directory where restart files are found.
            dst: str
                Directory where plots & tables will be created.
            year: int
                Year of the benchmark simulation.
            is_gchp: bool
                Denotes if this is GCHP (True) or GCC (False) data.
            overwrite: bool
                Denotes whether to ovewrite existing budget tables.
            spcdb_dir: str
                Directory where species_database.yml is stored.
        """
        # ------------------------------
        # Arguments from outside
        # ------------------------------
        self.devstr = devstr
        self.devdir = devdir
        self.devrstdir = devrstdir
        self.dst = dst
        self.is_gchp = is_gchp
        self.overwrite = overwrite

        # ------------------------------
        # Benchmark year
        # ------------------------------
        self.y0 = year
        self.y1 = self.y0 + 1
        self.y0_str = "{}".format(self.y0)
        self.y1_str = "{}".format(self.y1)

        # ------------------------------
        # Collection file lists
        # ------------------------------

        # Restarts
        if self.is_gchp:
            RstInit = join(self.devrstdir,
                           "initial_GEOSChem_rst.c48_TransportTracers.nc")
            RstFinal = join(
                self.devrstdir,
                "gcchem_internal_checkpoint.restart.{}*.nc4".format(
                    self.y1_str))
        else:
            RstInit = join(self.devrstdir,
                           "GEOSChem.Restart.{}*nc4".format(self.y0_str))
            RstFinal = join(self.devrstdir,
                            "GEOSChem.Restart.{}*.nc4".format(self.y1_str))
        # Diagnostics
        HemcoDiag = join(self.devdir,
                         "HEMCO_diagnostics.{}*.nc".format(self.y0_str))
        DryDep = join(self.devdir, "*.DryDep.{}*.nc4".format(self.y0_str))
        RadioNucl = join(self.devdir,
                         "*.RadioNuclide.{}*.nc4".format(self.y0_str))
        if is_gchp:
            StateMetAvg = join(self.devdir,
                               "*.StateMet_avg.{}*.nc4".format(self.y0_str))

            StateMet = join(self.devdir,
                            "*.StateMet.{}*.nc4".format(self.y0_str))

            # Set a logical if we need to read StateMet_avg or StateMet
            gchp_use_statemet_avg = os.path.exists(StateMetAvg)

        else:
            StateMet = join(self.devdir,
                            "*.StateMet.{}*.nc4".format(self.y0_str))
        SpeciesConc = join(self.devdir,
                           "*.SpeciesConc.{}*.nc4".format(self.y0_str))
        WetLossConv = join(self.devdir,
                           "*.WetLossConv.{}*.nc4".format(self.y0_str))
        WetLossLS = join(self.devdir,
                         "*.WetLossLS.{}*.nc4".format(self.y0_str))
        GCHPEmiss = join(self.devdir,
                         "*.Emissions.{}*.nc4".format(self.y0_str))

        # ------------------------------
        # Read data collections
        # ------------------------------

        # Restarts
        skip_vars = constants.skip_these_vars
        extra_kwargs = {}

        self.ds_ini = xr.open_mfdataset(RstInit,
                                        drop_variables=skip_vars,
                                        **extra_kwargs)
        self.ds_end = xr.open_mfdataset(RstFinal,
                                        drop_variables=skip_vars,
                                        **extra_kwargs)

        # Change the restart datasets into format similar to GCC, and flip
        # vertical axis.  Also test if the restart files have the BXHEIGHT
        # variable contained within them.
        if is_gchp:
            self.ds_ini = rename_and_flip_gchp_rst_vars(self.ds_ini)
            self.ds_end = rename_and_flip_gchp_rst_vars(self.ds_end)

        # Diagnostics
        self.ds_dcy = xr.open_mfdataset(RadioNucl,
                                        drop_variables=skip_vars,
                                        **extra_kwargs)
        self.ds_dry = xr.open_mfdataset(DryDep,
                                        drop_variables=skip_vars,
                                        **extra_kwargs)
        self.ds_cnc = xr.open_mfdataset(SpeciesConc,
                                        drop_variables=skip_vars,
                                        **extra_kwargs)
        self.ds_wcv = xr.open_mfdataset(WetLossConv,
                                        drop_variables=skip_vars,
                                        **extra_kwargs)
        self.ds_wls = xr.open_mfdataset(WetLossLS,
                                        drop_variables=skip_vars,
                                        **extra_kwargs)

        # Met fields
        # For GCHP: Read from StateMet_avg if present (otherwise StateMet)
        if is_gchp and gchp_use_statemet_avg:
            self.ds_met = xr.open_mfdataset(StateMetAvg,
                                            drop_variables=skip_vars,
                                            **extra_kwargs)
        else:
            self.ds_met = xr.open_mfdataset(StateMet,
                                            drop_variables=skip_vars,
                                            **extra_kwargs)

        # Emissions
        if self.is_gchp:
            self.ds_hco = xr.open_mfdataset(GCHPEmiss,
                                            drop_variables=skip_vars,
                                            **extra_kwargs)
        else:
            self.ds_hco = xr.open_mfdataset(HemcoDiag,
                                            drop_variables=skip_vars,
                                            **extra_kwargs)

        # Area and troposphere mask
        # The area in m2 is on the restart file grid
        # The area in cm2 is on the History diagnostic grid
        # Both grids are identical in GCClassic but differ in GCHP
        if self.is_gchp:
            if 'Met_AREAM2' not in self.ds_met.data_vars.keys():
                msg = 'Could not find Met_AREAM2 in StateMet_avg collection!'
                raise ValueError(msg)
            area_m2 = self.ds_met["Met_AREAM2"].isel(time=0)
            area_m2 = reshape_MAPL_CS(area_m2)
            self.area_m2 = area_m2
            self.area_cm2 = self.ds_met["Met_AREAM2"] * 1.0e4
        else:
            self.area_m2 = self.ds_met["AREA"].isel(time=0)
            self.area_cm2 = self.area_m2 * 1.0e4
        self.tropmask = get_troposphere_mask(self.ds_met)

        # ------------------------------
        # Months and days
        # ------------------------------
        self.N_MONTHS = 12
        self.N_MONTHS_FLOAT = self.N_MONTHS * 1.0

        # Days per month in the benchmark year
        self.d_per_mon = np.zeros(self.N_MONTHS)
        for t in range(self.N_MONTHS):
            self.d_per_mon[t] = monthrange(self.y0, t + 1)[1] * 1.0

        # Days in the benchmark year
        self.d_per_yr = np.sum(self.d_per_mon)

        # Fraction of year occupied by each month
        self.frac_of_yr = np.zeros(self.N_MONTHS)
        for t in range(self.N_MONTHS):
            self.frac_of_yr[t] = self.d_per_mon[t] / self.d_per_yr

        # ------------------------------
        # Species info
        # ------------------------------

        # List of species (and subsets for the trop & strat)
        self.species_list = ["Pb210", "Be7", "Be10"]

        # Read the species database
        path = join(spcdb_dir, "species_database.yml")
        spcdb = yaml_load_file(open(path))

        # Molecular weights [g mol-1], as taken from the species database
        self.mw = {}
        for v in self.species_list:
            self.mw[v] = spcdb[v]["MW_g"]
        self.mw["Air"] = constants.MW_AIR_g

        # kg/s --> g/day
        self.kg_s_to_g_d_value = 86400.0 * 1000.0

        # ------------------------------
        # Conversion factors
        # ------------------------------
        self.kg_per_mol = {}
        self.vv_to_g = {}
        self.mcm2s_to_g_d = {}
        self.kg_s_to_g_d = {}
        for spc in self.species_list:

            # kg/s --> g/day (same for all species)
            self.kg_s_to_g_d[spc] = self.kg_s_to_g_d_value

            # kg/mole for each species
            self.kg_per_mol[spc] = constants.AVOGADRO / (self.mw[spc] * 1e-3)

            # v/v dry --> g
            self.vv_to_g[spc] = self.ds_met["Met_AD"].values  \
                * (self.mw[spc] / self.mw["Air"]) * 1000.0

            # molec/cm2/s --> g/day
            self.mcm2s_to_g_d[spc] = self.area_cm2.values \
                / self.kg_per_mol[spc] \
                * self.kg_s_to_g_d[spc]