Skip to content

Commit d75b031

Browse files
authored
Merge pull request #5 from ckrening/panond_2
Updated notes and comments
2 parents dfe34b3 + 238db5c commit d75b031

File tree

1 file changed

+51
-2
lines changed

1 file changed

+51
-2
lines changed

pvlib/iotools/panond.py

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ def element_type(element):
3333
"""
3434
Determine if an element is a list then pass to num_type()
3535
"""
36-
if ',' in element: # Detect a list
36+
if ',' in element: # Detect a list.
37+
# .pan/.ond don't use ',' to indicate 1000. If that changes,
38+
# a new method of list detection needs to be found.
3739
values = element.split(',')
3840
element_out = []
3941
for val in values: # Determine datatype of each value
@@ -66,6 +68,46 @@ def parse_panond(fbuf):
6668
6769
Notes
6870
-----
71+
The parser was intended for use with .pan and .ond files that were created
72+
for use by PVsyst. At time of publication, no documentation for these
73+
files was available. So, this parser is based on inferred logic, rather
74+
than anything specified by PVsyst.
75+
76+
The parser assumes that the file being parsed uses indendation of two
77+
spaces (' ') to create new level in a nested dicitonary, and that
78+
key/values pairs of interest are separated using '='. This further means
79+
that lines not containing '=' were ommitted from the final returned
80+
dictionary.
81+
82+
Additionally, the indented lines often contain values themselves. This
83+
leads to a conflict with the .pan/.ond file and the ability of nested
84+
dicitonaries to capture that information. The solution implemented here is
85+
to repeat that key to the new nested dictioary within that new level.
86+
Example below.
87+
88+
Sample file:
89+
90+
'level1 = first level
91+
key1 = value1
92+
level2 = second level
93+
key2 = value2'
94+
95+
output:
96+
97+
{
98+
level1: first level
99+
key1: value1,
100+
level2:{
101+
level2: second level,
102+
key2: value2
103+
}
104+
}
105+
106+
The parser takes an additional step to infer the datatype present in
107+
each value. The .pan/.ond files appear to have intentially left datatype
108+
indicators (e.g. floats have '.' decimals). However, there is still the
109+
possibility that the datatype applied from this parser is incorrect. In
110+
that event the user would need to convert to the desired datatype.
69111
70112
See Also
71113
--------
@@ -84,15 +126,19 @@ def parse_panond(fbuf):
84126
continue
85127
# Reading blank lines. Stopping one short to avoid index error.
86128
# Last line never contains important data.
129+
# Creating variables to assist new level in dictionary creation logic
87130
indent_lvl_1 = (len(lines[i]) - len(lines[i].lstrip(' '))) // 2
88131
indent_lvl_2 = (len(lines[i + 1]) - len(lines[i + 1].lstrip(' '))) // 2
132+
# Split the line into key/value pair
89133
line_data = lines[i].split('=')
90134
key = line_data[0].strip()
135+
# Logical to make sure there is a value to extract
91136
if len(line_data) > 1:
92137
value = element_type(line_data[1].strip())
93138
else:
94139
value = None
95-
# add a level to the dict. The key here will be ignored.
140+
# add a level to the dict. If a key/value pair triggers the new level,
141+
# the key/value will be repeated in the new dict level.
96142
# Not vital to file function.
97143
if indent_lvl_2 > indent_lvl_1:
98144
current_level = dict_levels[indent_lvl_1]
@@ -131,6 +177,9 @@ def read_panond(file):
131177
132178
Notes
133179
-----
180+
The read function simply converts a file path to a file-like object and
181+
passes it to the parser. At time of creation, tested .pan/.ond files used
182+
UTF-8 encoding.
134183
135184
See Also
136185
--------

0 commit comments

Comments
 (0)