Calculations Service

CalculationService provides access to functionality related to calculations in windPRO. The CalculationService gives access to common functionalities for all calculations, e.g. generating reports or starting the calculation. Additionally, some calculations have specialized services to access the properties of this calculation. For those calculation windPRO scripting offers access via specialized services. All calculation types available via windPRO scripting are listed below:

Calculation types in windPRO scripting

Calculation type

Description

Scripting Service

CalcFlow

Flowrequest file for export

not available

CalcMesoPoint

Mesoscale data on demand

not available

CalcMCP

MCP calculation

CalcMCPService

CalcMCP2005

MCP version 2005

not available

CalcNoise

Noise calculation from DECIBEL

CalcDecibelService

CalcPark

PARK calculation

CalcParkService

CalcResource

RESOURCE calculation

CalcResourceService

CalcShadow

Shadow calculation from ZVI

CalcShadowService

CalcSiteCompliance

Site compliance calculation

not available

CalcStatgen

STATGEN wind statistic

CalcStatgenService

CalcWaspCfd

WAsP CFD calculation

not available

CalcZVI

Visual Impact calculations

CalcZVIService

In the following a few examples are give. To use the service you need to call get_service from the WindProApi class with the service as a parameter.

import os
from windproapi.utils import get_windpro_sample_path
from windproapi import WindProApi

_windproapi = WindProApi()
_windproapi.start_windpro_random_port()
calculation_service = _windproapi.get_service('CalculationService')

To get all calculation of a specific type use GetCalcs() with the calculation type as a parameter.

project_service = _windproapi.get_service('ProjectService')
working_dir = os.path.join(get_windpro_sample_path("4.0"), 'New Salem\\4.0')
project_path = os.path.join(working_dir, 'New Salem.w40p')
project_service.LoadFromFile(project_path)

all_park_calcs = calculation_service.GetCalcs('CalcPark')
print(all_park_calcs)

# Output:
"""
{
'Handle': 1102300,
'Name': 'PARK: new energy concept-CFD based',
'ModNum': 110,
'CalcNum': 1,
'CalcType': 'CalcPark'
}...
"""

To create an empty calculation use CreateEmpty with the calculation as the parameter

Handle = calculation_service.CreateEmpty('CalcPark')

You can save calculations to files with SaveToFile. It needs two parameters. The first has to be the handle of the calculation you want to save. The second parameter is the path with filename, where you want to save it.

Path = "C:/Calculations/FILENAME.xml"

calculation_service.SaveToFile(Handle, Path)

If you have a calculation saved, you can create a calculation in WindPro from a file with CreateFromFile(). It takes in two parameters, the calculation type and the path to the file.

Warning

To ensure scripts are not interrupted pop up windows are suppressed as much as possible. If you will choose a file name that is not compatible with Windows naming restrictions the file cannot be generated but no warning or error message will appear.

Path = "C:/Calculations/FILENAME.xml"

# calcFromFile will store a handle for the new calculation
calcFromFile = calculation_service.CreateFromFile('CalcPark', Path)

You can clone a calculation with Clone, this method needs the handle of the calculation you want to clone as a parameter. This is especially useful for running many calculations with different sets of inputs, for example for sensitivity studies.

# ClonedCalc will store a new handle for the new calculation
ClonedCalc = calculation_service.Clone(Handle)

Results from a calculation are only available as a result to file. GetResToFiles result to file options are that are available for that calculation. To save a result to a file use ResultToFile. It takes in three parameters, the handle for the calculation, the calculation type, and the path where it should be saved.

ResToFile = calculation_service.GetResToFiles(Handle)
calculation_service.ResultToFile(Handle, 'Park time variation', Path)

It is possible to automatically create PDF reports using scripting. To get all available reports of a calculation use GetReports with the handle of the calculation as a parameter.

# Reports stores information of all the reports beloning to the calculation
Reports = calculation_service.GetReports(Handle)
print(Reports)
# Output
"""
{
'ID': '40',
'Name': 'Scaling info',
'IsResToFile': False
}...
"""

To save a report to a pdf file use SaveReportToPdf with the handle for the calculation as first parameter, the reportID as the second parameter, and the path you want to save it to as the last parameter.

reportID = 24
# SaveToPdf stores a true value if succes
SaveToPdf = calculation_service.SaveReportAsPdf(Handle, reportID, path)

