def monthly_labels(self): """ months between winter and summer solstice in order of months after solstices for plotting purposes """ for month, lab in zip( [1, 2, 3, 4, 5], ['Jan/Nov', 'Feb/Oct', 'Mar/Sep', 'Apr/Aug', 'May/Jul']): hours = pd.date_range(start='{}/21/2019'.format(month), end='{}/22/2019'.format(month), freq='1T', tz=self.time_zone) alts = 90 - get_altitude_fast(self.lat, self.lng, hours.values) azs = (get_azimuth_fast(self.lat, self.lng, hours.values) + 90) * \ np.pi / 180. sel = alts <= 88 xs, ys = self.polar_2_cartesian(alts[sel], azs[sel]) self.ax.plot(xs, ys, color=self.cmap(0.858), lw=0.5, zorder=3, ls='--') # get the angle of the line between 80 and 90 on the right hand side of the # plot for the angel of rotation of the text sel = (alts > 70) & (alts < 80) xs, ys = self.polar_2_cartesian(alts[sel], azs[sel]) ys = ys[xs > 0] xs = xs[xs > 0] grad = (ys[-15] - ys[0]) / (xs[-15] - xs[0]) grad_inc = np.arctan(grad) sel = alts < 70 # plot the text at the positions near the 70 deg line xs, ys = self.polar_2_cartesian(alts[sel], azs[sel]) if len(xs) != 0: self.ax.text( xs[-1], ys[-1], '{}'.format(lab), color='black', zorder=6, fontproperties=self.prop, fontsize=10, rotation=360 + (grad_inc * 180. / np.pi) + 5, )
def testGetAzimuthFast(self): day = datetime.datetime( 2016, 12, 19, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(hours=12))) for hour in range(7, 19): when = day + datetime.timedelta(hours=hour) az = solar.get_azimuth_fast(-43, 172, when) az_expected = solar.get_azimuth(-43, 172, when) self.assertAlmostEqual(az, az_expected, delta=1.5)
def calcAZ(): angles = [] print("Started computing azimuth Angles", datetime.datetime.now()) dd = pd.date_range(start="2014-01-01 00:30", end="2014-12-31 23:30", freq='H', tz='Asia/Kolkata') for x in dd: angles.append(get_azimuth_fast(19.11, 72.9052, x.to_pydatetime())) return (angles)
def test_numpy(): """ get_altitude and get_azimuth, with lat, lon and date arrays """ pysolar.use_numpy() lat = np.array([45., 40.]) lon = np.array([3., 4.]) time = np.array(['2018-05-08T12:15:00', '2018-05-08T15:00:00'], dtype='datetime64') print(solar.get_altitude_fast(lat, lon, time)) print(solar.get_azimuth_fast(lat, lon, time))
def test_with_fixed_position(): """ get_altitude and get_azimuth, with scalar position """ pysolar.use_numpy() lat = 50. lon = 3. time = np.array(['2018-05-08T12:15:00', '2018-05-08T15:00:00'], dtype='datetime64') print(solar.get_altitude_fast(lat, lon, time)) print(solar.get_azimuth_fast(lat, lon, time))
def test_numpy(): """ get_altitude and get_azimuth, with lat, lon and date arrays """ pysolar.use_numpy() lat = np.array([45., 40.]) lon = np.array([3., 4.]) time = np.array(['2018-05-08T12:15:00', '2018-05-08T15:00:00'], dtype='datetime64') print(solar.get_altitude_fast(lat, lon, time)) print(solar.get_azimuth_fast(lat, lon, time))
def test_with_fixed_position(): """ get_altitude and get_azimuth, with scalar position """ pysolar.use_numpy() lat = 50. lon = 3. time = np.array(['2018-05-08T12:15:00', '2018-05-08T15:00:00'], dtype='datetime64') print(solar.get_altitude_fast(lat, lon, time)) print(solar.get_azimuth_fast(lat, lon, time))
def test_with_fixed_time(): """ get_altitude and get_azimuth, with scalar date """ pysolar.use_numpy() lat = np.array([45., 40.]) lon = np.array([3., 4.]) time = datetime(2018, 5, 8, 12, 0, 0, tzinfo=pytz.UTC) print(solar.get_altitude(lat, lon, time)) print(solar.get_azimuth(lat, lon, time)) print(solar.get_altitude_fast(lat, lon, time)) print(solar.get_azimuth_fast(lat, lon, time))
def test_with_fixed_time(): """ get_altitude and get_azimuth, with scalar date """ pysolar.use_numpy() lat = np.array([45., 40.]) lon = np.array([3., 4.]) time = datetime(2018, 5, 8, 12, 0, 0, tzinfo=pytz.UTC) print(solar.get_altitude(lat, lon, time)) print(solar.get_azimuth(lat, lon, time)) print(solar.get_altitude_fast(lat, lon, time)) print(solar.get_azimuth_fast(lat, lon, time))
def hour_labels(self): """ summer/winter hour labels """ for month, col in zip([6, 12], ['black', 'black']): hours = pd.date_range(start='{}/21/2019'.format(month), end='{}/22/2019'.format(month), freq='3H', tz=self.time_zone) print(hours) labels = hours.strftime('%-I%p') print(labels) alts = 90 - get_altitude_fast(self.lat, self.lng, hours.values) azs = (get_azimuth_fast(self.lat, self.lng, hours.values) + 90) * np.pi / 180. print(alts, azs * 180 / np.pi) sel = (alts <= 88) xs, ys = self.polar_2_cartesian(alts[sel], azs[sel]) self.ax.scatter(xs * -1, ys, marker='o', color=col, s=10, zorder=5) if month == 6: ys += 8.0 else: ys -= 9.0 for i in range(labels[sel].shape[0]): print(xs[i] * -1, ys[i], labels[sel][i]) self.ax.text(xs[i] * -1, ys[i], labels[sel][i], color=col, ha='center', va='center', fontproperties=self.prop, fontsize=12, zorder=6)
def plot_solstice(self, month, solstice_color): """ azs = azimuths which range from 0 to 90 where zero is the edge of the circle and 90 the center, however this is reversed for the axis hence we restrict the azimuths to < 90 """ times = pd.date_range(start='{}/21/2019'.format(month), end='{}/22/2019'.format(month), freq='1T', tz=self.time_zone)[:-1] alts = 90 - get_altitude_fast(self.lat, self.lng, times.values) azs = (get_azimuth_fast(self.lat, self.lng, times.values) + 90) * np.pi / 180. # converts angle, radius to x and y coords xs, ys = self.polar_2_cartesian(alts, azs) #ax.plot(xs_winter, ys_winter, color='black', lw=1.5, zorder=2) self.ax.plot(xs, ys, color=solstice_color, lw=1.8, zorder=3) return times, alts, azs, xs, ys
def test_solar_get_azimuth_fast_raise_error(self): with self.assertRaises(NoTimeZoneInfoError): solar.get_azimuth_fast(self.lat, self.lon, self.unaware)
def test_solar_get_azimuth_fast_no_error(self): try: solar.get_azimuth_fast(self.lat, self.lon, self.aware) except NoTimeZoneInfoError: self.fail("""'NoTimeZoneInfoError' should not be raised \ as 'datetime' object is tz-aware.""")
def SW_Wm2_topo(self, ni=10): """ Short-wave downwelling radiation corrected using a modified version of TOPOscale. Partitions into direct and diffuse """ # add variable to ncdf file vn_diff = 'SW_topo_diffuse' # variable name var = self.rg.createVariable(vn_diff, 'f4', ('time', 'station')) var.long_name = 'TOPOscale-corrected diffuse solar radiation' var.units = 'W m-2' var.standard_name = 'surface_diffuse_downwelling_shortwave_flux_in_air' vn_dir = 'SW_topo_direct' # variable name var = self.rg.createVariable(vn_dir, 'f4', ('time', 'station')) var.long_name = 'TOPOscale-corrected direct solar radiation' var.units = 'W m-2' var.standard_name = 'surface_direct_downwelling_shortwave_flux_in_air' # interpolate station by station nc_time = self.nc_sf.variables['time'] py_time = nc.num2date(nc_time[:], nc_time.units, nc_time.calendar, only_use_cftime_datetimes=False) py_time = np.array([pytz.utc.localize(t) for t in py_time]) lat = self.getValues(self.nc_pl, 'latitude', ni) lon = self.getValues(self.nc_pl, 'longitude', ni) sw = self.getValues(self.nc_sf, 'ssrd', ni) / self.interval_in # [J m-2] --> [W m-2] grid_elev = self.getValues( self.nc_to, 'z', ni)[0, :] / 9.80665 # z has 2 dimensions from the scaling step station_elev = self.getValues(self.nc_pl, 'height', ni) svf = self.get_sky_view() slope = self.get_slope() aspect = self.get_aspect() interpolation_time = nc_time[:].astype(np.int64) for n, s in enumerate(self.rg.variables['station'][:].tolist()): zenith = solar_zenith(lat=lat[n], lon=lon[n], time=py_time) diffuse, corrected_direct = elevation_corrected_sw( zenith=zenith, grid_sw=sw[:, n], lat=np.ones_like(sw[:, n]) * lat[n], lon=np.ones_like(sw[:, n]) * lon[n], time=py_time, grid_elevation=np.ones_like(sw[:, n]) * grid_elev[n], sub_elevation=np.ones_like(sw[:, n]) * station_elev[n]) diffuse = diffuse * svf[n] # apply sky-view factor if not np.all(slope == 0): azimuth = get_azimuth_fast(lat[n], lon[n], py_time) cos_i_sub = illumination_angle(zenith, azimuth, slope[n], aspect[n]) cos_i_grid = np.cos(np.radians(zenith)) corrected_direct = shading_corrected_sw_direct( corrected_direct, cos_i_sub, cos_i_grid) sensible_values_mask = np.where( cos_i_grid < 0.001, 0, 1) * np.where( corrected_direct > 1366, 0, 1) corrected_direct *= sensible_values_mask f = interp1d(interpolation_time * 3600, corrected_direct, kind='linear') self.rg.variables[vn_dir][:, n] = f(self.times_out_nc) f = interp1d(interpolation_time * 3600, diffuse, kind='linear') self.rg.variables[vn_diff][:, n] = f(self.times_out_nc)
def calc_azimuth_for_datetime(lat, lon): return solar.get_azimuth_fast(lat, lon, raster_datetime)
def calc_azimuth_for_datetime(lat, lon): return solar.get_azimuth_fast(lat, lon, raster_datetime).astype( np.dtype('float32'))