def cdf_ssm_geo_generator(satnums,dt,localdir=None): code = 'cdf' for satnum in satnums: cdf = dmspcdf_tools.get_cdf(satnum,dt.year,dt.month,dt.day,'ssm') sod = special_datetime.datetimearr2sod(cdf['Epoch'][:]).flatten() glat = cdf['SC_GEOCENTRIC_LAT'][:] glon = cdf['SC_GEOCENTRIC_LON'][:] #mlat = cdf['SC_AACGM_LAT'][:] db = cdf['DELTA_B_SC'][:] dbx,dby,dbz = db[:,0],db[:,1],db[:,2] #db_noaa = cdf['DELTA_B_SC_ORIG'][:] #dbx_noaa,dby_noaa,dbz_noaa = db_noaa[:,0],db_noaa[:,1],db_noaa[:,2] yield code,satnum,dt,sod,glat,glon,dbx,dby,dbz
def __init__(self, cdffile, imgdir=None, make_plot=True, plot_failed=False, csvdir=None, writecsv=True, csvvars=['mlat', 'mlt']): """Constructor for absatday Parameters ---------- cdffile : str DMSP SSJ CDF file (probably from NASA CDAWeb) imgdir : str, optional Path to dump boundary identification images to (must exist) If None looks for environment variable DMSP_DIR_ABIMG make_plot : bool, optional Plot of each successful identification (the default is True) plot_failed : bool, optional Also plot unsuccesful passes (the default is False) csvdir : str, optional Directory to dump CSV files to (must exist) If None looks for environment variable DMSP_DIR_ABCSV If still fails raises RuntimeError writecsv : bool, optional Write a CSV file of boundary identifications (the default is True) csvvars : list, optional List of optional variables to include in each line of the CSV file. See abcsv for more details. (default=['mlat', 'mlt']) """ self.log = logging.getLogger(loggername + '.' + self.__class__.__name__) self.cdf = pycdf.CDF(cdffile) #Parse out spacecraft so we know how to handle J4/J5 differences if 'dmsp' in cdffile: # Get the spacecraft number from the filename self.satnum = int( os.path.split(cdffile)[-1].split('dmsp-f')[-1][:2]) self.log.info("Satellite number determined to be " + "{:d}".format(self.satnum)) else: raise RuntimeError( ('Unexpected CDF filename {:s}, '.format(cdffile) + 'could not parse out DMSP number')) self.cdffn = cdffile self.make_plot = make_plot # Make plots of passes T/F self.plot_failed = plot_failed #Plot failed identifications also T/F self.writecsv = writecsv # Write pass identifications to a file self.time = self.cdf['Epoch'][:] self.uts = special_datetime.datetimearr2sod(self.time) self.hod = self.uts / 3600. self.diff_flux = self.cdf['ELE_DIFF_ENERGY_FLUX'][:] self.diff_flux_std = self.cdf['ELE_DIFF_ENERGY_FLUX_STD'][:] self.total_flux = self.cdf['ELE_TOTAL_ENERGY_FLUX'][:] #The uncertainty in the CDF is relative self.total_flux_std = self.cdf['ELE_TOTAL_ENERGY_FLUX_STD'][:] # Handle filtering out any data without enough counts countthresh = 2. self.counts = (self.cdf['ELE_COUNTS_OBS'][:] - self.cdf['ELE_COUNTS_BKG'][:]) #Zero out any dubious fluxes self.diff_flux[self.counts <= countthresh] = 0.0 latvar, ltvar = 'SC_APEX_LAT', 'SC_APEX_MLT' if latvar not in self.cdf or ltvar not in self.cdf: # v1.1.3 self.log.warning(('Unable to find APEX latitude or local ' + 'time variables in CDF file. Falling ' + 'back to AACGM magnetic coordinates')) latvar, ltvar = 'SC_AACGM_LAT', 'SC_AACGM_LTIME' self.mlat = self.cdf[latvar][:] self.mlt = self.cdf[ltvar][:] self.channel_energies = self.cdf['CHANNEL_ENERGIES'][:] self.xings = self.simple_passes(self.mlat) self.polarpasses = [] # Look for environemnt variables to define paths if no paths provided imgdir = self.if_none_use_envvar(imgdir, 'DMSP_DIR_ABIMG') if imgdir is None: raise RuntimeError( 'No image dir passed & no DMSP_DIR_ABIMG envvar') self.imgdir = imgdir csvdir = self.if_none_use_envvar(csvdir, 'DMSP_DIR_ABCSV') if csvdir is None: raise RuntimeError('No csv dir passed & no DMSP_DIR_ABCSV envvar') cdffn_noext = os.path.splitext(os.path.split(cdffile)[-1])[0] csvfile = '_'.join([cdffn_noext, 'boundaries.csv']) self.csv = abcsv(csvdir, csvfile, cdffile, csvvars=csvvars, writecsv=self.writecsv) # Start processing the polar passes one by one for i in range(len(self.xings) - 1): newpass = abpolarpass(self, self.xings[i], self.xings[i + 1] - 1) self.polarpasses.append(newpass)
sys.path.append('/home/liamk/seshat/glowcond/glow098release/GLOW/') import pyglow098 from geospacepy import special_datetime, dmspcdf_tools, dmsp_spectrogram, satplottools #from ovationpyme import ovation_prime #op_cond_estimator = ovation_prime.ConductanceEstimator(datetime.datetime(2010,5,27,12),datetime.datetime(2010,5,30,12)) year, month, day = 2010, 5, 29 sat = 16 cdf = dmspcdf_tools.get_cdf(sat, year, month, day, 'ssj') cdfm = dmspcdf_tools.get_cdf(sat, year, month, day, 'ssm') cdfies = dmspcdf_tools.get_cdf(sat, year, month, day, 'ssies') dts = cdf['Epoch'][:] uts = special_datetime.datetimearr2sod(cdf['Epoch'][:]) auroral_region = cdf['AURORAL_REGION'][:].flatten() chen = cdf['CHANNEL_ENERGIES'][:] glats = cdf['SC_GEOCENTRIC_LAT'][:] glons = cdf['SC_GEOCENTRIC_LON'][:] mlats = cdf['SC_APEX_LAT'][:] mlts = cdf['SC_APEX_MLT'][:] oi = cdf['ORBIT_INDEX'][:] auroral = np.logical_and(auroral_region > 1, glats > 0.) auroral_eflux = cdf['ELE_DIFF_ENERGY_FLUX'][:][auroral, :] * 1.6e-12 auroral_flux = cdf['ELE_DIFF_ENERGY_FLUX'][:][auroral, :] / chen auroral_avg_energy = cdf['ELE_AVG_ENERGY'][:][auroral] auroral_total_eflux = cdf['ELE_TOTAL_ENERGY_FLUX'][:][auroral] * 1.6e-12 deltaB = cdfm['DELTA_B_APX'][:][auroral, :]
def plot_orbit_cond(sat, year, month, day, orbit, minlat=50., plotdir=None): # #Prepare Plots # import matplotlib.gridspec as gridspec from matplotlib.colors import LogNorm gs = gridspec.GridSpec(4, 11) f = pp.figure() #a0 = f.add_subplot(511) #a05 = f.add_subplot(512) split = 9 cbwidth = 1 a1 = pp.subplot(gs[0, :split]) a11 = pp.subplot(gs[0, split:split + cbwidth]) a2 = pp.subplot(gs[1, :split]) a22 = pp.subplot(gs[1:2, split:]) a3 = pp.subplot(gs[2, :split]) #a33 = pp.subplot(gs[2,split:]) a4 = pp.subplot(gs[3, :split]) a44 = pp.subplot(gs[3, split:split + cbwidth]) # # Get conductance CDF # cdffn = get_cdf(sat, year, month, day, 'ssj', cdfdir=cdfdir, return_file=True) cdffn_cond = get_cond_cdffn(cdffn) cdffn_cond_leaf = os.path.split(cdffn_cond)[-1] cdffn_cond_leaf = os.path.splitext(cdffn_cond_leaf)[0] hemi = 'N' if np.sign(orbit) == 1 else 'S' # # Figure Filename # if plotdir is None: plotdir = '/home/liamk/code/glowcond/%s' % (cdffn_cond_leaf) if not os.path.exists(plotdir): os.makedirs(plotdir) figfn = os.path.join( plotdir, '%s_%s_%d.png' % (cdffn_cond_leaf, hemi, np.abs(orbit))) with pycdf.CDF(cdffn_cond) as cdf: orbit_index = cdf['ORBIT_INDEX'][:].flatten() mlats = cdf['SC_APEX_LAT'][:].flatten() in_orbit = orbit_index == orbit subset = np.logical_and(in_orbit, np.abs(mlats) > minlat) dts = cdf['Epoch'][:][subset] uts = special_datetime.datetimearr2sod( cdf['Epoch'][:]).flatten()[subset] hod = uts / 3600. auroral_region = cdf['AURORAL_REGION'][:].flatten()[subset] chen = cdf['CHANNEL_ENERGIES'][:] glats = cdf['SC_GEOCENTRIC_LAT'][:].flatten()[subset] glons = cdf['SC_GEOCENTRIC_LON'][:].flatten()[subset] mlats = cdf['SC_APEX_LAT'][:].flatten()[subset] mlts = cdf['SC_APEX_MLT'][:].flatten()[subset] eflux = cdf['ELE_DIFF_ENERGY_FLUX'][:][subset, :] avg_energy = cdf['ELE_AVG_ENERGY'][:].flatten()[subset] total_eflux = cdf['ELE_TOTAL_ENERGY_FLUX'][:].flatten()[subset] total_eflux *= 1.6e-12 #eV/cm/s/sr -> mW/m^2 eflux *= 1.6e-12 z = cdf['CONDUCTIVITY_ALTITUDES'][:] ped = cdf['PEDERSEN_CONDUCTIVITY'][:][subset] hall = cdf['HALL_CONDUCTIVITY'][:][subset] intped = cdf['PEDERSEN_CONDUCTANCE'][:][subset] inthall = cdf['HALL_CONDUCTANCE'][:][subset] if spectrograms: #Plot Electron energy flux dmsp_spectrogram.dmsp_spectrogram( hod, eflux, chen, datalabel=None, cblims=[1e-7, 1e-2], ax=a1, ax_cb=a11, fluxunits='Electron\nEnergy Flux\n[mW/m^2]') #Plot Pedersen Conductance a2.plot(hod, intped, 'r.-', label='DMSP+GLOW') #a2.plot(uts[:-1],np.diff(inthall),label='dPed') #a2.set_ylim([0,120]) #a2.set_ylim([0,1]) a2.legend(ncol=2, loc=0) a2.set_ylabel('Pedersen\n Conductance\n[S]') satplottools.draw_dialplot(a22) x, y = satplottools.latlt2cart(mlats, mlts, hemi) a22.plot(x, y, 'k.') a22.text(x[-1], y[-1], 'End') #Plot Hall Conductance a3.plot(hod, inthall, 'r.-', label='DMSP+GLOW') a3.legend(ncol=2, loc=0) a3.set_ylabel('Hall\n Conductance\n[S]') #Draw conductivity as a pcolor plot with log-scaled color scale try: ped[ped <= 0.] = 0.01 T, Z = np.meshgrid(hod, z) mappable = a4.pcolor(T, Z, ped.T, norm=LogNorm(vmin=np.nanmin(ped), vmax=np.nanmax(ped)), cmap='jet') cb = pp.colorbar(mappable, cax=a44) cb.ax.set_ylabel('Pedersen\nConductivity\n [S/m]') a4.set_ylabel('Altitude\n[km]') except: pass for ax in [a1, a2, a3]: ax.xaxis.set_ticklabels([]) for ax in [a1, a2, a3, a4]: ax.set_xlim(hod[0], hod[-1]) a4.set_xlabel('Hour of Day') f.suptitle('%.2d-%2.d-%d %s orbit %d' % (year, month, day, hemi, orbit)) f.savefig(figfn) pp.close(f)
def run_ssj_glow(sat, year, month, day, cdfdir=None, minlat=50., create_conductance_cdf=False, clobber=True, silent=False): """ Calculate the conductivities along DMSP satellite track for a particular day """ n_processers = 4 test = False # Test for intent(out) bug maxwellian = False # Use maxwellian spectrum instead of DMSP SSJ dt = datetime.datetime(year, month, day, 12, 0, 0) cdffn = dmspcdf_tools.get_cdf(sat, year, month, day, 'ssj', return_file=True) if not os.path.exists(cdffn): raise NoSSJCDFError('No such CDF %s' % (cdffn)) with pycdf.CDF(cdffn) as cdf: dts = cdf['Epoch'][:] uts = special_datetime.datetimearr2sod(cdf['Epoch'][:]).flatten() n_times = uts.shape[0] auroral_region = cdf['AURORAL_REGION'][:].flatten() chen = cdf['CHANNEL_ENERGIES'][:] glats = cdf['SC_GEOCENTRIC_LAT'][:].flatten() mlats = cdf['SC_APEX_LAT'][:].flatten() glons = cdf['SC_GEOCENTRIC_LON'][:].flatten() nflux = cdf['ELE_DIFF_ENERGY_FLUX'][:] / chen * np.pi avg_energy = cdf['ELE_AVG_ENERGY'][:].flatten() total_eflux = cdf['ELE_TOTAL_ENERGY_FLUX'][:].flatten() * np.pi #STD is already in mW/m^2 total_eflux_std = cdf['ELE_TOTAL_ENERGY_FLUX_STD'][:].flatten() total_eflux *= 1.6e-12 #eV/cm/s/sr -> mW/m^2 min_mlat = 50. # #Pack up the inputs # startsec = special_datetime.datetime2sod(datetime.datetime.now()) inputs, results, subset_masks = [], [], [] for i_subset in range(n_processers): subset_length = n_times / n_processers uts_start, uts_end = i_subset * subset_length, (i_subset + 1) * subset_length in_lats = np.abs(mlats) > min_mlat subset_mask = np.logical_and(uts >= uts_start, uts < uts_end) subset_mask = np.logical_and(subset_mask, in_lats) subset_masks.append(subset_mask) uts_in = uts[subset_mask] glats_in = glats[subset_mask] glons_in = glons[subset_mask] nflux_in = nflux[subset_mask, :] avg_energy_in = avg_energy[subset_mask] total_eflux_in = total_eflux[subset_mask] total_eflux_std_in = total_eflux_std[subset_mask] #Zero uncertain fluxes (potential source of strange dayside bands) uncert_flux = total_eflux_in < total_eflux_std_in / 2 total_eflux_in[uncert_flux] = 0. nflux_in[uncert_flux, :] = 0. inputs.append( (year, month, day, uts_in, glats_in, glons_in, nflux_in, avg_energy_in, total_eflux_in, test, maxwellian)) # #Pass to the pool # if n_processers > 1: pool = multiprocessing.Pool(n_processers) results = pool.map(mappable_glow, inputs) else: results = [mappable_glow(inputs[0])] endsec = special_datetime.datetime2sod(datetime.datetime.now()) print('------Took %.1f minutes-----' % ((endsec - startsec) / 60.)) # #Unpack the results # for i_subset in range(n_processers): subset_mask = subset_masks[i_subset] z, subset_pedcond, subset_hallcond, subset_intped, subset_inthall = results[ i_subset][:] if i_subset == 0: #Initialize the things pedcond, hallcond = np.zeros( (n_times, len(z.flatten()))), np.zeros( (n_times, len(z.flatten()))) pedcond.fill(np.nan) hallcond.fill(np.nan) intped, inthall = np.zeros_like(glats), np.zeros_like(glats) intped.fill(np.nan) inthall.fill(np.nan) #Store the conductances pedcond[subset_mask, :] = subset_pedcond hallcond[subset_mask, :] = subset_hallcond intped[subset_mask] = subset_intped inthall[subset_mask] = subset_inthall if create_conductance_cdf: cdffn_cond = get_cond_cdffn(cdffn) if os.path.exists(cdffn_cond): if clobber: print('Conductance CDF %s will be clobbered.' % (cdffn_cond)) os.remove(cdffn_cond) shutil.copyfile(cdffn, cdffn_cond) else: raise IOError( 'Conductance CDF %s exists and clobber is False' % (cdffn_cond)) #Copy the SSJ file shutil.copyfile(cdffn, cdffn_cond) if not os.path.exists(cdffn_cond): raise RuntimeError('Conductance file %s not copied' % (cdffn_cond)) with pycdf.CDF(cdffn_cond) as cdf_cond: cdf_cond.readonly(False) # Modify the file cdf_cond['CONDUCTIVITY_ALTITUDES'] = z cdf_cond['CONDUCTIVITY_ALTITUDES'].attrs['UNITS'] = 'km' cdf_cond['PEDERSEN_CONDUCTANCE'] = intped cdf_cond['PEDERSEN_CONDUCTANCE'].attrs['UNITS'] = 'S' cdf_cond['HALL_CONDUCTANCE'] = inthall cdf_cond['HALL_CONDUCTANCE'].attrs['UNITS'] = 'S' cdf_cond['PEDERSEN_CONDUCTIVITY'] = pedcond cdf_cond['PEDERSEN_CONDUCTIVITY'].attrs['UNITS'] = 'S/m' cdf_cond['HALL_CONDUCTIVITY'] = hallcond cdf_cond['HALL_CONDUCTIVITY'].attrs['UNITS'] = 'S/m'