first commit

This commit is contained in:
Senad Uka
2017-11-07 09:23:57 +01:00
commit 0eee92660a
356 changed files with 747259 additions and 0 deletions

0
test/helpers/__init__.py Normal file
View File

View File

@@ -0,0 +1,35 @@
import unittest
from nose.tools import eq_
from numpy import array
from helix.calculators.bom_helper import get_panel_type_counts
from helix.constants.panel_type import PanelType
from helix.models.panel import Panel
class BomHelperTest(unittest.TestCase):
def test_get_panel_type_counts(self):
panels = [Panel(panel_type=PanelType.Corner),
Panel(panel_type=PanelType.NorthSouth),
Panel(panel_type=PanelType.EastWest),
Panel(panel_type=PanelType.Middle),
Panel(panel_type=PanelType.Corner),
Panel(panel_type=PanelType.EastWest),
Panel(panel_type=PanelType.Corner),
Panel(panel_type=PanelType.EastWest),
Panel(panel_type=PanelType.Corner),
Panel(panel_type=PanelType.EastWest),
Panel(panel_type=PanelType.EastWest),
Panel(panel_type=PanelType.EastWest),
Panel(panel_type=PanelType.Corner),
Panel(panel_type=PanelType.NorthSouth),
Panel(panel_type=PanelType.EastWest)]
counts = get_panel_type_counts(panels)
eq_(counts[PanelType.Corner], 5)
eq_(counts[PanelType.NorthSouth], 2)
eq_(counts[PanelType.EastWest], 7)
eq_(counts[PanelType.Middle], 1)

View File

@@ -0,0 +1,67 @@
import unittest
from helix.csv_builder import CsvBuilder
from nose.tools import eq_
from numpy import array
from helix.constants.panel_type import PanelType
from helix.models.coordinate import Coordinate
from helix.models.panel import Panel
class CsvBuilderTest(unittest.TestCase):
def setUp(self):
self.subject = CsvBuilder()
def test_build_cad_output_correct_csv(self):
panels = [
Panel(handle='FOO', blockname='BAR', wind_zone=0, panel_type=PanelType.Corner, subarray=1, pressure=1.026,
ballast=10, presented_link_tray=1, cross_tray=0, wind_anchors=0, id=10, original_coordinate=Coordinate(2, 3.0, rotation=4.00), seismic_anchors=0),
Panel(handle='BAZ', blockname='QUX', wind_zone=2, panel_type=PanelType.Middle, subarray=1, pressure=3.033,
ballast=3, presented_link_tray=0, cross_tray=1, wind_anchors=1, id=11, original_coordinate=Coordinate(1, 0.5, rotation=.25), seismic_anchors=1),
Panel(handle='EGGS', blockname='SPAM', wind_zone=0, panel_type=PanelType.Corner, subarray=1, pressure=1.026,
ballast=10, presented_link_tray=1, cross_tray=0, wind_anchors=0, id=12, original_coordinate=Coordinate(2, 3.0, rotation=4.00), seismic_anchors=2)
]
expected_csv = "HANDLE\tBLOCKNAME\tWIND\tPOS\tSUBARRAY\tPSF\tBAL\tLTRAY\tXTRAY\tANC\tID\tXCOORD\tYCOORD\tANGLE\r\n" \
"FOO\tBAR\tA\t1\t1\t1.03\t10\t1\t-\t-\t10\t2\t3.0\t4.0\r\n" \
"BAZ\tQUX\tC\t4\t1\t3.03\t3\t-\t1\t1S\t11\t1\t0.5\t0.25\r\n" \
"EGGS\tSPAM\tA\t1\t1\t1.03\t10\t1\t-\tSS\t12\t2\t3.0\t4.0\r\n"
eq_(self.subject.build_cad_output(panels), expected_csv)
def test_build_cad_output_correct_csv_with_fuzzy_wind_zone_if_exists(self):
panels = [
Panel(handle='FOO', blockname='BAR', wind_zone=0, panel_type=PanelType.Corner, subarray=1, pressure=1.026,
ballast=10, presented_link_tray=1, cross_tray=0, wind_anchors=0, id=10, original_coordinate=Coordinate(2, 3.0, rotation=4.00), seismic_anchors=0),
Panel(handle='BAZ', blockname='QUX', wind_zone=2, panel_type=PanelType.Middle, subarray=1, pressure=3.033,
ballast=3, presented_link_tray=0, cross_tray=1, wind_anchors=1, id=11, original_coordinate=Coordinate(1, 0.5, rotation=.25), seismic_anchors=1,
fuzzy_wind_zone=True),
Panel(handle='EGGS', blockname='SPAM', wind_zone=0, panel_type=PanelType.Corner, subarray=1, pressure=1.026,
ballast=10, presented_link_tray=1, cross_tray=0, wind_anchors=0, id=12, original_coordinate=Coordinate(2, 3.0, rotation=4.00), seismic_anchors=2,
fuzzy_wind_zone=True)
]
expected_csv = "HANDLE\tBLOCKNAME\tWIND\tPOS\tSUBARRAY\tPSF\tBAL\tLTRAY\tXTRAY\tANC\tID\tXCOORD\tYCOORD\tANGLE\tFUZZYWINDZONE\r\n" \
"FOO\tBAR\tA\t1\t1\t1.03\t10\t1\t-\t-\t10\t2\t3.0\t4.0\t0\r\n" \
"BAZ\tQUX\tC\t4\t1\t3.03\t3\t-\t1\t1S\t11\t1\t0.5\t0.25\t1\r\n" \
"EGGS\tSPAM\tA\t1\t1\t1.03\t10\t1\t-\tSS\t12\t2\t3.0\t4.0\t1\r\n"
eq_(self.subject.build_cad_output(panels), expected_csv)
def test_build_bom_output_outputs_bom(self):
expected_csv = "Part #\tDescription\tTotal\r\n6\tFoo\t404\r\n5\tBar\"\t503\r\n7\tBaz\t1337\r\n"
calculated_columns = array([[6, 'Foo', 404],
[5, 'Bar"', 503],
[7, 'Baz', 1337]])
eq_(self.subject.build_bom_output(calculated_columns), expected_csv)
def test_build_cad_output_with_incomplete_input(self):
panels = [
Panel(subarray=1, id=1, original_coordinate=Coordinate(2, 3.0, rotation=4.00))
]
expected_csv = "HANDLE\tBLOCKNAME\tWIND\tPOS\tSUBARRAY\tPSF\tBAL\tLTRAY\tXTRAY\tANC\tID\tXCOORD\tYCOORD\tANGLE\r\n" \
"\t\t\t\t1\t\t\t-\t-\t-\t1\t2\t3.0\t4.0\r\n"
eq_(self.subject.build_cad_output(panels), expected_csv)

View File

