简体   繁体   中英

PVLIB: Problems to calculate the hour angle using PVLIB

I'm trying to calculate the hour angle for using the PVLIB's function " pvl.solarposition.hour_angle() ".

The code that I'm developing is structured in 02 parts:

  • First I'm transforming GPS time (seconds of week) in UTC Time formated in ' %Y-%m-%d %H:%M:%S' . The result obtained here is in UTC time because the GPS time is refering in UTC.
  • On second part I try to calculate the hour angle using PVLIB and on this part I'm having problems.

When I'll run the hour angle the python is returning the an error message:

"naive_times = times.tz_localize(None) # naive but still localized AttributeError: 'str' object has no attribute 'tz_localize".

I know that this erros is about the class for variable "final_time" on the code implemented. According the PVLIB documentation this variable is need stay on class pandas.DatetimeIndex ( https://pvlib-python.readthedocs.io/en/latest/generated/pvlib.solarposition.hour_angle.html ) and I dont know transform correctly the GPS time to this class and then, use this result on the PVLIB to compute the hour angle.

Bellow follow part of algorithm that I'm using here on the tests:


import datetime
import pvlib as pvl


t_gps = 138088.886582 #seconds of week

lat = -23.048576 # degress
long = -46.305043 # degrees


## Transfomring the GPS time (seconds of week) in Date Time

## The result printed here is in UTC time because the GPS time is refered in UTC Time.

datetimeformat = ('%Y-%m-%d %H:%M:%S')
leapsecond = 37
epoch = datetime.datetime.strptime ( "1980-01-06 00:00:00" , datetimeformat)
decorrido = datetime.timedelta( days = (2024 * 7 ), seconds = t_gps + leapsecond)
final_time = datetime.datetime.strftime(epoch + decorrido, datetimeformat)
print(final_time)
print(type(final_time))

## Calculating the hour angle using PVLIB

solar_declin = pvl.solarposition.declination_spencer71(295)
print(solar_declin)

eq_time = pvl.solarposition.equation_of_time_pvcdrom(295)
print(eq_time)

hour_angle = pvl.solarposition.hour_angle(final_time, long, eq_time)
print(hour_angle)

For this problem my questions are:

  1. How may I transform GPS time (seconds of week) to the format ' %Y-%m-%d %H:%M:%S' and on the class pandas.DatetimeIndex ?

    1. How the result after the GPS time transformation is in UTC time, I need convert to the local time first and transform again for UTC time including the tz_localize?

In my approach i use astropy library for converting gps time into date time format. Next convert this time to Datetimeindex with pandas;

=^..^=

import pandas as pd
import pvlib as pvl
from astropy.time import Time

latitude = -23.048576 # degress
longitude = -46.305043 # degrees

# convert gps seconds to time format
gps_time = 138088.886582
t = Time(gps_time, format='gps')
t = Time(t, format='iso')

# create empty df
df = pd.DataFrame(columns = ['Timestamp'])

# create date time series
time_series = pd.to_datetime(str(t), infer_datetime_format=True)

# append time series to data frame
df = df.append({'Timestamp': pd.to_datetime(time_series)}, ignore_index=True)
df = df.append({'Timestamp': pd.to_datetime(time_series)}, ignore_index=True)

# create time index
time_index = pd.DatetimeIndex(df.Timestamp)

# calculate hour angle
hour_angle = pvl.solarposition.hour_angle(time_index, longitude, latitude*60)

Output:

[-356.58415383 -356.58415383]

Instead of using datetime or strings to fill your DatetimeIndex , create pandas.Timestamp , the pandas version of datetime.datetime .

First build a Posix timestamp, aka seconds from epoch:

week_number = 2024
t_gps = 138088.886582
leapsecond = 37
posix_ts = week_number * 7 * 24 * 60 * 60 + t_gps + leapsecond

Then build a Timestamp :

pandas_ts = Timestamp.utcfromtimestamp(posix_ts)
>>> Timestamp('2008-10-17 14:22:05.886582')

At this point, the Timestamp is "naive": while build as UTC, it does not contain time zone information, so:

pandas_ts = pandas_ts.tz_localize("UTC")
>>> Timestamp('2008-10-17 14:22:05.886582+0000', tz='UTC')

Finally, you can convert to your local time zone:

pandas_ts = pandas_ts.tz_convert("my_time_zone")  # replace by correct tz
>>> Timestamp('2008-10-17 NN:22:05.886582+XXXX', tz='my_time_zone')

and build the required DatetimeIndex :

di = DatetimeIndex([pandas_ts])
print(di)  # shows the time zone in the type (dtype='datetime64[ns, my_time_zone]')

long = -46.305043
eq_time = pvl.solarposition.equation_of_time_pvcdrom(295)
hour_angle = pvl.solarposition.hour_angle(di, long, eq_time)
print(hour_angle)

Don't mix tz_localize and tz_convert and remember to always set the timezone. This way you control the creation of the DatetimeIndex , using string you rely on the automatic parsing by pandas , problematic with time zone.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM