-
Notifications
You must be signed in to change notification settings - Fork 460
Fix #11087 - Duplicate Table Names in Tabular Output #11106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
… ALL integration and perf tests for now
|
|
It was quite broken, see the OutputChanges md for details
… we don't duplicate tests
|
| set(HTML_PATH "${OUTPUT_DIR_PATH}/eplustbl.htm") | ||
| if(EXISTS "${HTML_PATH}") | ||
| message("Checking uniqueness of HTML Table FullNames:") | ||
| message(STATUS "${Python_EXECUTABLE} ${SOURCE_DIR}/scripts/dev/ensure_unique_html_tables.py ${OUTPUT_DIR_PATH}") | ||
| execute_process( | ||
| COMMAND ${Python_EXECUTABLE} "${SOURCE_DIR}/scripts/dev/ensure_unique_html_tables.py" "${OUTPUT_DIR_PATH}" | ||
| RESULT_VARIABLE RESULT | ||
| ECHO_OUTPUT_VARIABLE | ||
| ECHO_ERROR_VARIABLE | ||
| ) | ||
|
|
||
| if(NOT RESULT EQUAL 0) | ||
| message("Test Failed: HTML output tables are NOT unique") | ||
| return() | ||
| endif() | ||
| endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had initially defined a test named "${TEST_CATEGORY}.${IDF_NAME}.EnsureUniqueTableNames" which depended on each.
Pros:
- Adds a clear output message about the failure
- Cons: doubles the number of test. And you can rerun via
ctest -R EnsureUniqueTableNamesand will NOT rerun the integration tests it depends on
So I decided to move this inside RunSimulation.cmake.
cf f0f99f5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will admit, I was taken aback when I saw a new parameter defined for RunSimulation, but after a couple seconds, I realized what you must be doing. Good stuff here.
| if __name__ == "__main__": | ||
| parser = argparse.ArgumentParser(description="Compare Output Reports.") | ||
| parser.add_argument("out_dir", type=Path, help="Output directory where to find the reports") | ||
| parser.add_argument( | ||
| "--skip-missing", action="store_true", default=False, help="Do not raise if the eplustbl.htm isn't found" | ||
| ) | ||
| args = parser.parse_args() | ||
|
|
||
| out_dir = args.out_dir.resolve() | ||
| if not (out_dir.exists() and out_dir.is_dir()): | ||
| raise IOError(f"'{out_dir}' is not a valid directory") | ||
| html_path = out_dir / "eplustbl.htm" | ||
| if not html_path.exists(): | ||
| if args.skip_missing: | ||
| print(f"Skipping missing HTML file: {html_path}") | ||
| exit(0) | ||
| raise IOError(f"HTML '{html_path}' does not exist") | ||
|
|
||
| ensure_unique_html_tables(html_path=html_path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New script.
| RE_FULLNAME = re.compile(r"<!-- FullName:(?P<activeReportName>[^_]+)_(?P<activeForName>[^_]+)_(?P<subtitle>[^_]+)-->") | ||
|
|
||
|
|
||
| def format_row(row, col_widths): | ||
| return "| " + " | ".join(f"{str(cell):<{col_widths[i]}}" for i, cell in enumerate(row)) + " |" | ||
|
|
||
|
|
||
| def ensure_unique_html_tables(html_path: Path): | ||
| """ | ||
| Ensure that each HTML table in the report has a unique name. | ||
| If duplicates are found, append a number to the duplicate names. | ||
| """ | ||
| content = html_path.read_text() | ||
|
|
||
| matches = RE_FULLNAME.findall(content) | ||
| if not matches: | ||
| raise ValueError("No HTML tables found with FullName pattern") | ||
|
|
||
| # Filter only duplicates (count > 1) | ||
| duplicates = [ | ||
| (activeReportName, activeForName, subtitle, count) | ||
| for (activeReportName, activeForName, subtitle), count in Counter(matches).items() | ||
| if count > 1 | ||
| ] | ||
|
|
||
| # Include header row in width calculation | ||
| if duplicates: | ||
| print(f"Found {len(duplicates)} duplicate HTML table(s) based on FullName\n") | ||
| header = [("activeReportName", "activeForName", "subtitle", "count")] | ||
| rows = header + duplicates | ||
| # Compute max width for each column | ||
| col_widths = [max(len(str(row[i])) for row in rows) for i in range(len(header[0]))] | ||
|
|
||
| print(format_row(rows[0], col_widths)) | ||
| print("|-" + "-|-".join("-" * w for w in col_widths) + "-|") | ||
| for row in duplicates: | ||
| print(format_row(row, col_widths)) | ||
|
|
||
| exit(1) | ||
| else: | ||
| print("No duplicates found.") | ||
| exit(0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty simple: parse the FUllName stuff into 3-tuples. Counter to find duplicates, format as markdown table, then exit 1.
$ python EnergyPlus/scripts/dev/ensure_unique_html_tables.py EnergyPlus-build-release/testfiles/SingleFamilyHouse_HP_Slab_Dehumidification/
Found 1 duplicate HTML table(s) based on FullName
| activeReportName | activeForName | subtitle | count |
|------------------------|-----------------|--------------|-------|
| Initialization Summary | Entire Facility | Material:Air | 2 |
(py312)(3.2.2)julien@EnergyPlus-build-release$ echo $?
1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When running via ctest
741: Test command: /usr/bin/cmake "-DSOURCE_DIR=/home/julien/Software/Others/EnergyPlus" "-DBINARY_DIR=/home/julien/Software/Others/EnergyPlus-build-release" "-DENERGYPLUS_EXE=/home/julien/Software/Others/EnergyPlus-build-release/Products/energyplus-25.2.0" "-DIDF_FILE=_FuelCellTest200.idf" "-DEPW_FILE=USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.epw" "-DENERGYPLUS_FLAGS= -D -r" "-DBUILD_FORTRAN=ON" "-DTEST_FILE_FOLDER=testfiles" "-DRUN_CALLGRIND:BOOL=FALSE" "-DVALGRIND=" "-DRUN_PERF_STAT:BOOL=FALSE" "-DPERF=" "-DPython_EXECUTABLE=/home/julien/.pyenv/versions/3.12.2/bin/python3.12" "-P" "/home/julien/Software/Others/EnergyPlus/cmake/RunSimulation.cmake"
741: Working Directory: /home/julien/Software/Others/EnergyPlus-build-release/testfiles
741: Test timeout computed to be: 9999879
741: Running Simulation:
741: -- /home/julien/Software/Others/EnergyPlus-build-release/Products/energyplus-25.2.0 -w /home/julien/Software/Others/EnergyPlus/weather/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.epw -d /home/julien/Software/Others/EnergyPlus-build-release/testfiles/_FuelCellTest200/ -D -r /home/julien/Software/Others/EnergyPlus/testfiles/_FuelCellTest200.idf
741: EnergyPlus Starting
[....]
741: EnergyPlus Completed Successfully.
741: Checking uniqueness of HTML Table FullNames:
741: -- /home/julien/.pyenv/versions/3.12.2/bin/python3.12 /home/julien/Software/Others/EnergyPlus/scripts/dev/ensure_unique_html_tables.py /home/julien/Software/Others/EnergyPlus-build-release/testfiles/_FuelCellTest200/
741: Found 1 duplicate HTML table(s) based on FullName
741:
741: | activeReportName | activeForName | subtitle | count |
741: |------------------------|-----------------|-------------|-------|
741: | Initialization Summary | Entire Facility | Fuel Supply | 2 |
741: Test Failed: HTML output tables are NOT unique
1/1 Test #741: integration._FuelCellTest200 .....***Failed Error regular expression found in output. Regex=[Test Failed] 0.65 sec
0% tests passed, 1 tests failed out of 1
| ### EIO and HTML Table Output: Initialization Summary | ||
|
|
||
| A number of changes related to finding duplicated HTML tables (based on FullName) have been made. | ||
|
|
||
| See Pull Request [#11106](https://github.com/NREL/EnergyPlus/pull/11106). | ||
|
|
||
| #### Schedules | ||
|
|
||
| The `Output:Schedules` object controls whether the schedules are reported to the EIO, which would end up in the Initialization Summary report of the HTML if the `Output:Table:SummaryReports` asks for it. | ||
| The `Output:Schedules` object has a `Key Field` which can be either `Timestep` or `Hourly`, and it is **not** a unique object, meaning you can request **both**. | ||
|
|
||
| A few issues where occurring with the former EIO report (which is parsed to produce the HTML tables): | ||
|
|
||
| * The headers where not specific to a given `Key Field` (= Report Level), so if you requested both they would show in both reports in the HTML table | ||
| * The headers were NOT aligned with the data rows, so some tables were not present in the HTML (WeekSchedule, ScheduleTypeLimots= | ||
| * The `ScheduleTypeLimits` were issued in both `Timestep` and `Hourly` reports in the EIO | ||
|
|
||
| ```diff | ||
| ! <Output Reporting Tolerances>, Tolerance for Time Heating Setpoint Not Met, Tolerance for Zone Cooling Setpoint Not Met Time | ||
| Output Reporting Tolerances, 0.200, 0.200, | ||
| +! <ScheduleTypeLimits>,Name,Limited? {Yes/No},Minimum,Maximum,Continuous? {Yes/No - Discrete} | ||
| +ScheduleTypeLimits,FRACTION,Yes,0.00,1.00,Yes | ||
| +ScheduleTypeLimits,ANY NUMBER,No,N/A,N/A,N/A | ||
| ! Schedule Details Report=Timestep ===================== | ||
| -! <ScheduleType>,Name,Limited? {Yes/No},Minimum,Maximum,Continuous? {Yes/No - Discrete} | ||
| -! <DaySchedule>,Name,ScheduleType,Interpolated {Yes/No},Time (HH:MM) =>,00:15,00:30,[...],23:30,23:45,24:00 | ||
| +! <DaySchedule - Timestep>,Name,ScheduleType,Interpolated {Average/Linear/No},Time (HH:MM) =>,00:15,00:30,[...],23:30,23:45,24:00 | ||
| -! <WeekSchedule>,Name,Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Holiday,SummerDesignDay,WinterDesignDay,CustomDay1,CustomDay2 | ||
| +! <WeekSchedule - Timestep>,Name,Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Holiday,SummerDesignDay,WinterDesignDay,CustomDay1,CustomDay2 | ||
| -! <Schedule>,Name,ScheduleType,{Until Date,WeekSchedule}** Repeated until Dec 31 | ||
| +! <Schedule - Timestep>,Name,ScheduleType,{Until Date,WeekSchedule}** Repeated until Dec 31 | ||
| -ScheduleTypeLimits,FRACTION,Average,0.00,1.00,Yes | ||
| -ScheduleTypeLimits,ANY NUMBER,No,N/A,N/A,N/A | ||
| -DaySchedule,TDEFAULTPROFILE,FRACTION,No,Values:,0.88,0.88,[...],0.82,0.82 | ||
| +DaySchedule - Timestep,TDEFAULTPROFILE,FRACTION,No,Values:,0.88,0.88,[...],0.82,0.82 | ||
| -Schedule:Week:Daily,CT WEEKSCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE | ||
| +WeekSchedule - Timestep,CT WEEKSCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE | ||
| -Schedule,ZONE CONTROL TYPE SCHEDULE,CONTROLTYPE,Through Dec 31,CT WEEKSCHEDULE | ||
| +Schedule - Timestep,ZONE CONTROL TYPE SCHEDULE,CONTROLTYPE,Through Dec 31,CT WEEKSCHEDULE | ||
| ! Schedule Details Report=Hourly ===================== | ||
| -! <ScheduleType>,Name,Limited? {Yes/No},Minimum,Maximum,Continuous? {Yes/No - Discrete} | ||
| -! <DaySchedule>,Name,ScheduleType,Interpolated {Yes/No},Time (HH:MM) =>,01:00,02:00,[...],23:00,24:00 | ||
| +! <DaySchedule - Hourly>,Name,ScheduleType,Interpolated {Average/Linear/No},Time (HH:MM) =>,01:00,02:00,[...],23:00,24:00 | ||
| -! <WeekSchedule>,Name,Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Holiday,SummerDesignDay,WinterDesignDay,CustomDay1,CustomDay2 | ||
| +! <WeekSchedule - Hourly>,Name,Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Holiday,SummerDesignDay,WinterDesignDay,CustomDay1,CustomDay2 | ||
| -! <Schedule>,Name,ScheduleType,{Until Date,WeekSchedule}** Repeated until Dec 31 | ||
| +! <Schedule - Hourly>,Name,ScheduleType,{Until Date,WeekSchedule}** Repeated until Dec 31 | ||
| -ScheduleTypeLimits,FRACTION,Average,0.00,1.00,Yes | ||
| -ScheduleTypeLimits,ANY NUMBER,No,N/A,N/A,N/A | ||
| -DaySchedule,TDEFAULTPROFILE,FRACTION,No,Values:,0.88,0.92,[...],0.75,0.82 | ||
| +DaySchedule - Hourly,TDEFAULTPROFILE,FRACTION,No,Values:,0.88,0.92,[...],0.75,0.82 | ||
| -Schedule:Week:Daily,CT WEEKSCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE | ||
| +WeekSchedule - Hourly,CT WEEKSCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE,CT DAY SCHEDULE | ||
| -Schedule,ZONE CONTROL TYPE SCHEDULE,CONTROLTYPE,Through Dec 31,CT WEEKSCHEDULE | ||
| +Schedule - Hourly,ZONE CONTROL TYPE SCHEDULE,CONTROLTYPE,Through Dec 31,CT WEEKSCHEDULE | ||
| ``` | ||
|
|
||
| #### Warmup Convergence Information | ||
|
|
||
| When `Output:Diagnostics` has the `ReportDetailedWarmupConvergence` enabled, both the regular report and the detailed one were named `Warmup Convergence Information` resulting in duplicated HTML tables that would include lines from the other report. | ||
|
|
||
| The `ReportDetailedWarmupConvergence` report (the one that shows the status at each timestep/hour until convergence is reached) was renamed to `Warmup Convergence Information - Detailed`. | ||
|
|
||
| #### Material:Air | ||
|
|
||
| The `Output:Constructions` has two possible keys: `Materials` and `Constructions`. Both were adding a table named `Material:Air`. The Constructions one was renamed to `Material:Air CTF Summary` to match the surrounding tables. | ||
|
|
||
| #### Fuel Supply | ||
|
|
||
| When using `Generator:FuelSupply`, the header was written twice in the EIO Initialization Summary as `! <Fuel Supply>,...` leading to two identical tables in the HTML report. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Explain and document the changes
| "! <Material CTF Summary>,Material Name,Thickness {{m}},Conductivity {{w/m-K}},Density {{kg/m3}},Specific Heat " | ||
| "{{J/kg-K}},ThermalResistance {{m2-K/w}}\n"); | ||
| print(state.files.eio, "! <Material:Air>,Material Name,ThermalResistance {{m2-K/w}}\n"); | ||
| print(state.files.eio, "! <Material:Air CTF Summary>,Material Name,ThermalResistance {{m2-K/w}}\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DUplicated "Material:Air" table.
| switch (thisMaterial->group) { | ||
| case Material::Group::AirGap: { | ||
| static constexpr std::string_view Format_702(" Material:Air,{},{:12.4N}\n"); | ||
| static constexpr std::string_view Format_702(" Material:Air CTF Summary,{},{:12.4N}\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicated Material:Air Table.
Output:Constructions,Materials; will add a table for each Material:Air.
Output:Constructions,Constructions; (this one) will add a SECOND table now called Material:Air CTF Summary.
Taking integration.SingleFamilyHouse_HP_Slab as example:
Originally, the Material:Air table for Materials has a duplicated row
The second is even worse, it includes everything
After
First, Materials table:
Second, COnstruction table
| print(state.files.eio, | ||
| "! <Fuel Supply>, Fuel Supply Name, Lower Heating Value [J/kmol], Lower Heating Value [kJ/kg], Higher " | ||
| "Heating Value [KJ/kg], Molecular Weight [g/mol] \n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // Report the ScheduleTypeLimits only once, not for each report level. | ||
| if (NumFields > 0) { | ||
| ReportScheduleTypeLimits(state); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent.
| if (auto [it, inserted] = reportLevelSet.insert(reportLevel); inserted) { | ||
| // If this is the first time we see this report level, we need to report the details | ||
| ReportScheduleDetails(state, reportLevel); | ||
| } else { | ||
| ShowWarningCustom(state, | ||
| eoh, | ||
| format("Report level {} has already been processed. This report level will not be processed again.", | ||
| reportLevelNames[(int)reportLevel])); | ||
| continue; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Report only once for each ReportLevel, in case you put twice "Output:Schedules,Timestep;" for eg
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good
| } | ||
| } | ||
|
|
||
| void ReportScheduleDetails(EnergyPlusData &state, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I completely revamped this function, using vectors instead of fortran arrays, etc.
I took 1ZoneUncontrolled_DD2009.idf and I added a couple more schedules for testing. Not sure if I should commit that change.
I added this
Schedule:Day:List,
Example Weather Temp, !- Name
Any Number, !- Schedule Type Limits Name
Average, !- Interpolate to Timestep
15, !- Minutes per Item
19.55, !- Value 1
20.1, !- <none>
20.65, !- <none>
21.2, !- <none>
21.25, !- <none>
21.3, !- <none>
21.35, !- <none>
21.4, !- <none>
21.25, !- <none>
21.1, !- <none>
20.95, !- <none>
20.8, !- <none>
20.625, !- <none>
20.45, !- <none>
20.275, !- <none>
20.1, !- <none>
19.95, !- <none>
19.8, !- <none>
19.65, !- <none>
19.5, !- <none>
19.625, !- <none>
19.75, !- <none>
19.875, !- <none>
20, !- <none>
20.25, !- <none>
20.5, !- <none>
20.75, !- <none>
21, !- <none>
21.1, !- <none>
21.2, !- <none>
21.3, !- <none>
21.4, !- <none>
21.8, !- <none>
22.2, !- <none>
22.6, !- <none>
23, !- <none>
23, !- <none>
23, !- <none>
23, !- <none>
23, !- <none>
23.375, !- <none>
23.75, !- <none>
24.125, !- <none>
24.5, !- <none>
24.45, !- <none>
24.4, !- <none>
24.35, !- <none>
24.3, !- <none>
24.225, !- <none>
24.15, !- <none>
24.075, !- <none>
24, !- <none>
23.95, !- <none>
23.9, !- <none>
23.85, !- <none>
23.8, !- <none>
23.85, !- <none>
23.9, !- <none>
23.95, !- <none>
24, !- <none>
24, !- <none>
24, !- <none>
24, !- <none>
24, !- <none>
23.825, !- <none>
23.65, !- <none>
23.475, !- <none>
23.3, !- <none>
23.1, !- <none>
22.9, !- <none>
22.7, !- <none>
22.5, !- <none>
22.275, !- <none>
22.05, !- <none>
21.825, !- <none>
21.6, !- <none>
21.4, !- <none>
21.2, !- <none>
21, !- <none>
20.8, !- <none>
20.7, !- <none>
20.6, !- <none>
20.5, !- <none>
20.4, !- <none>
20.3, !- <none>
20.2, !- <none>
20.1, !- <none>
20, !- <none>
20, !- <none>
20, !- <none>
20, !- <none>
20, !- <none>
19.75, !- <none>
19.5, !- <none>
19.25, !- <none>
19; !- <none>
ScheduleTypeLimits,
ControlType, !- Name
0, !- Lower Limit Value
4, !- Upper Limit Value
DISCRETE; !- Numeric Type
Schedule:Day:Interval,
CT Day Schedule, !- Name
ControlType, !- Schedule Type Limits Name
Linear, !- Interpolate to Timestep
Until: 01:00, !- Time 1
2, !- Value Until Time 1
Until: 03:00, !- Time 2
4, !- Value Until Time 2
Until: 24:00, !- Time 2
4; !- Value Until Time 2
Schedule:Week:Compact,
CT WeekSchedule, !- Name
For: Alldays, !- DayType List 1
CT Day Schedule; !- Schedule:Day Name 1
Schedule:Year,
Zone Control Type Schedule, !- Name
ControlType, !- Schedule Type Limits Name
CT WeekSchedule, !- Schedule:Week Name 1
1, !- Start Month 1
1, !- Start Day 1
12, !- End Month 1
31; !- End Day 1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
Regressions are all okNotebook of the RegressionsPlease see my jupyter notebook at https://gist.github.com/jmarrec/c907ca0bc00722356fb94b80176a82ca 305 EIO diffs
I inspected these diffs manually, they're all related to the ScheduleManager refactor I did. see the notebook in the Gist 61 Table Big Diffs37 are very short and cna be ruled out. I inspected the others manually, they all look fine. |
| from pathlib import Path | ||
|
|
||
| RE_FULLNAME = re.compile(r"<!-- FullName:(?P<activeReportName>[^_]+)_(?P<activeForName>[^_]+)_(?P<subtitle>[^_]+)-->") | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally think using regular expressions makes this type of script more difficult to understand (but then again, I almost never choose to use regular expressions...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like regexes. this one is simple too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JasonGlazer if this script were going to need to be modified regularly with more complexity, I may lean away from a complex regex. In this case, I agree it's not too complicated, we won't need to edit this script almost ever, and when we do -- plenty of tools out there to explain the regex to us :)
| if args.skip_missing: | ||
| print(f"Skipping missing HTML file: {html_path}") | ||
| exit(0) | ||
| raise IOError(f"HTML '{html_path}' does not exist") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there any files that produce tables and not HTML tables?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is more like we may have IDF files that turn it off.
| if (auto [it, inserted] = reportLevelSet.insert(reportLevel); inserted) { | ||
| // If this is the first time we see this report level, we need to report the details | ||
| ReportScheduleDetails(state, reportLevel); | ||
| } else { | ||
| ShowWarningCustom(state, | ||
| eoh, | ||
| format("Report level {} has already been processed. This report level will not be processed again.", | ||
| reportLevelNames[(int)reportLevel])); | ||
| continue; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good
Myoldmopar
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great stuff. I'll test it out locally, and fix the tiny little typo in the output rules file, but this should be ready to go. And a great addition.
| set(HTML_PATH "${OUTPUT_DIR_PATH}/eplustbl.htm") | ||
| if(EXISTS "${HTML_PATH}") | ||
| message("Checking uniqueness of HTML Table FullNames:") | ||
| message(STATUS "${Python_EXECUTABLE} ${SOURCE_DIR}/scripts/dev/ensure_unique_html_tables.py ${OUTPUT_DIR_PATH}") | ||
| execute_process( | ||
| COMMAND ${Python_EXECUTABLE} "${SOURCE_DIR}/scripts/dev/ensure_unique_html_tables.py" "${OUTPUT_DIR_PATH}" | ||
| RESULT_VARIABLE RESULT | ||
| ECHO_OUTPUT_VARIABLE | ||
| ECHO_ERROR_VARIABLE | ||
| ) | ||
|
|
||
| if(NOT RESULT EQUAL 0) | ||
| message("Test Failed: HTML output tables are NOT unique") | ||
| return() | ||
| endif() | ||
| endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will admit, I was taken aback when I saw a new parameter defined for RunSimulation, but after a couple seconds, I realized what you must be doing. Good stuff here.
| // Report the ScheduleTypeLimits only once, not for each report level. | ||
| if (NumFields > 0) { | ||
| ReportScheduleTypeLimits(state); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent.
| The `Output:Schedules` object controls whether the schedules are reported to the EIO, which would end up in the Initialization Summary report of the HTML if the `Output:Table:SummaryReports` asks for it. | ||
| The `Output:Schedules` object has a `Key Field` which can be either `Timestep` or `Hourly`, and it is **not** a unique object, meaning you can request **both**. | ||
|
|
||
| A few issues where occurring with the former EIO report (which is parsed to produce the HTML tables): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor typo where -> were
|
OK, I'll let the GHA instances spin up real quick, but no need to wait on them, I just fixed the typo. This is merging in a moment. Thanks @jmarrec . |
|








Pull request overview
Description of the purpose of this PR
Current failures
Pull Request Author
Reviewer