@@ -0,0 +1,558 @@
from collections import OrderedDict
import os
import unittest
from unittest.mock import MagicMock
from nose.tools import eq_
from helix.constants.anchor_type import AnchorType
from helix.constants.module_type import ModuleType
from helix.constants.panel_type import PanelType
from helix.constants.version import version
from helix.doc_gen_params_builder import DocGenParamsBuilder
from helix.models.coordinate import Coordinate
from helix.models.panel import Panel
from helix.models.sql.inverters import Inverter
from helix.models.sql.power_stations import PowerStation
from helix.models.sql.sites import Site
from helix.models.sql.standalone_inverters import StandaloneInverter
from helix.models.subarray import Subarray
from helix.user_values import UserValues
class DocGenParamsBuilderTest(unittest.TestCase):
def setUp(self):
self.site = Site(system_type='1')
self.site.project_name = ''
self.site.building_height = 0
self.site.building_width = 0
self.site.building_length = 0
self.site.parapet_height = 0
self.site.ballast_block_weight = 0
self.site.max_psf = 0
self.site.anchor_type = AnchorType.OMG_PowerGrip_Plus.value
self.site.exposure_category = 'C'
self.site.wind_speed = 0
self.site.spectral_response = 1
self.site.importance_factor = 1
self.site.module_type = ModuleType.Cell96.value
self.user_values = UserValues(None, self.site)
self.calculator = MagicMock()
self.image_presenter = MagicMock()
os.environ['SP_DOCGEN_API_KEY'] = 'TestDocGenApiKey'
def tearDown(self):
os.environ['SP_DOCGEN_API_KEY'] = ''
def test_build_single_tilt(self):
self.site.system_type = '0'
subject = DocGenParamsBuilder(self.user_values, self.user_values.system_type(), self.calculator, self.image_presenter)
self.calculator.L_B.return_value = 0.001
self.calculator.k_z.return_value = 0.949932
self.calculator.q_z.return_value = 0.12453
self.calculator.get_computed_csv_columns.return_value = []
self.calculator.documentation_summary_values.return_value = {'summary': 'foo'}
self.calculator.summary_table.return_value = OrderedDict({PanelType.Corner:
{'anchors': [1],
'ballast blocks': [6],
'pressure': ['4.46']}})
self.calculator.minimum_array_sizes.return_value = [123]
self.calculator.documentation_bom.return_value = []
self.calculator.documentation_bom.return_value = [
('88764', 9),
('modules', 0)
]
self.image_presenter.generate_image.return_value = "".encode("utf-8")
params = subject.build()
expected = {
'apiKey': 'TestDocGenApiKey',
'templateName': 'Helix_Single_Tilt_Template',
'nameValuePairs': [
{'name': '1_a_anc', 'value': 1},
{'name': '1_a_bb', 'value': 6},
{'name': '1_a_psf', 'value': '4.46'},
{'name': 'anchor_type', 'value': 'OMG PowerGrip Plus'},
{'name': 'ballast_block_weight', 'value': 0.0},
{'name': 'building_height', 'value': 0.0},
{'name': 'building_length', 'value': 0.0},
{'name': 'building_width', 'value': 0.0},
{'name': 'exposure_category', 'value': 'C'},
{'name': 'exposure_category_transition_distance', 'value': 0},
{'name': 'kz', 'value': 0.95},
{'name': 'lb', 'value': 0.0},
{'name': 'max_allowable_system_pressure', 'value': 0.0},
{'name': 'min_a', 'value': 123},
{'name': 'module_type', 'value': '96 Cell'},
{'name': 'parapet_height', 'value': 0.0},
{'name': 'power_station_string', 'value': ''},
{'name': 'project_name', 'value': ''},
{'name': 'qz', 'value': 0.12},
{'name': 'seismic_importance_factor', 'value': 1.0},
{'name': 'spectral_response', 'value': 1.0},
{'name': 'standalone_inverter_string', 'value': ''},
{'name': 'subarrays_string', 'value': ''},
{'name': 'summary', 'value': 'foo'},
{'name': 'system_type', 'value': 'Single-Tilt'},
{'name': 'total_88764', 'value': 9},
{'name': 'total_modules', 'value': 0},
{'name': 'version', 'value': version()},
{'name': 'wind_speed', 'value': 0.0},
],
'dynamicImages': [
{'imageKey': 'array_image', 'base64encodedImage': ''}
]
}
eq_(params, expected)
def test_build_dual_tilt(self):
self.site.system_type = '1'
subject = DocGenParamsBuilder(self.user_values, self.user_values.system_type(), self.calculator, self.image_presenter)
self.calculator.L_B.return_value = 0
self.calculator.k_z.return_value = 0
self.calculator.q_z.return_value = 0
self.calculator.get_computed_csv_columns.return_value = []
self.calculator.documentation_summary_values.return_value = {'summary': 'foo'}
self.image_presenter.generate_image.return_value = "".encode("utf-8")
params = subject.build()
eq_(sorted(params.keys()), ['apiKey', 'dynamicImages', 'nameValuePairs', 'templateName'])
eq_(params['apiKey'], 'TestDocGenApiKey')
eq_(params['templateName'], 'Helix_Dual_Tilt_Template')
def test_site_characterization(self):
self.site.system_type = '0'
self.site.project_name = 'Test Project Name'
self.site.building_height = 100
self.site.building_width = 1000
self.site.building_length = 1500
self.site.parapet_height = 0
self.site.ballast_block_weight = 20
self.site.max_psf = 17
self.site.anchor_type = AnchorType.EcoFasten.value
self.site.exposure_category = 'D'
self.site.wind_speed = 110
self.site.spectral_response = 1
self.site.importance_factor = 1
self.site.module_type = ModuleType.Cell96.value
self.calculator.L_B.return_value = 23
self.calculator.k_z.return_value = 34
self.calculator.q_z.return_value = 45
self.calculator.get_computed_csv_columns.return_value = [
Panel(),
Panel()
]
subject = DocGenParamsBuilder(self.user_values, self.user_values.system_type(), self.calculator, self.image_presenter)
expected_site_characterization = {
'project_name': 'Test Project Name',
'building_height': 100.0,
'building_width': 1000.0,
'building_length': 1500.0,
'parapet_height': 0.0,
'ballast_block_weight': 20.0,
'max_allowable_system_pressure': 17,
'anchor_type': 'EcoFasten Eco 65',
'exposure_category': 'D',
'exposure_category_transition_distance': 0,
'wind_speed': 110,
'spectral_response': 1,
'seismic_importance_factor': 1,
'module_type': '96 Cell',
'system_type': 'Single-Tilt',
'total_modules': 2,
'version': version(),
'lb': 23,
'kz': 34,
'qz': 45
}
eq_(subject.site_characterization(), expected_site_characterization)
def test_build_panel_attributes_dual_tilt(self):
self.site.system_type = '1'
self.calculator.summary_table.return_value = OrderedDict({
PanelType.Corner:
{'anchors': [1, 1, 0, 0, 0],
'ballast blocks': [6, 0, 13, 5, 0],
'pressure': ['4.46', '2.40', '6.86', '4.08', '2.40']},
PanelType.NorthSouth:
{'anchors': [1, 0, 0, 0, 0],
'ballast blocks': [0, 19, 9, 3, 0],
'pressure': ['2.40', '8.94', '5.47', '3.41', '2.40']},
PanelType.EastWest:
{'anchors': [1, 0, 0, 0, 0],
'ballast blocks': [0, 19, 9, 3, 0],
'pressure': ['2.26', '8.77', '5.35', '3.27', '2.26']},
PanelType.Middle:
{'anchors': [0, 0, 0, 0, 0],
'ballast blocks': [16, 8, 3, 0, 0],
'pressure': ['7.76', '5.01', '3.27', '2.26', '2.26']}
})
self.calculator.minimum_array_sizes.return_value = [22, 19, 23, 19, 6]
subject = DocGenParamsBuilder(self.user_values, self.user_values.system_type(), self.calculator, self.image_presenter)
expected = {
'1_a_bb': 6,
'1_b_bb': 0,
'1_c_bb': 13,
'1_d_bb': 5,
'1_e_bb': 0,
'1_a_anc': 1,
'1_b_anc': 1,
'1_c_anc': 0,
'1_d_anc': 0,
'1_e_anc': 0,
'1_a_psf': '4.46',
'1_b_psf': '2.40',
'1_c_psf': '6.86',
'1_d_psf': '4.08',
'1_e_psf': '2.40',
'2_a_bb': 0,
'2_b_bb': 19,
'2_c_bb': 9,
'2_d_bb': 3,
'2_e_bb': 0,
'2_a_anc': 1,
'2_b_anc': 0,
'2_c_anc': 0,
'2_d_anc': 0,
'2_e_anc': 0,
'2_a_psf': '2.40',
'2_b_psf': '8.94',
'2_c_psf': '5.47',
'2_d_psf': '3.41',
'2_e_psf': '2.40',
'3_a_bb': 0,
'3_b_bb': 19,
'3_c_bb': 9,
'3_d_bb': 3,
'3_e_bb': 0,
'3_a_anc': 1,
'3_b_anc': 0,
'3_c_anc': 0,
'3_d_anc': 0,
'3_e_anc': 0,
'3_a_psf': '2.26',
'3_b_psf': '8.77',
'3_c_psf': '5.35',
'3_d_psf': '3.27',
'3_e_psf': '2.26',
'4_a_bb': 16,
'4_b_bb': 8,
'4_c_bb': 3,
'4_d_bb': 0,
'4_e_bb': 0,
'4_a_anc': 0,
'4_b_anc': 0,
'4_c_anc': 0,
'4_d_anc': 0,
'4_e_anc': 0,
'4_a_psf': '7.76',
'4_b_psf': '5.01',
'4_c_psf': '3.27',
'4_d_psf': '2.26',
'4_e_psf': '2.26',
'min_a': 22,
'min_b': 19,
'min_c': 23,
'min_d': 19,
'min_e': 6
}
eq_(subject.panel_attributes(), expected)
def test_build_bom(self):
self.calculator.documentation_bom.return_value = [
('512200', 480),
('513832', 0),
('513833', 790),
('513836', 0),
('513841', 196),
('anchors', 262),
('ballast', 6786),
('modules', 1726)
]
subject = DocGenParamsBuilder(self.user_values, self.user_values.system_type(), self.calculator, self.image_presenter)
expected = {
'total_512200': 480,
'total_513832': 0,
'total_513833': 790,
'total_513836': 0,
'total_513841': 196,
'total_anchors': 262,
'total_ballast': 6786,
'total_modules': 1726
}
eq_(subject.bom(), expected)
def test_build_power_station(self):
power_station_1 = PowerStation(
description='1',
quantity=1,
ac_run_length=55,
inverters=[
Inverter(
model='4',
strings_per_inverter=2,
sunshade=True,
dc_switch=False
),
Inverter(
model='5',
strings_per_inverter=5,
sunshade=False,
dc_switch=False
)
]
)
power_station_2 = PowerStation(
description='2',
quantity=3,
ac_run_length=89,
inverters=[
Inverter(
model='6',
strings_per_inverter=6,
sunshade=False,
dc_switch=True
),
Inverter(
model='8',
strings_per_inverter=8,
sunshade=False,
dc_switch=False
)
]
)
self.site.power_stations = [power_station_1, power_station_2]
expected = {
'power_station_string': """
Description: 1
\tQuantity: 1
\tAC Run Length: 55
\tInverters:
\t\tModel: 12kW SMA Tripower - 514686
\t\tStrings per inverter: 2
\t\tSunShade: Yes
\t\tModel: 15kW SMA Tripower - 514687
\t\tStrings per inverter: 5
Description: 2
\tQuantity: 3
\tAC Run Length: 89
\tInverters:
\t\tModel: 20kW SMA Tripower - 512676
\t\tStrings per inverter: 6
\t\tDC Switch: Yes
\t\tModel: 24kW SMA Tripower - 514685
\t\tStrings per inverter: 8
"""
}
subject = DocGenParamsBuilder(self.user_values, self.user_values.system_type(), self.calculator, self.image_presenter)
eq_(subject.power_stations(), expected)
def test_standalone_inverters(self):
power_station = PowerStation(
description='My Power Station',
quantity=1,
ac_run_length=45,
inverters=[
Inverter(
model='8',
strings_per_inverter=7,
sunshade=True,
dc_switch=True
),
Inverter(
model='4',
strings_per_inverter=2,
sunshade=False,
dc_switch=False
)
]
)
standalone_inverter_1 = StandaloneInverter(
inverter=[Inverter(model='6', strings_per_inverter='5', sunshade=True, dc_switch=False)],
ac_run_length=45,
attachment_point=power_station,
)
standalone_inverter_2 = StandaloneInverter(
inverter=[Inverter(model='4', strings_per_inverter='3', sunshade=False, dc_switch=True)],
ac_run_length=45,
attachment_point=None,
)
self.site.power_stations = [power_station]
self.site.standalone_inverters = [standalone_inverter_1, standalone_inverter_2]
subject = DocGenParamsBuilder(self.user_values, self.user_values.system_type(), self.calculator, self.image_presenter)
"""
AC Run Length: 3
Attachment Point: Switch Gear
Model: 20kW SMA Tripower - 512676
Strings per inverter: 6
Sunshade: Yes
DC Switch: Yes
"""
expected = {
'standalone_inverter_string': """
\tAC Run Length: 45
\tAttachment Point: My Power Station
\tModel: 20kW SMA Tripower - 512676
\tStrings per inverter: 5
\tSunShade: Yes
\tAC Run Length: 45
\tAttachment Point: Switch Gear
\tModel: 12kW SMA Tripower - 514686
\tStrings per inverter: 3
\tDC Switch: Yes
"""
}
eq_(subject.standalone_inverters(), expected)
def test_subarray_summary(self):
self.calculator.subarray_summary.return_value = [
Subarray(subarray_number=1, origin=Coordinate(0, 0), required_seismic_anchors=11, weight=23782.67, start_row=0,
size=192),
Subarray(subarray_number=2, origin=Coordinate(0, 0), required_seismic_anchors=0, weight=13113.05,
start_row=192, size=96)
]
subject = DocGenParamsBuilder(self.user_values, self.user_values.system_type(), self.calculator, self.image_presenter)
expected = {
'subarrays_string': """
\tSubarray: 1
\tSeismic Anchors: 11
\tWeight: 23,783 lbs
\tSubarray: 2
\tSeismic Anchors: 0
\tWeight: 13,113 lbs
"""
}
eq_(subject.subarray_summary(), expected)
def test_array_image(self):
panels = [
Panel(id=1)
]
subarrays = [
Subarray(subarray_number=1)
]
self.calculator.get_computed_csv_columns.return_value = panels
self.calculator.subarrays = subarrays
self.image_presenter.generate_image.return_value = "hello world".encode("utf-8")
subject = DocGenParamsBuilder(self.user_values, self.user_values.system_type(), self.calculator, self.image_presenter)
expected = {'array_image': 'aGVsbG8gd29ybGQ='}
eq_(subject.array_image(), expected)
self.image_presenter.generate_image.assert_called_once_with(panels, subarrays)
def test_convert_list_params_to_dict(self):
list_params = [
{
'name': 'foo',
'value': 'bar'
},
{
'name': 'cat',
'value': 'dog'
}
]
expected = {
'foo': 'bar',
'cat': 'dog'
}
eq_(DocGenParamsBuilder.convert_list_params_to_dict(list_params), expected)
def test_convert_dict_params_to_list(self):
dict_params = {
'foo': 'bar',
'cat': 'dog',
'fast': 'slow',
}
expected = sorted([
{
'name': 'foo',
'value': 'bar'
},
{
'name': 'cat',
'value': 'dog'
},
{
'name': 'fast',
'value': 'slow'
}
], key=lambda k: k['name'])
eq_(DocGenParamsBuilder.convert_dict_params_to_list(dict_params), expected)
def test_convert_dict_parms_to_list_other_names(self):
dict_params = {
'foo': 'bar',
'cat': 'dog',
'fast': 'slow',
}
expected = sorted([
{
'baz': 'foo',
'qux': 'bar'
},
{
'baz': 'cat',
'qux': 'dog'
},
{
'baz': 'fast',
'qux': 'slow'
}
], key=lambda k: k['baz'])
eq_(DocGenParamsBuilder.convert_dict_params_to_list(dict_params, key_name='baz', value_name='qux'), expected)

View File

