diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 444b849cd..e2d7d4445 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 3.7.13 +current_version = 3.7.16 commit = True tag = True diff --git a/.cookiecutterrc b/.cookiecutterrc index b96357fc4..ba4716559 100644 --- a/.cookiecutterrc +++ b/.cookiecutterrc @@ -54,7 +54,7 @@ default_context: sphinx_doctest: "no" sphinx_theme: "sphinx-py3doc-enhanced-theme" test_matrix_separate_coverage: "no" - version: 3.7.13 + version: 3.7.16 version_manager: "bump2version" website: "https://github.com/NREL" year_from: "2023" diff --git a/README.rst b/README.rst index b07f38bea..8ecffc5d8 100644 --- a/README.rst +++ b/README.rst @@ -56,9 +56,9 @@ Free software: `MIT license `__ :alt: Supported implementations :target: https://pypi.org/project/geophires-x -.. |commits-since| image:: https://img.shields.io/github/commits-since/softwareengineerprogrammer/GEOPHIRES-X/v3.7.13.svg +.. |commits-since| image:: https://img.shields.io/github/commits-since/softwareengineerprogrammer/GEOPHIRES-X/v3.7.16.svg :alt: Commits since latest release - :target: https://github.com/softwareengineerprogrammer/GEOPHIRES-X/compare/v3.7.13...main + :target: https://github.com/softwareengineerprogrammer/GEOPHIRES-X/compare/v3.7.16...main .. |docs| image:: https://readthedocs.org/projects/GEOPHIRES-X/badge/?style=flat :target: https://nrel.github.io/GEOPHIRES-X diff --git a/docs/conf.py b/docs/conf.py index 7f843f048..c6aa0309c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -18,7 +18,7 @@ year = '2025' author = 'NREL' copyright = f'{year}, {author}' -version = release = '3.7.13' +version = release = '3.7.16' pygments_style = 'trac' templates_path = ['./templates'] diff --git a/setup.py b/setup.py index d72ebfc12..f47a74903 100755 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ def read(*names, **kwargs): setup( name='geophires-x', - version='3.7.13', + version='3.7.16', license='MIT', description='GEOPHIRES is a free and open-source geothermal techno-economic simulator.', long_description='{}\n{}'.format( diff --git a/src/geophires_x/Economics.py b/src/geophires_x/Economics.py index 57961c201..2b92739bc 100644 --- a/src/geophires_x/Economics.py +++ b/src/geophires_x/Economics.py @@ -1221,7 +1221,13 @@ def __init__(self, model: Model): Max=100, UnitType=Units.ENERGYCOST, PreferredUnits=EnergyCostUnit.DOLLARSPERKWH, - CurrentUnits=EnergyCostUnit.DOLLARSPERKWH + CurrentUnits=EnergyCostUnit.DOLLARSPERKWH, + ToolTipText="The maximum price to which the electricity sale price can escalate. For example, if " + "Starting Electricity Sale Price = 0.10 USD/kWh and Electricity Escalation Rate = " + "0.01 USD/kWh/yr: Electricity Price will reach 0.15 USD/kWh after 4 years of escalation. " + "The price will then remain at 0.15 USD/kWh for the remaining years of the project lifetime. " + "If the Ending Electricity Sale Price is not reached by escalation during the project " + "lifetime, then the value will have no effect beyond allowing escalation to occur every year." ) self.ElecEscalationStart = self.ParameterDict[self.ElecEscalationStart.Name] = intParameter( "Electricity Escalation Start Year", @@ -1541,7 +1547,7 @@ def __init__(self, model: Model): CurrentUnits=EnergyCostUnit.DOLLARSPERMMBTU ) # $/MMBTU self.Cstim = self.OutputParameterDict[self.Cstim.Name] = OutputParameter( - Name="O&M Surface Plant costs", + Name="O&M Surface Plant costs", # FIXME wrong name - should be Stimulation Costs UnitType=Units.CURRENCY, PreferredUnits=CurrencyUnit.MDOLLARS, CurrentUnits=CurrencyUnit.MDOLLARS diff --git a/src/geophires_x/OutputsS_DAC_GT.py b/src/geophires_x/OutputsS_DAC_GT.py index b92d83e80..cf29b9a8d 100644 --- a/src/geophires_x/OutputsS_DAC_GT.py +++ b/src/geophires_x/OutputsS_DAC_GT.py @@ -27,35 +27,41 @@ def PrintOutputs(self, model) -> tuple: sdac_results: list[OutputTableItem] = [] f.write(NL) f.write(NL) - f.write(" ***S_DAC_GT ECONOMICS***" + NL) + f.write(" ***S-DAC-GT ECONOMICS***\n") f.write(NL) f.write(NL) - f.write(f" S-DAC-GT Report: Levelized Cost of Direct Air Capture (LCOD)" + NL) + + msdac = model.sdacgteconomics + + f.write(f" S-DAC-GT Report: Levelized Cost of Direct Air Capture (LCOD)\n") sdac_results.append(OutputTableItem('S-DAC-GT Report: Levelized Cost of Direct Air Capture (LCOD)')) - f.write(f" Using grid-based electricity only: {model.sdacgteconomics.LCOD_elec.value:10.2f} " + model.sdacgteconomics.LCOD_elec.PreferredUnits.value + NL) - sdac_results.append(OutputTableItem('Using grid-based electricity only', '{0:10.2f}'.format(model.sdacgteconomics.LCOD_elec.value), model.sdacgteconomics.LCOD_elec.PreferredUnits.value)) - f.write(f" Using natural gas only: {model.sdacgteconomics.LCOD_ng.value:10.2f} " + model.sdacgteconomics.LCOD_ng.PreferredUnits.value + NL) - sdac_results.append(OutputTableItem('Using natural gas only', '{0:10.2f}'.format(model.sdacgteconomics.LCOD_ng.value), model.sdacgteconomics.LCOD_ng.PreferredUnits.value)) - f.write(f" Using geothermal energy only: {model.sdacgteconomics.LCOD_geo.value:10.2f} " + model.sdacgteconomics.LCOD_geo.PreferredUnits.value + NL + NL) - sdac_results.append(OutputTableItem('Using geothermal energy only', '{0:10.2f}'.format(model.sdacgteconomics.LCOD_geo.value), model.sdacgteconomics.LCOD_geo.PreferredUnits.value)) - f.write(f" S-DAC-GT Report: CO2 Intensity of process (percent of CO2 mitigated that is emitted by S-DAC process)" + NL) + lcod_prefix = 'LCOD' + f.write(f" {lcod_prefix} using grid-based electricity only: {model.sdacgteconomics.LCOD_elec.value:10.2f} {msdac.LCOD_elec.PreferredUnits.value}\n") + sdac_results.append(OutputTableItem(f'Using grid-based electricity only', '{0:10.2f}'.format(msdac.LCOD_elec.value), msdac.LCOD_elec.PreferredUnits.value)) + f.write(f" {lcod_prefix} using natural gas only: {model.sdacgteconomics.LCOD_ng.value:10.2f} {msdac.LCOD_ng.PreferredUnits.value}\n") + sdac_results.append(OutputTableItem('Using natural gas only', '{0:10.2f}'.format(model.sdacgteconomics.LCOD_ng.value), msdac.LCOD_ng.PreferredUnits.value)) + f.write(f" {lcod_prefix} using geothermal energy only: {model.sdacgteconomics.LCOD_geo.value:10.2f} {msdac.LCOD_geo.PreferredUnits.value}\n\n") + sdac_results.append(OutputTableItem(f'Using geothermal energy only', '{0:10.2f}'.format(msdac.LCOD_geo.value), msdac.LCOD_geo.PreferredUnits.value)) + + f.write(f" S-DAC-GT Report: CO2 Intensity of process (percent of CO2 mitigated that is emitted by S-DAC process)\n") sdac_results.append(OutputTableItem('S-DAC-GT Report: CO2 Intensity of process (percent of CO2 mitigated that is emitted by S-DAC process)')) - f.write(f" Using grid-based electricity only: {model.sdacgteconomics.CO2total_elec.value*100.0:10.2f}%" + NL) - sdac_results.append(OutputTableItem('Using grid-based electricity only', '{0:10.2f}'.format(model.sdacgteconomics.CO2total_elec.value*100.0), '%')) - f.write(f" Using natural gas only: {model.sdacgteconomics.CO2total_ng.value*100:10.2f}%" + NL) - sdac_results.append(OutputTableItem('Using natural gas only', '{0:10.2f}'.format(model.sdacgteconomics.CO2total_ng.value*100.0), '%')) - f.write(f" Using geothermal energy only: {model.sdacgteconomics.CO2total_geo.value*100:10.2f}%" + NL + NL) - sdac_results.append(OutputTableItem('Using geothermal energy only', '{0:10.2f}'.format(model.sdacgteconomics.CO2total_geo.value*100.0), '%')) - f.write(f" Geothermal LCOH: {model.sdacgteconomics.LCOH.value:10.4f} " + model.sdacgteconomics.LCOH.PreferredUnits.value + NL) - sdac_results.append(OutputTableItem('Geothermal LCOH', '{0:10.4f}'.format(model.sdacgteconomics.LCOH.value), model.sdacgteconomics.LCOH.PreferredUnits.value)) - f.write(f" Geothermal Ratio (electricity vs heat):{model.sdacgteconomics.percent_thermal_energy_going_to_heat.value*100:10.4f}%" + NL) - sdac_results.append(OutputTableItem('Geothermal Ratio (electricity vs heat)', '{0:10.4f}'.format(model.sdacgteconomics.percent_thermal_energy_going_to_heat.value*100.0), '%')) - f.write(f" Percent Energy Devoted To Process: {model.sdacgteconomics.EnergySplit.value*100:10.4f}%" + NL + NL) - sdac_results.append(OutputTableItem('Percent Energy Devoted To Process', '{0:10.4f}'.format(model.sdacgteconomics.EnergySplit.value*100.0), '%')) - f.write(f" Total Tonnes of CO2 Captured: {model.sdacgteconomics.CarbonExtractedTotal.value:,.2f} " + model.sdacgteconomics.CarbonExtractedTotal.PreferredUnits.value + NL) - sdac_results.append(OutputTableItem('Total Tonnes of CO2 Captured', '{0:,.2f}'.format(model.sdacgteconomics.CarbonExtractedTotal.value), model.sdacgteconomics.CarbonExtractedTotal.PreferredUnits.value)) - f.write(f" Total Cost of Capture: {model.sdacgteconomics.S_DAC_GTCummCashFlow.value[len(model.sdacgteconomics.S_DAC_GTCummCashFlow.value)-1]:,.2f} " + model.sdacgteconomics.S_DAC_GTCummCashFlow.PreferredUnits.value + NL) - sdac_results.append(OutputTableItem('Total Cost of Capture', '{0:,.2f}'.format(model.sdacgteconomics.S_DAC_GTCummCashFlow.value[len(model.sdacgteconomics.S_DAC_GTCummCashFlow.value)-1]), model.sdacgteconomics.S_DAC_GTCummCashFlow.PreferredUnits.value)) + co2i_prefix = 'CO2 Intensity' + f.write(f" {co2i_prefix} using grid-based electricity only: {msdac.CO2total_elec.value*100.0:10.2f} %\n") # TODO CurrentUnits + sdac_results.append(OutputTableItem('Using grid-based electricity only', '{0:10.2f}'.format(msdac.CO2total_elec.value*100.0), '%')) + f.write(f" {co2i_prefix} using natural gas only: {msdac.CO2total_ng.value*100:10.2f} %\n") # TODO CurrentUnits + sdac_results.append(OutputTableItem('Using natural gas only', '{0:10.2f}'.format(msdac.CO2total_ng.value*100.0), '%')) + f.write(f" {co2i_prefix} using geothermal energy only: {msdac.CO2total_geo.value*100:10.2f} %\n\n") # TODO CurrentUnits + sdac_results.append(OutputTableItem('Using geothermal energy only', '{0:10.2f}'.format(msdac.CO2total_geo.value*100.0), '%')) + f.write(f" Geothermal LCOH: {msdac.LCOH.value:10.4f} {msdac.LCOH.PreferredUnits.value}\n") + sdac_results.append(OutputTableItem('Geothermal LCOH', '{0:10.4f}'.format(msdac.LCOH.value), msdac.LCOH.PreferredUnits.value)) + f.write(f" Geothermal Ratio (electricity vs heat):{msdac.percent_thermal_energy_going_to_heat.value*100:10.4f} %\n") # TODO CurrentUnits + sdac_results.append(OutputTableItem('Geothermal Ratio (electricity vs heat)', '{0:10.4f}'.format(msdac.percent_thermal_energy_going_to_heat.value*100.0), '%')) + f.write(f" Percent Energy Devoted To Process: {msdac.EnergySplit.value*100:10.4f} %\n\n") # TODO CurrentUnits + sdac_results.append(OutputTableItem('Percent Energy Devoted To Process', '{0:10.4f}'.format(msdac.EnergySplit.value*100.0), '%')) + f.write(f" Total Tonnes of CO2 Captured: {msdac.CarbonExtractedTotal.value:,.2f} {msdac.CarbonExtractedTotal.PreferredUnits.value}\n") + sdac_results.append(OutputTableItem('Total Tonnes of CO2 Captured', '{0:,.2f}'.format(msdac.CarbonExtractedTotal.value), msdac.CarbonExtractedTotal.PreferredUnits.value)) + f.write(f" Total Cost of Capture: {msdac.S_DAC_GTCummCashFlow.value[len(msdac.S_DAC_GTCummCashFlow.value)-1]:,.2f} {msdac.S_DAC_GTCummCashFlow.PreferredUnits.value}\n") + sdac_results.append(OutputTableItem('Total Cost of Capture', '{0:,.2f}'.format(msdac.S_DAC_GTCummCashFlow.value[len(msdac.S_DAC_GTCummCashFlow.value)-1]), msdac.S_DAC_GTCummCashFlow.PreferredUnits.value)) f.write(NL) # Build the data frame to hold the SDAC result profile @@ -77,9 +83,9 @@ def PrintOutputs(self, model) -> tuple: f.write(NL) f.write(" **********************" + NL) - f.write(" * S_DAC_GT PROFILE *" + NL) + f.write(" * S-DAC-GT PROFILE *" + NL) f.write(" **********************" + NL) - f.write("Year Carbon Cumm. Carbon S_DAC_GT S_DAC_GT Cumm. Cumm. Cost" + NL) + f.write("Year Carbon Cumm. Carbon S-DAC-GT S-DAC-GT Cumm. Cumm. Cost" + NL) f.write("Since Captured Captured Annual Cost Cash Flow Cost Per Tonne" + NL) f.write("Start ("+model.sdacgteconomics.CarbonExtractedAnnually.PreferredUnits.value + ") ("+model.sdacgteconomics.S_DAC_GTCummCarbonExtracted.PreferredUnits.value + @@ -93,11 +99,13 @@ def PrintOutputs(self, model) -> tuple: except BaseException as ex: tb = sys.exc_info()[2] + msg = "Error: GEOPHIRES failed to Failed to write the output file. Exiting...Line %i" % tb.tb_lineno + print(str(ex)) - print("Error: GEOPHIRES failed to Failed to write the output file. Exiting....Line %i" % tb.tb_lineno) + print(msg) model.logger.critical(str(ex)) - model.logger.critical("Error: GEOPHIRES failed to Failed to write the output file. Exiting....Line %i" % tb.tb_lineno) - sys.exit() + model.logger.critical(msg) + raise RuntimeError(msg, e) model.logger.info(f'Complete {str(__class__)}: {__name__}') diff --git a/src/geophires_x/__init__.py b/src/geophires_x/__init__.py index 475a8dce3..687f883de 100644 --- a/src/geophires_x/__init__.py +++ b/src/geophires_x/__init__.py @@ -1 +1 @@ -__version__ = '3.7.13' +__version__ = '3.7.16' diff --git a/src/geophires_x_client/geophires_x_result.py b/src/geophires_x_client/geophires_x_result.py index 5628c1e5b..cbaec5c4c 100644 --- a/src/geophires_x_client/geophires_x_result.py +++ b/src/geophires_x_client/geophires_x_result.py @@ -98,6 +98,19 @@ class GeophiresXResult: 'Project MOIC (including carbon credit)', 'Project Payback Period (including carbon credit)', ], + 'S-DAC-GT ECONOMICS': [ + # TODO S-DAC-GT Report sub-titles as string value fields + 'LCOD using grid-based electricity only', + 'LCOD using natural gas only', + 'LCOD using geothermal energy only', + 'CO2 Intensity using grid-based electricity only', + 'CO2 Intensity using natural gas only', + 'CO2 Intensity using geothermal energy only', + 'Geothermal LCOH', + 'Geothermal Ratio (electricity vs heat)', + 'Percent Energy Devoted To Process', + 'Total Cost of Capture', + ], 'ENGINEERING PARAMETERS': [ 'Number of Production Wells', 'Number of Injection Wells', @@ -359,6 +372,10 @@ def __init__(self, output_file_path, logger_name=None): if ccus_profile is not None: self.result['CCUS PROFILE'] = ccus_profile + sdacgt_profile = self._get_sdacgt_profile() + if sdacgt_profile is not None: + self.result['S-DAC-GT PROFILE'] = sdacgt_profile + self.result['metadata'] = {'output_file_path': self.output_file_path} for metadata_field in GeophiresXResult._METADATA_FIELDS: self.result['metadata'][metadata_field] = self._get_equal_sign_delimited_field(metadata_field) @@ -583,6 +600,27 @@ def extract_table_header(lines: list) -> list: self._logger.debug(f'Failed to get extended economic profile: {e}') return None + def _get_sdacgt_profile(self): + def extract_table_header(lines: list) -> list: + # Tried various regexy approaches to extract this programmatically but landed on hard-coding. + return [ + 'Year Since Start', + 'Carbon Captured (tonne/yr)', + 'Cumm. Carbon Captured (tonne)', + 'S-DAC-GT Annual Cost (USD/yr)', + 'S-DAC-GT Cumm. Cash Flow (USD)', + 'Cumm. Cost Per Tonne (USD/tonne)', + ] + + try: + lines = self._get_profile_lines('S-DAC-GT PROFILE') + profile = [extract_table_header(lines)] + profile.extend(self._extract_addons_style_table_data(lines)) + return profile + except BaseException as e: + self._logger.debug(f'Failed to get S-DAC-GT profile: {e}') + return None + def _get_ccus_profile(self): """ FIXME TODO - transform from revenue & cashflow if present (CCUS profile replaced by revenue & cashflow @@ -669,10 +707,11 @@ def _get_data_from_profile_lines(self, profile_lines): return data def _parse_number(self, number_str, field='string') -> int | float: - if number_str == 'N/A': + if number_str == 'N/A' or number_str is None: return None try: + number_str = number_str.replace(',', '') if '.' in number_str: # TODO should probably ideally use decimal.Decimal to preserve precision, # i.e. 1.00 for USD instead of 1.0 diff --git a/src/geophires_x_schema_generator/geophires-request.json b/src/geophires_x_schema_generator/geophires-request.json index 58657a73b..53204fd73 100644 --- a/src/geophires_x_schema_generator/geophires-request.json +++ b/src/geophires_x_schema_generator/geophires-request.json @@ -1956,7 +1956,7 @@ "maximum": 100 }, "Ending Electricity Sale Price": { - "description": "", + "description": "The maximum price to which the electricity sale price can escalate. For example, if Starting Electricity Sale Price = 0.10 USD/kWh and Electricity Escalation Rate = 0.01 USD/kWh/yr: Electricity Price will reach 0.15 USD/kWh after 4 years of escalation. The price will then remain at 0.15 USD/kWh for the remaining years of the project lifetime. If the Ending Electricity Sale Price is not reached by escalation during the project lifetime, then the value will have no effect beyond allowing escalation to occur every year.", "type": "number", "units": "USD/kWh", "category": "Economics", diff --git a/tests/examples/S-DAC-GT.out b/tests/examples/S-DAC-GT.out index 499441831..7161cd7d3 100644 --- a/tests/examples/S-DAC-GT.out +++ b/tests/examples/S-DAC-GT.out @@ -4,10 +4,10 @@ Simulation Metadata ---------------------- - GEOPHIRES Version: 3.7.1 - Simulation Date: 2025-01-22 - Simulation Time: 10:48 - Calculation Time: 0.107 sec + GEOPHIRES Version: 3.7.15 + Simulation Date: 2025-02-27 + Simulation Time: 10:36 + Calculation Time: 0.100 sec ***SUMMARY OF RESULTS*** @@ -246,31 +246,31 @@ ________________________________________________________________________________ - ***S_DAC_GT ECONOMICS*** + ***S-DAC-GT ECONOMICS*** S-DAC-GT Report: Levelized Cost of Direct Air Capture (LCOD) - Using grid-based electricity only: 387.69 USD/tonne - Using natural gas only: 312.00 USD/tonne - Using geothermal energy only: 288.87 USD/tonne + LCOD using grid-based electricity only: 387.69 USD/tonne + LCOD using natural gas only: 312.00 USD/tonne + LCOD using geothermal energy only: 288.87 USD/tonne S-DAC-GT Report: CO2 Intensity of process (percent of CO2 mitigated that is emitted by S-DAC process) - Using grid-based electricity only: 94.52% - Using natural gas only: 64.85% - Using geothermal energy only: 36.91% + CO2 Intensity using grid-based electricity only: 94.52 % + CO2 Intensity using natural gas only: 64.85 % + CO2 Intensity using geothermal energy only: 36.91 % Geothermal LCOH: 0.0017 USD/kWh - Geothermal Ratio (electricity vs heat): 20.7259% - Percent Energy Devoted To Process: 50.0000% + Geothermal Ratio (electricity vs heat): 20.7259 % + Percent Energy Devoted To Process: 50.0000 % Total Tonnes of CO2 Captured: 2,246,284.10 tonne Total Cost of Capture: 499,311,405.59 USD ********************** - * S_DAC_GT PROFILE * + * S-DAC-GT PROFILE * ********************** -Year Carbon Cumm. Carbon S_DAC_GT S_DAC_GT Cumm. Cumm. Cost +Year Carbon Cumm. Carbon S-DAC-GT S-DAC-GT Cumm. Cumm. Cost Since Captured Captured Annual Cost Cash Flow Cost Per Tonne Start (tonne/yr) (tonne) (USD/yr) (USD) (USD/tonne) 1 78,330.80 78,330.80 17,411,627.98 17,411,627.98 222.28 diff --git a/tests/test_geophires_x_client.py b/tests/test_geophires_x_client.py index 028d26f16..d3e2cfc23 100644 --- a/tests/test_geophires_x_client.py +++ b/tests/test_geophires_x_client.py @@ -528,3 +528,38 @@ def test_parse_chp_percent_cost_allocation(self): def test_parse_annualized_capital_costs(self): result = GeophiresXResult(self._get_test_file_path('examples/example1_addons.out')) self.assertIsNotNone(result.result['CAPITAL COSTS (M$)']['Annualized capital costs']['value']) + + def test_parse_number_with_commas(self): + result = GeophiresXResult(self._get_test_file_path('examples/S-DAC-GT.out')) + sdac_e = result.result['S-DAC-GT ECONOMICS'] + self.assertAlmostEqualWithinPercentage(499_311_405.59, sdac_e['Total Cost of Capture']['value']) + + self.assertAlmostEqualWithinPercentage(0.0017, sdac_e['Geothermal LCOH']['value']) + + self.assertAlmostEqualWithinPercentage(20.7259, sdac_e['Geothermal Ratio (electricity vs heat)']['value']) + + def test_parse_sdacgt_profile(self): + result = GeophiresXResult(self._get_test_file_path('examples/S-DAC-GT.out')) + sdacgt_profile = result.result['S-DAC-GT PROFILE'] + self.assertIsNotNone(sdacgt_profile) + self.assertEqual( + sdacgt_profile[0], + [ + 'Year Since Start', + 'Carbon Captured (tonne/yr)', + 'Cumm. Carbon Captured (tonne)', + 'S-DAC-GT Annual Cost (USD/yr)', + 'S-DAC-GT Cumm. Cash Flow (USD)', + 'Cumm. Cost Per Tonne (USD/tonne)', + ], + ) + + # Values below need to be synchronized if S-DAC-GT example output values change. + self.assertEqual(sdacgt_profile[1], [1, 78330.8, 78330.8, 17411627.98, 17411627.98, 222.28]) + + self.assertEqual( + sdacgt_profile[15], + [15, 76263.89, 1167207.48, 16952186.81, 259450710.33, 222.28], + ) + + self.assertEqual(sdacgt_profile[30], [30, 61974.61, 2246284.1, 13775920.11, 499311405.59, 222.28])