| @@ 82-177 (lines=96) @@ | ||
| 79 | return sun.transform_to(altaz).zen.value |
|
| 80 | ||
| 81 | ||
| 82 | def read_spectra(year, orbit, spec_base=None, skip_upleg=True): |
|
| 83 | """Read and examine SCIAMACHY orbit spectra |
|
| 84 | ||
| 85 | Reads the limb spactra and extracts the dates, times, latitudes, |
|
| 86 | longitudes to be used to re-assess the retrieved geolocations. |
|
| 87 | ||
| 88 | Parameters |
|
| 89 | ---------- |
|
| 90 | year: int |
|
| 91 | The measurement year to select the corresponding subdir |
|
| 92 | below `spec_base` (see below). |
|
| 93 | orbit: int |
|
| 94 | SCIAMACHY/Envisat orbit number of the spectra. |
|
| 95 | spec_base: str, optional |
|
| 96 | The root path to the level 1c spectra. Uses the current |
|
| 97 | dir if not set or set to `None` (default). |
|
| 98 | skip_upleg: bool, optional |
|
| 99 | Skip upleg limb scans, i.e. night time scans. For NO retrievals, |
|
| 100 | those are not used and should be not used here. |
|
| 101 | Default: True |
|
| 102 | ||
| 103 | Returns |
|
| 104 | ------- |
|
| 105 | (dts, times, lats, lons, mlsts, alsts, eotcorr) |
|
| 106 | """ |
|
| 107 | fail = (None,) * 7 |
|
| 108 | if spec_base is None: |
|
| 109 | spec_base = os.curdir |
|
| 110 | spec_path = os.path.join(spec_base, "{0}".format(year)) |
|
| 111 | spec_path2 = os.path.join(spec_base, "{0}".format(int(year) + 1)) |
|
| 112 | logging.debug("spec_path: %s", spec_path) |
|
| 113 | logging.debug("spec_path2: %s", spec_path) |
|
| 114 | if not (os.path.isdir(spec_path) or os.path.isdir(spec_path2)): |
|
| 115 | return fail |
|
| 116 | ||
| 117 | # the star stands for the (optional) date subdir |
|
| 118 | # to find all spectra for the orbit |
|
| 119 | spfiles = glob.glob( |
|
| 120 | '{0}/*/SCIA_limb_*_1_0_{1:05d}.dat.l_mpl_binary' |
|
| 121 | .format(spec_path, orbit)) |
|
| 122 | # sometimes for whatever reason the orbit ends up in the wrong year subdir |
|
| 123 | # looks in the subdir for the following year as well. |
|
| 124 | spfiles += glob.glob( |
|
| 125 | '{0}/*/SCIA_limb_*_1_0_{1:05d}.dat.l_mpl_binary' |
|
| 126 | .format(spec_path2, orbit)) |
|
| 127 | if len(spfiles) < 2: |
|
| 128 | return fail |
|
| 129 | ||
| 130 | dts = [] |
|
| 131 | times = [] |
|
| 132 | lats = [] |
|
| 133 | lons = [] |
|
| 134 | mlsts = [] |
|
| 135 | alsts = [] |
|
| 136 | ||
| 137 | sls = sl.scia_limb_scan() |
|
| 138 | for f in sorted(spfiles): |
|
| 139 | sls.read_from_file(f) |
|
| 140 | # copy the values from the l1c file |
|
| 141 | lat, lon = sls.cent_lat_lon[:2] |
|
| 142 | mlst, alst, eotcorr = sls.local_solar_time(False) |
|
| 143 | tp_lats = sls.limb_data.tp_lat |
|
| 144 | date = sls.date |
|
| 145 | # debug output if requested |
|
| 146 | logging.debug("file: %s", f) |
|
| 147 | logging.debug("lat: %s, lon: %s", lat, lon) |
|
| 148 | logging.debug("mlst: %s, alst: %s, eotcorr: %s", mlst, alst, eotcorr) |
|
| 149 | logging.debug("tp_lats: %s", tp_lats) |
|
| 150 | logging.debug("date: %s", date) |
|
| 151 | if skip_upleg and ((tp_lats[1] - tp_lats[-2]) < 0.5): |
|
| 152 | # Exclude non-downleg measurements where the latitude |
|
| 153 | # of the last real tangent point (the last is dark sky) |
|
| 154 | # is larger than or too close to the first latitude. |
|
| 155 | # Requires an (empirical) separation of +0.5 degree. |
|
| 156 | logging.debug("excluding upleg point at: %s, %s", lat, lon) |
|
| 157 | continue |
|
| 158 | dtdate = pd.to_datetime(dt.datetime(*date), utc=True) |
|
| 159 | time_hour = dtdate.hour + dtdate.minute / 60.0 + dtdate.second / 3600.0 |
|
| 160 | logging.debug("mean lst: %s, apparent lst: %s, EoT: %s", mlst, alst, eotcorr) |
|
| 161 | dts.append(dtdate) |
|
| 162 | times.append(time_hour) |
|
| 163 | lats.append(lat) |
|
| 164 | lons.append(lon) |
|
| 165 | mlsts.append(mlst) |
|
| 166 | alsts.append(alst) |
|
| 167 | ||
| 168 | if len(lats) < 2: |
|
| 169 | # interpolation will fail with less than 2 points |
|
| 170 | return fail |
|
| 171 | ||
| 172 | return (np.asarray(dts), |
|
| 173 | np.asarray(times), |
|
| 174 | np.asarray(lats), |
|
| 175 | np.asarray(lons), |
|
| 176 | np.asarray(mlsts), |
|
| 177 | np.asarray(alsts), eotcorr) |
|
| 178 | ||
| 179 | ||
| 180 | def _get_orbit_ds(filename): |
|
| @@ 81-176 (lines=96) @@ | ||
| 78 | return sun.transform_to(altaz).zen.value |
|
| 79 | ||
| 80 | ||
| 81 | def read_spectra(year, orbit, spec_base=None, skip_upleg=True): |
|
| 82 | """Read and examine SCIAMACHY orbit spectra |
|
| 83 | ||
| 84 | Reads the limb spactra and extracts the dates, times, latitudes, |
|
| 85 | longitudes to be used to re-assess the retrieved geolocations. |
|
| 86 | ||
| 87 | Parameters |
|
| 88 | ---------- |
|
| 89 | year: int |
|
| 90 | The measurement year to select the corresponding subdir |
|
| 91 | below `spec_base` (see below). |
|
| 92 | orbit: int |
|
| 93 | SCIAMACHY/Envisat orbit number of the spectra. |
|
| 94 | spec_base: str, optional |
|
| 95 | The root path to the level 1c spectra. Uses the current |
|
| 96 | dir if not set or set to `None` (default). |
|
| 97 | skip_upleg: bool, optional |
|
| 98 | Skip upleg limb scans, i.e. night time scans. For NO retrievals, |
|
| 99 | those are not used and should be not used here. |
|
| 100 | Default: True |
|
| 101 | ||
| 102 | Returns |
|
| 103 | ------- |
|
| 104 | (dts, times, lats, lons, mlsts, alsts, eotcorr) |
|
| 105 | """ |
|
| 106 | fail = (None,) * 7 |
|
| 107 | if spec_base is None: |
|
| 108 | spec_base = os.curdir |
|
| 109 | spec_path = os.path.join(spec_base, "{0}".format(year)) |
|
| 110 | spec_path2 = os.path.join(spec_base, "{0}".format(int(year) + 1)) |
|
| 111 | logging.debug("spec_path: %s", spec_path) |
|
| 112 | logging.debug("spec_path2: %s", spec_path) |
|
| 113 | if not (os.path.isdir(spec_path) or os.path.isdir(spec_path2)): |
|
| 114 | return fail |
|
| 115 | ||
| 116 | # the star stands for the (optional) date subdir |
|
| 117 | # to find all spectra for the orbit |
|
| 118 | spfiles = glob.glob( |
|
| 119 | '{0}/*/SCIA_limb_*_1_0_{1:05d}.dat.l_mpl_binary' |
|
| 120 | .format(spec_path, orbit)) |
|
| 121 | # sometimes for whatever reason the orbit ends up in the wrong year subdir |
|
| 122 | # looks in the subdir for the following year as well. |
|
| 123 | spfiles += glob.glob( |
|
| 124 | '{0}/*/SCIA_limb_*_1_0_{1:05d}.dat.l_mpl_binary' |
|
| 125 | .format(spec_path2, orbit)) |
|
| 126 | if len(spfiles) < 2: |
|
| 127 | return fail |
|
| 128 | ||
| 129 | dts = [] |
|
| 130 | times = [] |
|
| 131 | lats = [] |
|
| 132 | lons = [] |
|
| 133 | mlsts = [] |
|
| 134 | alsts = [] |
|
| 135 | ||
| 136 | sls = sl.scia_limb_scan() |
|
| 137 | for f in sorted(spfiles): |
|
| 138 | sls.read_from_file(f) |
|
| 139 | # copy the values from the l1c file |
|
| 140 | lat, lon = sls.cent_lat_lon[:2] |
|
| 141 | mlst, alst, eotcorr = sls.local_solar_time(False) |
|
| 142 | tp_lats = sls.limb_data.tp_lat |
|
| 143 | date = sls.date |
|
| 144 | # debug output if requested |
|
| 145 | logging.debug("file: %s", f) |
|
| 146 | logging.debug("lat: %s, lon: %s", lat, lon) |
|
| 147 | logging.debug("mlst: %s, alst: %s, eotcorr: %s", mlst, alst, eotcorr) |
|
| 148 | logging.debug("tp_lats: %s", tp_lats) |
|
| 149 | logging.debug("date: %s", date) |
|
| 150 | if skip_upleg and ((tp_lats[1] - tp_lats[-2]) < 0.5): |
|
| 151 | # Exclude non-downleg measurements where the latitude |
|
| 152 | # of the last real tangent point (the last is dark sky) |
|
| 153 | # is larger than or too close to the first latitude. |
|
| 154 | # Requires an (empirical) separation of +0.5 degree. |
|
| 155 | logging.debug("excluding upleg point at: %s, %s", lat, lon) |
|
| 156 | continue |
|
| 157 | dtdate = pd.to_datetime(dt.datetime(*date), utc=True) |
|
| 158 | time_hour = dtdate.hour + dtdate.minute / 60.0 + dtdate.second / 3600.0 |
|
| 159 | logging.debug("mean lst: %s, apparent lst: %s, EoT: %s", mlst, alst, eotcorr) |
|
| 160 | dts.append(dtdate) |
|
| 161 | times.append(time_hour) |
|
| 162 | lats.append(lat) |
|
| 163 | lons.append(lon) |
|
| 164 | mlsts.append(mlst) |
|
| 165 | alsts.append(alst) |
|
| 166 | ||
| 167 | if len(lats) < 2: |
|
| 168 | # interpolation will fail with less than 2 points |
|
| 169 | return fail |
|
| 170 | ||
| 171 | return (np.asarray(dts), |
|
| 172 | np.asarray(times), |
|
| 173 | np.asarray(lats), |
|
| 174 | np.asarray(lons), |
|
| 175 | np.asarray(mlsts), |
|
| 176 | np.asarray(alsts), eotcorr) |
|
| 177 | ||
| 178 | ||
| 179 | class _circ_interp(object): |
|