@@ -0,0 +1,946 @@
from math import pi, cos, sin
import unittest
from unittest.mock import MagicMock
from nose.tools import eq_
from helix.Services.dxf_helper import DXFHelper
from helix.constants.module_type_constants.dual_tilt_96_cell_constants import DualTilt96CellConstants
from helix.constants.panel_type import PanelType
from helix.constants.system_type import SystemType
from helix.models.coordinate import Coordinate
from helix.models.dxf.dxf_error import DXFError
from helix.models.dxf.graph_direction import GraphDirection
from helix.models.dxf.graph_node import GraphNode
from helix.models.dxf.polygon import Polygon
from helix.models.panel import Panel
from helix.models.subarray import Subarray
class DXFHelperTest(unittest.TestCase):
def setUp(self):
self.subject = DXFHelper()
def test_generate_panels(self):
modules = [
Polygon(points=[(-2319.403, 687.080), (-2367.852, 648.146), (-2397.356, 684.863), (-2348.907, 723.792)]),
Polygon(points=[(-2270.9747, 726.000), (-2319.419, 687.063), (-2348.923, 723.780), (-2300.478, 762.709)])
]
translated_modules = [
Polygon(points=[(77.953, 38.933), (29.504, 0.0), (0.0, 36.717), (48.449, 75.646)]),
Polygon(points=[(126.382, 77.850), (77.937, 38.917), (48.433, 75.634), (96.878, 114.563)])
]
panels = self.subject.generate_panels(modules, translated_modules)
expected = [
Panel(id=1, coordinate=Coordinate(38.977, 37.824, 38.78204144530477), original_coordinate=Coordinate(-2358.3795, 685.970, 38.78204144530477)),
Panel(id=2, coordinate=Coordinate(87.407, 76.741, 38.78435126730565), original_coordinate=Coordinate(-2309.949, 724.888, 38.78435126730565))
]
eq_(panels, expected)
def test_should_consolidate_modules_returns_false_for_single_tilt(self):
eq_(self.subject.should_consolidate_modules(None, SystemType.singleTilt, None), False)
def test_should_consolidate_modules_returns_true_for_dual_tilt_that_are_not_consolidated(self):
modules = [
Polygon(points=[(-5.17655, -38.8958), (-7.73719, -34.4719), (-4.81221, -32.7789), (-2.25157, -37.2028)]),
Polygon(points=[(-2.25157, -37.2028), (-5.17655, -38.8958), (1.04417, -35.2963), (-1.88081, -36.9894)]),
]
eq_(self.subject.should_consolidate_modules(modules, SystemType.dualTilt, DualTilt96CellConstants()), True)
def test_should_consolidate_modules_returns_false_for_dual_tilt_that_are_consolidated(self):
modules = [
Polygon(points=[(0.0, 68.795), (48.453, 107.732), (103.732, 38.937), (55.28, 0.0)]),
]
eq_(self.subject.should_consolidate_modules(modules, SystemType.dualTilt, DualTilt96CellConstants()), False)
def test_consolidate_dual_tilt_modules(self):
modules = [
Polygon(points=[(0.0, 68.795), (48.453, 107.732), (76.091, 73.338), (27.634, 34.401)]),
Polygon(points=[(103.732, 38.937), (55.28, 0.0), (27.642, 34.393), (76.098, 73.331)]),
]
expected_modules = [
Polygon(points=[(0.0, 68.795), (48.453, 107.732), (103.732, 38.937), (55.28, 0.0)]),
]
module_format = None
panels = self.subject.consolidate_dual_tilt_modules(modules,
SystemType.dualTilt,
module_format)
eq_(panels, expected_modules)
def test_consolidate_dual_tilt_modules_does_nothing_if_given_single_tilt_modules(self):
modules = [
Polygon(points=[(0.0, 68.795), (48.453, 107.732), (76.091, 73.338), (27.634, 34.401)]),
Polygon(points=[(103.732, 38.937), (55.28, 0.0), (27.642, 34.393), (76.098, 73.331)]),
]
expected_modules = [
Polygon(points=[(0.0, 68.795), (48.453, 107.732), (76.091, 73.338), (27.634, 34.401)]),
Polygon(points=[(103.732, 38.937), (55.28, 0.0), (27.642, 34.393), (76.098, 73.331)]),
]
module_format = None
panels = self.subject.consolidate_dual_tilt_modules(modules,
SystemType.singleTilt,
module_format)
eq_(panels, expected_modules)
def test_consolidates_dual_tilt_modules_throws_if_given_dual_tilt_but_unpairable_modules(self):
modules = [
Polygon(points=[(0.0, 68.795), (48.453, 107.732), (76.091, 73.338), (27.634, 34.401)]),
Polygon(points=[(1103.732, 38.937), (155.28, 0.0), (127.642, 34.393), (176.098, 73.331)]),
]
try:
module_format = None
self.subject.consolidate_dual_tilt_modules(modules,
SystemType.dualTilt,
module_format)
assert False
except DXFError as error:
eq_(error.message, "Error - not a dual tilt file, or invalid dual tilt design.")
def test_generate_polygons(self):
lines = [
MagicMock(start=(-589.128, 174.518), end=(-601.434, 164.629)),
MagicMock(start=(-601.434, 164.629), end=(-608.928, 173.955)),
MagicMock(start=(-608.928, 173.955), end=(-596.622, 183.843)),
MagicMock(start=(-596.622, 183.843), end=(-589.128, 174.518))
]
polygons = self.subject.generate_polygons(lines)
expected = [Polygon(points=[(-589.128, 174.518), (-601.434, 164.629), (-608.928, 173.955), (-596.622, 183.843)])]
eq_(polygons, expected)
def test_generate_polygons_seperate_point(self):
lines = [
MagicMock(start=(-589.128, 174.518), end=(-601.434, 164.629)),
MagicMock(start=(-601.434, 164.629), end=(-608.928, 173.955)),
MagicMock(start=(1, 2), end=(3, 4)),
MagicMock(start=(-608.928, 173.955), end=(-596.622, 183.843)),
MagicMock(start=(-596.622, 183.843), end=(-589.128, 174.518))
]
polygons = self.subject.generate_polygons(lines)
expected = [
Polygon(points=[(-589.128, 174.518), (-601.434, 164.629), (-608.928, 173.955)]),
Polygon(points=[(1, 2), (3, 4)]),
Polygon(points=[(-608.928, 173.955), (-596.622, 183.843), (-589.128, 174.518)])
]
eq_(polygons, expected)
def test_build_polygons(self):
entities = [
MagicMock(layer='Modules', start=(-589.128, 174.518), end=(-601.434, 164.629)),
MagicMock(layer='Modules', start=(-601.434, 164.629), end=(-608.928, 173.955)),
MagicMock(layer='Modules', start=(-608.928, 173.955), end=(-596.622, 183.843)),
MagicMock(layer='Modules', start=(-596.622, 183.843), end=(-589.128, 174.518)),
MagicMock(layer='Buildings', start=(-576.827, 184.403), end=(-589.132, 174.514)),
MagicMock(layer='Buildings', start=(-589.132, 174.514), end=(-596.626, 183.84)),
MagicMock(layer='Buildings', start=(-596.626, 183.84), end=(-584.321, 193.728)),
MagicMock(layer='Buildings', start=(-584.321, 193.728), end=(-576.827, 184.403)),
]
polygons = self.subject.build_polygons(entities)
inches_per_feet = 12
buildings = [Polygon(points=[(inches_per_feet * -576.827, inches_per_feet * 184.403), (inches_per_feet * -589.132, inches_per_feet * 174.514), (inches_per_feet * -596.626, inches_per_feet * 183.84), (inches_per_feet * -584.321, inches_per_feet * 193.728)])]
modules = [Polygon(points=[(inches_per_feet * -589.128, inches_per_feet * 174.518), (inches_per_feet * -601.434, inches_per_feet * 164.629), (inches_per_feet * -608.928, inches_per_feet * 173.955), (inches_per_feet * -596.622, inches_per_feet * 183.843)])]
expected = (buildings, modules)
eq_(polygons, expected)
def test_translate_towards_origin(self):
buildings = [Polygon(points=[(-576.827, 184.403), (-589.132, 174.514), (-596.626, 183.84), (-584.321, 193.728)])]
modules = [Polygon(points=[(-589.128, 174.518), (-601.434, 164.629), (-608.928, 173.955), (-596.622, 183.843)])]
expected_buildings = [Polygon(points=[(32.101, 19.774), (19.796, 9.885), (12.302, 19.211), (24.607, 29.099)])]
expected_modules = [Polygon(points=[(19.8, 9.889), (7.494, 0), (0, 9.326), (12.306, 19.214)])]
eq_(self.subject.translate_towards_origin(buildings, modules), (expected_buildings, expected_modules))
def test_get_polygons_counterclockwise(self):
polygons = [Polygon(points=[(0, 0), (0, 1), (1, 1), (1, 0)]),
Polygon(points=[(0, 0), (0, 2), (2, 2), (2, 0)]),
Polygon(points=[(0, 0), (2, 0), (2, 2), (0, 2)])]
expected_polygons = [Polygon(points=[(1, 0), (1, 1), (0, 1), (0, 0)]),
Polygon(points=[(2, 0), (2, 2), (0, 2), (0, 0)]),
Polygon(points=[(0, 0), (2, 0), (2, 2), (0, 2)])]
eq_(self.subject.get_polygons_counterclockwise(polygons), expected_polygons)
def test_build_node_graph(self):
panels = [
Panel(coordinate=Coordinate(10, 0, rotation=0)),
Panel(coordinate=Coordinate(20, 0, rotation=0)),
Panel(coordinate=Coordinate(10, 20, rotation=0)),
Panel(coordinate=Coordinate(20, 20, rotation=0))
]
node_graph = self.subject.build_node_graph(panels, (10, 10))
node_a = GraphNode(Panel(coordinate=Coordinate(10, 0, rotation=0)), 10, 10)
node_b = GraphNode(Panel(coordinate=Coordinate(20, 0, rotation=0)), 10, 10)
node_c = GraphNode(Panel(coordinate=Coordinate(10, 20, rotation=0)), 10, 10)
node_d = GraphNode(Panel(coordinate=Coordinate(20, 20, rotation=0)), 10, 10)
node_a.add_neighbor(node_b, GraphDirection.East)
node_c.add_neighbor(node_d, GraphDirection.East)
expected = [node_a, node_b, node_c, node_d]
eq_(node_graph, expected)
def test_build_node_graph_weird_case(self):
panels = [
Panel(coordinate=Coordinate(38.04431188249998, 857.508730771, -51.21962134154259)),
Panel(coordinate=Coordinate(86.50299946749976, 896.449696681, -51.21563589970276))
]
node_graph = self.subject.build_node_graph(panels, (88.24, 62.16))
node_a = GraphNode(Panel(coordinate=Coordinate(38.04431188249998, 857.508730771, -51.21962134154259)), 88.24, 62.16)
node_b = GraphNode(Panel(coordinate=Coordinate(86.50299946749976, 896.449696681, -51.21563589970276)), 88.24, 62.16)
node_a.add_neighbor(node_b, GraphDirection.North)
eq_(node_graph, [node_a, node_b])
def test_build_node_graph_throws_dxf_validation_error_if_there_are_panels_with_no_neighbors(self):
panels = [
Panel(coordinate=Coordinate(10, 0, rotation=0)),
Panel(coordinate=Coordinate(20, 0, rotation=0)),
Panel(coordinate=Coordinate(100, 200, rotation=0))
]
try:
self.subject.build_node_graph(panels, (10, 10))
assert False
except DXFError as error:
eq_(error.message, "Error - invalid module spacing. Please check to make sure the correct system type and panel spacing are present")
def test_detect_subarrays(self):
node_a = GraphNode(Panel(coordinate=Coordinate(1, 0, rotation=0)), 1, 1)
node_b = GraphNode(Panel(coordinate=Coordinate(2, 0, rotation=0)), 1, 1)
node_c = GraphNode(Panel(coordinate=Coordinate(1, 2, rotation=0)), 1, 1)
node_a.add_neighbor(node_b, GraphDirection.East)
nodes = [node_a, node_b, node_c]
panels = [node.panel for node in nodes]
subarrays = self.subject.detect_subarrays(nodes, panels)
expected = [
Subarray(subarray_number=1, start_row=0, size=2),
Subarray(subarray_number=2, start_row=2, size=1)
]
eq_(subarrays, expected)
def test_throws_dxf_validation_error_if_blows_stack_during_subarray_detection(self):
nodes = []
for i in range(3000):
nodes.append(GraphNode(Panel(coordinate=Coordinate(i, 0)), i, 0))
for i in range(1, 3000):
node_a = nodes[i - 1]
node = nodes[i]
node.add_neighbor(node_a, GraphDirection.East)
panels = [node.panel for node in nodes]
try:
subarrays = self.subject.detect_subarrays(nodes, panels)
eq_(len(subarrays), 0)
except DXFError as error:
eq_(error.message, "Array size is too big. Max is 150' by 150'.")
def test_detect_panel_types(self):
node_0_0 = GraphNode(Panel(coordinate=Coordinate(0, 0, rotation=0)), 1, 1)
node_1_0 = GraphNode(Panel(coordinate=Coordinate(1, 0, rotation=0)), 1, 1)
node_2_0 = GraphNode(Panel(coordinate=Coordinate(2, 0, rotation=0)), 1, 1)
node_3_0 = GraphNode(Panel(coordinate=Coordinate(3, 0, rotation=0)), 1, 1)
node_0_1 = GraphNode(Panel(coordinate=Coordinate(0, 1, rotation=0)), 1, 1)
node_1_1 = GraphNode(Panel(coordinate=Coordinate(1, 1, rotation=0)), 1, 1)
node_2_1 = GraphNode(Panel(coordinate=Coordinate(2, 1, rotation=0)), 1, 1)
node_3_1 = GraphNode(Panel(coordinate=Coordinate(3, 1, rotation=0)), 1, 1)
node_0_2 = GraphNode(Panel(coordinate=Coordinate(0, 2, rotation=0)), 1, 1)
node_1_2 = GraphNode(Panel(coordinate=Coordinate(1, 2, rotation=0)), 1, 1)
node_2_2 = GraphNode(Panel(coordinate=Coordinate(2, 2, rotation=0)), 1, 1)
node_0_0.add_neighbor(node_0_1, GraphDirection.North)
node_0_0.add_neighbor(node_1_1, GraphDirection.NorthEast)
node_0_0.add_neighbor(node_1_0, GraphDirection.East)
node_2_0.add_neighbor(node_1_0, GraphDirection.West)
node_2_0.add_neighbor(node_1_1, GraphDirection.NorthWest)
node_2_0.add_neighbor(node_2_1, GraphDirection.North)
node_2_0.add_neighbor(node_3_1, GraphDirection.NorthEast)
node_2_0.add_neighbor(node_3_0, GraphDirection.East)
node_1_1.add_neighbor(node_0_1, GraphDirection.West)
node_1_1.add_neighbor(node_1_0, GraphDirection.South)
node_1_1.add_neighbor(node_1_2, GraphDirection.North)
node_1_1.add_neighbor(node_2_1, GraphDirection.East)
node_3_1.add_neighbor(node_2_1, GraphDirection.West)
node_0_2.add_neighbor(node_0_1, GraphDirection.South)
node_0_2.add_neighbor(node_1_1, GraphDirection.SouthEast)
node_0_2.add_neighbor(node_1_2, GraphDirection.East)
node_2_2.add_neighbor(node_1_2, GraphDirection.West)
node_2_2.add_neighbor(node_1_1, GraphDirection.SouthWest)
node_2_2.add_neighbor(node_2_1, GraphDirection.South)
node_2_2.add_neighbor(node_3_1, GraphDirection.SouthEast)
nodes = [
node_0_0,
node_1_0,
node_2_0,
node_3_0,
node_0_1,
node_1_1,
node_2_1,
node_3_1,
node_0_2,
node_1_2,
node_2_2
]
self.subject.detect_panel_types(nodes)
def assert_has_type(node, panel_type):
eq_(node.panel.panel_type, panel_type)
assert_has_type(node_0_0, PanelType.Corner)
assert_has_type(node_1_0, PanelType.NorthSouth)
assert_has_type(node_2_0, PanelType.NorthSouth)
assert_has_type(node_3_0, PanelType.Corner)
assert_has_type(node_0_1, PanelType.EastWest)
assert_has_type(node_1_1, PanelType.Middle)
assert_has_type(node_2_1, PanelType.Middle)
assert_has_type(node_3_1, PanelType.Corner)
assert_has_type(node_0_2, PanelType.Corner)
assert_has_type(node_1_2, PanelType.NorthSouth)
assert_has_type(node_2_2, PanelType.Corner)
def test_detect_dual_tilt_wind_zones_simple_rectangle_mid_lb(self):
system_type = SystemType.dualTilt
panel_0_0 = Panel(coordinate=Coordinate(0, 0, rotation=0), id='0_0')
panel_1_0 = Panel(coordinate=Coordinate(1, 0, rotation=0), id='1_0')
panel_2_0 = Panel(coordinate=Coordinate(2, 0, rotation=0), id='2_0')
panel_3_0 = Panel(coordinate=Coordinate(3, 0, rotation=0), id='3_0')
panel_0_1 = Panel(coordinate=Coordinate(0, 1, rotation=0), id='0_1')
panel_1_1 = Panel(coordinate=Coordinate(1, 1, rotation=0), id='1_1')
panel_2_1 = Panel(coordinate=Coordinate(2, 1, rotation=0), id='2_1')
panel_3_1 = Panel(coordinate=Coordinate(3, 1, rotation=0), id='3_1')
panel_0_2 = Panel(coordinate=Coordinate(0, 2, rotation=0), id='0_2')
panel_1_2 = Panel(coordinate=Coordinate(1, 2, rotation=0), id='1_2')
panel_2_2 = Panel(coordinate=Coordinate(2, 2, rotation=0), id='2_2')
panels = [
panel_0_2, panel_1_2, panel_2_2,
panel_0_1, panel_1_1, panel_2_1, panel_3_1,
panel_0_0, panel_1_0, panel_2_0, panel_3_0,
]
sorted_panels = sorted(panels, key=lambda x: x.id)
modules = [Polygon(points=[(p.coordinate.x, p.coordinate.y)]) for p in sorted_panels]
buildings = [
Polygon(points=[
(-0.5, -0.5),
(3.5, -0.5),
(3.5, 2.5),
(-0.5, 2.5)
])
]
l_b = 0.55
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
def assert_has_wind_zone(panel, wind_zone):
eq_(panel.wind_zone, wind_zone)
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E
assert_has_wind_zone(panel_0_0, 0)
assert_has_wind_zone(panel_1_0, 1)
assert_has_wind_zone(panel_2_0, 1)
assert_has_wind_zone(panel_3_0, 0)
assert_has_wind_zone(panel_0_1, 1)
assert_has_wind_zone(panel_1_1, 2)
assert_has_wind_zone(panel_2_1, 2)
assert_has_wind_zone(panel_3_1, 1)
assert_has_wind_zone(panel_0_2, 0)
assert_has_wind_zone(panel_1_2, 1)
assert_has_wind_zone(panel_2_2, 1)
def test_detect_dual_tilt_wind_zones_simple_rectangle_high_lb(self):
system_type = SystemType.dualTilt
panel_0_0 = Panel(coordinate=Coordinate(0, 0, rotation=0), id='0_0')
panel_1_0 = Panel(coordinate=Coordinate(1, 0, rotation=0), id='1_0')
panel_2_0 = Panel(coordinate=Coordinate(2, 0, rotation=0), id='2_0')
panel_3_0 = Panel(coordinate=Coordinate(3, 0, rotation=0), id='3_0')
panel_0_1 = Panel(coordinate=Coordinate(0, 1, rotation=0), id='0_1')
panel_1_1 = Panel(coordinate=Coordinate(1, 1, rotation=0), id='1_1')
panel_2_1 = Panel(coordinate=Coordinate(2, 1, rotation=0), id='2_1')
panel_3_1 = Panel(coordinate=Coordinate(3, 1, rotation=0), id='3_1')
panel_0_2 = Panel(coordinate=Coordinate(0, 2, rotation=0), id='0_2')
panel_1_2 = Panel(coordinate=Coordinate(1, 2, rotation=0), id='1_2')
panel_2_2 = Panel(coordinate=Coordinate(2, 2, rotation=0), id='2_2')
panels = [
panel_0_2, panel_1_2, panel_2_2,
panel_0_1, panel_1_1, panel_2_1, panel_3_1,
panel_0_0, panel_1_0, panel_2_0, panel_3_0,
]
sorted_panels = sorted(panels, key=lambda x: x.id)
modules = [Polygon(points=[(p.coordinate.x, p.coordinate.y)]) for p in sorted_panels]
buildings = [
Polygon(points=[
(-0.5, -0.5),
(3.5, -0.5),
(3.5, 2.5),
(-0.5, 2.5)
])
]
def assert_has_wind_zone(panel, wind_zone):
eq_(panel.wind_zone, wind_zone)
l_b = 1
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
assert_has_wind_zone(panel_0_0, 0)
assert_has_wind_zone(panel_1_0, 0)
assert_has_wind_zone(panel_2_0, 0)
assert_has_wind_zone(panel_3_0, 0)
assert_has_wind_zone(panel_0_1, 0)
assert_has_wind_zone(panel_1_1, 1)
assert_has_wind_zone(panel_2_1, 1)
assert_has_wind_zone(panel_3_1, 0)
assert_has_wind_zone(panel_0_2, 0)
assert_has_wind_zone(panel_1_2, 0)
assert_has_wind_zone(panel_2_2, 0)
def test_detect_dual_tilt_wind_zones_simple_rectangle_low_lb(self):
system_type = SystemType.dualTilt
panel_0_0 = Panel(coordinate=Coordinate(0, 0, rotation=0), id='0_0')
panel_1_0 = Panel(coordinate=Coordinate(1, 0, rotation=0), id='1_0')
panel_2_0 = Panel(coordinate=Coordinate(2, 0, rotation=0), id='2_0')
panel_3_0 = Panel(coordinate=Coordinate(3, 0, rotation=0), id='3_0')
panel_0_1 = Panel(coordinate=Coordinate(0, 1, rotation=0), id='0_1')
panel_1_1 = Panel(coordinate=Coordinate(1, 1, rotation=0), id='1_1')
panel_2_1 = Panel(coordinate=Coordinate(2, 1, rotation=0), id='2_1')
panel_3_1 = Panel(coordinate=Coordinate(3, 1, rotation=0), id='3_1')
panel_0_2 = Panel(coordinate=Coordinate(0, 2, rotation=0), id='0_2')
panel_1_2 = Panel(coordinate=Coordinate(1, 2, rotation=0), id='1_2')
panel_2_2 = Panel(coordinate=Coordinate(2, 2, rotation=0), id='2_2')
panels = [
panel_0_2, panel_1_2, panel_2_2,
panel_0_1, panel_1_1, panel_2_1, panel_3_1,
panel_0_0, panel_1_0, panel_2_0, panel_3_0,
]
sorted_panels = sorted(panels, key=lambda x: x.id)
modules = [Polygon(points=[(p.coordinate.x, p.coordinate.y)]) for p in sorted_panels]
buildings = [
Polygon(points=[
(-0.5, -0.5),
(3.5, -0.5),
(3.5, 2.5),
(-0.5, 2.5)
])
]
def assert_has_wind_zone(panel, wind_zone):
eq_(panel.wind_zone, wind_zone)
l_b = 0.3
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E
assert_has_wind_zone(panel_0_0, 1)
assert_has_wind_zone(panel_1_0, 2)
assert_has_wind_zone(panel_2_0, 2)
assert_has_wind_zone(panel_3_0, 1)
assert_has_wind_zone(panel_0_1, 2)
assert_has_wind_zone(panel_1_1, 3)
assert_has_wind_zone(panel_2_1, 3)
assert_has_wind_zone(panel_3_1, 2)
assert_has_wind_zone(panel_0_2, 1)
assert_has_wind_zone(panel_1_2, 2)
assert_has_wind_zone(panel_2_2, 2)
# try again with a lower l_B
l_b = 0.3
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
def assert_has_wind_zone(panel, wind_zone):
eq_(panel.wind_zone, wind_zone)
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E
assert_has_wind_zone(panel_0_0, 1)
assert_has_wind_zone(panel_1_0, 2)
assert_has_wind_zone(panel_2_0, 2)
assert_has_wind_zone(panel_3_0, 1)
assert_has_wind_zone(panel_0_1, 2)
assert_has_wind_zone(panel_1_1, 3)
assert_has_wind_zone(panel_2_1, 3)
assert_has_wind_zone(panel_3_1, 2)
assert_has_wind_zone(panel_0_2, 1)
assert_has_wind_zone(panel_1_2, 2)
assert_has_wind_zone(panel_2_2, 2)
def test_detect_dual_tilt_wind_zones_simple_rectangle_very_low_lb(self):
system_type = SystemType.dualTilt
panel_0_0 = Panel(coordinate=Coordinate(0, 0, rotation=0), id='0_0')
panel_1_0 = Panel(coordinate=Coordinate(1, 0, rotation=0), id='1_0')
panel_2_0 = Panel(coordinate=Coordinate(2, 0, rotation=0), id='2_0')
panel_3_0 = Panel(coordinate=Coordinate(3, 0, rotation=0), id='3_0')
panel_0_1 = Panel(coordinate=Coordinate(0, 1, rotation=0), id='0_1')
panel_1_1 = Panel(coordinate=Coordinate(1, 1, rotation=0), id='1_1')
panel_2_1 = Panel(coordinate=Coordinate(2, 1, rotation=0), id='2_1')
panel_3_1 = Panel(coordinate=Coordinate(3, 1, rotation=0), id='3_1')
panel_0_2 = Panel(coordinate=Coordinate(0, 2, rotation=0), id='0_2')
panel_1_2 = Panel(coordinate=Coordinate(1, 2, rotation=0), id='1_2')
panel_2_2 = Panel(coordinate=Coordinate(2, 2, rotation=0), id='2_2')
panels = [
panel_0_2, panel_1_2, panel_2_2,
panel_0_1, panel_1_1, panel_2_1, panel_3_1,
panel_0_0, panel_1_0, panel_2_0, panel_3_0,
]
sorted_panels = sorted(panels, key=lambda x: x.id)
modules = [Polygon(points=[(p.coordinate.x, p.coordinate.y)]) for p in sorted_panels]
buildings = [
Polygon(points=[
(-0.5, -0.5),
(3.5, -0.5),
(3.5, 2.5),
(-0.5, 2.5)
])
]
def assert_has_wind_zone(panel, wind_zone):
eq_(panel.wind_zone, wind_zone)
l_b = 0.2
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E
assert_has_wind_zone(panel_0_0, 2)
assert_has_wind_zone(panel_1_0, 3)
assert_has_wind_zone(panel_2_0, 3)
assert_has_wind_zone(panel_3_0, 2)
assert_has_wind_zone(panel_0_1, 3)
assert_has_wind_zone(panel_1_1, 4)
assert_has_wind_zone(panel_2_1, 4)
assert_has_wind_zone(panel_3_1, 3)
assert_has_wind_zone(panel_0_2, 2)
assert_has_wind_zone(panel_1_2, 3)
assert_has_wind_zone(panel_2_2, 3)
# try again with a lower l_B
l_b = 0.3
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
def assert_has_wind_zone(panel, wind_zone):
eq_(panel.wind_zone, wind_zone)
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E
assert_has_wind_zone(panel_0_0, 1)
assert_has_wind_zone(panel_1_0, 2)
assert_has_wind_zone(panel_2_0, 2)
assert_has_wind_zone(panel_3_0, 1)
assert_has_wind_zone(panel_0_1, 2)
assert_has_wind_zone(panel_1_1, 3)
assert_has_wind_zone(panel_2_1, 3)
assert_has_wind_zone(panel_3_1, 2)
assert_has_wind_zone(panel_0_2, 1)
assert_has_wind_zone(panel_1_2, 2)
assert_has_wind_zone(panel_2_2, 2)
def test_detect_single_tilt_wind_zones_simple_rectangle_mid_lb(self):
system_type = SystemType.singleTilt
panel_0_0 = Panel(coordinate=Coordinate(0, 0, rotation=0), id='0_0')
panel_1_0 = Panel(coordinate=Coordinate(1, 0, rotation=0), id='1_0')
panel_2_0 = Panel(coordinate=Coordinate(2, 0, rotation=0), id='2_0')
panel_3_0 = Panel(coordinate=Coordinate(3, 0, rotation=0), id='3_0')
panel_0_1 = Panel(coordinate=Coordinate(0, 1, rotation=0), id='0_1')
panel_1_1 = Panel(coordinate=Coordinate(1, 1, rotation=0), id='1_1')
panel_2_1 = Panel(coordinate=Coordinate(2, 1, rotation=0), id='2_1')
panel_3_1 = Panel(coordinate=Coordinate(3, 1, rotation=0), id='3_1')
panel_0_2 = Panel(coordinate=Coordinate(0, 2, rotation=0), id='0_2')
panel_1_2 = Panel(coordinate=Coordinate(1, 2, rotation=0), id='1_2')
panel_2_2 = Panel(coordinate=Coordinate(2, 2, rotation=0), id='2_2')
panel_3_2 = Panel(coordinate=Coordinate(3, 2, rotation=0), id='3_2')
panels = [
panel_0_2, panel_1_2, panel_2_2, panel_3_2,
panel_0_1, panel_1_1, panel_2_1, panel_3_1,
panel_0_0, panel_1_0, panel_2_0, panel_3_0,
]
sorted_panels = sorted(panels, key=lambda x: x.id)
modules = [Polygon(points=[(p.coordinate.x, p.coordinate.y)]) for p in sorted_panels]
buildings = [
Polygon(points=[
(-0.5, -0.5),
(3.5, -0.5),
(3.5, 2.5),
(-0.5, 2.5)
])
]
l_b = 0.55
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
def assert_has_wind_zone(panel, wind_zone):
assert wind_zone == panel.wind_zone, "Expected panel to be in wind_zone %d, got %d" % (wind_zone, panel.wind_zone)
eq_(panel.wind_zone, wind_zone)
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E
assert_has_wind_zone(panel_0_0, 8)
assert_has_wind_zone(panel_1_0, 7)
assert_has_wind_zone(panel_2_0, 7)
assert_has_wind_zone(panel_3_0, 8)
assert_has_wind_zone(panel_0_1, 9)
assert_has_wind_zone(panel_1_1, 2)
assert_has_wind_zone(panel_2_1, 2)
assert_has_wind_zone(panel_3_1, 9)
assert_has_wind_zone(panel_0_2, 0)
assert_has_wind_zone(panel_1_2, 2)
assert_has_wind_zone(panel_2_2, 2)
assert_has_wind_zone(panel_3_2, 0)
def test_detect_single_tilt_wind_zones_simple_rectangle_low_lb(self):
system_type = SystemType.singleTilt
panel_0_0 = Panel(coordinate=Coordinate(0, 0, rotation=0), id='0_0')
panel_1_0 = Panel(coordinate=Coordinate(1, 0, rotation=0), id='1_0')
panel_2_0 = Panel(coordinate=Coordinate(2, 0, rotation=0), id='2_0')
panel_3_0 = Panel(coordinate=Coordinate(3, 0, rotation=0), id='3_0')
panel_0_1 = Panel(coordinate=Coordinate(0, 1, rotation=0), id='0_1')
panel_1_1 = Panel(coordinate=Coordinate(1, 1, rotation=0), id='1_1')
panel_2_1 = Panel(coordinate=Coordinate(2, 1, rotation=0), id='2_1')
panel_3_1 = Panel(coordinate=Coordinate(3, 1, rotation=0), id='3_1')
panel_0_2 = Panel(coordinate=Coordinate(0, 2, rotation=0), id='0_2')
panel_1_2 = Panel(coordinate=Coordinate(1, 2, rotation=0), id='1_2')
panel_2_2 = Panel(coordinate=Coordinate(2, 2, rotation=0), id='2_2')
panel_3_2 = Panel(coordinate=Coordinate(3, 2, rotation=0), id='3_2')
panels = [
panel_0_2, panel_1_2, panel_2_2, panel_3_2,
panel_0_1, panel_1_1, panel_2_1, panel_3_1,
panel_0_0, panel_1_0, panel_2_0, panel_3_0,
]
sorted_panels = sorted(panels, key=lambda x: x.id)
modules = [Polygon(points=[(p.coordinate.x, p.coordinate.y)]) for p in sorted_panels]
buildings = [
Polygon(points=[
(-0.5, -0.5),
(3.5, -0.5),
(3.5, 2.5),
(-0.5, 2.5)
])
]
l_b = 0.35
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
def assert_has_wind_zone(panel, wind_zone):
assert wind_zone == panel.wind_zone, "Expected panel to be in wind_zone %d, got %d" % (wind_zone, panel.wind_zone)
eq_(panel.wind_zone, wind_zone)
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E, 5 is F, 6 is G, 7 is H, 8 is I, 9 is J, 10 is K
# A, I, H, B, J, C, E, F, G, D, K (order of most uplift force
assert_has_wind_zone(panel_0_0, 9)
assert_has_wind_zone(panel_1_0, 4)
assert_has_wind_zone(panel_2_0, 4)
assert_has_wind_zone(panel_3_0, 9)
assert_has_wind_zone(panel_0_1, 2)
assert_has_wind_zone(panel_1_1, 5)
assert_has_wind_zone(panel_2_1, 5)
assert_has_wind_zone(panel_3_1, 2)
assert_has_wind_zone(panel_0_2, 0)
assert_has_wind_zone(panel_1_2, 3)
assert_has_wind_zone(panel_2_2, 3)
assert_has_wind_zone(panel_3_2, 0)
def test_detect_dual_tilt_wind_zones_10_gon_building(self):
system_type = SystemType.dualTilt
panel_0_0 = Panel(coordinate=Coordinate(0, 0, rotation=0), id='0_0')
panel_1_0 = Panel(coordinate=Coordinate(1, 0, rotation=0), id='1_0')
panel_2_0 = Panel(coordinate=Coordinate(2, 0, rotation=0), id='2_0')
panel_3_0 = Panel(coordinate=Coordinate(3, 0, rotation=0), id='3_0')
panel_0_1 = Panel(coordinate=Coordinate(0, 1, rotation=0), id='0_1')
panel_1_1 = Panel(coordinate=Coordinate(1, 1, rotation=0), id='1_1')
panel_2_1 = Panel(coordinate=Coordinate(2, 1, rotation=0), id='2_1')
panel_3_1 = Panel(coordinate=Coordinate(3, 1, rotation=0), id='3_1')
panel_0_2 = Panel(coordinate=Coordinate(0, 2, rotation=0), id='0_2')
panel_1_2 = Panel(coordinate=Coordinate(1, 2, rotation=0), id='1_2')
panel_2_2 = Panel(coordinate=Coordinate(2, 2, rotation=0), id='2_2')
panels = [
panel_0_2, panel_1_2, panel_2_2,
panel_0_1, panel_1_1, panel_2_1, panel_3_1,
panel_0_0, panel_1_0, panel_2_0, panel_3_0,
]
sorted_panels = sorted(panels, key=lambda x: x.id)
modules = [Polygon(points=[(p.coordinate.x, p.coordinate.y)]) for p in sorted_panels]
points = []
radius = 3
building_vertices = 10
for step in range(building_vertices, 0, -1): # create a 10-gon
angle = (2 * pi / building_vertices) * step
x = radius * sin(angle)
y = radius * cos(angle)
points.append((x, y))
buildings = [Polygon(points=points)]
l_b = 2
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
def assert_has_wind_zone(panel, wind_zone):
eq_(panel.wind_zone, wind_zone)
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E
assert_has_wind_zone(panel_0_0, 4)
assert_has_wind_zone(panel_1_0, 4)
assert_has_wind_zone(panel_2_0, 4)
assert_has_wind_zone(panel_3_0, 4)
assert_has_wind_zone(panel_0_1, 4)
assert_has_wind_zone(panel_1_1, 4)
assert_has_wind_zone(panel_2_1, 4)
assert_has_wind_zone(panel_3_1, 4)
assert_has_wind_zone(panel_0_2, 4)
assert_has_wind_zone(panel_1_2, 4)
assert_has_wind_zone(panel_2_2, 4)
def test_detect_dual_tilt_wind_zones_hexagon_building(self):
system_type = SystemType.dualTilt
panel_0_0 = Panel(coordinate=Coordinate(0, 0, rotation=0), id='0_0')
panel_1_0 = Panel(coordinate=Coordinate(1, 0, rotation=0), id='1_0')
panel_2_0 = Panel(coordinate=Coordinate(2, 0, rotation=0), id='2_0')
panel_3_0 = Panel(coordinate=Coordinate(3, 0, rotation=0), id='3_0')
panel_0_1 = Panel(coordinate=Coordinate(0, 1, rotation=0), id='0_1')
panel_1_1 = Panel(coordinate=Coordinate(1, 1, rotation=0), id='1_1')
panel_2_1 = Panel(coordinate=Coordinate(2, 1, rotation=0), id='2_1')
panel_3_1 = Panel(coordinate=Coordinate(3, 1, rotation=0), id='3_1')
panel_0_2 = Panel(coordinate=Coordinate(0, 2, rotation=0), id='0_2')
panel_1_2 = Panel(coordinate=Coordinate(1, 2, rotation=0), id='1_2')
panel_2_2 = Panel(coordinate=Coordinate(2, 2, rotation=0), id='2_2')
panels = [
panel_0_2, panel_1_2, panel_2_2,
panel_0_1, panel_1_1, panel_2_1, panel_3_1,
panel_0_0, panel_1_0, panel_2_0, panel_3_0,
]
sorted_panels = sorted(panels, key=lambda x: x.id)
modules = [Polygon(points=[(p.coordinate.x, p.coordinate.y)]) for p in sorted_panels]
points = []
radius = 4
building_vertices = 6
for step in range(building_vertices, 0, -1): # create a 10-gon
angle = (2 * pi / building_vertices) * step
x = radius * sin(angle)
y = radius * cos(angle)
points.append((x + 1, y + 1))
buildings = [Polygon(points=points)]
l_b = 1
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
def assert_has_wind_zone(panel, wind_zone):
assert panel.wind_zone == wind_zone, "expected panel to be in wind zone %d, got %d" % (wind_zone, panel.wind_zone)
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E
assert_has_wind_zone(panel_0_0, 1)
assert_has_wind_zone(panel_1_0, 2)
assert_has_wind_zone(panel_2_0, 1)
assert_has_wind_zone(panel_3_0, 1)
assert_has_wind_zone(panel_0_1, 2)
assert_has_wind_zone(panel_1_1, 2)
assert_has_wind_zone(panel_2_1, 2)
assert_has_wind_zone(panel_3_1, 1)
assert_has_wind_zone(panel_0_2, 1)
assert_has_wind_zone(panel_1_2, 2)
assert_has_wind_zone(panel_2_2, 1)
def test_detect_dual_tilt_wind_zones_triangle_building(self):
system_type = SystemType.dualTilt
panel_0_0 = Panel(coordinate=Coordinate(0, 0, rotation=0), id='0_0')
panel_1_0 = Panel(coordinate=Coordinate(1, 0, rotation=0), id='1_0')
panel_2_0 = Panel(coordinate=Coordinate(2, 0, rotation=0), id='2_0')
panel_3_0 = Panel(coordinate=Coordinate(3, 0, rotation=0), id='3_0')
panel_0_1 = Panel(coordinate=Coordinate(0, 1, rotation=0), id='0_1')
panel_1_1 = Panel(coordinate=Coordinate(1, 1, rotation=0), id='1_1')
panel_2_1 = Panel(coordinate=Coordinate(2, 1, rotation=0), id='2_1')
panel_3_1 = Panel(coordinate=Coordinate(3, 1, rotation=0), id='3_1')
panel_0_2 = Panel(coordinate=Coordinate(0, 2, rotation=0), id='0_2')
panel_1_2 = Panel(coordinate=Coordinate(1, 2, rotation=0), id='1_2')
panel_2_2 = Panel(coordinate=Coordinate(2, 2, rotation=0), id='2_2')
panels = [
panel_0_2, panel_1_2, panel_2_2,
panel_0_1, panel_1_1, panel_2_1, panel_3_1,
panel_0_0, panel_1_0, panel_2_0, panel_3_0,
]
sorted_panels = sorted(panels, key=lambda x: x.id)
modules = [Polygon(points=[(p.coordinate.x, p.coordinate.y)]) for p in sorted_panels]
points = []
radius = 4
building_vertices = 3
for step in range(building_vertices, 0, -1): # create a 10-gon
angle = (2 * pi / building_vertices) * step
x = radius * sin(angle)
y = radius * cos(angle)
points.append((x + 1, y + 1))
buildings = [Polygon(points=points)]
l_b = 1
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
def assert_has_wind_zone(panel, wind_zone):
assert panel.wind_zone == wind_zone, "expected panel to be in wind zone %d, got %d" % (wind_zone, panel.wind_zone)
assert panel.fuzzy_wind_zone, "expected panel to be in a fuzzy wind zone"
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E
assert_has_wind_zone(panel_0_0, 1)
assert_has_wind_zone(panel_1_0, 1)
assert_has_wind_zone(panel_2_0, 1)
assert_has_wind_zone(panel_3_0, 0)
assert_has_wind_zone(panel_0_1, 1)
assert_has_wind_zone(panel_1_1, 2)
assert_has_wind_zone(panel_2_1, 1)
assert_has_wind_zone(panel_3_1, 1)
assert_has_wind_zone(panel_0_2, 1)
assert_has_wind_zone(panel_1_2, 1)
assert_has_wind_zone(panel_2_2, 1)
def test_compute_corner_directions(self):
data = [
{
'building_points': [(0, 0), (10, 0), (10, 10), (0, 10)],
'expected_corner_dirs': [(False, False), (False, True), (True, True), (True, False)]
},
{
'building_points': [(0, 0), (10, 0), (2, 10)],
'expected_corner_dirs': [(False, False), (False, True), (True, False)]
},
{
'building_points': [(0, 0), (10, 0), (7, 10)],
'expected_corner_dirs': [(False, False), (False, True), (True, True)]
},
{
'building_points': [(0, 0), (10, 0), (7, 2)],
'expected_corner_dirs': [(False, False), (False, True), (True, False)]
},
{
'building_points': [(0, 0), (3, -10), (10, 0)],
'expected_corner_dirs': [(True, False), (False, False), (True, True)]
},
{
'building_points': [(-1, -1), (1, 4), (0, 10)],
'expected_corner_dirs': [(False, False), (False, True), (True, False)]
},
{
'building_points': [(1, -1), (0, 10), (-1, 4)],
'expected_corner_dirs': [(False, True), (True, True), (False, False)]
},
{
'building_points': [(0, 1), (4, 0), (8, 2)],
'expected_corner_dirs': [(True, False), (False, True), (True, True)]
},
{
'building_points': [(0, 2), (4, 0), (8, 1)],
'expected_corner_dirs': [(True, False), (False, False), (True, True)]
}
]
for item in data:
building = item['building_points']
expected = item['expected_corner_dirs']
corners = []
for i in range(len(building)):
corners.append((building[i - 1], building[i], building[(i + 1) % len(building)]))
for expected, (prev, vertex, next) in zip(expected, corners):
print('given:', self.subject.compute_corner_directions(vertex, prev, next, 0))
assert self.subject.compute_corner_directions(vertex, prev, next, 0) == expected

