def process_solar_lines(): PATH = "/Users/matt/Downloads/solar-generation-and-demand-italy-20152016/TimeSeries_TotalSolarGen_and_Load_IT_2016.csv" LAT = 42.6711769 LONG = 12.4625580 result = [[]] with open(PATH) as f: first_line = True spot = -1 for line in csv.reader(f): if not first_line: t = datetime.datetime.strptime(line[0], '%Y-%m-%dT%H:%M:%SZ') args = [LAT, LONG, pytz.UTC.localize(t)] alt, az = solar.get_altitude_fast(*args), solar.get_azimuth(*args) if az < spot: result.append([]) result[-1].append({'altitude': alt, 'azimuth': az, 'power': line[2]}) spot = az else: first_line = False json.dump(result, open('solar.json', 'w+'))
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 testGetAltitudeFast(self): # location is in NZ, use relevant timezone 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) al = solar.get_altitude_fast(-43, 172, when) al_expected = solar.get_altitude(-43, 172, when) self.assertAlmostEqual(al, al_expected, delta=1)
def solar_calc(longitude, latitude, date, high_accuracy=False): """ numpy vectorize func """ altitude_deg = None if high_accuracy: altitude_deg = get_altitude(latitude, longitude, date) else: altitude_deg = get_altitude_fast(latitude, longitude, date) return get_radiation_direct(date, altitude_deg)
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_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_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_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 process_messing(): PATH = "/Users/matt/Downloads/solar-generation-and-demand-italy-20152016/TimeSeries_TotalSolarGen_and_Load_IT_2016.csv" LAT = 42.6711769 LONG = 12.4625580 with open(PATH) as f, open('alt_az_pwr.csv','w+') as o: o.write('altitude,azimuth,power\n') first_line = True for line in csv.reader(f): if not first_line: t = datetime.datetime.strptime(line[0], '%Y-%m-%dT%H:%M:%SZ') args = [LAT, LONG, pytz.UTC.localize(t)] o.write('{},{},{}\n'.format(solar.get_altitude_fast(*args), solar.get_azimuth(*args), line[2])) else: first_line = False
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 test_numpy_radiation(): """ get_radiation_direct with lat, lon, and date as arrays """ pysolar.use_numpy() lat = np.array([45., 40., 40.]) lon = np.array([3., 4., 3.]) time = np.array([ '2018-05-08T12:15:00', '2018-05-08T15:00:00', '2018-05-08T03:00:00', ], dtype='datetime64') altitude = solar.get_altitude_fast(lat, lon, time) rad_results = radiation.get_radiation_direct(time, altitude) assert rad_results[2] == 0 print(rad_results)
def sunpos( pandasindex, lat, lon, ): import datetime from pysolar.solar import get_altitude_fast import numpy as np # converts this index to UTC tzinfo = pandasindex.tzinfo if tzinfo is not None: pandasindex = pandasindex.copy().tz_convert(None) # add the local timezone as fixed offset localtz, localutc = datetime.datetime.now(), datetime.datetime.utcnow() dttz = round((localutc - localtz).total_seconds() / 3600) pandasindex = pandasindex.copy() + datetime.timedelta(hours=dttz) alt = get_altitude_fast(lat, lon, pandasindex) alt = np.where(alt >= 0, True, False) return alt
def __init__(self, lat, lng, cloud_data, cmap, prop): """ """ print('Creating Solar Irradiance Plot.') self.cmap = plt.get_cmap(cmap) self.prop = prop tf = timezonefinder.TimezoneFinder() self.time_zone = pytz.timezone(tf.certain_timezone_at(lng=lng, lat=lat)) date_rng = pd.date_range( start='1/1/{}'.format(datetime.datetime.now().year), end='1/1/{}'.format(datetime.datetime.now().year + 1), freq='H', tz=self.time_zone)[:-1] alts = get_altitude_fast(lat, lng, date_rng.values) irradiances = np.array([ get_radiation_direct(date, alt) if alt > 0 else 0 for date, alt in zip(date_rng, alts) ]) irr = pd.DataFrame({ 'Month': date_rng.month, 'Day': date_rng.day, 'irradiance': irradiances }) irr_by_day = irr.groupby(['Month', 'Day']).irradiance.sum() / 1000.0 irr = pd.DataFrame({ 'Mean': irr_by_day.groupby('Month').mean(), 'Std': irr_by_day.groupby('Month').std() }) self.irr = irr self.clouds = cloud_data.clouds
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 calc_altitude_for_datetime(lat, lon): return solar.get_altitude_fast(lat, lon, raster_datetime).astype( np.dtype('float32'))
def compare_time(green, time_measure="year", **kwargs): """ Compare/plot two different green measures with the same segmentation engine/settings. Apply simple linear regression to figure out if there is correlation between the different variables. """ green_kwargs = select_green_model(green) tiler = TileManager(cubic_pictures=True, **green_kwargs, **kwargs) green_res = tiler.green_direct() sorted_res = {} long_res = {} sun = Sun() x_label="?" y_label="greenery" for i in tqdm(range(len(green_res["green"]))): dt_str = green_res["timestamp"][i] green = green_res["green"][i] lat = green_res["lat"][i] long = green_res["long"][i] dt = get_time_from_str(dt_str) dt = dt.replace(tzinfo=datetime.timezone.utc) if time_measure == "year": tm = dt.year elif time_measure == "month": tm = dt.month elif time_measure == "all_month": tm = (dt.year-2016)*12 + dt.month-1 elif time_measure == "hour": tm = sun.timeToDawnDusk(dt, longitude=long, latitude=lat, time_zone='UTC') tm = round(tm*4, 0)/4 elif time_measure == "sun_angle": tm = round(get_altitude_fast(lat, long, dt)/2, 0)*2 x_label="Sun altitude (degrees)" elif time_measure == "minute": tm = dt.minute elif time_measure == "second": tm = dt.second try: sorted_res[tm].append(green) long_res[tm].append(long) except KeyError: sorted_res[tm] = [] sorted_res[tm].append(green) long_res[tm] = [] long_res[tm].append(long) # if tm in sorted_res: # sorted_res[tm][0] += green # sorted_res[tm][1] += 1 # else: # sorted_res[tm] = [green, 1] tm_array = np.zeros(len(sorted_res)) green_avg = np.zeros(len(sorted_res)) green_err = np.zeros(len(sorted_res)) long_avg = np.zeros(len(sorted_res)) long_err = np.zeros(len(sorted_res)) i = 0 for tm in sorted_res: tm_array[i] = tm green_avg[i] = np.array(sorted_res[tm]).mean() green_err[i] = stats.sem(np.array(sorted_res[tm])) long_avg[i] = np.array(long_res[tm]).mean() long_err[i] = stats.sem(np.array(long_res[tm])) i += 1 order = np.argsort(tm_array) # print(tm_array, green_avg, green_err) plt.figure() plt.errorbar(tm_array[order], green_avg[order], green_err[order]) plt.xlabel(x_label) plt.ylabel(y_label) plt.show()
def test_solar_get_altitude_fast_raise_error(self): with self.assertRaises(NoTimeZoneInfoError): solar.get_altitude_fast(self.lat, self.lon, self.unaware)
def test_solar_get_altitude_fast_no_error(self): try: solar.get_altitude_fast(self.lat, self.lon, self.aware) except NoTimeZoneInfoError: self.fail("""'NoTimeZoneInfoError' should not be raised \ as 'datetime' object is tz-aware.""")
def getAltitude(time): return solar.get_altitude_fast(climates[climate]['lat'], climates[climate]['long'], time)
def calc_altitude_for_datetime(lat, lon): return solar.get_altitude_fast(lat, lon, raster_datetime)
def add_solar(netCDFfiles): # add incoming radiation out_files = [] for fn in netCDFfiles: # Change the creation date in the filename to today now = datetime.utcnow() fn_new = fn if os.path.basename(fn).startswith("IMOS_"): fn_new_split = os.path.basename(fn).split('_') fn_new_split[-1] = "C-" + now.strftime("%Y%m%d") + ".nc" fn_new = os.path.join(os.path.dirname(fn), '_'.join(fn_new_split)) # If a new (different) filename has been successfully generated, make # a copy of the old file with the new name if fn_new != fn: print('copying file to ', fn_new) # copy file shutil.copy(fn, fn_new) out_files.append(fn_new) ds = Dataset(fn_new, 'a') lat = ds.variables['LATITUDE'][:] lon = ds.variables['LONGITUDE'][:] ndepth = ds.variables['NOMINAL_DEPTH'][:] print('lat ', lat, ' lon ', lon) time_var = ds.variables['TIME'] print('number of points ', len(time_var)) dt = num2date(time_var[:], units=time_var.units, calendar=time_var.calendar, only_use_cftime_datetimes=False) dt_utc = [d.replace(tzinfo=pytz.UTC) for d in dt] print('time start ', dt_utc[0]) altitude_deg = get_altitude_fast(lat, lon, dt) rad = extraterrestrial_irrad(lat, lon, dt, 1361) if ndepth > 0: #depth_var = ds.variables['PRES'] #depth = depth_var[:] depth = np.ones_like(rad) * ndepth par = rad * np.exp(-0.04 * depth) * 2.114 else: par = rad * 2.114 print("altitude", altitude_deg[0], " rad ", rad[0]) if 'ALT' in ds.variables: ncVarOut = ds.variables["ALT"] else: ncVarOut = ds.createVariable( "ALT", "f4", ("TIME", ), fill_value=np.nan, zlib=True) # fill_value=nan otherwise defaults to max ncVarOut[:] = altitude_deg ncVarOut.units = "degree" ncVarOut.long_name = 'sun_altitude' ncVarOut.coordinates = 'TIME LATITUDE LONGITUDE NOMINAL_DEPTH' ncVarOut.comment = "using http://docs.pysolar.org/en/latest/ v0.8 get_altitude" if 'SOLAR' in ds.variables: ncVarOut = ds.variables["SOLAR"] else: ncVarOut = ds.createVariable( "SOLAR", "f4", ("TIME", ), fill_value=np.nan, zlib=True) # fill_value=nan otherwise defaults to max ncVarOut[:] = rad ncVarOut.units = "W/m2" ncVarOut.long_name = 'incoming_solar_radiation' ncVarOut.coordinates = 'TIME LATITUDE LONGITUDE NOMINAL_DEPTH' ncVarOut.comment = "using http://docs.pysolar.org/en/latest/ v0.8 extraterrestrial_irrad() with incoming = 1361 W/m^2" if 'ePAR' in ds.variables: ncVarOut = ds.variables["ePAR"] else: ncVarOut = ds.createVariable( "ePAR", "f4", ("TIME", ), fill_value=np.nan, zlib=True) # fill_value=nan otherwise defaults to max ncVarOut[:] = par ncVarOut.units = "umol/m^2/s" ncVarOut.long_name = 'incoming_solar_radiation converted to PAR (x2.114) attenuated by depth' ncVarOut.coordinates = 'TIME LATITUDE LONGITUDE NOMINAL_DEPTH' ncVarOut.comment = "using http://docs.pysolar.org/en/latest/ v0.8 extraterrestrial_irrad() with incoming = 1361 W/m^2, x 2.114, kd = 0.04" # update the history attribute try: hist = ds.history + "\n" except AttributeError: hist = "" ds.setncattr( 'history', hist + datetime.utcnow().strftime("%Y-%m-%d") + " : added incoming radiation") ds.close() return out_files
def compare_time(green, time_measure="year", **kwargs): """ Compare/plot two different green measures with the same segmentation engine/settings. Apply simple linear regression to figure out if there is correlation between the different variables. """ green_kwargs = select_green_model(green) tiler = TileManager(cubic_pictures=True, all_years=True, **green_kwargs, **kwargs) green_res = tiler.green_direct() spotted_green = _rearrange_green_res(green_res) # print(spotted_green) sorted_res = {} long_res = {} sun = Sun() x_label = time_measure y_label = "greenery" x_res = {} tm_avail = {} overall_avg = 0 register_matplotlib_converters() for comp_list in tqdm(spotted_green): overall_avg += np.mean(np.array( green_res["green"])[comp_list]) / len(spotted_green) if len(comp_list) < 2: continue tm_val = [] green_val = [] for i in range(len(comp_list)): idx = comp_list[i] dt_str = green_res["timestamp"][idx] green = green_res["green"][idx] lat = green_res["lat"][idx] long = green_res["long"][idx] dt = get_time_from_str(dt_str) dt = dt.replace(tzinfo=datetime.timezone.utc) if time_measure == "year": tm = dt.year elif time_measure == "month": tm = dt.month elif time_measure == "day": tm = dt.day elif time_measure == "all_month": tm = (dt.year - 2016) * 12 + dt.month - 1 elif time_measure == "hour": tm = sun.timeToDawnDusk(dt, longitude=long, latitude=lat, time_zone='UTC') tm = round(tm * 4, 0) / 4 elif time_measure == "sun_angle": tm = round(get_altitude_fast(lat, long, dt) / 2, 0) * 2 x_label = "Sun altitude (degrees)" elif time_measure == "minute": tm = dt.minute elif time_measure == "second": tm = dt.second tm_val.append(tm) green_val.append(green) if tm not in tm_avail: tm_avail[tm] = 0 for i in range(len(comp_list)): for j in range(i + 1, len(comp_list)): green_i = green_val[i] green_j = green_val[j] tm_i = tm_val[i] tm_j = tm_val[j] if tm_i not in x_res: x_res[tm_i] = {} if tm_j not in x_res[tm_i]: x_res[tm_i][tm_j] = np.zeros(2) # if abs(green_i-green_j) > 0.1: # idx_i = comp_list[i] # idx_j = comp_list[j] # lat_i = green_res["lat"][idx_i] # lat_j = green_res["lat"][idx_j] # long_i = green_res["long"][idx_i] # long_j = green_res["long"][idx_j] # dist = fast_coor_to_dist(lat_i, long_i, lat_j, long_j) # print(lat_i, long_i, lat_j, long_j) # print(idx_i, idx_j, dist, comp_list) # print(green_res["pano_id"][idx_i], green_res["pano_id"][idx_j]) # exit() x_res[tm_i][tm_j] += np.array([1, green_i - green_j]) single_res = {} for tm_i in x_res: for tm_j in x_res[tm_i]: if tm_i not in single_res: single_res[tm_i] = 0 if tm_j not in single_res: single_res[tm_j] = 0 new_avg = x_res[tm_i][tm_j][1] / x_res[tm_i][tm_j][0] / ( 2 * (len(tm_avail) - 1)) single_res[tm_i] += new_avg single_res[tm_j] -= new_avg tm_array = np.array(list(single_res.keys())) green_avg = np.array(list(single_res.values())) + overall_avg # print(f"{tm_i} += {new_avg}, {tm_j} -= {new_avg}") # print(x_res) # print(single_res) # exit() # if tm in sorted_res: # sorted_res[tm][0] += green # sorted_res[tm][1] += 1 # else: # sorted_res[tm] = [green, 1] # tm_array = np.zeros(len(sorted_res)) # green_avg = np.zeros(len(sorted_res)) # green_err = np.zeros(len(sorted_res)) # # long_avg = np.zeros(len(sorted_res)) # long_err = np.zeros(len(sorted_res)) # # i = 0 # for tm in sorted_res: # tm_array[i] = tm # green_avg[i] = np.array(sorted_res[tm]).mean() # green_err[i] = stats.sem(np.array(sorted_res[tm])) # long_avg[i] = np.array(long_res[tm]).mean() # long_err[i] = stats.sem(np.array(long_res[tm])) # i += 1 order = np.argsort(tm_array) if time_measure == "all_month": new_array = [] for tm in tm_array: new_array.append(datetime.date(2016 + tm // 12, (tm % 12) + 1, 15)) tm_array = np.array(new_array) # print(tm_array, green_avg) # print(green_res["timestamp"]) plt.figure() plt.scatter(tm_array[order], green_avg[order]) plt.xlabel(x_label) plt.ylabel(y_label) plt.show()