<s> from __future__ import division <EOL> import logging <EOL> pvl_logger = logging . getLogger ( '<STR_LIT>' ) <EOL> import numpy as np <EOL> import pandas as pd <EOL> from pvlib . tools import cosd , sind <EOL> from pvlib . pvsystem import PVSystem <EOL> from pvlib . location import Location <EOL> from pvlib import irradiance , atmosphere <EOL> class SingleAxisTracker ( PVSystem ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , axis_tilt = <NUM_LIT:0> , axis_azimuth = <NUM_LIT:0> , <EOL> max_angle = <NUM_LIT> , backtrack = True , gcr = <NUM_LIT> / <NUM_LIT> , ** kwargs ) : <EOL> self . axis_tilt = axis_tilt <EOL> self . axis_azimuth = axis_azimuth <EOL> self . max_angle = max_angle <EOL> self . backtrack = backtrack <EOL> self . gcr = gcr <EOL> super ( SingleAxisTracker , self ) . __init__ ( ** kwargs ) <EOL> def singleaxis ( self , apparent_zenith , apparent_azimuth ) : <EOL> tracking_data = singleaxis ( apparent_zenith , apparent_azimuth , <EOL> self . axis_tilt , self . axis_azimuth , <EOL> self . max_angle , <EOL> self . backtrack , self . gcr ) <EOL> return tracking_data <EOL> def localize ( self , location = None , latitude = None , longitude = None , <EOL> ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> if location is None : <EOL> location = Location ( latitude , longitude , ** kwargs ) <EOL> return LocalizedSingleAxisTracker ( pvsystem = self , location = location ) <EOL> def get_irradiance ( self , dni , ghi , dhi , <EOL> dni_extra = None , airmass = None , model = '<STR_LIT>' , <EOL> ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> surface_tilt = kwargs . pop ( '<STR_LIT>' , self . surface_tilt ) <EOL> surface_azimuth = kwargs . pop ( '<STR_LIT>' , self . surface_azimuth ) <EOL> try : <EOL> solar_zenith = kwargs [ '<STR_LIT>' ] <EOL> except KeyError : <EOL> solar_zenith = self . solar_zenith <EOL> try : <EOL> solar_azimuth = kwargs [ '<STR_LIT>' ] <EOL> except KeyError : <EOL> solar_azimuth = self . solar_azimuth <EOL> if dni_extra is None : <EOL> dni_extra = irradiance . extraradiation ( solar_zenith . index ) <EOL> dni_extra = pd . Series ( dni_extra , index = solar_zenith . index ) <EOL> if airmass is None : <EOL> airmass = atmosphere . relativeairmass ( solar_zenith ) <EOL> return irradiance . total_irrad ( surface_tilt , <EOL> surface_azimuth , <EOL> solar_zenith , <EOL> solar_azimuth , <EOL> dni , ghi , dhi , <EOL> dni_extra = dni_extra , airmass = airmass , <EOL> model = model , <EOL> albedo = self . albedo , <EOL> ** kwargs ) <EOL> class LocalizedSingleAxisTracker ( SingleAxisTracker , Location ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , pvsystem = None , location = None , ** kwargs ) : <EOL> if pvsystem is not None : <EOL> pv_dict = pvsystem . __dict__ <EOL> else : <EOL> pv_dict = { } <EOL> if location is not None : <EOL> loc_dict = location . __dict__ <EOL> else : <EOL> loc_dict = { } <EOL> new_kwargs = dict ( list ( pv_dict . items ( ) ) + <EOL> list ( loc_dict . items ( ) ) + <EOL> list ( kwargs . items ( ) ) ) <EOL> super ( LocalizedSingleAxisTracker , self ) . __init__ ( ** new_kwargs ) <EOL> def singleaxis ( apparent_zenith , apparent_azimuth , <EOL> axis_tilt = <NUM_LIT:0> , axis_azimuth = <NUM_LIT:0> , max_angle = <NUM_LIT> , <EOL> backtrack = True , gcr = <NUM_LIT> / <NUM_LIT> ) : <EOL> """<STR_LIT>""" <EOL> pvl_logger . debug ( '<STR_LIT>' ) <EOL> pvl_logger . debug ( '<STR_LIT>' + <EOL> '<STR_LIT>' , <EOL> axis_tilt , axis_azimuth , max_angle , backtrack , gcr ) <EOL> pvl_logger . debug ( '<STR_LIT>' , <EOL> apparent_zenith . head ( ) , apparent_azimuth . head ( ) ) <EOL> try : <EOL> pd . util . testing . assert_index_equal ( apparent_azimuth . index , <EOL> apparent_zenith . index ) <EOL> except AssertionError : <EOL> raise ValueError ( '<STR_LIT>' + <EOL> '<STR_LIT>' ) <EOL> times = apparent_azimuth . index <EOL> az = apparent_azimuth - <NUM_LIT> <EOL> apparent_elevation = <NUM_LIT> - apparent_zenith <EOL> x = cosd ( apparent_elevation ) * sind ( az ) <EOL> y = cosd ( apparent_elevation ) * cosd ( az ) <EOL> z = sind ( apparent_elevation ) <EOL> axis_azimuth_south = axis_azimuth - <NUM_LIT> <EOL> pvl_logger . debug ( '<STR_LIT>' , axis_azimuth_south ) <EOL> xp = x * cosd ( axis_azimuth_south ) - y * sind ( axis_azimuth_south ) ; <EOL> yp = ( x * cosd ( axis_tilt ) * sind ( axis_azimuth_south ) + <EOL> y * cosd ( axis_tilt ) * cosd ( axis_azimuth_south ) - <EOL> z * sind ( axis_tilt ) ) <EOL> zp = ( x * sind ( axis_tilt ) * sind ( axis_azimuth_south ) + <EOL> y * sind ( axis_tilt ) * cosd ( axis_azimuth_south ) + <EOL> z * cosd ( axis_tilt ) ) <EOL> wid = pd . Series ( <NUM_LIT> - np . degrees ( np . arctan2 ( zp , xp ) ) , index = times ) <EOL> wid [ zp <= <NUM_LIT:0> ] = np . nan <EOL> if backtrack : <EOL> pvl_logger . debug ( '<STR_LIT>' ) <EOL> axes_distance = <NUM_LIT:1> / gcr <EOL> temp = np . minimum ( axes_distance * cosd ( wid ) , <NUM_LIT:1> ) <EOL> wc = np . degrees ( np . arccos ( temp ) ) <EOL> v = wid < <NUM_LIT:0> <EOL> widc = pd . Series ( index = times ) <EOL> widc [ ~ v ] = wid [ ~ v ] - wc [ ~ v ] ; <EOL> widc [ v ] = wid [ v ] + wc [ v ] ; <EOL> else : <EOL> pvl_logger . debug ( '<STR_LIT>' ) <EOL> widc = wid <EOL> tracker_theta = widc . copy ( ) <EOL> tracker_theta [ tracker_theta > max_angle ] = max_angle <EOL> tracker_theta [ tracker_theta < - max_angle ] = - max_angle <EOL> panel_norm = np . array ( [ sind ( tracker_theta ) , <EOL> tracker_theta * <NUM_LIT:0> , <EOL> cosd ( tracker_theta ) ] ) <EOL> sun_vec = np . array ( [ xp , yp , zp ] ) <EOL> aoi = np . degrees ( np . arccos ( np . abs ( np . sum ( sun_vec * panel_norm , axis = <NUM_LIT:0> ) ) ) ) <EOL> aoi = pd . Series ( aoi , index = times ) <EOL> rot_x = np . array ( [ [ <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:0> ] , <EOL> [ <NUM_LIT:0> , cosd ( - axis_tilt ) , - sind ( - axis_tilt ) ] , <EOL> [ <NUM_LIT:0> , sind ( - axis_tilt ) , cosd ( - axis_tilt ) ] ] ) <EOL> pvl_logger . debug ( '<STR_LIT>' , rot_x ) <EOL> panel_norm_earth = np . dot ( rot_x , panel_norm ) . T <EOL> pvl_logger . debug ( '<STR_LIT>' , panel_norm_earth ) <EOL> projected_normal = np . array ( [ panel_norm_earth [ : , <NUM_LIT:0> ] , <EOL> panel_norm_earth [ : , <NUM_LIT:1> ] , <EOL> panel_norm_earth [ : , <NUM_LIT:2> ] * <NUM_LIT:0> ] ) . T <EOL> pvl_logger . debug ( '<STR_LIT>' , projected_normal ) <EOL> panel_norm_earth_mag = np . sqrt ( np . nansum ( panel_norm_earth ** <NUM_LIT:2> , axis = <NUM_LIT:1> ) ) <EOL> projected_normal_mag = np . sqrt ( np . nansum ( projected_normal ** <NUM_LIT:2> , axis = <NUM_LIT:1> ) ) <EOL> pvl_logger . debug ( '<STR_LIT>' , <EOL> panel_norm_earth_mag , projected_normal_mag ) <EOL> non_zeros = projected_normal_mag != <NUM_LIT:0> <EOL> projected_normal [ non_zeros ] = ( projected_normal [ non_zeros ] . T / <EOL> projected_normal_mag [ non_zeros ] ) . T <EOL> pvl_logger . debug ( '<STR_LIT>' , <EOL> projected_normal ) <EOL> surface_azimuth = pd . Series ( <EOL> np . degrees ( np . arctan2 ( projected_normal [ : , <NUM_LIT:1> ] , projected_normal [ : , <NUM_LIT:0> ] ) ) , <EOL> index = times ) <EOL> surface_azimuth = <NUM_LIT> - surface_azimuth + axis_azimuth <EOL> surface_azimuth [ surface_azimuth < <NUM_LIT:0> ] += <NUM_LIT> <EOL> surface_azimuth [ surface_azimuth >= <NUM_LIT> ] -= <NUM_LIT> <EOL> surface_tilt = ( <NUM_LIT> - np . degrees ( np . arccos ( <EOL> pd . DataFrame ( panel_norm_earth * projected_normal , <EOL> index = times ) . sum ( axis = <NUM_LIT:1> ) ) ) ) <EOL> df_out = pd . DataFrame ( { '<STR_LIT>' : tracker_theta , '<STR_LIT>' : aoi , <EOL> '<STR_LIT>' : surface_azimuth , <EOL> '<STR_LIT>' : surface_tilt } , <EOL> index = times ) <EOL> df_out [ apparent_zenith > <NUM_LIT> ] = np . nan <EOL> return df_out </s>