View File

@@ -0,0 +1,93 @@
import unittest
from PIL import Image
from io import BytesIO
import mockredis
from helix.calculators.calculator import Calculator
from helix.constants.anchor_type import AnchorType
from helix.constants.exposure_category import ExposureCategory
from helix.constants.module_type import ModuleType
from helix.constants.system_type import SystemType
from helix.models.coordinate import Coordinate
from helix.models.panel import Panel
from helix.models.sql.sites import Site
from helix.models.subarray import Subarray
from helix.presenters.image_presenter import ImagePresenter
from helix.store import Store
from helix.user_values import UserValues
from test.fixtures.sample_image_presented_panel_data import panels_pseries_single_tilt, subarrays_pseries_single_tilt
from test.test_helpers import assert_image_equal
class ImagePresenterTest(unittest.TestCase):
def test_generate_image_taller_than_is_wide(self):
# This is input_dual_tilt_128_crafted.tsv
# With inputs as:
# System Type: Dual-Tilt
# Module Type: 128 Cell
# Building Height: 100.0
# Building Width: 50.0
# Building Length: 100.0
# Parapet Height: 0.0
# Wind Speed: 110
# Exposure Category: C
# Ballast Block Weight: 14.0
# Max Allowable System Pressure: 10.0
# Anchor Type: OMG PowerGrip Plus
# S_DS: 1.0
panels = [
Panel(wind_zone=3, subarray=1, coordinate=Coordinate(0, 0), ballast=20, wind_anchors=0, seismic_anchors=0),
Panel(wind_zone=3, subarray=1, coordinate=Coordinate(0, 1), ballast=0, wind_anchors=0, seismic_anchors=1),
Panel(wind_zone=2, subarray=2, coordinate=Coordinate(0, 0), ballast=8, wind_anchors=1, seismic_anchors=0),
Panel(wind_zone=2, subarray=2, coordinate=Coordinate(1, 0), ballast=0, wind_anchors=1, seismic_anchors=1),
Panel(wind_zone=2, subarray=2, coordinate=Coordinate(0, 1), ballast=0, wind_anchors=1, seismic_anchors=1),
Panel(wind_zone=2, subarray=2, coordinate=Coordinate(1, 1), ballast=0, wind_anchors=1, seismic_anchors=1)
]
subarrays = [
Subarray(subarray_number=1, origin=Coordinate(0, 0), start_row=0, size=2),
Subarray(subarray_number=2, origin=Coordinate(0, 2), start_row=2, size=4)
]
expected_image = Image.open("test/fixtures/images/expected_dual_tilt_pseries_image.png")
received_bytes = ImagePresenter(SystemType.dualTilt, ModuleType.Cell128).generate_image(panels, subarrays)
received_image = Image.open(BytesIO(received_bytes))
assert_image_equal(received_image, expected_image, error=0.001)
def test_generate_image_wider_than_is_tall(self):
# This is input_single_tilt_pseries_coordinates.tsv
# With inputs as:
# System Type: Single-Tilt
# Module Type: P-Series
# Building Height: 100.0
# Building Width: 100.0
# Building Length: 100.0
# Parapet Height: 1.0
# Wind Speed: 100
# Exposure Category: C
# Ballast Block Weight: 14.0
# Max Allowable System Pressure: 12.0
# Anchor Type: OMG PowerGrip Plus
# S_DS: 1.0
panels = panels_pseries_single_tilt
subarrays = subarrays_pseries_single_tilt
expected_image = Image.open("test/fixtures/images/expected_single_tilt_pseries_image.png")
received_bytes = ImagePresenter(SystemType.singleTilt, ModuleType.PSeries).generate_image(panels, subarrays)
received_image = Image.open(BytesIO(received_bytes))
assert_image_equal(received_image, expected_image, error=0.5)
def test_return_image_stating_system_too_large_if_more_than_3000_panels_submitted(self):
panels = [Panel() for _ in range(3000)]
subarrays = []
expected_image = Image.open("test/fixtures/images/expected_too_many_panels.png")
received_bytes = ImagePresenter(SystemType.singleTilt, ModuleType.PSeries).generate_image(panels, subarrays)
received_image = Image.open(BytesIO(received_bytes))
assert_image_equal(received_image, expected_image, error=5e-2)

