@@ -27,7 +27,7 @@ def test_solar_noon():
2727 index = index , dtype = np .float64 )
2828 expect = expect [SINGLEAXIS_COL_ORDER ]
2929
30- assert_frame_equal (expect , tracker_data )
30+ assert_frame_equal (expect , tracker_data [ SINGLEAXIS_COL_ORDER ] )
3131
3232
3333def test_scalars ():
@@ -86,7 +86,7 @@ def test_nans():
8686 [nan , nan , nan , nan ],
8787 [nan , nan , nan , nan ]]),
8888 columns = ['tracker_theta' , 'aoi' , 'surface_azimuth' , 'surface_tilt' ])
89- assert_frame_equal (tracker_data , expect )
89+ assert_frame_equal (tracker_data [ SINGLEAXIS_COL_ORDER ] , expect )
9090
9191
9292def test_arrays_multi ():
@@ -122,7 +122,7 @@ def test_azimuth_north_south():
122122 index = [0 ], dtype = np .float64 )
123123 expect = expect [SINGLEAXIS_COL_ORDER ]
124124
125- assert_frame_equal (expect , tracker_data )
125+ assert_frame_equal (expect , tracker_data [ SINGLEAXIS_COL_ORDER ] )
126126
127127 tracker_data = tracking .singleaxis (apparent_zenith , apparent_azimuth ,
128128 axis_tilt = 0 , axis_azimuth = 0 ,
@@ -131,7 +131,7 @@ def test_azimuth_north_south():
131131
132132 expect ['tracker_theta' ] *= - 1
133133
134- assert_frame_equal (expect , tracker_data )
134+ assert_frame_equal (expect , tracker_data [ SINGLEAXIS_COL_ORDER ] )
135135
136136
137137def test_max_angle ():
@@ -147,7 +147,7 @@ def test_max_angle():
147147 index = [0 ], dtype = np .float64 )
148148 expect = expect [SINGLEAXIS_COL_ORDER ]
149149
150- assert_frame_equal (expect , tracker_data )
150+ assert_frame_equal (expect , tracker_data [ SINGLEAXIS_COL_ORDER ] )
151151
152152
153153def test_min_angle ():
@@ -163,7 +163,7 @@ def test_min_angle():
163163 index = [0 ], dtype = np .float64 )
164164 expect = expect [SINGLEAXIS_COL_ORDER ]
165165
166- assert_frame_equal (expect , tracker_data )
166+ assert_frame_equal (expect , tracker_data [ SINGLEAXIS_COL_ORDER ] )
167167
168168
169169def test_backtrack ():
@@ -180,7 +180,7 @@ def test_backtrack():
180180 index = [0 ], dtype = np .float64 )
181181 expect = expect [SINGLEAXIS_COL_ORDER ]
182182
183- assert_frame_equal (expect , tracker_data )
183+ assert_frame_equal (expect , tracker_data [ SINGLEAXIS_COL_ORDER ] )
184184
185185 tracker_data = tracking .singleaxis (apparent_zenith , apparent_azimuth ,
186186 axis_tilt = 0 , axis_azimuth = 0 ,
@@ -192,7 +192,7 @@ def test_backtrack():
192192 index = [0 ], dtype = np .float64 )
193193 expect = expect [SINGLEAXIS_COL_ORDER ]
194194
195- assert_frame_equal (expect , tracker_data )
195+ assert_frame_equal (expect , tracker_data [ SINGLEAXIS_COL_ORDER ] )
196196
197197
198198def test_axis_tilt ():
@@ -210,7 +210,7 @@ def test_axis_tilt():
210210 index = [0 ], dtype = np .float64 )
211211 expect = expect [SINGLEAXIS_COL_ORDER ]
212212
213- assert_frame_equal (expect , tracker_data )
213+ assert_frame_equal (expect , tracker_data [ SINGLEAXIS_COL_ORDER ] )
214214
215215 tracker_data = tracking .singleaxis (apparent_zenith , apparent_azimuth ,
216216 axis_tilt = 30 , axis_azimuth = 0 ,
@@ -222,7 +222,7 @@ def test_axis_tilt():
222222 index = [0 ], dtype = np .float64 )
223223 expect = expect [SINGLEAXIS_COL_ORDER ]
224224
225- assert_frame_equal (expect , tracker_data )
225+ assert_frame_equal (expect , tracker_data [ SINGLEAXIS_COL_ORDER ] )
226226
227227
228228def test_axis_azimuth ():
@@ -239,7 +239,7 @@ def test_axis_azimuth():
239239 index = [0 ], dtype = np .float64 )
240240 expect = expect [SINGLEAXIS_COL_ORDER ]
241241
242- assert_frame_equal (expect , tracker_data )
242+ assert_frame_equal (expect , tracker_data [ SINGLEAXIS_COL_ORDER ] )
243243
244244 apparent_zenith = pd .Series ([30 ])
245245 apparent_azimuth = pd .Series ([180 ])
@@ -254,7 +254,7 @@ def test_axis_azimuth():
254254 index = [0 ], dtype = np .float64 )
255255 expect = expect [SINGLEAXIS_COL_ORDER ]
256256
257- assert_frame_equal (expect , tracker_data )
257+ assert_frame_equal (expect , tracker_data [ SINGLEAXIS_COL_ORDER ] )
258258
259259
260260def test_horizon_flat ():
@@ -272,7 +272,7 @@ def test_horizon_flat():
272272 [ 0. , 45. , 270. , 0. ],
273273 [ nan , nan , nan , nan ]]),
274274 columns = ['tracker_theta' , 'aoi' , 'surface_azimuth' , 'surface_tilt' ])
275- assert_frame_equal (out , expected )
275+ assert_frame_equal (out [ SINGLEAXIS_COL_ORDER ] , expected )
276276
277277
278278def test_horizon_tilted ():
@@ -288,7 +288,7 @@ def test_horizon_tilted():
288288 [ 0. , 45. , 180. , 90. ],
289289 [ 179. , 45. , 359. , 90. ]]),
290290 columns = ['tracker_theta' , 'aoi' , 'surface_azimuth' , 'surface_tilt' ])
291- assert_frame_equal (out , expected )
291+ assert_frame_equal (out [ SINGLEAXIS_COL_ORDER ] , expected )
292292
293293
294294def test_low_sun_angles ():
@@ -301,8 +301,8 @@ def test_low_sun_angles():
301301 'aoi' : np .array ([80.420987 ]),
302302 'surface_azimuth' : np .array ([253.897886 ]),
303303 'surface_tilt' : np .array ([64.341094 ])}
304- for k , v in result .items ():
305- assert_allclose (expected [k ], v )
304+ for k , v in expected .items ():
305+ assert_allclose (v , result [k ])
306306
307307
308308def test_calc_axis_tilt ():
@@ -389,6 +389,57 @@ def test_slope_aware_backtracking():
389389 check_less_precise = True )
390390
391391
392+ def test_singleaxis_backtracking_flag ():
393+ """Test that is_backtracking is True when backtracking is active."""
394+ # low sun angle that triggers backtracking
395+ apparent_zenith = pd .Series ([80 ])
396+ apparent_azimuth = pd .Series ([90 ])
397+
398+ # with backtrack=True and a low sun angle, backtracking should be active
399+ tracker_data = tracking .singleaxis (apparent_zenith , apparent_azimuth ,
400+ axis_tilt = 0 , axis_azimuth = 0 ,
401+ max_angle = 90 , backtrack = True ,
402+ gcr = 2.0 / 7.0 )
403+ assert tracker_data ['is_backtracking' ].iloc [0 ] is np .bool_ (True )
404+
405+ # with backtrack=False, is_backtracking should always be False
406+ tracker_data = tracking .singleaxis (apparent_zenith , apparent_azimuth ,
407+ axis_tilt = 0 , axis_azimuth = 0 ,
408+ max_angle = 90 , backtrack = False ,
409+ gcr = 2.0 / 7.0 )
410+ assert tracker_data ['is_backtracking' ].iloc [0 ] is np .bool_ (False )
411+
412+ # at solar noon (small zenith), backtracking should not be active
413+ index = pd .date_range (start = '20180701T1200' , freq = '1s' , periods = 1 )
414+ apparent_zenith_noon = pd .Series ([10 ], index = index )
415+ apparent_azimuth_noon = pd .Series ([180 ], index = index )
416+ tracker_data = tracking .singleaxis (apparent_zenith_noon ,
417+ apparent_azimuth_noon ,
418+ axis_tilt = 0 , axis_azimuth = 0 ,
419+ max_angle = 90 , backtrack = True ,
420+ gcr = 2.0 / 7.0 )
421+ assert tracker_data ['is_backtracking' ].iloc [0 ] is np .bool_ (False )
422+
423+
424+ def test_singleaxis_at_limit_flag ():
425+ """Test that is_at_limit is True when angle is clipped."""
426+ # 60 degree ideal angle clipped to 45 degree max
427+ apparent_zenith = pd .Series ([60 ])
428+ apparent_azimuth = pd .Series ([90 ])
429+ tracker_data = tracking .singleaxis (apparent_zenith , apparent_azimuth ,
430+ axis_tilt = 0 , axis_azimuth = 0 ,
431+ max_angle = 45 , backtrack = True ,
432+ gcr = 2.0 / 7.0 )
433+ assert tracker_data ['is_at_limit' ].iloc [0 ] is np .bool_ (True )
434+
435+ # 60 degree ideal angle within 90 degree max — should not be clipped
436+ tracker_data = tracking .singleaxis (apparent_zenith , apparent_azimuth ,
437+ axis_tilt = 0 , axis_azimuth = 0 ,
438+ max_angle = 90 , backtrack = True ,
439+ gcr = 2.0 / 7.0 )
440+ assert tracker_data ['is_at_limit' ].iloc [0 ] is np .bool_ (False )
441+
442+
392443def test_singleaxis_aoi_gh1221 ():
393444 # vertical tracker
394445 loc = pvlib .location .Location (40.1134 , - 88.3695 )
0 commit comments