For changing a calculation with it specialized service it need to be opened. This is equivalent to opening the calculation in windPRO but the calculation will not open in the GUI. While a calculation is open for editing, it is not possible to to use methods ResultToFile and SaveReportAsPdf. Trying those methods will result in error messages in your script. You should also only open one calculation at a time within scripting.

Warning

You can still open the same calculation from the GUI the same time as scripting. This should be avoided to prevent unexpected behaviour.

For modifying the calculation you need to load it with the respective calculation service. Modifications are done with the respective Get... and Set... methods The workflow on a short example code is illustrated below for the ParkService:

from windproapi import nan_to_skipvalue

calc_park_service = _windproapi.get_service('CalcParkService')

Handle = calculation_service.CreateEmpty('CalcPark')
calculation_service.OpenCalcForEdit(Handle)
park_calc = calc_park_service.GetParkCalc()
park_calc.WakeModelType = "ParkWakeModelNOJensenPark2"
nan_to_skipvalue(park_calc)
calc_park_service.SetParkCalc(park_calc)
calculation_service.CloseCalc(True)
calculation_service.Calculate(Handle)

The above examples are for illustration only and do not give a runnable example without the right imports. You will need to download the sample project New Salem from windPRO. The example accesses some calculations, gives the meta-information, recalculates an example, and saves some reports.

"""
Copyright 2023 EMD International
License for this script: MIT https://opensource.org/license/mit/
License for windPRO commercial software: https://www.emd-international.com/contact-us/general-terms-conditions-sale/
"""

import os
from pprint import pprint
from windproapi.utils import get_windpro_sample_path
from windproapi import WindProApi
from windproapi import nan_to_skipvalue

# Opening windPRO
_windproapi = WindProApi()
working_dir = os.path.join(get_windpro_sample_path('4.0'), 'New Salem\\4.0')
project_path = os.path.join(working_dir, 'New Salem.w40p')

_windproapi.start_windpro_random_port()

# Services
project_service = _windproapi.get_service('ProjectService')
calculation_service = _windproapi.get_service('CalculationService')
calc_park_service = _windproapi.get_service('CalcParkService')

# Open project
project_service.LoadFromFile(filename=project_path)

# Printing all the calculations present in the project
for i in range(calculation_service.GetCount()):
    print(calculation_service.GetCalc(ndx=i))

# Finding only PARK calculations. This is the CalcType that was available in all calculations
all_park_calcs = calculation_service.GetCalcs(calcType='CalcPark')
print('All available PARK calculations')
print(all_park_calcs)

# Now to exporting and importing files.
# Getting the handle of the first PARK calculation.
handle = all_park_calcs[1]['Handle']
name = all_park_calcs[1]['Name']
path_export = os.path.join(working_dir, 'park_result.xml')
calculation_service.SaveToFile(handle=handle, filename=path_export)

# Recalculating the PARK results. This does not change the result as we have not changed any of the inputs.
calculation_service.Calculate(handle=handle)

# Cloning one result. Can be useful if results should be
cloned_calc = calculation_service.Clone(handle=handle)

# Saving the data in the result to a file.
path_result = os.path.join(working_dir, 'park_result.csv')
res_to_file = calculation_service.GetResToFiles(handle=handle)
print(f'Result {res_to_file}')
calculation_service.ResultToFile(handle=handle, id='Park time variation', filename=path_result)

# Check what reports are available and export the main result
reports = calculation_service.GetReports(handle=handle)
reports_dict = {d['Name']: d['ID'] for d in reports}
pprint(reports_dict)
calculation_service.SaveReportAsPdf(handle=handle, id=reports_dict['Main Result'],
                                    filename=os.path.join(working_dir, f'Main_result_{name}.pdf'))
# All reports are exported in a combined pdf
calculation_service.SaveReportAsPdf(handle=handle, id=-1, filename=os.path.join(working_dir, f'All_result_{name}.pdf'))

# Making a new calculation within the project that can later be manipulated.
handle_new_park = calculation_service.CreateEmpty(calcType='CalcPark')
# To change settings in a calculation it need to be opened.
# More specific examples how to modify calucations are found in respective calculation service.
calculation_service.OpenCalcForEdit(handle=handle_new_park)
# calculations need to be closed before interacting with the GUI again.
calculation_service.CloseCalc(save=True)