View File

@@ -0,0 +1,77 @@
import unittest
from nose.tools import eq_
from helix.helpers.nodequadtree import Bounds, NodeQuadTree
from helix.models.coordinate import Coordinate
class DummyNode:
def __init__(self, x, y):
self.coordinate = Coordinate(x, y)
class NodeQuadTreeTest(unittest.TestCase):
def setUp(self):
self.quadTree = NodeQuadTree(1, Bounds(0, 100, 0, 100), 0.5)
def test_lower_leaves(self):
nodes = [
DummyNode(1, 1),
DummyNode(4, 1),
DummyNode(6, 1),
DummyNode(9, 1),
DummyNode(1, 9),
DummyNode(4, 9),
DummyNode(6, 9),
DummyNode(9, 9)
]
for i in range(100):
for n in nodes:
self.quadTree.insert(n)
output = []
self.quadTree.report(output)
expected = [0, 0, 0, 0, 200, 200, 200, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0]
eq_(output, expected)
def test_top_level_degenerate(self):
nodes = []
for i in range(0, 100):
nodes.append(DummyNode(50, i))
nodes.append(DummyNode(i, 50))
for n in nodes:
self.quadTree.insert(n)
output = []
self.quadTree.report(output)
expected = [200, 0, 0, 0, 0]
eq_(output, expected)
def test_every_point(self):
nodes = []
for x in range(0, 100):
for y in range(0, 100):
nodes.append(DummyNode(x, y))
for n in nodes:
self.quadTree.insert(n)
output = []
self.quadTree.report(output)
expected = [199, 0, 49, 23, 25, 30, 30, 36, 23, 25, 30, 30, 36, 23, 25, 30, 30, 36, 23, 25, 30, 30, 36, 49, 23,
30, 25, 36, 30, 23, 30, 25, 36, 30, 23, 30, 25, 36, 30, 23, 30, 25, 36, 30, 49, 23, 30, 36, 25, 30,
23, 30, 36, 25, 30, 23, 30, 36, 25, 30, 23, 30, 36, 25, 30, 49, 23, 36, 30, 30, 25, 23, 36, 30, 30,
25, 23, 36, 30, 30, 25, 23, 36, 30, 30, 25, 0, 49, 23, 25, 30, 30, 36, 23, 25, 30, 30, 36, 23, 25,
30, 30, 36, 23, 25, 30, 30, 36, 48, 23, 30, 25, 36, 30, 22, 30, 20, 36, 24, 23, 30, 25, 36, 30, 22,
30, 20, 36, 24, 49, 23, 30, 36, 25, 30, 23, 30, 36, 25, 30, 23, 30, 36, 25, 30, 23, 30, 36, 25, 30,
48, 23, 36, 30, 30, 25, 22, 36, 24, 30, 20, 23, 36, 30, 30, 25, 22, 36, 24, 30, 20, 0, 49, 23, 25,
30, 30, 36, 23, 25, 30, 30, 36, 23, 25, 30, 30, 36, 23, 25, 30, 30, 36, 49, 23, 30, 25, 36, 30, 23,
30, 25, 36, 30, 23, 30, 25, 36, 30, 23, 30, 25, 36, 30, 48, 23, 30, 36, 25, 30, 23, 30, 36, 25, 30,
22, 30, 36, 20, 24, 22, 30, 36, 20, 24, 48, 23, 36, 30, 30, 25, 23, 36, 30, 30, 25, 22, 36, 30, 24,
20, 22, 36, 30, 24, 20, 0, 49, 23, 25, 30, 30, 36, 23, 25, 30, 30, 36, 23, 25, 30, 30, 36, 23, 25,
30, 30, 36, 48, 23, 30, 25, 36, 30, 22, 30, 20, 36, 24, 23, 30, 25, 36, 30, 22, 30, 20, 36, 24, 48,
23, 30, 36, 25, 30, 23, 30, 36, 25, 30, 22, 30, 36, 20, 24, 22, 30, 36, 20, 24, 47, 23, 36, 30, 30,
25, 22, 36, 24, 30, 20, 22, 36, 30, 24, 20, 21, 36, 24, 24, 16]
eq_(output, expected)

View File

@@ -0,0 +1,244 @@
import unittest
from numpy.testing import assert_array_equal, assert_equal
from helix.constants.module_type import ModuleType
from helix.models.coordinate import Coordinate
from helix.models.panel import Panel
from helix.models.subarray import Subarray
from helix.presenters.panel_presenter import ProjectPresenter
from helix.constants.system_type import SystemType
from helix.constants.panel_type import PanelType
class PanelPresenterTest(unittest.TestCase):
def test_get_table_data_single_tilt_96cell(self):
self.subject = ProjectPresenter(SystemType.singleTilt, ModuleType.Cell96)
panels = [
Panel(wind_zone=0, subarray=1, panel_type=PanelType.Middle, coordinate=Coordinate(0, 2), pressure=1.17, ballast=20, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=1),
Panel(wind_zone=0, subarray=1, panel_type=PanelType.NorthSouth, coordinate=Coordinate(3, 1), pressure=1.17, ballast=17, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=2),
Panel(wind_zone=0, subarray=1, panel_type=PanelType.NorthSouth, coordinate=Coordinate(2, 1), pressure=1.17, ballast=0, presented_link_tray=0, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=3),
Panel(wind_zone=0, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(1, 1), pressure=1.17, ballast=47, presented_link_tray=2, cross_tray=4, wind_anchors=0, seismic_anchors=1, id=4),
Panel(wind_zone=0, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 1), pressure=1.17, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=5),
Panel(wind_zone=0, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(3, 0), pressure=1.17, ballast=8, presented_link_tray=1, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=6),
Panel(wind_zone=0, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(2, 0), pressure=1.17, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=7),
Panel(wind_zone=0, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(1, 0), pressure=1.17, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=8),
Panel(wind_zone=0, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(0, 0), pressure=1.17, ballast=35, presented_link_tray=2, cross_tray=3, wind_anchors=0, seismic_anchors=1, id=9),
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(3, 1), pressure=2.56, ballast=20, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=10),
Panel(wind_zone=3, subarray=2, panel_type=PanelType.EastWest, coordinate=Coordinate(2, 1), pressure=2.56, ballast=17, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=11),
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Middle, coordinate=Coordinate(1, 1), pressure=2.56, ballast=0, presented_link_tray=0, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=12),
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(0, 1), pressure=2.56, ballast=47, presented_link_tray=2, cross_tray=4, wind_anchors=0, seismic_anchors=1, id=13),
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(3, 0), pressure=2.56, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=14),
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(2, 0), pressure=2.56, ballast=8, presented_link_tray=1, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=15),
Panel(wind_zone=3, subarray=2, panel_type=PanelType.NorthSouth, coordinate=Coordinate(1, 0), pressure=2.56, ballast=35, presented_link_tray=2, cross_tray=3, wind_anchors=0, seismic_anchors=1, id=16)
]
subarrays = [
Subarray(subarray_number=1, origin=Coordinate(0, 0), start_row=0, size=9),
Subarray(subarray_number=2, origin=Coordinate(0, 2), start_row=9, size=7)
]
expected = [
{'x': 0, 'y': 1, 'width': 1, 'height': 1, 'data': {'panel_id': 1, 'panel_type': 4, 'ballast': 20, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 1, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
{'x': 3, 'y': 2, 'width': 1, 'height': 1, 'data': {'panel_id': 2, 'panel_type': 2, 'ballast': 17, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 1, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
{'x': 2, 'y': 2, 'width': 1, 'height': 1, 'data': {'panel_id': 3, 'panel_type': 2, 'ballast': 0, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 0, 'link_trays': 0, 'psf': 1.17, 'subarray': 1}},
{'x': 1, 'y': 2, 'width': 1, 'height': 1, 'data': {'panel_id': 4, 'panel_type': 1, 'ballast': 47, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 4, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
{'x': 0, 'y': 2, 'width': 1, 'height': 1, 'data': {'panel_id': 5, 'panel_type': 3, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
{'x': 3, 'y': 3, 'width': 1, 'height': 1, 'data': {'panel_id': 6, 'panel_type': 3, 'ballast': 8, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 0, 'link_trays': 1, 'psf': 1.17, 'subarray': 1}},
{'x': 2, 'y': 3, 'width': 1, 'height': 1, 'data': {'panel_id': 7, 'panel_type': 3, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
{'x': 1, 'y': 3, 'width': 1, 'height': 1, 'data': {'panel_id': 8, 'panel_type': 1, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
{'x': 0, 'y': 3, 'width': 1, 'height': 1, 'data': {'panel_id': 9, 'panel_type': 1, 'ballast': 35, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 3, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
{'x': 3, 'y': 0, 'width': 1, 'height': 1, 'data': {'panel_id': 10, 'panel_type': 1, 'ballast': 20, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 1, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
{'x': 2, 'y': 0, 'width': 1, 'height': 1, 'data': {'panel_id': 11, 'panel_type': 3, 'ballast': 17, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 1, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
{'x': 1, 'y': 0, 'width': 1, 'height': 1, 'data': {'panel_id': 12, 'panel_type': 4, 'ballast': 0, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 0, 'link_trays': 0, 'psf': 2.56, 'subarray': 2}},
{'x': 0, 'y': 0, 'width': 1, 'height': 1, 'data': {'panel_id': 13, 'panel_type': 1, 'ballast': 47, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 4, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
{'x': 3, 'y': 1, 'width': 1, 'height': 1, 'data': {'panel_id': 14, 'panel_type': 1, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 2, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
{'x': 2, 'y': 1, 'width': 1, 'height': 1, 'data': {'panel_id': 15, 'panel_type': 1, 'ballast': 8, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 0, 'link_trays': 1, 'psf': 2.56, 'subarray': 2}},
{'x': 1, 'y': 1, 'width': 1, 'height': 1, 'data': {'panel_id': 16, 'panel_type': 2, 'ballast': 35, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 3, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
]
received = self.subject.get_panel_data(panels, subarrays)
assert_array_equal(received, expected)
def test_get_buildings_data(self):
self.subject = ProjectPresenter(SystemType.singleTilt, ModuleType.Cell96)
buildings = [ [ Coordinate(-60,-60), Coordinate(60,-60), Coordinate(60,60), Coordinate(-60,60) ] ] # big square
expected_buildings = [[ {'x': -60, '_Coordinate__rounded_x': -60, 'y': 60, '_Coordinate__rounded_y': -60, 'rotation': 0.0},
{'x': 60, '_Coordinate__rounded_x': 60, 'y': 60, '_Coordinate__rounded_y': -60, 'rotation': 0.0},
{'x': 60, '_Coordinate__rounded_x': 60, 'y': -60, '_Coordinate__rounded_y': 60, 'rotation': 0.0},
{'x': -60, '_Coordinate__rounded_x': -60, 'y': -60, '_Coordinate__rounded_y': 60, 'rotation': 0.0}]]
actual_buildings = self.subject.get_buildings(buildings)
assert_array_equal(actual_buildings,expected_buildings)
def test_get_max_y(self):
self.subject = ProjectPresenter(SystemType.singleTilt, ModuleType.Cell96)
panels = [
Panel(wind_zone=0, subarray=1, panel_type=PanelType.Middle, coordinate=Coordinate(0, 2), pressure=1.17, ballast=20, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=1),
Panel(wind_zone=0, subarray=1, panel_type=PanelType.NorthSouth, coordinate=Coordinate(3, 1), pressure=1.17, ballast=17, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=2),
]
buildings = [ [ Coordinate(-60,-60), Coordinate(60,-60), Coordinate(60,60), Coordinate(-60,60) ] ] # big square
expected_max_y = 60
actual_max_y = self.subject.get_max_y(buildings,panels)
assert_equal(actual_max_y, expected_max_y)
expected_max_y = 2
actual_max_y = self.subject.get_max_y([],panels)
assert_equal(actual_max_y, expected_max_y)
def test_get_table_data_single_tilt_128cell(self):
self.subject = ProjectPresenter(SystemType.singleTilt, ModuleType.Cell128)
panels = [
Panel(wind_zone=0, subarray=1, panel_type=PanelType.Middle, coordinate=Coordinate(0, 2), pressure=1.17, ballast=20, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=1),
Panel(wind_zone=0, subarray=1, panel_type=PanelType.NorthSouth, coordinate=Coordinate(3, 1), pressure=1.17, ballast=17, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=2),
Panel(wind_zone=0, subarray=1, panel_type=PanelType.NorthSouth, coordinate=Coordinate(2, 1), pressure=1.17, ballast=0, presented_link_tray=0, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=3),
Panel(wind_zone=0, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(1, 1), pressure=1.17, ballast=47, presented_link_tray=2, cross_tray=4, wind_anchors=0, seismic_anchors=1, id=4),
Panel(wind_zone=0, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 1), pressure=1.17, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=5),
Panel(wind_zone=0, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(3, 0), pressure=1.17, ballast=8, presented_link_tray=1, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=6),
Panel(wind_zone=0, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(2, 0), pressure=1.17, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=7),
Panel(wind_zone=0, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(1, 0), pressure=1.17, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=8),
Panel(wind_zone=0, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(0, 0), pressure=1.17, ballast=35, presented_link_tray=2, cross_tray=3, wind_anchors=0, seismic_anchors=1, id=9),
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(3, 1), pressure=2.56, ballast=20, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=10),
Panel(wind_zone=3, subarray=2, panel_type=PanelType.EastWest, coordinate=Coordinate(2, 1), pressure=2.56, ballast=17, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=11),
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Middle, coordinate=Coordinate(1, 1), pressure=2.56, ballast=0, presented_link_tray=0, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=12),
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(0, 1), pressure=2.56, ballast=47, presented_link_tray=2, cross_tray=4, wind_anchors=0, seismic_anchors=1, id=13),
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(3, 0), pressure=2.56, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=14),
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(2, 0), pressure=2.56, ballast=8, presented_link_tray=1, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=15),
Panel(wind_zone=3, subarray=2, panel_type=PanelType.NorthSouth, coordinate=Coordinate(1, 0), pressure=2.56, ballast=35, presented_link_tray=2, cross_tray=3, wind_anchors=0, seismic_anchors=1, id=16)
]
subarrays= [
Subarray(subarray_number=1, origin=Coordinate(0, 0), start_row=0, size=9),
Subarray(subarray_number=2, origin=Coordinate(0, 2), start_row=9, size=7)
]
expected = [
{'x': 0.0, 'y': 1, 'width': 1.5, 'height': 1, 'data': {'panel_id': 1, 'panel_type': 4, 'ballast': 20, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 1, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
{'x': 4.5, 'y': 2, 'width': 1.5, 'height': 1, 'data': {'panel_id': 2, 'panel_type': 2, 'ballast': 17, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 1, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
{'x': 3.0, 'y': 2, 'width': 1.5, 'height': 1, 'data': {'panel_id': 3, 'panel_type': 2, 'ballast': 0, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 0, 'link_trays': 0, 'psf': 1.17, 'subarray': 1}},
{'x': 1.5, 'y': 2, 'width': 1.5, 'height': 1, 'data': {'panel_id': 4, 'panel_type': 1, 'ballast': 47, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 4, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
{'x': 0.0, 'y': 2, 'width': 1.5, 'height': 1, 'data': {'panel_id': 5, 'panel_type': 3, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
{'x': 4.5, 'y': 3, 'width': 1.5, 'height': 1, 'data': {'panel_id': 6, 'panel_type': 3, 'ballast': 8, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 0, 'link_trays': 1, 'psf': 1.17, 'subarray': 1}},
{'x': 3.0, 'y': 3, 'width': 1.5, 'height': 1, 'data': {'panel_id': 7, 'panel_type': 3, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
{'x': 1.5, 'y': 3, 'width': 1.5, 'height': 1, 'data': {'panel_id': 8, 'panel_type': 1, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
{'x': 0.0, 'y': 3, 'width': 1.5, 'height': 1, 'data': {'panel_id': 9, 'panel_type': 1, 'ballast': 35, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 3, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
{'x': 4.5, 'y': 0, 'width': 1.5, 'height': 1, 'data': {'panel_id': 10, 'panel_type': 1, 'ballast': 20, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 1, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
{'x': 3.0, 'y': 0, 'width': 1.5, 'height': 1, 'data': {'panel_id': 11, 'panel_type': 3, 'ballast': 17, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 1, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
{'x': 1.5, 'y': 0, 'width': 1.5, 'height': 1, 'data': {'panel_id': 12, 'panel_type': 4, 'ballast': 0, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 0, 'link_trays': 0, 'psf': 2.56, 'subarray': 2}},
{'x': 0.0, 'y': 0, 'width': 1.5, 'height': 1, 'data': {'panel_id': 13, 'panel_type': 1, 'ballast': 47, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 4, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
{'x': 4.5, 'y': 1, 'width': 1.5, 'height': 1, 'data': {'panel_id': 14, 'panel_type': 1, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 2, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
{'x': 3.0, 'y': 1, 'width': 1.5, 'height': 1, 'data': {'panel_id': 15, 'panel_type': 1, 'ballast': 8, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 0, 'link_trays': 1, 'psf': 2.56, 'subarray': 2}},
{'x': 1.5, 'y': 1, 'width': 1.5, 'height': 1, 'data': {'panel_id': 16, 'panel_type': 2, 'ballast': 35, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 3, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
]
received = self.subject.get_panel_data(panels, subarrays)
assert_array_equal(received, expected)
def test_get_table_data_dual_tilt_96cell(self):
self.subject = ProjectPresenter(SystemType.dualTilt, ModuleType.Cell96)
panels =[
Panel(wind_zone=4, subarray=1, panel_type=PanelType.Middle, coordinate=Coordinate(0, 2), pressure=1.23, ballast=20, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=1),
Panel(wind_zone=4, subarray=1, panel_type=PanelType.NorthSouth, coordinate=Coordinate(3, 1), pressure=1.23, ballast=17, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=2),
Panel(wind_zone=4, subarray=1, panel_type=PanelType.NorthSouth, coordinate=Coordinate(2, 1), pressure=1.23, ballast=0, presented_link_tray=0, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=3),
Panel(wind_zone=4, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(1, 1), pressure=1.23, ballast=47, presented_link_tray=2, cross_tray=4, wind_anchors=0, seismic_anchors=1, id=4),
Panel(wind_zone=4, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 1), pressure=1.23, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=5),
Panel(wind_zone=4, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(3, 0), pressure=1.23, ballast=8, presented_link_tray=1, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=6),
Panel(wind_zone=4, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(2, 0), pressure=1.23, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=7),
Panel(wind_zone=4, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(1, 0), pressure=1.23, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=8),
Panel(wind_zone=4, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(0, 0), pressure=1.23, ballast=35, presented_link_tray=2, cross_tray=3, wind_anchors=0, seismic_anchors=1, id=9),
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(3, 1), pressure=3.14, ballast=20, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=10),
Panel(wind_zone=1, subarray=2, panel_type=PanelType.EastWest, coordinate=Coordinate(2, 1), pressure=3.14, ballast=17, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=11),
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Middle, coordinate=Coordinate(1, 1), pressure=3.14, ballast=0, presented_link_tray=0, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=12),
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(0, 1), pressure=3.14, ballast=47, presented_link_tray=2, cross_tray=4, wind_anchors=0, seismic_anchors=1, id=13),
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(3, 0), pressure=3.14, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=14),
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(2, 0), pressure=3.14, ballast=8, presented_link_tray=1, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=15),
Panel(wind_zone=1, subarray=2, panel_type=PanelType.NorthSouth, coordinate=Coordinate(1, 0), pressure=3.14, ballast=35, presented_link_tray=2, cross_tray=3, wind_anchors=0, seismic_anchors=1, id=16)
]
subarrays = [
Subarray(subarray_number=1, origin=Coordinate(0, 0), start_row=0, size=9),
Subarray(subarray_number=2, origin=Coordinate(0, 2), start_row=9, size=7)
]
expected = [
{'x': 0.0, 'y': 1, 'width': 1.5, 'height': 1, 'data': {'panel_id': 1, 'panel_type': 4, 'ballast': 20, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 1, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
{'x': 4.5, 'y': 2, 'width': 1.5, 'height': 1, 'data': {'panel_id': 2, 'panel_type': 2, 'ballast': 17, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 1, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
{'x': 3.0, 'y': 2, 'width': 1.5, 'height': 1, 'data': {'panel_id': 3, 'panel_type': 2, 'ballast': 0, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 0, 'link_trays': 0, 'psf': 1.23, 'subarray': 1}},
{'x': 1.5, 'y': 2, 'width': 1.5, 'height': 1, 'data': {'panel_id': 4, 'panel_type': 1, 'ballast': 47, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 4, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
{'x': 0.0, 'y': 2, 'width': 1.5, 'height': 1, 'data': {'panel_id': 5, 'panel_type': 3, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
{'x': 4.5, 'y': 3, 'width': 1.5, 'height': 1, 'data': {'panel_id': 6, 'panel_type': 3, 'ballast': 8, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 0, 'link_trays': 1, 'psf': 1.23, 'subarray': 1}},
{'x': 3.0, 'y': 3, 'width': 1.5, 'height': 1, 'data': {'panel_id': 7, 'panel_type': 3, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
{'x': 1.5, 'y': 3, 'width': 1.5, 'height': 1, 'data': {'panel_id': 8, 'panel_type': 1, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
{'x': 0.0, 'y': 3, 'width': 1.5, 'height': 1, 'data': {'panel_id': 9, 'panel_type': 1, 'ballast': 35, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 3, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
{'x': 4.5, 'y': 0, 'width': 1.5, 'height': 1, 'data': {'panel_id': 10, 'panel_type': 1, 'ballast': 20, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 1, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
{'x': 3.0, 'y': 0, 'width': 1.5, 'height': 1, 'data': {'panel_id': 11, 'panel_type': 3, 'ballast': 17, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 1, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
{'x': 1.5, 'y': 0, 'width': 1.5, 'height': 1, 'data': {'panel_id': 12, 'panel_type': 4, 'ballast': 0, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 0, 'link_trays': 0, 'psf': 3.14, 'subarray': 2}},
{'x': 0.0, 'y': 0, 'width': 1.5, 'height': 1, 'data': {'panel_id': 13, 'panel_type': 1, 'ballast': 47, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 4, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
{'x': 4.5, 'y': 1, 'width': 1.5, 'height': 1, 'data': {'panel_id': 14, 'panel_type': 1, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 2, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
{'x': 3.0, 'y': 1, 'width': 1.5, 'height': 1, 'data': {'panel_id': 15, 'panel_type': 1, 'ballast': 8, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 0, 'link_trays': 1, 'psf': 3.14, 'subarray': 2}},
{'x': 1.5, 'y': 1, 'width': 1.5, 'height': 1, 'data': {'panel_id': 16, 'panel_type': 2, 'ballast': 35, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 3, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
]
received = self.subject.get_panel_data(panels, subarrays)
assert_array_equal(received, expected)
def test_get_table_data_dual_tilt_128cell(self):
self.subject = ProjectPresenter(SystemType.dualTilt, ModuleType.Cell128)
panels =[
Panel(wind_zone=4, subarray=1, panel_type=PanelType.Middle, coordinate=Coordinate(0, 2), pressure=1.23, ballast=20, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=1),
Panel(wind_zone=4, subarray=1, panel_type=PanelType.NorthSouth, coordinate=Coordinate(3, 1), pressure=1.23, ballast=17, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=2),
Panel(wind_zone=4, subarray=1, panel_type=PanelType.NorthSouth, coordinate=Coordinate(2, 1), pressure=1.23, ballast=0, presented_link_tray=0, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=3),
Panel(wind_zone=4, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(1, 1), pressure=1.23, ballast=47, presented_link_tray=2, cross_tray=4, wind_anchors=0, seismic_anchors=1, id=4),
Panel(wind_zone=4, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 1), pressure=1.23, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=5),
Panel(wind_zone=4, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(3, 0), pressure=1.23, ballast=8, presented_link_tray=1, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=6),
Panel(wind_zone=4, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(2, 0), pressure=1.23, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=7),
Panel(wind_zone=4, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(1, 0), pressure=1.23, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=8),
Panel(wind_zone=4, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(0, 0), pressure=1.23, ballast=35, presented_link_tray=2, cross_tray=3, wind_anchors=0, seismic_anchors=1, id=9),
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(3, 1), pressure=3.14, ballast=20, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=10),
Panel(wind_zone=1, subarray=2, panel_type=PanelType.EastWest, coordinate=Coordinate(2, 1), pressure=3.14, ballast=17, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=11),
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Middle, coordinate=Coordinate(1, 1), pressure=3.14, ballast=0, presented_link_tray=0, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=12),
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(0, 1), pressure=3.14, ballast=47, presented_link_tray=2, cross_tray=4, wind_anchors=0, seismic_anchors=1, id=13),
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(3, 0), pressure=3.14, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=14),
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(2, 0), pressure=3.14, ballast=8, presented_link_tray=1, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=15),
Panel(wind_zone=1, subarray=2, panel_type=PanelType.NorthSouth, coordinate=Coordinate(1, 0), pressure=3.14, ballast=35, presented_link_tray=2, cross_tray=3, wind_anchors=0, seismic_anchors=1, id=16)
]
subarrays = [
Subarray(subarray_number=1, origin=Coordinate(0, 0), start_row=0, size=9),
Subarray(subarray_number=2, origin=Coordinate(0, 2), start_row=9, size=7)
]
expected = [
{'x': 0.0, 'y': 1.5, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 1, 'panel_type': 4, 'ballast': 20, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 1, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
{'x': 4.5, 'y': 3.0, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 2, 'panel_type': 2, 'ballast': 17, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 1, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
{'x': 3.0, 'y': 3.0, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 3, 'panel_type': 2, 'ballast': 0, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 0, 'link_trays': 0, 'psf': 1.23, 'subarray': 1}},
{'x': 1.5, 'y': 3.0, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 4, 'panel_type': 1, 'ballast': 47, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 4, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
{'x': 0.0, 'y': 3.0, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 5, 'panel_type': 3, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
{'x': 4.5, 'y': 4.5, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 6, 'panel_type': 3, 'ballast': 8, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 0, 'link_trays': 1, 'psf': 1.23, 'subarray': 1}},
{'x': 3.0, 'y': 4.5, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 7, 'panel_type': 3, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
{'x': 1.5, 'y': 4.5, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 8, 'panel_type': 1, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
{'x': 0.0, 'y': 4.5, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 9, 'panel_type': 1, 'ballast': 35, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 3, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
{'x': 4.5, 'y': 0.0, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 10, 'panel_type': 1, 'ballast': 20, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 1, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
{'x': 3.0, 'y': 0.0, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 11, 'panel_type': 3, 'ballast': 17, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 1, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
{'x': 1.5, 'y': 0.0, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 12, 'panel_type': 4, 'ballast': 0, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 0, 'link_trays': 0, 'psf': 3.14, 'subarray': 2}},
{'x': 0.0, 'y': 0.0, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 13, 'panel_type': 1, 'ballast': 47, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 4, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
{'x': 4.5, 'y': 1.5, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 14, 'panel_type': 1, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 2, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
{'x': 3.0, 'y': 1.5, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 15, 'panel_type': 1, 'ballast': 8, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 0, 'link_trays': 1, 'psf': 3.14, 'subarray': 2}},
{'x': 1.5, 'y': 1.5, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 16, 'panel_type': 2, 'ballast': 35, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 3, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
]
received = self.subject.get_panel_data(panels, subarrays)
assert_array_equal(received, expected)

View File

@@ -0,0 +1,55 @@
import unittest
from nose.tools import eq_
from helix.calculators.subarray_helper import get_subarray_sizes_and_rows, extract_subarray
from helix.models.panel import Panel
from helix.models.subarray import Subarray
class SubarrayHelperTest(unittest.TestCase):
def test_get_subarray_sizes_and_rows(self):
panels = [
Panel(ballast=5, subarray=2),
Panel(ballast=6, subarray=2),
Panel(ballast=2, subarray=2),
Panel(ballast=1, subarray=5),
Panel(ballast=5, subarray=5),
Panel(ballast=6, subarray=5),
Panel(ballast=8, subarray=5),
Panel(ballast=2, subarray=5),
Panel(ballast=2, subarray=6),
Panel(ballast=2, subarray=6)
]
result = get_subarray_sizes_and_rows(panels)
expected = [
Subarray(subarray_number=2, start_row=0, size=3),
Subarray(subarray_number=5, start_row=3, size=5),
Subarray(subarray_number=6, start_row=8, size=2)
]
eq_(expected, result)
def test_extract_subarray(self):
panels = [
Panel(ballast=5, subarray=2),
Panel(ballast=6, subarray=2),
Panel(ballast=2, subarray=2),
Panel(ballast=1, subarray=5),
Panel(ballast=5, subarray=5),
Panel(ballast=6, subarray=5),
Panel(ballast=8, subarray=5),
Panel(ballast=2, subarray=5),
Panel(ballast=2, subarray=6),
Panel(ballast=2, subarray=6)
]
result = extract_subarray(panels, 5)
expected = [
Panel(ballast=1, subarray=5),
Panel(ballast=5, subarray=5),
Panel(ballast=6, subarray=5),
Panel(ballast=8, subarray=5),
Panel(ballast=2, subarray=5)
]
eq_(result, expected)