#
# This code has been auto-generated by the MDE Workbench
# Version: 3.1.28.
#
# File: calculations.py
# Date: 2023-04-04 12:37
# Time: 12:37
#


import requests
import jsons
from requests import Response

from .constants import *
from .enums import *
from .entities import *
from .utilities import getAccessToken, getAnalyticsApiTarget, getClientAliasId


class Calculation(object):

    # Constructor.
    def __init__(self):

        # Calculation result code.
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.elapsedTime = 0.0

    # Post json to url and time the call
    def post_request(self, url: str, data: str, accessToken: str) -> Response:

        headers = {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer {}'.format(accessToken)
        }

        response = requests.post(url, data=data, headers=headers, verify = 'localhost' not in url)

        return response

    # Print out the messages
    def print_messages(self):

        for message in self.messages:
            print('     {0}'.format(message))

# Request object for a late explosion calculation.
class LateExplosionCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Material with post-discharge composition
        self.material = Material()

        # Dispersion scalar outputs
        self.scalarUdmOutputs = ScalarUdmOutputs()

        # Weather
        self.weather = Weather()

        # Cloud definition
        self.dispersionRecords = list[DispersionRecord]()

        # Number of dispersion records
        self.dispersionRecordCount = 0

        # Substrate
        self.substrate = Substrate()

        # Specification of cloud view
        self.dispersionOutputConfig = DispersionOutputConfig()

        # Explosion output configuration
        self.explosionOutputConfig = ExplosionOutputConfig()

        # Explosion parameters
        self.explosionParameters = ExplosionParameters()

        # Explosion confined volumes
        self.explosionConfinedVolumes = list[ExplosionConfinedVolume]()

        # Number of confined explosion sources
        self.explosionConfinedVolumeCount = 0

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()


# Late explosion calculation class.
class LateExplosionCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Material with post-discharge composition
        self.material = Material()

        # Dispersion scalar outputs
        self.scalarUdmOutputs = ScalarUdmOutputs()

        # Weather
        self.weather = Weather()

        # Cloud definition
        self.dispersionRecords = list[DispersionRecord]()


        # Substrate
        self.substrate = Substrate()

        # Specification of cloud view
        self.dispersionOutputConfig = DispersionOutputConfig()

        # Explosion output configuration
        self.explosionOutputConfig = ExplosionOutputConfig()

        # Explosion parameters
        self.explosionParameters = ExplosionParameters()

        # Explosion confined volumes
        self.explosionConfinedVolumes = list[ExplosionConfinedVolume]()


        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Calculation outputs.
        # Uniform confined explosion overpressure result
        self.explosionUnifConfOverpressureResult = ExplosionOverpressureResult()

        # Unconfined explosion overpressure result
        self.explosionUnconfOverpressureResult = ExplosionOverpressureResult()

        # Eror code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # LateExplosion calculation run method.
    def run(self) -> ResultCode:

        # Create the late explosion request.
        lateExplosionCalculationRequest = LateExplosionCalculationRequest()

        # Initialise the member properties.

        lateExplosionCalculationRequest.material = self.material
        lateExplosionCalculationRequest.scalarUdmOutputs = self.scalarUdmOutputs
        lateExplosionCalculationRequest.weather = self.weather
        lateExplosionCalculationRequest.dispersionRecords = self.dispersionRecords
        lateExplosionCalculationRequest.dispersionRecordCount = len(self.dispersionRecords)
        lateExplosionCalculationRequest.substrate = self.substrate
        lateExplosionCalculationRequest.dispersionOutputConfig = self.dispersionOutputConfig
        lateExplosionCalculationRequest.explosionOutputConfig = self.explosionOutputConfig
        lateExplosionCalculationRequest.explosionParameters = self.explosionParameters
        lateExplosionCalculationRequest.explosionConfinedVolumes = self.explosionConfinedVolumes
        lateExplosionCalculationRequest.explosionConfinedVolumeCount = len(self.explosionConfinedVolumes)
        lateExplosionCalculationRequest.dispersionParameters = self.dispersionParameters

        requestJson = jsons.dumps(lateExplosionCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatelateexplosion?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            lateExplosionCalculationResponse = LateExplosionCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                lateExplosionCalculationResponse.initialiseFromDictionary(json)

                self.explosionUnifConfOverpressureResult = lateExplosionCalculationResponse.explosionUnifConfOverpressureResult
                self.explosionUnconfOverpressureResult = lateExplosionCalculationResponse.explosionUnconfOverpressureResult
                self.resultCode = lateExplosionCalculationResponse.resultCode
                self.messages = lateExplosionCalculationResponse.messages
                self.calculationElapsedTime = lateExplosionCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the LateExplosion calculation object to print itself.
    def print(self):

        # LateExplosion
        print('** LateExplosion')

        # material
        self.material.print()

        # scalarUdmOutputs
        self.scalarUdmOutputs.print()

        # weather
        self.weather.print()

        for item in self.dispersionRecords:
            item.print()


        # substrate
        self.substrate.print()

        # dispersionOutputConfig
        self.dispersionOutputConfig.print()

        # explosionOutputConfig
        self.explosionOutputConfig.print()

        # explosionParameters
        self.explosionParameters.print()

        for item in self.explosionConfinedVolumes:
            item.print()


        # dispersionParameters
        self.dispersionParameters.print()

        # explosionUnifConfOverpressureResult
        self.explosionUnifConfOverpressureResult.print()

        # explosionUnconfOverpressureResult
        self.explosionUnconfOverpressureResult.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a late explosion calculation.
class LateExplosionCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Uniform confined explosion overpressure result
        self.explosionUnifConfOverpressureResult = ExplosionOverpressureResult()

        # Unconfined explosion overpressure result
        self.explosionUnconfOverpressureResult = ExplosionOverpressureResult()

        # Eror code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Uniform confined explosion overpressure result
        self.explosionUnifConfOverpressureResult.initialiseFromDictionary(data['explosionUnifConfOverpressureResult'])

        # Unconfined explosion overpressure result
        self.explosionUnconfOverpressureResult.initialiseFromDictionary(data['explosionUnconfOverpressureResult'])

        # Eror code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a vessel leak flammable linked run calculation.
class VesselLeakFlammableLinkedRunCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Vessel definition
        self.vessel = Vessel()

        # Leak scenario
        self.leak = Leak()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # The dispersing surface
        self.substrate = Substrate()

        # Weather definition
        self.weather = Weather()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Concentration at which the dispersion calculations will terminate (v/v fraction)
        self.endPointConcentration = 0.0

        # Fire model parameters
        self.flammableParameters = FlammableParameters()

        # Explosion parameters
        self.explosionParameters = ExplosionParameters()

        # Concentration levels
        self.dispersionOutputConfigs = list[DispersionOutputConfig]()

        # Number of concentration levels
        self.dispersionOutputConfigCount = 0

        # Radiation levels
        self.flammableOutputConfigs = list[FlammableOutputConfig]()

        # Number of radiation levels
        self.flammableOutputConfigCount = 0

        # Overpressure levels
        self.explosionOutputConfigs = list[ExplosionOutputConfig]()

        # Number of overpressure levels
        self.explosionOutputConfigCount = 0

        # Explosion confined volumes
        self.explosionConfinedVolumes = list[ExplosionConfinedVolume]()

        # Number of confined explosion sources
        self.explosionConfinedVolumeCount = 0


# Vessel leak flammable linked run calculation class.
class VesselLeakFlammableLinkedRunCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Vessel definition
        self.vessel = Vessel()

        # Leak scenario
        self.leak = Leak()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # The dispersing surface
        self.substrate = Substrate()

        # Weather definition
        self.weather = Weather()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Concentration at which the dispersion calculations will terminate (v/v fraction)
        self.endPointConcentration = 0.0

        # Fire model parameters
        self.flammableParameters = FlammableParameters()

        # Explosion parameters
        self.explosionParameters = ExplosionParameters()

        # Concentration levels
        self.dispersionOutputConfigs = list[DispersionOutputConfig]()


        # Radiation levels
        self.flammableOutputConfigs = list[FlammableOutputConfig]()


        # Overpressure levels
        self.explosionOutputConfigs = list[ExplosionOutputConfig]()


        # Explosion confined volumes
        self.explosionConfinedVolumes = list[ExplosionConfinedVolume]()


        # Calculation outputs.
        # Discharge data for table
        self.dischargeRecord = DischargeRecord()

        # Description for entry point parameter exitMaterial not found.
        self.exitMaterial = Material()

        # Description for entry point parameter dischargeResult not found.
        self.dischargeResult = DischargeResult()

        # Distances to jet fire radiation levels
        self.distancesToJetFireRadiation = []

        # Ellipses to jet fire radiation levels
        self.jetContourPoints = list[LocalPosition]()

        # Number of contour points for jet fire ellipses per radiation level
        self.nJetCountourPoints = []

        # Areas of jet fire ellipses
        self.areaEllipseJet = []

        # Distances to concentration levels
        self.distancesToConcentration = []

        # Concentration levels
        self.concentrationsUsed = []

        # Maximum concentration footprints at given concentration levels
        self.concContourPoints = list[LocalPosition]()

        # Number of contour points per concentration level
        self.nConcCountourPoints = []

        # Areas of maximum concentration footprints
        self.areaFootprintConc = []

        # Distances to pool fire radiation levels
        self.distancesToPoolFireRadiation = []

        # Ellipses to pool fire radiation levels
        self.poolContourPoints = list[LocalPosition]()

        # Number of contour points for pool fire ellipses per radiation level
        self.nPoolCountourPoints = []

        # Areas of pool fire ellipses
        self.areaEllipsePool = []

        # Explosion overpressure results
        self.explosionOverpressureResults = list[ExplosionOverpressureResult]()

        # Flame results for jet fire
        self.jetFireFlameResult = FlameResult()

        # Flame results for pool fire
        self.poolFireFlameResult = PoolFireFlameResult()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # VesselLeakFlammableLinkedRun calculation run method.
    def run(self) -> ResultCode:

        # Create the vessel leak flammable linked run request.
        vesselLeakFlammableLinkedRunCalculationRequest = VesselLeakFlammableLinkedRunCalculationRequest()

        # Initialise the member properties.

        vesselLeakFlammableLinkedRunCalculationRequest.vessel = self.vessel
        vesselLeakFlammableLinkedRunCalculationRequest.leak = self.leak
        vesselLeakFlammableLinkedRunCalculationRequest.dischargeParameters = self.dischargeParameters
        vesselLeakFlammableLinkedRunCalculationRequest.substrate = self.substrate
        vesselLeakFlammableLinkedRunCalculationRequest.weather = self.weather
        vesselLeakFlammableLinkedRunCalculationRequest.dispersionParameters = self.dispersionParameters
        vesselLeakFlammableLinkedRunCalculationRequest.endPointConcentration = self.endPointConcentration
        vesselLeakFlammableLinkedRunCalculationRequest.flammableParameters = self.flammableParameters
        vesselLeakFlammableLinkedRunCalculationRequest.explosionParameters = self.explosionParameters
        vesselLeakFlammableLinkedRunCalculationRequest.dispersionOutputConfigs = self.dispersionOutputConfigs
        vesselLeakFlammableLinkedRunCalculationRequest.dispersionOutputConfigCount = len(self.dispersionOutputConfigs)
        vesselLeakFlammableLinkedRunCalculationRequest.flammableOutputConfigs = self.flammableOutputConfigs
        vesselLeakFlammableLinkedRunCalculationRequest.flammableOutputConfigCount = len(self.flammableOutputConfigs)
        vesselLeakFlammableLinkedRunCalculationRequest.explosionOutputConfigs = self.explosionOutputConfigs
        vesselLeakFlammableLinkedRunCalculationRequest.explosionOutputConfigCount = len(self.explosionOutputConfigs)
        vesselLeakFlammableLinkedRunCalculationRequest.explosionConfinedVolumes = self.explosionConfinedVolumes
        vesselLeakFlammableLinkedRunCalculationRequest.explosionConfinedVolumeCount = len(self.explosionConfinedVolumes)

        requestJson = jsons.dumps(vesselLeakFlammableLinkedRunCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'vesselleakflammablelinkedrun?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            vesselLeakFlammableLinkedRunCalculationResponse = VesselLeakFlammableLinkedRunCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                vesselLeakFlammableLinkedRunCalculationResponse.initialiseFromDictionary(json)

                self.dischargeRecord = vesselLeakFlammableLinkedRunCalculationResponse.dischargeRecord
                self.exitMaterial = vesselLeakFlammableLinkedRunCalculationResponse.exitMaterial
                self.dischargeResult = vesselLeakFlammableLinkedRunCalculationResponse.dischargeResult
                self.distancesToJetFireRadiation = vesselLeakFlammableLinkedRunCalculationResponse.distancesToJetFireRadiation
                self.jetContourPoints = vesselLeakFlammableLinkedRunCalculationResponse.jetContourPoints
                self.nJetCountourPoints = vesselLeakFlammableLinkedRunCalculationResponse.nJetCountourPoints
                self.areaEllipseJet = vesselLeakFlammableLinkedRunCalculationResponse.areaEllipseJet
                self.distancesToConcentration = vesselLeakFlammableLinkedRunCalculationResponse.distancesToConcentration
                self.concentrationsUsed = vesselLeakFlammableLinkedRunCalculationResponse.concentrationsUsed
                self.concContourPoints = vesselLeakFlammableLinkedRunCalculationResponse.concContourPoints
                self.nConcCountourPoints = vesselLeakFlammableLinkedRunCalculationResponse.nConcCountourPoints
                self.areaFootprintConc = vesselLeakFlammableLinkedRunCalculationResponse.areaFootprintConc
                self.distancesToPoolFireRadiation = vesselLeakFlammableLinkedRunCalculationResponse.distancesToPoolFireRadiation
                self.poolContourPoints = vesselLeakFlammableLinkedRunCalculationResponse.poolContourPoints
                self.nPoolCountourPoints = vesselLeakFlammableLinkedRunCalculationResponse.nPoolCountourPoints
                self.areaEllipsePool = vesselLeakFlammableLinkedRunCalculationResponse.areaEllipsePool
                self.explosionOverpressureResults = vesselLeakFlammableLinkedRunCalculationResponse.explosionOverpressureResults
                self.jetFireFlameResult = vesselLeakFlammableLinkedRunCalculationResponse.jetFireFlameResult
                self.poolFireFlameResult = vesselLeakFlammableLinkedRunCalculationResponse.poolFireFlameResult
                self.resultCode = vesselLeakFlammableLinkedRunCalculationResponse.resultCode
                self.messages = vesselLeakFlammableLinkedRunCalculationResponse.messages
                self.calculationElapsedTime = vesselLeakFlammableLinkedRunCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the VesselLeakFlammableLinkedRun calculation object to print itself.
    def print(self):

        # VesselLeakFlammableLinkedRun
        print('** VesselLeakFlammableLinkedRun')

        # vessel
        self.vessel.print()

        # leak
        self.leak.print()

        # dischargeParameters
        self.dischargeParameters.print()

        # substrate
        self.substrate.print()

        # weather
        self.weather.print()

        # dispersionParameters
        self.dispersionParameters.print()

        print(self.endPointConcentration)
        print('{0}\t{1}'.format('End point concentration', self.endPointConcentration))

        # flammableParameters
        self.flammableParameters.print()

        # explosionParameters
        self.explosionParameters.print()

        for item in self.dispersionOutputConfigs:
            item.print()


        for item in self.flammableOutputConfigs:
            item.print()


        for item in self.explosionOutputConfigs:
            item.print()


        for item in self.explosionConfinedVolumes:
            item.print()


        # dischargeRecord
        self.dischargeRecord.print()

        # exitMaterial
        self.exitMaterial.print()

        # dischargeResult
        self.dischargeResult.print()

        # distancesToJetFireRadiation
        for item in self.distancesToJetFireRadiation:
            print('{0}'.format(item))

        for jetContourPoint in self.jetContourPoints:
            jetContourPoint.print()

        # nJetCountourPoints
        for item in self.nJetCountourPoints:
            print('{0}'.format(item))

        # areaEllipseJet
        for item in self.areaEllipseJet:
            print('{0}'.format(item))

        # distancesToConcentration
        for item in self.distancesToConcentration:
            print('{0}'.format(item))

        # concentrationsUsed
        for item in self.concentrationsUsed:
            print('{0}'.format(item))

        for concContourPoint in self.concContourPoints:
            concContourPoint.print()

        # nConcCountourPoints
        for item in self.nConcCountourPoints:
            print('{0}'.format(item))

        # areaFootprintConc
        for item in self.areaFootprintConc:
            print('{0}'.format(item))

        # distancesToPoolFireRadiation
        for item in self.distancesToPoolFireRadiation:
            print('{0}'.format(item))

        for poolContourPoint in self.poolContourPoints:
            poolContourPoint.print()

        # nPoolCountourPoints
        for item in self.nPoolCountourPoints:
            print('{0}'.format(item))

        # areaEllipsePool
        for item in self.areaEllipsePool:
            print('{0}'.format(item))

        # explosionOverpressureResults
        for item in self.explosionOverpressureResults:
            item.print()

        # jetFireFlameResult
        self.jetFireFlameResult.print()

        # poolFireFlameResult
        self.poolFireFlameResult.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a vessel leak flammable linked run calculation.
class VesselLeakFlammableLinkedRunCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Discharge data for table
        self.dischargeRecord = DischargeRecord()

        # Description for entry point parameter exitMaterial not found.
        self.exitMaterial = Material()

        # Description for entry point parameter dischargeResult not found.
        self.dischargeResult = DischargeResult()

        # Distances to jet fire radiation levels
        self.distancesToJetFireRadiation = []

        # Ellipses to jet fire radiation levels
        self.jetContourPoints = list[LocalPosition]()

        # Number of contour points for jet fire ellipses per radiation level
        self.nJetCountourPoints = []

        # Areas of jet fire ellipses
        self.areaEllipseJet = []

        # Distances to concentration levels
        self.distancesToConcentration = []

        # Concentration levels
        self.concentrationsUsed = []

        # Maximum concentration footprints at given concentration levels
        self.concContourPoints = list[LocalPosition]()

        # Number of contour points per concentration level
        self.nConcCountourPoints = []

        # Areas of maximum concentration footprints
        self.areaFootprintConc = []

        # Distances to pool fire radiation levels
        self.distancesToPoolFireRadiation = []

        # Ellipses to pool fire radiation levels
        self.poolContourPoints = list[LocalPosition]()

        # Number of contour points for pool fire ellipses per radiation level
        self.nPoolCountourPoints = []

        # Areas of pool fire ellipses
        self.areaEllipsePool = []

        # Explosion overpressure results
        self.explosionOverpressureResults = list[ExplosionOverpressureResult]()

        # Flame results for jet fire
        self.jetFireFlameResult = FlameResult()

        # Flame results for pool fire
        self.poolFireFlameResult = PoolFireFlameResult()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Discharge data for table
        self.dischargeRecord.initialiseFromDictionary(data['dischargeRecord'])

        # Description for entry point parameter exitMaterial not found.
        self.exitMaterial.initialiseFromDictionary(data['exitMaterial'])

        # Description for entry point parameter dischargeResult not found.
        self.dischargeResult.initialiseFromDictionary(data['dischargeResult'])

        # Distances to jet fire radiation levels
        if data['distancesToJetFireRadiation'] != None:
            for dataItem in data['distancesToJetFireRadiation']:
                self.distancesToJetFireRadiation.append(float(dataItem))

        # Ellipses to jet fire radiation levels
        if data['jetContourPoints'] != None:
            for dataItem in data['jetContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.jetContourPoints.append(localPosition)

        # Number of contour points for jet fire ellipses per radiation level
        if data['nJetCountourPoints'] != None:
            for dataItem in data['nJetCountourPoints']:
                self.nJetCountourPoints.append(int(dataItem))

        # Areas of jet fire ellipses
        if data['areaEllipseJet'] != None:
            for dataItem in data['areaEllipseJet']:
                self.areaEllipseJet.append(float(dataItem))

        # Distances to concentration levels
        if data['distancesToConcentration'] != None:
            for dataItem in data['distancesToConcentration']:
                self.distancesToConcentration.append(float(dataItem))

        # Concentration levels
        if data['concentrationsUsed'] != None:
            for dataItem in data['concentrationsUsed']:
                self.concentrationsUsed.append(float(dataItem))

        # Maximum concentration footprints at given concentration levels
        if data['concContourPoints'] != None:
            for dataItem in data['concContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.concContourPoints.append(localPosition)

        # Number of contour points per concentration level
        if data['nConcCountourPoints'] != None:
            for dataItem in data['nConcCountourPoints']:
                self.nConcCountourPoints.append(int(dataItem))

        # Areas of maximum concentration footprints
        if data['areaFootprintConc'] != None:
            for dataItem in data['areaFootprintConc']:
                self.areaFootprintConc.append(float(dataItem))

        # Distances to pool fire radiation levels
        if data['distancesToPoolFireRadiation'] != None:
            for dataItem in data['distancesToPoolFireRadiation']:
                self.distancesToPoolFireRadiation.append(float(dataItem))

        # Ellipses to pool fire radiation levels
        if data['poolContourPoints'] != None:
            for dataItem in data['poolContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.poolContourPoints.append(localPosition)

        # Number of contour points for pool fire ellipses per radiation level
        if data['nPoolCountourPoints'] != None:
            for dataItem in data['nPoolCountourPoints']:
                self.nPoolCountourPoints.append(int(dataItem))

        # Areas of pool fire ellipses
        if data['areaEllipsePool'] != None:
            for dataItem in data['areaEllipsePool']:
                self.areaEllipsePool.append(float(dataItem))

        # Explosion overpressure results
        if data['explosionOverpressureResults'] != None:
            for dataItem in data['explosionOverpressureResults']:
                explosionOverpressureResult = ExplosionOverpressureResult()
                explosionOverpressureResult.initialiseFromDictionary(dataItem)
                self.explosionOverpressureResults.append(explosionOverpressureResult)

        # Flame results for jet fire
        self.jetFireFlameResult.initialiseFromDictionary(data['jetFireFlameResult'])

        # Flame results for pool fire
        self.poolFireFlameResult.initialiseFromDictionary(data['poolFireFlameResult'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a sideview at time calculation.
class SideviewAtTimeCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # UDM scalar outputs
        self.scalarUdmOutputs = ScalarUdmOutputs()

        # Weather
        self.weather = Weather()

        # Dispersion definition
        self.dispersionRecords = list[DispersionRecord]()

        # Number of dispersion records
        self.dispersionRecordCount = 0

        # The dispersing surface
        self.substrate = Substrate()

        # Dispersion view configuration
        self.dispersionOutputConfig = DispersionOutputConfig()

        # Material with post-discharge composition
        self.material = Material()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()


# Sideview at time calculation class.
class SideviewAtTimeCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # UDM scalar outputs
        self.scalarUdmOutputs = ScalarUdmOutputs()

        # Weather
        self.weather = Weather()

        # Dispersion definition
        self.dispersionRecords = list[DispersionRecord]()


        # The dispersing surface
        self.substrate = Substrate()

        # Dispersion view configuration
        self.dispersionOutputConfig = DispersionOutputConfig()

        # Material with post-discharge composition
        self.material = Material()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Calculation outputs.
        # Concentration of interest
        self.concUsed = 0.0

        # Array of sideview results
        self.contourPoints = list[LocalPosition]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # SideviewAtTime calculation run method.
    def run(self) -> ResultCode:

        # Create the sideview at time request.
        sideviewAtTimeCalculationRequest = SideviewAtTimeCalculationRequest()

        # Initialise the member properties.

        sideviewAtTimeCalculationRequest.scalarUdmOutputs = self.scalarUdmOutputs
        sideviewAtTimeCalculationRequest.weather = self.weather
        sideviewAtTimeCalculationRequest.dispersionRecords = self.dispersionRecords
        sideviewAtTimeCalculationRequest.dispersionRecordCount = len(self.dispersionRecords)
        sideviewAtTimeCalculationRequest.substrate = self.substrate
        sideviewAtTimeCalculationRequest.dispersionOutputConfig = self.dispersionOutputConfig
        sideviewAtTimeCalculationRequest.material = self.material
        sideviewAtTimeCalculationRequest.dispersionParameters = self.dispersionParameters

        requestJson = jsons.dumps(sideviewAtTimeCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatesideviewattime?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            sideviewAtTimeCalculationResponse = SideviewAtTimeCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                sideviewAtTimeCalculationResponse.initialiseFromDictionary(json)

                self.concUsed = sideviewAtTimeCalculationResponse.concUsed
                self.contourPoints = sideviewAtTimeCalculationResponse.contourPoints
                self.resultCode = sideviewAtTimeCalculationResponse.resultCode
                self.messages = sideviewAtTimeCalculationResponse.messages
                self.calculationElapsedTime = sideviewAtTimeCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the SideviewAtTime calculation object to print itself.
    def print(self):

        # SideviewAtTime
        print('** SideviewAtTime')

        # scalarUdmOutputs
        self.scalarUdmOutputs.print()

        # weather
        self.weather.print()

        for item in self.dispersionRecords:
            item.print()


        # substrate
        self.substrate.print()

        # dispersionOutputConfig
        self.dispersionOutputConfig.print()

        # material
        self.material.print()

        # dispersionParameters
        self.dispersionParameters.print()

        # concUsed
        print('{0}\t{1}'.format('Conc used', self.concUsed))

        for contourPoint in self.contourPoints:
            contourPoint.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a sideview at time calculation.
class SideviewAtTimeCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Concentration of interest
        self.concUsed = 0.0

        # Array of sideview results
        self.contourPoints = list[LocalPosition]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Concentration of interest
        self.concUsed = float(data['concUsed'])

        # Array of sideview results
        if data['contourPoints'] != None:
            for dataItem in data['contourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.contourPoints.append(localPosition)

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a vessel leak max flammable cloud calculation.
class VesselLeakMaxFlammableCloudCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Vessel (pressurised or atmospheric)
        self.vessel = Vessel()

        # Leak failure case
        self.leak = Leak()

        # Weather
        self.weather = Weather()

        # The dispersing surface
        self.substrate = Substrate()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Options for controlling dispersion results (here used to set height of interest only)
        self.dispersionOutputConfig = DispersionOutputConfig()


# Vessel leak max flammable cloud calculation class.
class VesselLeakMaxFlammableCloudCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Vessel (pressurised or atmospheric)
        self.vessel = Vessel()

        # Leak failure case
        self.leak = Leak()

        # Weather
        self.weather = Weather()

        # The dispersing surface
        self.substrate = Substrate()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Options for controlling dispersion results (here used to set height of interest only)
        self.dispersionOutputConfig = DispersionOutputConfig()

        # Calculation outputs.
        # Collated discharge and flammable cloud characterisation results
        self.vesselLeakMaxFlammableCloudResults = VesselLeakMaxFlammableCloudResults()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # VesselLeakMaxFlammableCloud calculation run method.
    def run(self) -> ResultCode:

        # Create the vessel leak max flammable cloud request.
        vesselLeakMaxFlammableCloudCalculationRequest = VesselLeakMaxFlammableCloudCalculationRequest()

        # Initialise the member properties.

        vesselLeakMaxFlammableCloudCalculationRequest.vessel = self.vessel
        vesselLeakMaxFlammableCloudCalculationRequest.leak = self.leak
        vesselLeakMaxFlammableCloudCalculationRequest.weather = self.weather
        vesselLeakMaxFlammableCloudCalculationRequest.substrate = self.substrate
        vesselLeakMaxFlammableCloudCalculationRequest.dischargeParameters = self.dischargeParameters
        vesselLeakMaxFlammableCloudCalculationRequest.dispersionParameters = self.dispersionParameters
        vesselLeakMaxFlammableCloudCalculationRequest.dispersionOutputConfig = self.dispersionOutputConfig

        requestJson = jsons.dumps(vesselLeakMaxFlammableCloudCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatevesselleakmaxflammablecloud?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            vesselLeakMaxFlammableCloudCalculationResponse = VesselLeakMaxFlammableCloudCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                vesselLeakMaxFlammableCloudCalculationResponse.initialiseFromDictionary(json)

                self.vesselLeakMaxFlammableCloudResults = vesselLeakMaxFlammableCloudCalculationResponse.vesselLeakMaxFlammableCloudResults
                self.resultCode = vesselLeakMaxFlammableCloudCalculationResponse.resultCode
                self.messages = vesselLeakMaxFlammableCloudCalculationResponse.messages
                self.calculationElapsedTime = vesselLeakMaxFlammableCloudCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the VesselLeakMaxFlammableCloud calculation object to print itself.
    def print(self):

        # VesselLeakMaxFlammableCloud
        print('** VesselLeakMaxFlammableCloud')

        # vessel
        self.vessel.print()

        # leak
        self.leak.print()

        # weather
        self.weather.print()

        # substrate
        self.substrate.print()

        # dischargeParameters
        self.dischargeParameters.print()

        # dispersionParameters
        self.dispersionParameters.print()

        # dispersionOutputConfig
        self.dispersionOutputConfig.print()

        # vesselLeakMaxFlammableCloudResults
        self.vesselLeakMaxFlammableCloudResults.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a vessel leak max flammable cloud calculation.
class VesselLeakMaxFlammableCloudCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Collated discharge and flammable cloud characterisation results
        self.vesselLeakMaxFlammableCloudResults = VesselLeakMaxFlammableCloudResults()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Collated discharge and flammable cloud characterisation results
        self.vesselLeakMaxFlammableCloudResults.initialiseFromDictionary(data['vesselLeakMaxFlammableCloudResults'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a pool fire calculation.
class PoolFireCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Material with post-discharge composition
        self.material = Material()

        # Pool / source term definition
        self.poolRecords = list[PoolRecord]()

        # Number of pool records
        self.poolRecordCount = 0

        # Weather
        self.weather = Weather()

        # Substrate
        self.substrate = Substrate()

        # Flammable parameters
        self.flammableParameters = FlammableParameters()


# Pool fire calculation class.
class PoolFireCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Material with post-discharge composition
        self.material = Material()

        # Pool / source term definition
        self.poolRecords = list[PoolRecord]()


        # Weather
        self.weather = Weather()

        # Substrate
        self.substrate = Substrate()

        # Flammable parameters
        self.flammableParameters = FlammableParameters()

        # Calculation outputs.
        # Flame scalar result
        self.poolFireFlameResult = PoolFireFlameResult()

        # Array of pool fire flame records
        self.flameRecords = list[FlameRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # PoolFire calculation run method.
    def run(self) -> ResultCode:

        # Create the pool fire request.
        poolFireCalculationRequest = PoolFireCalculationRequest()

        # Initialise the member properties.

        poolFireCalculationRequest.material = self.material
        poolFireCalculationRequest.poolRecords = self.poolRecords
        poolFireCalculationRequest.poolRecordCount = len(self.poolRecords)
        poolFireCalculationRequest.weather = self.weather
        poolFireCalculationRequest.substrate = self.substrate
        poolFireCalculationRequest.flammableParameters = self.flammableParameters

        requestJson = jsons.dumps(poolFireCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatepoolfire?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            poolFireCalculationResponse = PoolFireCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                poolFireCalculationResponse.initialiseFromDictionary(json)

                self.poolFireFlameResult = poolFireCalculationResponse.poolFireFlameResult
                self.flameRecords = poolFireCalculationResponse.flameRecords
                self.resultCode = poolFireCalculationResponse.resultCode
                self.messages = poolFireCalculationResponse.messages
                self.calculationElapsedTime = poolFireCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the PoolFire calculation object to print itself.
    def print(self):

        # PoolFire
        print('** PoolFire')

        # material
        self.material.print()

        for item in self.poolRecords:
            item.print()


        # weather
        self.weather.print()

        # substrate
        self.substrate.print()

        # flammableParameters
        self.flammableParameters.print()

        # poolFireFlameResult
        self.poolFireFlameResult.print()

        for flameRecord in self.flameRecords:
            flameRecord.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a pool fire calculation.
class PoolFireCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Flame scalar result
        self.poolFireFlameResult = PoolFireFlameResult()

        # Array of pool fire flame records
        self.flameRecords = list[FlameRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Flame scalar result
        self.poolFireFlameResult.initialiseFromDictionary(data['poolFireFlameResult'])

        # Array of pool fire flame records
        if data['flameRecords'] != None:
            for dataItem in data['flameRecords']:
                flameRecord = FlameRecord()
                flameRecord.initialiseFromDictionary(dataItem)
                self.flameRecords.append(flameRecord)

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a corqa flash calculation.
class CorqaFlashCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # User-defined input material, pure component or mixture (max 20 components)
        self.material = Material()

        # Describes the fluid pressure, temperature, liquid fraction
        self.materialState = State()


# Corqa flash calculation class.
class CorqaFlashCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # User-defined input material, pure component or mixture (max 20 components)
        self.material = Material()

        # Describes the fluid pressure, temperature, liquid fraction
        self.materialState = State()

        # Calculation outputs.
        # Constant properties of the fluid
        self.constMatResult = ConstantMaterialResult()

        # Fluid properties at given conditions
        self.flashResult = FlashResult()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # CorqaFlash calculation run method.
    def run(self) -> ResultCode:

        # Create the corqa flash request.
        corqaFlashCalculationRequest = CorqaFlashCalculationRequest()

        # Initialise the member properties.

        corqaFlashCalculationRequest.material = self.material
        corqaFlashCalculationRequest.materialState = self.materialState

        requestJson = jsons.dumps(corqaFlashCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatecorqaflash?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            corqaFlashCalculationResponse = CorqaFlashCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                corqaFlashCalculationResponse.initialiseFromDictionary(json)

                self.constMatResult = corqaFlashCalculationResponse.constMatResult
                self.flashResult = corqaFlashCalculationResponse.flashResult
                self.resultCode = corqaFlashCalculationResponse.resultCode
                self.messages = corqaFlashCalculationResponse.messages
                self.calculationElapsedTime = corqaFlashCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the CorqaFlash calculation object to print itself.
    def print(self):

        # CorqaFlash
        print('** CorqaFlash')

        # material
        self.material.print()

        # materialState
        self.materialState.print()

        # constMatResult
        self.constMatResult.print()

        # flashResult
        self.flashResult.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a corqa flash calculation.
class CorqaFlashCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Constant properties of the fluid
        self.constMatResult = ConstantMaterialResult()

        # Fluid properties at given conditions
        self.flashResult = FlashResult()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Constant properties of the fluid
        self.constMatResult.initialiseFromDictionary(data['constMatResult'])

        # Fluid properties at given conditions
        self.flashResult.initialiseFromDictionary(data['flashResult'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a distances and ellipses to radiation levels calculation.
class DistancesAndEllipsesToRadiationLevelsCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Scalar flame results
        self.flameResult = FlameResult()

        # Flame definition
        self.flameRecords = list[FlameRecord]()

        # Number of flame records
        self.flameRecordCount = 0

        # Weather
        self.weather = Weather()

        # Flammable parameters
        self.flammableParameters = FlammableParameters()

        # Flammable output configs
        self.flammableOutputConfigs = list[FlammableOutputConfig]()

        # Number of radiation levels
        self.flammableOutputConfigCount = 0


# Distances and ellipses to radiation levels calculation class.
class DistancesAndEllipsesToRadiationLevelsCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Scalar flame results
        self.flameResult = FlameResult()

        # Flame definition
        self.flameRecords = list[FlameRecord]()


        # Weather
        self.weather = Weather()

        # Flammable parameters
        self.flammableParameters = FlammableParameters()

        # Flammable output configs
        self.flammableOutputConfigs = list[FlammableOutputConfig]()


        # Calculation outputs.
        # Distances to radiation levels
        self.distances = []

        # Contour points of radiation ellipses to radiation levels
        self.contourPoints = list[LocalPosition]()

        # Number of contour points per radiation level
        self.nCountourPoints = []

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # DistancesAndEllipsesToRadiationLevels calculation run method.
    def run(self) -> ResultCode:

        # Create the distances and ellipses to radiation levels request.
        distancesAndEllipsesToRadiationLevelsCalculationRequest = DistancesAndEllipsesToRadiationLevelsCalculationRequest()

        # Initialise the member properties.

        distancesAndEllipsesToRadiationLevelsCalculationRequest.flameResult = self.flameResult
        distancesAndEllipsesToRadiationLevelsCalculationRequest.flameRecords = self.flameRecords
        distancesAndEllipsesToRadiationLevelsCalculationRequest.flameRecordCount = len(self.flameRecords)
        distancesAndEllipsesToRadiationLevelsCalculationRequest.weather = self.weather
        distancesAndEllipsesToRadiationLevelsCalculationRequest.flammableParameters = self.flammableParameters
        distancesAndEllipsesToRadiationLevelsCalculationRequest.flammableOutputConfigs = self.flammableOutputConfigs
        distancesAndEllipsesToRadiationLevelsCalculationRequest.flammableOutputConfigCount = len(self.flammableOutputConfigs)

        requestJson = jsons.dumps(distancesAndEllipsesToRadiationLevelsCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatedistancesandellipsestoradiationlevels?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            distancesAndEllipsesToRadiationLevelsCalculationResponse = DistancesAndEllipsesToRadiationLevelsCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                distancesAndEllipsesToRadiationLevelsCalculationResponse.initialiseFromDictionary(json)

                self.distances = distancesAndEllipsesToRadiationLevelsCalculationResponse.distances
                self.contourPoints = distancesAndEllipsesToRadiationLevelsCalculationResponse.contourPoints
                self.nCountourPoints = distancesAndEllipsesToRadiationLevelsCalculationResponse.nCountourPoints
                self.resultCode = distancesAndEllipsesToRadiationLevelsCalculationResponse.resultCode
                self.messages = distancesAndEllipsesToRadiationLevelsCalculationResponse.messages
                self.calculationElapsedTime = distancesAndEllipsesToRadiationLevelsCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the DistancesAndEllipsesToRadiationLevels calculation object to print itself.
    def print(self):

        # DistancesAndEllipsesToRadiationLevels
        print('** DistancesAndEllipsesToRadiationLevels')

        # flameResult
        self.flameResult.print()

        for item in self.flameRecords:
            item.print()


        # weather
        self.weather.print()

        # flammableParameters
        self.flammableParameters.print()

        for item in self.flammableOutputConfigs:
            item.print()


        # distances
        for item in self.distances:
            print('{0}'.format(item))

        for contourPoint in self.contourPoints:
            contourPoint.print()

        # nCountourPoints
        for item in self.nCountourPoints:
            print('{0}'.format(item))

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a distances and ellipses to radiation levels calculation.
class DistancesAndEllipsesToRadiationLevelsCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Distances to radiation levels
        self.distances = []

        # Contour points of radiation ellipses to radiation levels
        self.contourPoints = list[LocalPosition]()

        # Number of contour points per radiation level
        self.nCountourPoints = []

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Distances to radiation levels
        if data['distances'] != None:
            for dataItem in data['distances']:
                self.distances.append(float(dataItem))

        # Contour points of radiation ellipses to radiation levels
        if data['contourPoints'] != None:
            for dataItem in data['contourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.contourPoints.append(localPosition)

        # Number of contour points per radiation level
        if data['nCountourPoints'] != None:
            for dataItem in data['nCountourPoints']:
                self.nCountourPoints.append(int(dataItem))

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a vessel leak tox simple linked run calculation.
class VesselLeakToxSimpleLinkedRunCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Vessel definition
        self.vessel = Vessel()

        # Leak scenario
        self.leak = Leak()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # The dispersing surface
        self.substrate = Substrate()

        # Weather definition
        self.weather = Weather()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Concentration at which the dispersion calculations will terminate (v/v fraction)
        self.endPointConcentration = 0.0

        # Mole fraction of toxic component
        self.moleFractionToxic = 0.0

        # Concentration levels
        self.dispersionOutputConfigs = list[DispersionOutputConfig]()

        # Number of concentration levels
        self.dispersionOutputConfigCount = 0


# Vessel leak tox simple linked run calculation class.
class VesselLeakToxSimpleLinkedRunCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Vessel definition
        self.vessel = Vessel()

        # Leak scenario
        self.leak = Leak()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # The dispersing surface
        self.substrate = Substrate()

        # Weather definition
        self.weather = Weather()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Concentration at which the dispersion calculations will terminate (v/v fraction)
        self.endPointConcentration = 0.0

        # Mole fraction of toxic component
        self.moleFractionToxic = 0.0

        # Concentration levels
        self.dispersionOutputConfigs = list[DispersionOutputConfig]()


        # Calculation outputs.
        # Discharge data for table
        self.dischargeRecord = DischargeRecord()

        # Description for entry point parameter exitMaterial not found.
        self.exitMaterial = Material()

        # Description for entry point parameter dischargeResult not found.
        self.dischargeResult = DischargeResult()

        # Distances to concentration levels
        self.distancesToConcentration = []

        # Concentration levels
        self.concentrationsUsed = []

        # Maximum concentration footprints at given concentration levels
        self.concContourPoints = list[LocalPosition]()

        # Number of contour points per concentration level
        self.nConcCountourPoints = []

        # Areas of maximum concentration footprints
        self.areaFootprintConc = []

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # VesselLeakToxSimpleLinkedRun calculation run method.
    def run(self) -> ResultCode:

        # Create the vessel leak tox simple linked run request.
        vesselLeakToxSimpleLinkedRunCalculationRequest = VesselLeakToxSimpleLinkedRunCalculationRequest()

        # Initialise the member properties.

        vesselLeakToxSimpleLinkedRunCalculationRequest.vessel = self.vessel
        vesselLeakToxSimpleLinkedRunCalculationRequest.leak = self.leak
        vesselLeakToxSimpleLinkedRunCalculationRequest.dischargeParameters = self.dischargeParameters
        vesselLeakToxSimpleLinkedRunCalculationRequest.substrate = self.substrate
        vesselLeakToxSimpleLinkedRunCalculationRequest.weather = self.weather
        vesselLeakToxSimpleLinkedRunCalculationRequest.dispersionParameters = self.dispersionParameters
        vesselLeakToxSimpleLinkedRunCalculationRequest.endPointConcentration = self.endPointConcentration
        vesselLeakToxSimpleLinkedRunCalculationRequest.moleFractionToxic = self.moleFractionToxic
        vesselLeakToxSimpleLinkedRunCalculationRequest.dispersionOutputConfigs = self.dispersionOutputConfigs
        vesselLeakToxSimpleLinkedRunCalculationRequest.dispersionOutputConfigCount = len(self.dispersionOutputConfigs)

        requestJson = jsons.dumps(vesselLeakToxSimpleLinkedRunCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatevesselleaktoxsimplelinkedrun?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            vesselLeakToxSimpleLinkedRunCalculationResponse = VesselLeakToxSimpleLinkedRunCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                vesselLeakToxSimpleLinkedRunCalculationResponse.initialiseFromDictionary(json)

                self.dischargeRecord = vesselLeakToxSimpleLinkedRunCalculationResponse.dischargeRecord
                self.exitMaterial = vesselLeakToxSimpleLinkedRunCalculationResponse.exitMaterial
                self.dischargeResult = vesselLeakToxSimpleLinkedRunCalculationResponse.dischargeResult
                self.distancesToConcentration = vesselLeakToxSimpleLinkedRunCalculationResponse.distancesToConcentration
                self.concentrationsUsed = vesselLeakToxSimpleLinkedRunCalculationResponse.concentrationsUsed
                self.concContourPoints = vesselLeakToxSimpleLinkedRunCalculationResponse.concContourPoints
                self.nConcCountourPoints = vesselLeakToxSimpleLinkedRunCalculationResponse.nConcCountourPoints
                self.areaFootprintConc = vesselLeakToxSimpleLinkedRunCalculationResponse.areaFootprintConc
                self.resultCode = vesselLeakToxSimpleLinkedRunCalculationResponse.resultCode
                self.messages = vesselLeakToxSimpleLinkedRunCalculationResponse.messages
                self.calculationElapsedTime = vesselLeakToxSimpleLinkedRunCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the VesselLeakToxSimpleLinkedRun calculation object to print itself.
    def print(self):

        # VesselLeakToxSimpleLinkedRun
        print('** VesselLeakToxSimpleLinkedRun')

        # vessel
        self.vessel.print()

        # leak
        self.leak.print()

        # dischargeParameters
        self.dischargeParameters.print()

        # substrate
        self.substrate.print()

        # weather
        self.weather.print()

        # dispersionParameters
        self.dispersionParameters.print()

        print(self.endPointConcentration)
        print('{0}\t{1}'.format('End point concentration', self.endPointConcentration))

        print(self.moleFractionToxic)
        print('{0}\t{1}'.format('Mole fraction toxic', self.moleFractionToxic))

        for item in self.dispersionOutputConfigs:
            item.print()


        # dischargeRecord
        self.dischargeRecord.print()

        # exitMaterial
        self.exitMaterial.print()

        # dischargeResult
        self.dischargeResult.print()

        # distancesToConcentration
        for item in self.distancesToConcentration:
            print('{0}'.format(item))

        # concentrationsUsed
        for item in self.concentrationsUsed:
            print('{0}'.format(item))

        for concContourPoint in self.concContourPoints:
            concContourPoint.print()

        # nConcCountourPoints
        for item in self.nConcCountourPoints:
            print('{0}'.format(item))

        # areaFootprintConc
        for item in self.areaFootprintConc:
            print('{0}'.format(item))

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a vessel leak tox simple linked run calculation.
class VesselLeakToxSimpleLinkedRunCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Discharge data for table
        self.dischargeRecord = DischargeRecord()

        # Description for entry point parameter exitMaterial not found.
        self.exitMaterial = Material()

        # Description for entry point parameter dischargeResult not found.
        self.dischargeResult = DischargeResult()

        # Distances to concentration levels
        self.distancesToConcentration = []

        # Concentration levels
        self.concentrationsUsed = []

        # Maximum concentration footprints at given concentration levels
        self.concContourPoints = list[LocalPosition]()

        # Number of contour points per concentration level
        self.nConcCountourPoints = []

        # Areas of maximum concentration footprints
        self.areaFootprintConc = []

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Discharge data for table
        self.dischargeRecord.initialiseFromDictionary(data['dischargeRecord'])

        # Description for entry point parameter exitMaterial not found.
        self.exitMaterial.initialiseFromDictionary(data['exitMaterial'])

        # Description for entry point parameter dischargeResult not found.
        self.dischargeResult.initialiseFromDictionary(data['dischargeResult'])

        # Distances to concentration levels
        if data['distancesToConcentration'] != None:
            for dataItem in data['distancesToConcentration']:
                self.distancesToConcentration.append(float(dataItem))

        # Concentration levels
        if data['concentrationsUsed'] != None:
            for dataItem in data['concentrationsUsed']:
                self.concentrationsUsed.append(float(dataItem))

        # Maximum concentration footprints at given concentration levels
        if data['concContourPoints'] != None:
            for dataItem in data['concContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.concContourPoints.append(localPosition)

        # Number of contour points per concentration level
        if data['nConcCountourPoints'] != None:
            for dataItem in data['nConcCountourPoints']:
                self.nConcCountourPoints.append(int(dataItem))

        # Areas of maximum concentration footprints
        if data['areaFootprintConc'] != None:
            for dataItem in data['areaFootprintConc']:
                self.areaFootprintConc.append(float(dataItem))

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a distances to radiation levels calculation.
class DistancesToRadiationLevelsCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Scalar flame results
        self.flameResult = FlameResult()

        # Flame definition
        self.flameRecords = list[FlameRecord]()

        # Number of flame records
        self.flameRecordCount = 0

        # Weather
        self.weather = Weather()

        # Flammable parameters
        self.flammableParameters = FlammableParameters()

        # Flammable output configurations
        self.flammableOutputConfigs = list[FlammableOutputConfig]()

        # Number of flammable output configurations
        self.flammableOutputConfigCount = 0


# Distances to radiation levels calculation class.
class DistancesToRadiationLevelsCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Scalar flame results
        self.flameResult = FlameResult()

        # Flame definition
        self.flameRecords = list[FlameRecord]()


        # Weather
        self.weather = Weather()

        # Flammable parameters
        self.flammableParameters = FlammableParameters()

        # Flammable output configurations
        self.flammableOutputConfigs = list[FlammableOutputConfig]()


        # Calculation outputs.
        # Distances to radiation level
        self.distances = []

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # DistancesToRadiationLevels calculation run method.
    def run(self) -> ResultCode:

        # Create the distances to radiation levels request.
        distancesToRadiationLevelsCalculationRequest = DistancesToRadiationLevelsCalculationRequest()

        # Initialise the member properties.

        distancesToRadiationLevelsCalculationRequest.flameResult = self.flameResult
        distancesToRadiationLevelsCalculationRequest.flameRecords = self.flameRecords
        distancesToRadiationLevelsCalculationRequest.flameRecordCount = len(self.flameRecords)
        distancesToRadiationLevelsCalculationRequest.weather = self.weather
        distancesToRadiationLevelsCalculationRequest.flammableParameters = self.flammableParameters
        distancesToRadiationLevelsCalculationRequest.flammableOutputConfigs = self.flammableOutputConfigs
        distancesToRadiationLevelsCalculationRequest.flammableOutputConfigCount = len(self.flammableOutputConfigs)

        requestJson = jsons.dumps(distancesToRadiationLevelsCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatedistancestoradiationlevels?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            distancesToRadiationLevelsCalculationResponse = DistancesToRadiationLevelsCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                distancesToRadiationLevelsCalculationResponse.initialiseFromDictionary(json)

                self.distances = distancesToRadiationLevelsCalculationResponse.distances
                self.resultCode = distancesToRadiationLevelsCalculationResponse.resultCode
                self.messages = distancesToRadiationLevelsCalculationResponse.messages
                self.calculationElapsedTime = distancesToRadiationLevelsCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the DistancesToRadiationLevels calculation object to print itself.
    def print(self):

        # DistancesToRadiationLevels
        print('** DistancesToRadiationLevels')

        # flameResult
        self.flameResult.print()

        for item in self.flameRecords:
            item.print()


        # weather
        self.weather.print()

        # flammableParameters
        self.flammableParameters.print()

        for item in self.flammableOutputConfigs:
            item.print()


        # distances
        for item in self.distances:
            print('{0}'.format(item))

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a distances to radiation levels calculation.
class DistancesToRadiationLevelsCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Distances to radiation level
        self.distances = []

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Distances to radiation level
        if data['distances'] != None:
            for dataItem in data['distances']:
                self.distances.append(float(dataItem))

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a flash calculation.
class FlashCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # User-defined input material, pure component or mixture (max 20 components)
        self.material = Material()

        # Describes the fluid pressure, temperature, liquid fraction
        self.materialState = State()


# Flash calculation class.
class FlashCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # User-defined input material, pure component or mixture (max 20 components)
        self.material = Material()

        # Describes the fluid pressure, temperature, liquid fraction
        self.materialState = State()

        # Calculation outputs.
        # Fluid properties at given conditions
        self.flashResult = FlashResult()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # Flash calculation run method.
    def run(self) -> ResultCode:

        # Create the flash request.
        flashCalculationRequest = FlashCalculationRequest()

        # Initialise the member properties.

        flashCalculationRequest.material = self.material
        flashCalculationRequest.materialState = self.materialState

        requestJson = jsons.dumps(flashCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculateflash?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            flashCalculationResponse = FlashCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                flashCalculationResponse.initialiseFromDictionary(json)

                self.flashResult = flashCalculationResponse.flashResult
                self.resultCode = flashCalculationResponse.resultCode
                self.messages = flashCalculationResponse.messages
                self.calculationElapsedTime = flashCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the Flash calculation object to print itself.
    def print(self):

        # Flash
        print('** Flash')

        # material
        self.material.print()

        # materialState
        self.materialState.print()

        # flashResult
        self.flashResult.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a flash calculation.
class FlashCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Fluid properties at given conditions
        self.flashResult = FlashResult()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Fluid properties at given conditions
        self.flashResult.initialiseFromDictionary(data['flashResult'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a vessel leak flam tox simple linked run calculation.
class VesselLeakFlamToxSimpleLinkedRunCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Vessel definition
        self.vessel = Vessel()

        # Leak scenario
        self.leak = Leak()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # The dispersing surface
        self.substrate = Substrate()

        # Weather definition
        self.weather = Weather()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Concentration at which the dispersion calculations will terminate (v/v fraction)
        self.endPointConcentration = 0.0

        # Fire model parameters
        self.flammableParameters = FlammableParameters()

        # Explosion parameters
        self.explosionParameters = ExplosionParameters()

        # Flammable concentration levels (LFL fraction, LFL, UFL)
        self.dispersionFlamOutputConfigs = list[DispersionOutputConfig]()

        # Number of flammable concentration levels (LFL fraction, LFL, UFL)
        self.dispersionFlamOutputConfigCount = 0

        # Mole fraction of toxic component
        self.moleFractionToxic = 0.0

        # Toxic concentration levels (concentration of interest)
        self.dispersionToxicOutputConfigs = list[DispersionOutputConfig]()

        # Number of toxic concentration levels (concentration of interest)
        self.dispersionToxicOutputConfigCount = 0

        # Radiation levels
        self.flammableOutputConfigs = list[FlammableOutputConfig]()

        # Number of radiation levels
        self.flammableOutputConfigCount = 0

        # Overpressure levels
        self.explosionOutputConfigs = list[ExplosionOutputConfig]()

        # Number of overpressure levels
        self.explosionOutputConfigCount = 0

        # Explosion confined volumes
        self.explosionConfinedVolumes = list[ExplosionConfinedVolume]()

        # Number of confined explosion sources
        self.explosionConfinedVolumeCount = 0


# Vessel leak flam tox simple linked run calculation class.
class VesselLeakFlamToxSimpleLinkedRunCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Vessel definition
        self.vessel = Vessel()

        # Leak scenario
        self.leak = Leak()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # The dispersing surface
        self.substrate = Substrate()

        # Weather definition
        self.weather = Weather()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Concentration at which the dispersion calculations will terminate (v/v fraction)
        self.endPointConcentration = 0.0

        # Fire model parameters
        self.flammableParameters = FlammableParameters()

        # Explosion parameters
        self.explosionParameters = ExplosionParameters()

        # Flammable concentration levels (LFL fraction, LFL, UFL)
        self.dispersionFlamOutputConfigs = list[DispersionOutputConfig]()


        # Mole fraction of toxic component
        self.moleFractionToxic = 0.0

        # Toxic concentration levels (concentration of interest)
        self.dispersionToxicOutputConfigs = list[DispersionOutputConfig]()


        # Radiation levels
        self.flammableOutputConfigs = list[FlammableOutputConfig]()


        # Overpressure levels
        self.explosionOutputConfigs = list[ExplosionOutputConfig]()


        # Explosion confined volumes
        self.explosionConfinedVolumes = list[ExplosionConfinedVolume]()


        # Calculation outputs.
        # Discharge data for table
        self.dischargeRecord = DischargeRecord()

        # Distances to jet fire radiation levels
        self.distancesToJetFireRadiation = []

        # Ellipses to jet fire radiation levels
        self.jetContourPoints = list[LocalPosition]()

        # Number of contour points for jet fire ellipses per radiation level
        self.nJetCountourPoints = []

        # Areas of jet fire ellipses
        self.areaEllipseJet = []

        # Distances to concentration levels (LFL fraction, LFL and UFL)
        self.distancesToFlamConcentration = []

        # Concentration levels (LFL fraction, LFL and UFL)
        self.flamConcentrationsUsed = []

        # Maximum concentration footprints at given concentration levels (LFL fraction, LFL and UFL)
        self.flamConcContourPoints = list[LocalPosition]()

        # Number of contour points per concentration level (LFL fraction, LFL and UFL)
        self.nFlamConcCountourPoints = []

        # Areas of maximum concentration footprints (LFL fraction, LFL and UFL)
        self.areaFootprintFlamConc = []

        # Distances to pool fire radiation levels
        self.distancesToPoolFireRadiation = []

        # Ellipses to pool fire radiation levels
        self.poolContourPoints = list[LocalPosition]()

        # Number of contour points for pool fire ellipses per radiation level
        self.nPoolCountourPoints = []

        # Areas of pool fire ellipses
        self.areaEllipsePool = []

        # Explosion overpressure results
        self.explosionOverpressureResults = list[ExplosionOverpressureResult]()

        # Distance to concentration of interest (using toxic averaging time)
        self.distancesToToxicConcentration = []

        # Concentration of interest
        self.toxicConcentrationUsed = []

        # Maximum concentration footprint to concentration of interest (using toxic averaging time)
        self.toxicConcContourPoints = list[LocalPosition]()

        # Number of contour points for maximum concentration footprint to concentration of interest
        self.nToxicConcCountourPoints = []

        # Area of maximum concentration footprints to concentration of interest (using toxic averaging time)
        self.areaFootprintToxicConc = []

        # Flame results for jet fire
        self.jetFireFlameResult = FlameResult()

        # Flame results for pool fire
        self.poolFireFlameResult = PoolFireFlameResult()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # VesselLeakFlamToxSimpleLinkedRun calculation run method.
    def run(self) -> ResultCode:

        # Create the vessel leak flam tox simple linked run request.
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest = VesselLeakFlamToxSimpleLinkedRunCalculationRequest()

        # Initialise the member properties.

        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.vessel = self.vessel
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.leak = self.leak
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.dischargeParameters = self.dischargeParameters
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.substrate = self.substrate
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.weather = self.weather
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.dispersionParameters = self.dispersionParameters
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.endPointConcentration = self.endPointConcentration
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.flammableParameters = self.flammableParameters
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.explosionParameters = self.explosionParameters
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.dispersionFlamOutputConfigs = self.dispersionFlamOutputConfigs
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.dispersionFlamOutputConfigCount = len(self.dispersionFlamOutputConfigs)
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.moleFractionToxic = self.moleFractionToxic
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.dispersionToxicOutputConfigs = self.dispersionToxicOutputConfigs
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.dispersionToxicOutputConfigCount = len(self.dispersionToxicOutputConfigs)
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.flammableOutputConfigs = self.flammableOutputConfigs
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.flammableOutputConfigCount = len(self.flammableOutputConfigs)
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.explosionOutputConfigs = self.explosionOutputConfigs
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.explosionOutputConfigCount = len(self.explosionOutputConfigs)
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.explosionConfinedVolumes = self.explosionConfinedVolumes
        vesselLeakFlamToxSimpleLinkedRunCalculationRequest.explosionConfinedVolumeCount = len(self.explosionConfinedVolumes)

        requestJson = jsons.dumps(vesselLeakFlamToxSimpleLinkedRunCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatevesselleakflamtoxsimplelinkedrun?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            vesselLeakFlamToxSimpleLinkedRunCalculationResponse = VesselLeakFlamToxSimpleLinkedRunCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                vesselLeakFlamToxSimpleLinkedRunCalculationResponse.initialiseFromDictionary(json)

                self.dischargeRecord = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.dischargeRecord
                self.distancesToJetFireRadiation = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.distancesToJetFireRadiation
                self.jetContourPoints = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.jetContourPoints
                self.nJetCountourPoints = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.nJetCountourPoints
                self.areaEllipseJet = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.areaEllipseJet
                self.distancesToFlamConcentration = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.distancesToFlamConcentration
                self.flamConcentrationsUsed = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.flamConcentrationsUsed
                self.flamConcContourPoints = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.flamConcContourPoints
                self.nFlamConcCountourPoints = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.nFlamConcCountourPoints
                self.areaFootprintFlamConc = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.areaFootprintFlamConc
                self.distancesToPoolFireRadiation = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.distancesToPoolFireRadiation
                self.poolContourPoints = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.poolContourPoints
                self.nPoolCountourPoints = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.nPoolCountourPoints
                self.areaEllipsePool = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.areaEllipsePool
                self.explosionOverpressureResults = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.explosionOverpressureResults
                self.distancesToToxicConcentration = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.distancesToToxicConcentration
                self.toxicConcentrationUsed = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.toxicConcentrationUsed
                self.toxicConcContourPoints = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.toxicConcContourPoints
                self.nToxicConcCountourPoints = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.nToxicConcCountourPoints
                self.areaFootprintToxicConc = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.areaFootprintToxicConc
                self.jetFireFlameResult = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.jetFireFlameResult
                self.poolFireFlameResult = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.poolFireFlameResult
                self.resultCode = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.resultCode
                self.messages = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.messages
                self.calculationElapsedTime = vesselLeakFlamToxSimpleLinkedRunCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the VesselLeakFlamToxSimpleLinkedRun calculation object to print itself.
    def print(self):

        # VesselLeakFlamToxSimpleLinkedRun
        print('** VesselLeakFlamToxSimpleLinkedRun')

        # vessel
        self.vessel.print()

        # leak
        self.leak.print()

        # dischargeParameters
        self.dischargeParameters.print()

        # substrate
        self.substrate.print()

        # weather
        self.weather.print()

        # dispersionParameters
        self.dispersionParameters.print()

        print(self.endPointConcentration)
        print('{0}\t{1}'.format('End point concentration', self.endPointConcentration))

        # flammableParameters
        self.flammableParameters.print()

        # explosionParameters
        self.explosionParameters.print()

        for item in self.dispersionFlamOutputConfigs:
            item.print()


        print(self.moleFractionToxic)
        print('{0}\t{1}'.format('Mole fraction toxic', self.moleFractionToxic))

        for item in self.dispersionToxicOutputConfigs:
            item.print()


        for item in self.flammableOutputConfigs:
            item.print()


        for item in self.explosionOutputConfigs:
            item.print()


        for item in self.explosionConfinedVolumes:
            item.print()


        # dischargeRecord
        self.dischargeRecord.print()

        # distancesToJetFireRadiation
        for item in self.distancesToJetFireRadiation:
            print('{0}'.format(item))

        for jetContourPoint in self.jetContourPoints:
            jetContourPoint.print()

        # nJetCountourPoints
        for item in self.nJetCountourPoints:
            print('{0}'.format(item))

        # areaEllipseJet
        for item in self.areaEllipseJet:
            print('{0}'.format(item))

        # distancesToFlamConcentration
        for item in self.distancesToFlamConcentration:
            print('{0}'.format(item))

        # flamConcentrationsUsed
        for item in self.flamConcentrationsUsed:
            print('{0}'.format(item))

        for flamConcContourPoint in self.flamConcContourPoints:
            flamConcContourPoint.print()

        # nFlamConcCountourPoints
        for item in self.nFlamConcCountourPoints:
            print('{0}'.format(item))

        # areaFootprintFlamConc
        for item in self.areaFootprintFlamConc:
            print('{0}'.format(item))

        # distancesToPoolFireRadiation
        for item in self.distancesToPoolFireRadiation:
            print('{0}'.format(item))

        for poolContourPoint in self.poolContourPoints:
            poolContourPoint.print()

        # nPoolCountourPoints
        for item in self.nPoolCountourPoints:
            print('{0}'.format(item))

        # areaEllipsePool
        for item in self.areaEllipsePool:
            print('{0}'.format(item))

        # explosionOverpressureResults
        for item in self.explosionOverpressureResults:
            item.print()

        # distancesToToxicConcentration
        for item in self.distancesToToxicConcentration:
            print('{0}'.format(item))

        # toxicConcentrationUsed
        for item in self.toxicConcentrationUsed:
            print('{0}'.format(item))

        for toxicConcContourPoint in self.toxicConcContourPoints:
            toxicConcContourPoint.print()

        # nToxicConcCountourPoints
        for item in self.nToxicConcCountourPoints:
            print('{0}'.format(item))

        # areaFootprintToxicConc
        for item in self.areaFootprintToxicConc:
            print('{0}'.format(item))

        # jetFireFlameResult
        self.jetFireFlameResult.print()

        # poolFireFlameResult
        self.poolFireFlameResult.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a vessel leak flam tox simple linked run calculation.
class VesselLeakFlamToxSimpleLinkedRunCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Discharge data for table
        self.dischargeRecord = DischargeRecord()

        # Distances to jet fire radiation levels
        self.distancesToJetFireRadiation = []

        # Ellipses to jet fire radiation levels
        self.jetContourPoints = list[LocalPosition]()

        # Number of contour points for jet fire ellipses per radiation level
        self.nJetCountourPoints = []

        # Areas of jet fire ellipses
        self.areaEllipseJet = []

        # Distances to concentration levels (LFL fraction, LFL and UFL)
        self.distancesToFlamConcentration = []

        # Concentration levels (LFL fraction, LFL and UFL)
        self.flamConcentrationsUsed = []

        # Maximum concentration footprints at given concentration levels (LFL fraction, LFL and UFL)
        self.flamConcContourPoints = list[LocalPosition]()

        # Number of contour points per concentration level (LFL fraction, LFL and UFL)
        self.nFlamConcCountourPoints = []

        # Areas of maximum concentration footprints (LFL fraction, LFL and UFL)
        self.areaFootprintFlamConc = []

        # Distances to pool fire radiation levels
        self.distancesToPoolFireRadiation = []

        # Ellipses to pool fire radiation levels
        self.poolContourPoints = list[LocalPosition]()

        # Number of contour points for pool fire ellipses per radiation level
        self.nPoolCountourPoints = []

        # Areas of pool fire ellipses
        self.areaEllipsePool = []

        # Explosion overpressure results
        self.explosionOverpressureResults = list[ExplosionOverpressureResult]()

        # Distance to concentration of interest (using toxic averaging time)
        self.distancesToToxicConcentration = []

        # Concentration of interest
        self.toxicConcentrationUsed = []

        # Maximum concentration footprint to concentration of interest (using toxic averaging time)
        self.toxicConcContourPoints = list[LocalPosition]()

        # Number of contour points for maximum concentration footprint to concentration of interest
        self.nToxicConcCountourPoints = []

        # Area of maximum concentration footprints to concentration of interest (using toxic averaging time)
        self.areaFootprintToxicConc = []

        # Flame results for jet fire
        self.jetFireFlameResult = FlameResult()

        # Flame results for pool fire
        self.poolFireFlameResult = PoolFireFlameResult()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Discharge data for table
        self.dischargeRecord.initialiseFromDictionary(data['dischargeRecord'])

        # Distances to jet fire radiation levels
        if data['distancesToJetFireRadiation'] != None:
            for dataItem in data['distancesToJetFireRadiation']:
                self.distancesToJetFireRadiation.append(float(dataItem))

        # Ellipses to jet fire radiation levels
        if data['jetContourPoints'] != None:
            for dataItem in data['jetContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.jetContourPoints.append(localPosition)

        # Number of contour points for jet fire ellipses per radiation level
        if data['nJetCountourPoints'] != None:
            for dataItem in data['nJetCountourPoints']:
                self.nJetCountourPoints.append(int(dataItem))

        # Areas of jet fire ellipses
        if data['areaEllipseJet'] != None:
            for dataItem in data['areaEllipseJet']:
                self.areaEllipseJet.append(float(dataItem))

        # Distances to concentration levels (LFL fraction, LFL and UFL)
        if data['distancesToFlamConcentration'] != None:
            for dataItem in data['distancesToFlamConcentration']:
                self.distancesToFlamConcentration.append(float(dataItem))

        # Concentration levels (LFL fraction, LFL and UFL)
        if data['flamConcentrationsUsed'] != None:
            for dataItem in data['flamConcentrationsUsed']:
                self.flamConcentrationsUsed.append(float(dataItem))

        # Maximum concentration footprints at given concentration levels (LFL fraction, LFL and UFL)
        if data['flamConcContourPoints'] != None:
            for dataItem in data['flamConcContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.flamConcContourPoints.append(localPosition)

        # Number of contour points per concentration level (LFL fraction, LFL and UFL)
        if data['nFlamConcCountourPoints'] != None:
            for dataItem in data['nFlamConcCountourPoints']:
                self.nFlamConcCountourPoints.append(int(dataItem))

        # Areas of maximum concentration footprints (LFL fraction, LFL and UFL)
        if data['areaFootprintFlamConc'] != None:
            for dataItem in data['areaFootprintFlamConc']:
                self.areaFootprintFlamConc.append(float(dataItem))

        # Distances to pool fire radiation levels
        if data['distancesToPoolFireRadiation'] != None:
            for dataItem in data['distancesToPoolFireRadiation']:
                self.distancesToPoolFireRadiation.append(float(dataItem))

        # Ellipses to pool fire radiation levels
        if data['poolContourPoints'] != None:
            for dataItem in data['poolContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.poolContourPoints.append(localPosition)

        # Number of contour points for pool fire ellipses per radiation level
        if data['nPoolCountourPoints'] != None:
            for dataItem in data['nPoolCountourPoints']:
                self.nPoolCountourPoints.append(int(dataItem))

        # Areas of pool fire ellipses
        if data['areaEllipsePool'] != None:
            for dataItem in data['areaEllipsePool']:
                self.areaEllipsePool.append(float(dataItem))

        # Explosion overpressure results
        if data['explosionOverpressureResults'] != None:
            for dataItem in data['explosionOverpressureResults']:
                explosionOverpressureResult = ExplosionOverpressureResult()
                explosionOverpressureResult.initialiseFromDictionary(dataItem)
                self.explosionOverpressureResults.append(explosionOverpressureResult)

        # Distance to concentration of interest (using toxic averaging time)
        if data['distancesToToxicConcentration'] != None:
            for dataItem in data['distancesToToxicConcentration']:
                self.distancesToToxicConcentration.append(float(dataItem))

        # Concentration of interest
        if data['toxicConcentrationUsed'] != None:
            for dataItem in data['toxicConcentrationUsed']:
                self.toxicConcentrationUsed.append(float(dataItem))

        # Maximum concentration footprint to concentration of interest (using toxic averaging time)
        if data['toxicConcContourPoints'] != None:
            for dataItem in data['toxicConcContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.toxicConcContourPoints.append(localPosition)

        # Number of contour points for maximum concentration footprint to concentration of interest
        if data['nToxicConcCountourPoints'] != None:
            for dataItem in data['nToxicConcCountourPoints']:
                self.nToxicConcCountourPoints.append(int(dataItem))

        # Area of maximum concentration footprints to concentration of interest (using toxic averaging time)
        if data['areaFootprintToxicConc'] != None:
            for dataItem in data['areaFootprintToxicConc']:
                self.areaFootprintToxicConc.append(float(dataItem))

        # Flame results for jet fire
        self.jetFireFlameResult.initialiseFromDictionary(data['jetFireFlameResult'])

        # Flame results for pool fire
        self.poolFireFlameResult.initialiseFromDictionary(data['poolFireFlameResult'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a max conc distance calculation.
class MaxConcDistanceCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # UDM scalar outputs
        self.scalarUdmOutputs = ScalarUdmOutputs()

        # Weather
        self.weather = Weather()

        # Dispersion definition
        self.dispersionRecords = list[DispersionRecord]()

        # Number of dispersion records
        self.dispersionRecordCount = 0

        # The dispersing surface
        self.substrate = Substrate()

        # Dispersion view configuration
        self.dispersionOutputConfig = DispersionOutputConfig()

        # Material with post-discharge composition
        self.material = Material()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()


# Max conc distance calculation class.
class MaxConcDistanceCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # UDM scalar outputs
        self.scalarUdmOutputs = ScalarUdmOutputs()

        # Weather
        self.weather = Weather()

        # Dispersion definition
        self.dispersionRecords = list[DispersionRecord]()


        # The dispersing surface
        self.substrate = Substrate()

        # Dispersion view configuration
        self.dispersionOutputConfig = DispersionOutputConfig()

        # Material with post-discharge composition
        self.material = Material()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Calculation outputs.
        # Concentration of interest
        self.concUsed = 0.0

        # Array of maximum concentration at x, y, z coordinates
        self.concentrationRecords = list[ConcentrationRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # MaxConcDistance calculation run method.
    def run(self) -> ResultCode:

        # Create the max conc distance request.
        maxConcDistanceCalculationRequest = MaxConcDistanceCalculationRequest()

        # Initialise the member properties.

        maxConcDistanceCalculationRequest.scalarUdmOutputs = self.scalarUdmOutputs
        maxConcDistanceCalculationRequest.weather = self.weather
        maxConcDistanceCalculationRequest.dispersionRecords = self.dispersionRecords
        maxConcDistanceCalculationRequest.dispersionRecordCount = len(self.dispersionRecords)
        maxConcDistanceCalculationRequest.substrate = self.substrate
        maxConcDistanceCalculationRequest.dispersionOutputConfig = self.dispersionOutputConfig
        maxConcDistanceCalculationRequest.material = self.material
        maxConcDistanceCalculationRequest.dispersionParameters = self.dispersionParameters

        requestJson = jsons.dumps(maxConcDistanceCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatemaxconcdistance?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            maxConcDistanceCalculationResponse = MaxConcDistanceCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                maxConcDistanceCalculationResponse.initialiseFromDictionary(json)

                self.concUsed = maxConcDistanceCalculationResponse.concUsed
                self.concentrationRecords = maxConcDistanceCalculationResponse.concentrationRecords
                self.resultCode = maxConcDistanceCalculationResponse.resultCode
                self.messages = maxConcDistanceCalculationResponse.messages
                self.calculationElapsedTime = maxConcDistanceCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the MaxConcDistance calculation object to print itself.
    def print(self):

        # MaxConcDistance
        print('** MaxConcDistance')

        # scalarUdmOutputs
        self.scalarUdmOutputs.print()

        # weather
        self.weather.print()

        for item in self.dispersionRecords:
            item.print()


        # substrate
        self.substrate.print()

        # dispersionOutputConfig
        self.dispersionOutputConfig.print()

        # material
        self.material.print()

        # dispersionParameters
        self.dispersionParameters.print()

        # concUsed
        print('{0}\t{1}'.format('Conc used', self.concUsed))

        for concentrationRecord in self.concentrationRecords:
            concentrationRecord.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a max conc distance calculation.
class MaxConcDistanceCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Concentration of interest
        self.concUsed = 0.0

        # Array of maximum concentration at x, y, z coordinates
        self.concentrationRecords = list[ConcentrationRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Concentration of interest
        self.concUsed = float(data['concUsed'])

        # Array of maximum concentration at x, y, z coordinates
        if data['concentrationRecords'] != None:
            for dataItem in data['concentrationRecords']:
                concentrationRecord = ConcentrationRecord()
                concentrationRecord.initialiseFromDictionary(dataItem)
                self.concentrationRecords.append(concentrationRecord)

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a mixture constant properties calculation.
class MixtureConstantPropertiesCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # User-defined input material (max 20 components)
        self.material = Material()


# Mixture constant properties calculation class.
class MixtureConstantPropertiesCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # User-defined input material (max 20 components)
        self.material = Material()

        # Calculation outputs.
        # Constant properties of the mixture
        self.mixConstantPropResult = MixtureConstantPropertiesResult()

        # Response code
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # MixtureConstantProperties calculation run method.
    def run(self) -> ResultCode:

        # Create the mixture constant properties request.
        mixtureConstantPropertiesCalculationRequest = MixtureConstantPropertiesCalculationRequest()

        # Initialise the member properties.

        mixtureConstantPropertiesCalculationRequest.material = self.material

        requestJson = jsons.dumps(mixtureConstantPropertiesCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatemixtureconstantproperties?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            mixtureConstantPropertiesCalculationResponse = MixtureConstantPropertiesCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                mixtureConstantPropertiesCalculationResponse.initialiseFromDictionary(json)

                self.mixConstantPropResult = mixtureConstantPropertiesCalculationResponse.mixConstantPropResult
                self.resultCode = mixtureConstantPropertiesCalculationResponse.resultCode
                self.messages = mixtureConstantPropertiesCalculationResponse.messages
                self.calculationElapsedTime = mixtureConstantPropertiesCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the MixtureConstantProperties calculation object to print itself.
    def print(self):

        # MixtureConstantProperties
        print('** MixtureConstantProperties')

        # material
        self.material.print()

        # mixConstantPropResult
        self.mixConstantPropResult.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a mixture constant properties calculation.
class MixtureConstantPropertiesCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Constant properties of the mixture
        self.mixConstantPropResult = MixtureConstantPropertiesResult()

        # Response code
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Constant properties of the mixture
        self.mixConstantPropResult.initialiseFromDictionary(data['mixConstantPropResult'])

        # Response code
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a user defined source linked run calculation.
class UserDefinedSourceLinkedRunCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Material
        self.material = Material()

        # Scalar discharge data
        self.dischargeResult = DischargeResult()

        # Discharge records
        self.dischargeRecords = list[DischargeRecord]()

        # Number of discharge records
        self.dischargeRecordCount = 0

        # Phase to be released (Vapour, Two-phase or Liquid)
        self.phaseToBeReleased = Phase.VAPOUR

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # The dispersing surface
        self.substrate = Substrate()

        # Weather definition
        self.weather = Weather()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Concentration at which the dispersion calculations will terminate (v/v fraction)
        self.endPointConcentration = 0.0

        # Fire model parameters
        self.flammableParameters = FlammableParameters()

        # Explosion parameters
        self.explosionParameters = ExplosionParameters()

        # Flammable concentration levels (LFL fraction, LFL, UFL)
        self.dispersionFlamOutputConfigs = list[DispersionOutputConfig]()

        # Number of flammable concentration levels (LFL fraction, LFL, UFL)
        self.dispersionFlamOutputConfigCount = 0

        # Toxic concentration levels (concentration of interest)
        self.dispersionToxicOutputConfigs = list[DispersionOutputConfig]()

        # Number of toxic concentration levels (concentration of interest)
        self.dispersionToxicOutputConfigCount = 0

        # Radiation levels
        self.flammableOutputConfigs = list[FlammableOutputConfig]()

        # Number of radiation levels
        self.flammableOutputConfigCount = 0

        # Overpressure levels
        self.explosionOutputConfigs = list[ExplosionOutputConfig]()

        # Number of overpressure levels
        self.explosionOutputConfigCount = 0

        # Explosion confined volumes
        self.explosionConfinedVolumes = list[ExplosionConfinedVolume]()

        # Number of confined explosion sources
        self.explosionConfinedVolumeCount = 0


# User defined source linked run calculation class.
class UserDefinedSourceLinkedRunCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Material
        self.material = Material()

        # Scalar discharge data
        self.dischargeResult = DischargeResult()

        # Discharge records
        self.dischargeRecords = list[DischargeRecord]()


        # Phase to be released (Vapour, Two-phase or Liquid)
        self.phaseToBeReleased = Phase.VAPOUR

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # The dispersing surface
        self.substrate = Substrate()

        # Weather definition
        self.weather = Weather()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Concentration at which the dispersion calculations will terminate (v/v fraction)
        self.endPointConcentration = 0.0

        # Fire model parameters
        self.flammableParameters = FlammableParameters()

        # Explosion parameters
        self.explosionParameters = ExplosionParameters()

        # Flammable concentration levels (LFL fraction, LFL, UFL)
        self.dispersionFlamOutputConfigs = list[DispersionOutputConfig]()


        # Toxic concentration levels (concentration of interest)
        self.dispersionToxicOutputConfigs = list[DispersionOutputConfig]()


        # Radiation levels
        self.flammableOutputConfigs = list[FlammableOutputConfig]()


        # Overpressure levels
        self.explosionOutputConfigs = list[ExplosionOutputConfig]()


        # Explosion confined volumes
        self.explosionConfinedVolumes = list[ExplosionConfinedVolume]()


        # Calculation outputs.
        # Distances to jet fire radiation levels
        self.distancesToJetFireRadiation = []

        # Callback function for jet fire radiation contour points
        self.jetContourPoints = list[LocalPosition]()

        # Number of points for jet fire contours per radiation level
        self.nJetContourPoints = []

        # Areas of jet fire contours
        self.areaContourJet = []

        # Distances to concentration levels (LFL fraction, LFL and UFL)
        self.distancesToFlamConcentration = []

        # Concentration levels (LFL fraction, LFL and UFL)
        self.flamConcentrationsUsed = []

        # Maximum concentration footprints at given concentration levels (LFL fraction, LFL and UFL)
        self.flamConcContourPoints = list[LocalPosition]()

        # Number of contour points per concentration level (LFL fraction, LFL and UFL)
        self.nFlamConcContourPoints = []

        # Areas of maximum concentration footprints (LFL fraction, LFL and UFL)
        self.areaFootprintFlamConc = []

        # Distances to pool fire radiation levels
        self.distancesToPoolFireRadiation = []

        # Callback function for pool fire radiation contour points
        self.poolContourPoints = list[LocalPosition]()

        # Number of points for pool fire contours per radiation level
        self.nPoolContourPoints = []

        # Areas of pool fire contours
        self.areaContourPool = []

        # Explosion overpressure results
        self.explosionOverpressureResults = list[ExplosionOverpressureResult]()

        # Distance to concentration of interest (using toxic averaging time)
        self.distancesToToxicConcentration = []

        # Concentration of interest
        self.toxicConcentrationUsed = []

        # Maximum concentration footprint to concentration of interest (using toxic averaging time)
        self.toxicConcContourPoints = list[LocalPosition]()

        # Number of contour points for maximum concentration footprint to concentration of interest
        self.nToxicConcContourPoints = []

        # Area of maximum concentration footprints to concentration of interest (using toxic averaging time)
        self.areaFootprintToxicConc = []

        # Flame results for jet fire
        self.jetFireFlameResult = FlameResult()

        # Flame results for pool fire
        self.poolFireFlameResult = PoolFireFlameResult()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # UserDefinedSourceLinkedRun calculation run method.
    def run(self) -> ResultCode:

        # Create the user defined source linked run request.
        userDefinedSourceLinkedRunCalculationRequest = UserDefinedSourceLinkedRunCalculationRequest()

        # Initialise the member properties.

        userDefinedSourceLinkedRunCalculationRequest.material = self.material
        userDefinedSourceLinkedRunCalculationRequest.dischargeResult = self.dischargeResult
        userDefinedSourceLinkedRunCalculationRequest.dischargeRecords = self.dischargeRecords
        userDefinedSourceLinkedRunCalculationRequest.dischargeRecordCount = len(self.dischargeRecords)
        userDefinedSourceLinkedRunCalculationRequest.phaseToBeReleased = self.phaseToBeReleased
        userDefinedSourceLinkedRunCalculationRequest.dischargeParameters = self.dischargeParameters
        userDefinedSourceLinkedRunCalculationRequest.substrate = self.substrate
        userDefinedSourceLinkedRunCalculationRequest.weather = self.weather
        userDefinedSourceLinkedRunCalculationRequest.dispersionParameters = self.dispersionParameters
        userDefinedSourceLinkedRunCalculationRequest.endPointConcentration = self.endPointConcentration
        userDefinedSourceLinkedRunCalculationRequest.flammableParameters = self.flammableParameters
        userDefinedSourceLinkedRunCalculationRequest.explosionParameters = self.explosionParameters
        userDefinedSourceLinkedRunCalculationRequest.dispersionFlamOutputConfigs = self.dispersionFlamOutputConfigs
        userDefinedSourceLinkedRunCalculationRequest.dispersionFlamOutputConfigCount = len(self.dispersionFlamOutputConfigs)
        userDefinedSourceLinkedRunCalculationRequest.dispersionToxicOutputConfigs = self.dispersionToxicOutputConfigs
        userDefinedSourceLinkedRunCalculationRequest.dispersionToxicOutputConfigCount = len(self.dispersionToxicOutputConfigs)
        userDefinedSourceLinkedRunCalculationRequest.flammableOutputConfigs = self.flammableOutputConfigs
        userDefinedSourceLinkedRunCalculationRequest.flammableOutputConfigCount = len(self.flammableOutputConfigs)
        userDefinedSourceLinkedRunCalculationRequest.explosionOutputConfigs = self.explosionOutputConfigs
        userDefinedSourceLinkedRunCalculationRequest.explosionOutputConfigCount = len(self.explosionOutputConfigs)
        userDefinedSourceLinkedRunCalculationRequest.explosionConfinedVolumes = self.explosionConfinedVolumes
        userDefinedSourceLinkedRunCalculationRequest.explosionConfinedVolumeCount = len(self.explosionConfinedVolumes)

        requestJson = jsons.dumps(userDefinedSourceLinkedRunCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculateuserdefinedsourcelinkedrun?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            userDefinedSourceLinkedRunCalculationResponse = UserDefinedSourceLinkedRunCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                userDefinedSourceLinkedRunCalculationResponse.initialiseFromDictionary(json)

                self.distancesToJetFireRadiation = userDefinedSourceLinkedRunCalculationResponse.distancesToJetFireRadiation
                self.jetContourPoints = userDefinedSourceLinkedRunCalculationResponse.jetContourPoints
                self.nJetContourPoints = userDefinedSourceLinkedRunCalculationResponse.nJetContourPoints
                self.areaContourJet = userDefinedSourceLinkedRunCalculationResponse.areaContourJet
                self.distancesToFlamConcentration = userDefinedSourceLinkedRunCalculationResponse.distancesToFlamConcentration
                self.flamConcentrationsUsed = userDefinedSourceLinkedRunCalculationResponse.flamConcentrationsUsed
                self.flamConcContourPoints = userDefinedSourceLinkedRunCalculationResponse.flamConcContourPoints
                self.nFlamConcContourPoints = userDefinedSourceLinkedRunCalculationResponse.nFlamConcContourPoints
                self.areaFootprintFlamConc = userDefinedSourceLinkedRunCalculationResponse.areaFootprintFlamConc
                self.distancesToPoolFireRadiation = userDefinedSourceLinkedRunCalculationResponse.distancesToPoolFireRadiation
                self.poolContourPoints = userDefinedSourceLinkedRunCalculationResponse.poolContourPoints
                self.nPoolContourPoints = userDefinedSourceLinkedRunCalculationResponse.nPoolContourPoints
                self.areaContourPool = userDefinedSourceLinkedRunCalculationResponse.areaContourPool
                self.explosionOverpressureResults = userDefinedSourceLinkedRunCalculationResponse.explosionOverpressureResults
                self.distancesToToxicConcentration = userDefinedSourceLinkedRunCalculationResponse.distancesToToxicConcentration
                self.toxicConcentrationUsed = userDefinedSourceLinkedRunCalculationResponse.toxicConcentrationUsed
                self.toxicConcContourPoints = userDefinedSourceLinkedRunCalculationResponse.toxicConcContourPoints
                self.nToxicConcContourPoints = userDefinedSourceLinkedRunCalculationResponse.nToxicConcContourPoints
                self.areaFootprintToxicConc = userDefinedSourceLinkedRunCalculationResponse.areaFootprintToxicConc
                self.jetFireFlameResult = userDefinedSourceLinkedRunCalculationResponse.jetFireFlameResult
                self.poolFireFlameResult = userDefinedSourceLinkedRunCalculationResponse.poolFireFlameResult
                self.resultCode = userDefinedSourceLinkedRunCalculationResponse.resultCode
                self.messages = userDefinedSourceLinkedRunCalculationResponse.messages
                self.calculationElapsedTime = userDefinedSourceLinkedRunCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the UserDefinedSourceLinkedRun calculation object to print itself.
    def print(self):

        # UserDefinedSourceLinkedRun
        print('** UserDefinedSourceLinkedRun')

        # material
        self.material.print()

        # dischargeResult
        self.dischargeResult.print()

        for item in self.dischargeRecords:
            item.print()


        print(self.phaseToBeReleased)
        print('{0}\t{1}'.format('Phase to be released', self.phaseToBeReleased))

        # dischargeParameters
        self.dischargeParameters.print()

        # substrate
        self.substrate.print()

        # weather
        self.weather.print()

        # dispersionParameters
        self.dispersionParameters.print()

        print(self.endPointConcentration)
        print('{0}\t{1}'.format('End point concentration', self.endPointConcentration))

        # flammableParameters
        self.flammableParameters.print()

        # explosionParameters
        self.explosionParameters.print()

        for item in self.dispersionFlamOutputConfigs:
            item.print()


        for item in self.dispersionToxicOutputConfigs:
            item.print()


        for item in self.flammableOutputConfigs:
            item.print()


        for item in self.explosionOutputConfigs:
            item.print()


        for item in self.explosionConfinedVolumes:
            item.print()


        # distancesToJetFireRadiation
        for item in self.distancesToJetFireRadiation:
            print('{0}'.format(item))

        for jetContourPoint in self.jetContourPoints:
            jetContourPoint.print()

        # nJetContourPoints
        for item in self.nJetContourPoints:
            print('{0}'.format(item))

        # areaContourJet
        for item in self.areaContourJet:
            print('{0}'.format(item))

        # distancesToFlamConcentration
        for item in self.distancesToFlamConcentration:
            print('{0}'.format(item))

        # flamConcentrationsUsed
        for item in self.flamConcentrationsUsed:
            print('{0}'.format(item))

        for flamConcContourPoint in self.flamConcContourPoints:
            flamConcContourPoint.print()

        # nFlamConcContourPoints
        for item in self.nFlamConcContourPoints:
            print('{0}'.format(item))

        # areaFootprintFlamConc
        for item in self.areaFootprintFlamConc:
            print('{0}'.format(item))

        # distancesToPoolFireRadiation
        for item in self.distancesToPoolFireRadiation:
            print('{0}'.format(item))

        for poolContourPoint in self.poolContourPoints:
            poolContourPoint.print()

        # nPoolContourPoints
        for item in self.nPoolContourPoints:
            print('{0}'.format(item))

        # areaContourPool
        for item in self.areaContourPool:
            print('{0}'.format(item))

        # explosionOverpressureResults
        for item in self.explosionOverpressureResults:
            item.print()

        # distancesToToxicConcentration
        for item in self.distancesToToxicConcentration:
            print('{0}'.format(item))

        # toxicConcentrationUsed
        for item in self.toxicConcentrationUsed:
            print('{0}'.format(item))

        for toxicConcContourPoint in self.toxicConcContourPoints:
            toxicConcContourPoint.print()

        # nToxicConcContourPoints
        for item in self.nToxicConcContourPoints:
            print('{0}'.format(item))

        # areaFootprintToxicConc
        for item in self.areaFootprintToxicConc:
            print('{0}'.format(item))

        # jetFireFlameResult
        self.jetFireFlameResult.print()

        # poolFireFlameResult
        self.poolFireFlameResult.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a user defined source linked run calculation.
class UserDefinedSourceLinkedRunCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Distances to jet fire radiation levels
        self.distancesToJetFireRadiation = []

        # Callback function for jet fire radiation contour points
        self.jetContourPoints = list[LocalPosition]()

        # Number of points for jet fire contours per radiation level
        self.nJetContourPoints = []

        # Areas of jet fire contours
        self.areaContourJet = []

        # Distances to concentration levels (LFL fraction, LFL and UFL)
        self.distancesToFlamConcentration = []

        # Concentration levels (LFL fraction, LFL and UFL)
        self.flamConcentrationsUsed = []

        # Maximum concentration footprints at given concentration levels (LFL fraction, LFL and UFL)
        self.flamConcContourPoints = list[LocalPosition]()

        # Number of contour points per concentration level (LFL fraction, LFL and UFL)
        self.nFlamConcContourPoints = []

        # Areas of maximum concentration footprints (LFL fraction, LFL and UFL)
        self.areaFootprintFlamConc = []

        # Distances to pool fire radiation levels
        self.distancesToPoolFireRadiation = []

        # Callback function for pool fire radiation contour points
        self.poolContourPoints = list[LocalPosition]()

        # Number of points for pool fire contours per radiation level
        self.nPoolContourPoints = []

        # Areas of pool fire contours
        self.areaContourPool = []

        # Explosion overpressure results
        self.explosionOverpressureResults = list[ExplosionOverpressureResult]()

        # Distance to concentration of interest (using toxic averaging time)
        self.distancesToToxicConcentration = []

        # Concentration of interest
        self.toxicConcentrationUsed = []

        # Maximum concentration footprint to concentration of interest (using toxic averaging time)
        self.toxicConcContourPoints = list[LocalPosition]()

        # Number of contour points for maximum concentration footprint to concentration of interest
        self.nToxicConcContourPoints = []

        # Area of maximum concentration footprints to concentration of interest (using toxic averaging time)
        self.areaFootprintToxicConc = []

        # Flame results for jet fire
        self.jetFireFlameResult = FlameResult()

        # Flame results for pool fire
        self.poolFireFlameResult = PoolFireFlameResult()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Distances to jet fire radiation levels
        if data['distancesToJetFireRadiation'] != None:
            for dataItem in data['distancesToJetFireRadiation']:
                self.distancesToJetFireRadiation.append(float(dataItem))

        # Callback function for jet fire radiation contour points
        if data['jetContourPoints'] != None:
            for dataItem in data['jetContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.jetContourPoints.append(localPosition)

        # Number of points for jet fire contours per radiation level
        if data['nJetContourPoints'] != None:
            for dataItem in data['nJetContourPoints']:
                self.nJetContourPoints.append(int(dataItem))

        # Areas of jet fire contours
        if data['areaContourJet'] != None:
            for dataItem in data['areaContourJet']:
                self.areaContourJet.append(float(dataItem))

        # Distances to concentration levels (LFL fraction, LFL and UFL)
        if data['distancesToFlamConcentration'] != None:
            for dataItem in data['distancesToFlamConcentration']:
                self.distancesToFlamConcentration.append(float(dataItem))

        # Concentration levels (LFL fraction, LFL and UFL)
        if data['flamConcentrationsUsed'] != None:
            for dataItem in data['flamConcentrationsUsed']:
                self.flamConcentrationsUsed.append(float(dataItem))

        # Maximum concentration footprints at given concentration levels (LFL fraction, LFL and UFL)
        if data['flamConcContourPoints'] != None:
            for dataItem in data['flamConcContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.flamConcContourPoints.append(localPosition)

        # Number of contour points per concentration level (LFL fraction, LFL and UFL)
        if data['nFlamConcContourPoints'] != None:
            for dataItem in data['nFlamConcContourPoints']:
                self.nFlamConcContourPoints.append(int(dataItem))

        # Areas of maximum concentration footprints (LFL fraction, LFL and UFL)
        if data['areaFootprintFlamConc'] != None:
            for dataItem in data['areaFootprintFlamConc']:
                self.areaFootprintFlamConc.append(float(dataItem))

        # Distances to pool fire radiation levels
        if data['distancesToPoolFireRadiation'] != None:
            for dataItem in data['distancesToPoolFireRadiation']:
                self.distancesToPoolFireRadiation.append(float(dataItem))

        # Callback function for pool fire radiation contour points
        if data['poolContourPoints'] != None:
            for dataItem in data['poolContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.poolContourPoints.append(localPosition)

        # Number of points for pool fire contours per radiation level
        if data['nPoolContourPoints'] != None:
            for dataItem in data['nPoolContourPoints']:
                self.nPoolContourPoints.append(int(dataItem))

        # Areas of pool fire contours
        if data['areaContourPool'] != None:
            for dataItem in data['areaContourPool']:
                self.areaContourPool.append(float(dataItem))

        # Explosion overpressure results
        if data['explosionOverpressureResults'] != None:
            for dataItem in data['explosionOverpressureResults']:
                explosionOverpressureResult = ExplosionOverpressureResult()
                explosionOverpressureResult.initialiseFromDictionary(dataItem)
                self.explosionOverpressureResults.append(explosionOverpressureResult)

        # Distance to concentration of interest (using toxic averaging time)
        if data['distancesToToxicConcentration'] != None:
            for dataItem in data['distancesToToxicConcentration']:
                self.distancesToToxicConcentration.append(float(dataItem))

        # Concentration of interest
        if data['toxicConcentrationUsed'] != None:
            for dataItem in data['toxicConcentrationUsed']:
                self.toxicConcentrationUsed.append(float(dataItem))

        # Maximum concentration footprint to concentration of interest (using toxic averaging time)
        if data['toxicConcContourPoints'] != None:
            for dataItem in data['toxicConcContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.toxicConcContourPoints.append(localPosition)

        # Number of contour points for maximum concentration footprint to concentration of interest
        if data['nToxicConcContourPoints'] != None:
            for dataItem in data['nToxicConcContourPoints']:
                self.nToxicConcContourPoints.append(int(dataItem))

        # Area of maximum concentration footprints to concentration of interest (using toxic averaging time)
        if data['areaFootprintToxicConc'] != None:
            for dataItem in data['areaFootprintToxicConc']:
                self.areaFootprintToxicConc.append(float(dataItem))

        # Flame results for jet fire
        self.jetFireFlameResult.initialiseFromDictionary(data['jetFireFlameResult'])

        # Flame results for pool fire
        self.poolFireFlameResult.initialiseFromDictionary(data['poolFireFlameResult'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a properties dnv p t calculation.
class PropertiesDnvPTCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Composition (5 max as using spreadsheet entry point)
        self.material = Material()

        # Range of temperatures and pressures to be considered
        self.range = PTRange()


# Properties dnv p t calculation class.
class PropertiesDnvPTCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Composition (5 max as using spreadsheet entry point)
        self.material = Material()

        # Range of temperatures and pressures to be considered
        self.range = PTRange()

        # Calculation outputs.
        # Batch of property results at individial PT values
        self.result = PropertiesDnvPT1()

        # Batch of property results at individial PT values
        self.result2 = PropertiesDnvPT2()

        # Batch of property results at individial PT values
        self.result3 = PropertiesDnvPT3()

        # Response code
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # PropertiesDnvPT calculation run method.
    def run(self) -> ResultCode:

        # Create the properties dnv p t request.
        propertiesDnvPTCalculationRequest = PropertiesDnvPTCalculationRequest()

        # Initialise the member properties.

        propertiesDnvPTCalculationRequest.material = self.material
        propertiesDnvPTCalculationRequest.range = self.range

        requestJson = jsons.dumps(propertiesDnvPTCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatepropertiesdnvpt?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            propertiesDnvPTCalculationResponse = PropertiesDnvPTCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                propertiesDnvPTCalculationResponse.initialiseFromDictionary(json)

                self.result = propertiesDnvPTCalculationResponse.result
                self.result2 = propertiesDnvPTCalculationResponse.result2
                self.result3 = propertiesDnvPTCalculationResponse.result3
                self.resultCode = propertiesDnvPTCalculationResponse.resultCode
                self.messages = propertiesDnvPTCalculationResponse.messages
                self.calculationElapsedTime = propertiesDnvPTCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the PropertiesDnvPT calculation object to print itself.
    def print(self):

        # PropertiesDnvPT
        print('** PropertiesDnvPT')

        # material
        self.material.print()

        # range
        self.range.print()

        # result
        self.result.print()

        # result2
        self.result2.print()

        # result3
        self.result3.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a properties dnv p t calculation.
class PropertiesDnvPTCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Batch of property results at individial PT values
        self.result = PropertiesDnvPT1()

        # Batch of property results at individial PT values
        self.result2 = PropertiesDnvPT2()

        # Batch of property results at individial PT values
        self.result3 = PropertiesDnvPT3()

        # Response code
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Batch of property results at individial PT values
        self.result.initialiseFromDictionary(data['result'])

        # Batch of property results at individial PT values
        self.result2.initialiseFromDictionary(data['result2'])

        # Batch of property results at individial PT values
        self.result3.initialiseFromDictionary(data['result3'])

        # Response code
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a u d s set liq frac from temperature calculation.
class UDSSetLiqFracFromTemperatureCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Material
        self.material = Material()

        # Phase to be released (should be Two-Phase, if not this method simply returns)
        self.phaseToBeReleased = Phase.VAPOUR

        # Input temperature
        self.temperature = 0.0


# U d s set liq frac from temperature calculation class.
class UDSSetLiqFracFromTemperatureCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Material
        self.material = Material()

        # Phase to be released (should be Two-Phase, if not this method simply returns)
        self.phaseToBeReleased = Phase.VAPOUR

        # Input temperature
        self.temperature = 0.0

        # Calculation outputs.
        # Calculated liquid fraction
        self.liquidFraction = 0.0

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # UDSSetLiqFracFromTemperature calculation run method.
    def run(self) -> ResultCode:

        # Create the u d s set liq frac from temperature request.
        udsSetLiqFracFromTemperatureCalculationRequest = UDSSetLiqFracFromTemperatureCalculationRequest()

        # Initialise the member properties.

        udsSetLiqFracFromTemperatureCalculationRequest.material = self.material
        udsSetLiqFracFromTemperatureCalculationRequest.phaseToBeReleased = self.phaseToBeReleased
        udsSetLiqFracFromTemperatureCalculationRequest.temperature = self.temperature

        requestJson = jsons.dumps(udsSetLiqFracFromTemperatureCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculateudssetliqfracfromtemperature?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            udsSetLiqFracFromTemperatureCalculationResponse = UDSSetLiqFracFromTemperatureCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                udsSetLiqFracFromTemperatureCalculationResponse.initialiseFromDictionary(json)

                self.liquidFraction = udsSetLiqFracFromTemperatureCalculationResponse.liquidFraction
                self.resultCode = udsSetLiqFracFromTemperatureCalculationResponse.resultCode
                self.messages = udsSetLiqFracFromTemperatureCalculationResponse.messages
                self.calculationElapsedTime = udsSetLiqFracFromTemperatureCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the UDSSetLiqFracFromTemperature calculation object to print itself.
    def print(self):

        # UDSSetLiqFracFromTemperature
        print('** UDSSetLiqFracFromTemperature')

        # material
        self.material.print()

        print(self.phaseToBeReleased)
        print('{0}\t{1}'.format('Phase to be released', self.phaseToBeReleased))

        print(self.temperature)
        print('{0}\t{1}'.format('Temperature', self.temperature))

        # liquidFraction
        print('{0}\t{1}'.format('Liquid fraction', self.liquidFraction))

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a u d s set liq frac from temperature calculation.
class UDSSetLiqFracFromTemperatureCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Calculated liquid fraction
        self.liquidFraction = 0.0

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Calculated liquid fraction
        self.liquidFraction = float(data['liquidFraction'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a radiation transect calculation.
class RadiationTransectCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Scalar flame results
        self.flameResult = FlameResult()

        # Flame definition
        self.flameRecords = list[FlameRecord]()

        # Number of flame records
        self.flameRecordCount = 0

        # Weather
        self.weather = Weather()

        # Flammable parameters
        self.flammableParameters = FlammableParameters()

        # Settings of flammable contours view
        self.flammableOutputConfig = FlammableOutputConfig()


# Radiation transect calculation class.
class RadiationTransectCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Scalar flame results
        self.flameResult = FlameResult()

        # Flame definition
        self.flameRecords = list[FlameRecord]()


        # Weather
        self.weather = Weather()

        # Flammable parameters
        self.flammableParameters = FlammableParameters()

        # Settings of flammable contours view
        self.flammableOutputConfig = FlammableOutputConfig()

        # Calculation outputs.
        # Array of radiation results along transect
        self.radiationRecords = list[RadiationRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # RadiationTransect calculation run method.
    def run(self) -> ResultCode:

        # Create the radiation transect request.
        radiationTransectCalculationRequest = RadiationTransectCalculationRequest()

        # Initialise the member properties.

        radiationTransectCalculationRequest.flameResult = self.flameResult
        radiationTransectCalculationRequest.flameRecords = self.flameRecords
        radiationTransectCalculationRequest.flameRecordCount = len(self.flameRecords)
        radiationTransectCalculationRequest.weather = self.weather
        radiationTransectCalculationRequest.flammableParameters = self.flammableParameters
        radiationTransectCalculationRequest.flammableOutputConfig = self.flammableOutputConfig

        requestJson = jsons.dumps(radiationTransectCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculateradiationtransect?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            radiationTransectCalculationResponse = RadiationTransectCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                radiationTransectCalculationResponse.initialiseFromDictionary(json)

                self.radiationRecords = radiationTransectCalculationResponse.radiationRecords
                self.resultCode = radiationTransectCalculationResponse.resultCode
                self.messages = radiationTransectCalculationResponse.messages
                self.calculationElapsedTime = radiationTransectCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the RadiationTransect calculation object to print itself.
    def print(self):

        # RadiationTransect
        print('** RadiationTransect')

        # flameResult
        self.flameResult.print()

        for item in self.flameRecords:
            item.print()


        # weather
        self.weather.print()

        # flammableParameters
        self.flammableParameters.print()

        # flammableOutputConfig
        self.flammableOutputConfig.print()

        for radiationRecord in self.radiationRecords:
            radiationRecord.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a radiation transect calculation.
class RadiationTransectCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Array of radiation results along transect
        self.radiationRecords = list[RadiationRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Array of radiation results along transect
        if data['radiationRecords'] != None:
            for dataItem in data['radiationRecords']:
                radiationRecord = RadiationRecord()
                radiationRecord.initialiseFromDictionary(dataItem)
                self.radiationRecords.append(radiationRecord)

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a vessel leak calculation.
class VesselLeakCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Vessel (pressurised or atmospheric)
        self.vessel = Vessel()

        # Leak failure case
        self.leak = Leak()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()


# Vessel leak calculation class.
class VesselLeakCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Vessel (pressurised or atmospheric)
        self.vessel = Vessel()

        # Leak failure case
        self.leak = Leak()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # Calculation outputs.
        # Composition of the released material (may differ from storage composition)
        self.exitMaterial = Material()

        # Scalar discharge results
        self.dischargeResult = DischargeResult()

        # Array of discharge records
        self.dischargeRecords = list[DischargeRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # VesselLeak calculation run method.
    def run(self) -> ResultCode:

        # Create the vessel leak request.
        vesselLeakCalculationRequest = VesselLeakCalculationRequest()

        # Initialise the member properties.

        vesselLeakCalculationRequest.vessel = self.vessel
        vesselLeakCalculationRequest.leak = self.leak
        vesselLeakCalculationRequest.dischargeParameters = self.dischargeParameters

        requestJson = jsons.dumps(vesselLeakCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatevesselleak?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            vesselLeakCalculationResponse = VesselLeakCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                vesselLeakCalculationResponse.initialiseFromDictionary(json)

                self.exitMaterial = vesselLeakCalculationResponse.exitMaterial
                self.dischargeResult = vesselLeakCalculationResponse.dischargeResult
                self.dischargeRecords = vesselLeakCalculationResponse.dischargeRecords
                self.resultCode = vesselLeakCalculationResponse.resultCode
                self.messages = vesselLeakCalculationResponse.messages
                self.calculationElapsedTime = vesselLeakCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the VesselLeak calculation object to print itself.
    def print(self):

        # VesselLeak
        print('** VesselLeak')

        # vessel
        self.vessel.print()

        # leak
        self.leak.print()

        # dischargeParameters
        self.dischargeParameters.print()

        # exitMaterial
        self.exitMaterial.print()

        # dischargeResult
        self.dischargeResult.print()

        for dischargeRecord in self.dischargeRecords:
            dischargeRecord.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a vessel leak calculation.
class VesselLeakCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Composition of the released material (may differ from storage composition)
        self.exitMaterial = Material()

        # Scalar discharge results
        self.dischargeResult = DischargeResult()

        # Array of discharge records
        self.dischargeRecords = list[DischargeRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Composition of the released material (may differ from storage composition)
        self.exitMaterial.initialiseFromDictionary(data['exitMaterial'])

        # Scalar discharge results
        self.dischargeResult.initialiseFromDictionary(data['dischargeResult'])

        # Array of discharge records
        if data['dischargeRecords'] != None:
            for dataItem in data['dischargeRecords']:
                dischargeRecord = DischargeRecord()
                dischargeRecord.initialiseFromDictionary(dataItem)
                self.dischargeRecords.append(dischargeRecord)

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a u d s set temperature from liq frac calculation.
class UDSSetTemperatureFromLiqFracCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Material
        self.material = Material()

        # Phase to be released (should be Two-Phase, if not this method simply returns)
        self.phaseToBeReleased = Phase.VAPOUR

        # Input liquid fraction
        self.liquidFraction = 0.0


# U d s set temperature from liq frac calculation class.
class UDSSetTemperatureFromLiqFracCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Material
        self.material = Material()

        # Phase to be released (should be Two-Phase, if not this method simply returns)
        self.phaseToBeReleased = Phase.VAPOUR

        # Input liquid fraction
        self.liquidFraction = 0.0

        # Calculation outputs.
        # Calculated temperature
        self.temperature = 0.0

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # UDSSetTemperatureFromLiqFrac calculation run method.
    def run(self) -> ResultCode:

        # Create the u d s set temperature from liq frac request.
        udsSetTemperatureFromLiqFracCalculationRequest = UDSSetTemperatureFromLiqFracCalculationRequest()

        # Initialise the member properties.

        udsSetTemperatureFromLiqFracCalculationRequest.material = self.material
        udsSetTemperatureFromLiqFracCalculationRequest.phaseToBeReleased = self.phaseToBeReleased
        udsSetTemperatureFromLiqFracCalculationRequest.liquidFraction = self.liquidFraction

        requestJson = jsons.dumps(udsSetTemperatureFromLiqFracCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculateudssettemperaturefromliqfrac?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            udsSetTemperatureFromLiqFracCalculationResponse = UDSSetTemperatureFromLiqFracCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                udsSetTemperatureFromLiqFracCalculationResponse.initialiseFromDictionary(json)

                self.temperature = udsSetTemperatureFromLiqFracCalculationResponse.temperature
                self.resultCode = udsSetTemperatureFromLiqFracCalculationResponse.resultCode
                self.messages = udsSetTemperatureFromLiqFracCalculationResponse.messages
                self.calculationElapsedTime = udsSetTemperatureFromLiqFracCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the UDSSetTemperatureFromLiqFrac calculation object to print itself.
    def print(self):

        # UDSSetTemperatureFromLiqFrac
        print('** UDSSetTemperatureFromLiqFrac')

        # material
        self.material.print()

        print(self.phaseToBeReleased)
        print('{0}\t{1}'.format('Phase to be released', self.phaseToBeReleased))

        print(self.liquidFraction)
        print('{0}\t{1}'.format('Liquid fraction', self.liquidFraction))

        # temperature
        print('{0}\t{1}'.format('Temperature', self.temperature))

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a u d s set temperature from liq frac calculation.
class UDSSetTemperatureFromLiqFracCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Calculated temperature
        self.temperature = 0.0

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Calculated temperature
        self.temperature = float(data['temperature'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a calc thermo paths calculation.
class CalcThermoPathsCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Definition of pure component / mixture
        self.material = Material()

        # Initial pressure and temperature
        self.initialState = State()


# Calc thermo paths calculation class.
class CalcThermoPathsCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Definition of pure component / mixture
        self.material = Material()

        # Initial pressure and temperature
        self.initialState = State()

        # Calculation outputs.
        # Callback for individual points along the thermodynamic paths
        self.thermoPathRecords = list[ThermoPathRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # CalcThermoPaths calculation run method.
    def run(self) -> ResultCode:

        # Create the calc thermo paths request.
        calcThermoPathsCalculationRequest = CalcThermoPathsCalculationRequest()

        # Initialise the member properties.

        calcThermoPathsCalculationRequest.material = self.material
        calcThermoPathsCalculationRequest.initialState = self.initialState

        requestJson = jsons.dumps(calcThermoPathsCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatecalcthermopaths?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            calcThermoPathsCalculationResponse = CalcThermoPathsCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                calcThermoPathsCalculationResponse.initialiseFromDictionary(json)

                self.thermoPathRecords = calcThermoPathsCalculationResponse.thermoPathRecords
                self.resultCode = calcThermoPathsCalculationResponse.resultCode
                self.messages = calcThermoPathsCalculationResponse.messages
                self.calculationElapsedTime = calcThermoPathsCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the CalcThermoPaths calculation object to print itself.
    def print(self):

        # CalcThermoPaths
        print('** CalcThermoPaths')

        # material
        self.material.print()

        # initialState
        self.initialState.print()

        for thermoPathRecord in self.thermoPathRecords:
            thermoPathRecord.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a calc thermo paths calculation.
class CalcThermoPathsCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Callback for individual points along the thermodynamic paths
        self.thermoPathRecords = list[ThermoPathRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Callback for individual points along the thermodynamic paths
        if data['thermoPathRecords'] != None:
            for dataItem in data['thermoPathRecords']:
                thermoPathRecord = ThermoPathRecord()
                thermoPathRecord.initialiseFromDictionary(dataItem)
                self.thermoPathRecords.append(thermoPathRecord)

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a get mass from vessel calculation.
class GetMassFromVesselCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Vessel (pressurised)
        self.vessel = Vessel()


# Get mass from vessel calculation class.
class GetMassFromVesselCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Vessel (pressurised)
        self.vessel = Vessel()

        # Calculation outputs.
        # Mass inventory in the vessel (kg)
        self.massInventory = 0.0

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # GetMassFromVessel calculation run method.
    def run(self) -> ResultCode:

        # Create the get mass from vessel request.
        getMassFromVesselCalculationRequest = GetMassFromVesselCalculationRequest()

        # Initialise the member properties.

        getMassFromVesselCalculationRequest.vessel = self.vessel

        requestJson = jsons.dumps(getMassFromVesselCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculategetmassfromvessel?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            getMassFromVesselCalculationResponse = GetMassFromVesselCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                getMassFromVesselCalculationResponse.initialiseFromDictionary(json)

                self.massInventory = getMassFromVesselCalculationResponse.massInventory
                self.resultCode = getMassFromVesselCalculationResponse.resultCode
                self.messages = getMassFromVesselCalculationResponse.messages
                self.calculationElapsedTime = getMassFromVesselCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the GetMassFromVessel calculation object to print itself.
    def print(self):

        # GetMassFromVessel
        print('** GetMassFromVessel')

        # vessel
        self.vessel.print()

        # massInventory
        print('{0}\t{1}'.format('Mass inventory', self.massInventory))

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a get mass from vessel calculation.
class GetMassFromVesselCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Mass inventory in the vessel (kg)
        self.massInventory = 0.0

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Mass inventory in the vessel (kg)
        self.massInventory = float(data['massInventory'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a u d s temperature limits calculation.
class UDSTemperatureLimitsCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Material
        self.material = Material()

        # Phase to be released (Vapour, Two-phase or Liquid)
        self.phaseToBeReleased = Phase.VAPOUR


# U d s temperature limits calculation class.
class UDSTemperatureLimitsCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Material
        self.material = Material()

        # Phase to be released (Vapour, Two-phase or Liquid)
        self.phaseToBeReleased = Phase.VAPOUR

        # Calculation outputs.
        # Lower temperature limit to ensure consistency
        self.minTemperature = 0.0

        # Upper temperature limit to ensure consistency
        self.maxTemperature = 0.0

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # UDSTemperatureLimits calculation run method.
    def run(self) -> ResultCode:

        # Create the u d s temperature limits request.
        udsTemperatureLimitsCalculationRequest = UDSTemperatureLimitsCalculationRequest()

        # Initialise the member properties.

        udsTemperatureLimitsCalculationRequest.material = self.material
        udsTemperatureLimitsCalculationRequest.phaseToBeReleased = self.phaseToBeReleased

        requestJson = jsons.dumps(udsTemperatureLimitsCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculateudstemperaturelimits?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            udsTemperatureLimitsCalculationResponse = UDSTemperatureLimitsCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                udsTemperatureLimitsCalculationResponse.initialiseFromDictionary(json)

                self.minTemperature = udsTemperatureLimitsCalculationResponse.minTemperature
                self.maxTemperature = udsTemperatureLimitsCalculationResponse.maxTemperature
                self.resultCode = udsTemperatureLimitsCalculationResponse.resultCode
                self.messages = udsTemperatureLimitsCalculationResponse.messages
                self.calculationElapsedTime = udsTemperatureLimitsCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the UDSTemperatureLimits calculation object to print itself.
    def print(self):

        # UDSTemperatureLimits
        print('** UDSTemperatureLimits')

        # material
        self.material.print()

        print(self.phaseToBeReleased)
        print('{0}\t{1}'.format('Phase to be released', self.phaseToBeReleased))

        # minTemperature
        print('{0}\t{1}'.format('Min temperature', self.minTemperature))

        # maxTemperature
        print('{0}\t{1}'.format('Max temperature', self.maxTemperature))

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a u d s temperature limits calculation.
class UDSTemperatureLimitsCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Lower temperature limit to ensure consistency
        self.minTemperature = 0.0

        # Upper temperature limit to ensure consistency
        self.maxTemperature = 0.0

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Lower temperature limit to ensure consistency
        self.minTemperature = float(data['minTemperature'])

        # Upper temperature limit to ensure consistency
        self.maxTemperature = float(data['maxTemperature'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a weather conversion calculation.
class WeatherConversionCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Input live weather station data
        self.weatherStationData = WeatherStationData()


# Weather conversion calculation class.
class WeatherConversionCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Input live weather station data
        self.weatherStationData = WeatherStationData()

        # Calculation outputs.
        # Weather data used in our APIs
        self.weather = Weather()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # WeatherConversion calculation run method.
    def run(self) -> ResultCode:

        # Create the weather conversion request.
        weatherConversionCalculationRequest = WeatherConversionCalculationRequest()

        # Initialise the member properties.

        weatherConversionCalculationRequest.weatherStationData = self.weatherStationData

        requestJson = jsons.dumps(weatherConversionCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'utilities/calculateweatherconversion?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            weatherConversionCalculationResponse = WeatherConversionCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                weatherConversionCalculationResponse.initialiseFromDictionary(json)

                self.weather = weatherConversionCalculationResponse.weather
                self.resultCode = weatherConversionCalculationResponse.resultCode
                self.messages = weatherConversionCalculationResponse.messages
                self.calculationElapsedTime = weatherConversionCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the WeatherConversion calculation object to print itself.
    def print(self):

        # WeatherConversion
        print('** WeatherConversion')

        # weatherStationData
        self.weatherStationData.print()

        # weather
        self.weather.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a weather conversion calculation.
class WeatherConversionCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Weather data used in our APIs
        self.weather = Weather()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Weather data used in our APIs
        self.weather.initialiseFromDictionary(data['weather'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a max conc footprint calculation.
class MaxConcFootprintCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # UDM scalar outputs
        self.scalarUdmOutputs = ScalarUdmOutputs()

        # Weather
        self.weather = Weather()

        # Dispersion definition
        self.dispersionRecords = list[DispersionRecord]()

        # Number of dispersion records
        self.dispersionRecordCount = 0

        # The dispersing surface
        self.substrate = Substrate()

        # Dispersion view configuration
        self.dispersionOutputConfig = DispersionOutputConfig()

        # Material with post-discharge composition
        self.material = Material()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()


# Max conc footprint calculation class.
class MaxConcFootprintCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # UDM scalar outputs
        self.scalarUdmOutputs = ScalarUdmOutputs()

        # Weather
        self.weather = Weather()

        # Dispersion definition
        self.dispersionRecords = list[DispersionRecord]()


        # The dispersing surface
        self.substrate = Substrate()

        # Dispersion view configuration
        self.dispersionOutputConfig = DispersionOutputConfig()

        # Material with post-discharge composition
        self.material = Material()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Calculation outputs.
        # Concentration of interest
        self.concUsed = 0.0

        # Array of footprint results
        self.contourPoints = list[LocalPosition]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # MaxConcFootprint calculation run method.
    def run(self) -> ResultCode:

        # Create the max conc footprint request.
        maxConcFootprintCalculationRequest = MaxConcFootprintCalculationRequest()

        # Initialise the member properties.

        maxConcFootprintCalculationRequest.scalarUdmOutputs = self.scalarUdmOutputs
        maxConcFootprintCalculationRequest.weather = self.weather
        maxConcFootprintCalculationRequest.dispersionRecords = self.dispersionRecords
        maxConcFootprintCalculationRequest.dispersionRecordCount = len(self.dispersionRecords)
        maxConcFootprintCalculationRequest.substrate = self.substrate
        maxConcFootprintCalculationRequest.dispersionOutputConfig = self.dispersionOutputConfig
        maxConcFootprintCalculationRequest.material = self.material
        maxConcFootprintCalculationRequest.dispersionParameters = self.dispersionParameters

        requestJson = jsons.dumps(maxConcFootprintCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatemaxconcfootprint?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            maxConcFootprintCalculationResponse = MaxConcFootprintCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                maxConcFootprintCalculationResponse.initialiseFromDictionary(json)

                self.concUsed = maxConcFootprintCalculationResponse.concUsed
                self.contourPoints = maxConcFootprintCalculationResponse.contourPoints
                self.resultCode = maxConcFootprintCalculationResponse.resultCode
                self.messages = maxConcFootprintCalculationResponse.messages
                self.calculationElapsedTime = maxConcFootprintCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the MaxConcFootprint calculation object to print itself.
    def print(self):

        # MaxConcFootprint
        print('** MaxConcFootprint')

        # scalarUdmOutputs
        self.scalarUdmOutputs.print()

        # weather
        self.weather.print()

        for item in self.dispersionRecords:
            item.print()


        # substrate
        self.substrate.print()

        # dispersionOutputConfig
        self.dispersionOutputConfig.print()

        # material
        self.material.print()

        # dispersionParameters
        self.dispersionParameters.print()

        # concUsed
        print('{0}\t{1}'.format('Conc used', self.concUsed))

        for contourPoint in self.contourPoints:
            contourPoint.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a max conc footprint calculation.
class MaxConcFootprintCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Concentration of interest
        self.concUsed = 0.0

        # Array of footprint results
        self.contourPoints = list[LocalPosition]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Concentration of interest
        self.concUsed = float(data['concUsed'])

        # Array of footprint results
        if data['contourPoints'] != None:
            for dataItem in data['contourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.contourPoints.append(localPosition)

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a distances to conc levels calculation.
class DistancesToConcLevelsCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # UDM scalar outputs
        self.scalarUdmOutputs = ScalarUdmOutputs()

        # Weather
        self.weather = Weather()

        # Dispersion definition
        self.dispersionRecords = list[DispersionRecord]()

        # Number of dispersion records
        self.dispersionRecordCount = 0

        # The dispersing surface
        self.substrate = Substrate()

        # Concentration levels
        self.dispersionOutputConfigs = list[DispersionOutputConfig]()

        # Number of concentration levels
        self.dispersionOutputConfigCount = 0

        # Material with post-discharge composition
        self.material = Material()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()


# Distances to conc levels calculation class.
class DistancesToConcLevelsCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # UDM scalar outputs
        self.scalarUdmOutputs = ScalarUdmOutputs()

        # Weather
        self.weather = Weather()

        # Dispersion definition
        self.dispersionRecords = list[DispersionRecord]()


        # The dispersing surface
        self.substrate = Substrate()

        # Concentration levels
        self.dispersionOutputConfigs = list[DispersionOutputConfig]()


        # Material with post-discharge composition
        self.material = Material()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Calculation outputs.
        # Concentrations of interest
        self.concUsed = []

        # Distances to concentration of interest
        self.distances = []

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # DistancesToConcLevels calculation run method.
    def run(self) -> ResultCode:

        # Create the distances to conc levels request.
        distancesToConcLevelsCalculationRequest = DistancesToConcLevelsCalculationRequest()

        # Initialise the member properties.

        distancesToConcLevelsCalculationRequest.scalarUdmOutputs = self.scalarUdmOutputs
        distancesToConcLevelsCalculationRequest.weather = self.weather
        distancesToConcLevelsCalculationRequest.dispersionRecords = self.dispersionRecords
        distancesToConcLevelsCalculationRequest.dispersionRecordCount = len(self.dispersionRecords)
        distancesToConcLevelsCalculationRequest.substrate = self.substrate
        distancesToConcLevelsCalculationRequest.dispersionOutputConfigs = self.dispersionOutputConfigs
        distancesToConcLevelsCalculationRequest.dispersionOutputConfigCount = len(self.dispersionOutputConfigs)
        distancesToConcLevelsCalculationRequest.material = self.material
        distancesToConcLevelsCalculationRequest.dispersionParameters = self.dispersionParameters

        requestJson = jsons.dumps(distancesToConcLevelsCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatedistancestoconclevels?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            distancesToConcLevelsCalculationResponse = DistancesToConcLevelsCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                distancesToConcLevelsCalculationResponse.initialiseFromDictionary(json)

                self.concUsed = distancesToConcLevelsCalculationResponse.concUsed
                self.distances = distancesToConcLevelsCalculationResponse.distances
                self.resultCode = distancesToConcLevelsCalculationResponse.resultCode
                self.messages = distancesToConcLevelsCalculationResponse.messages
                self.calculationElapsedTime = distancesToConcLevelsCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the DistancesToConcLevels calculation object to print itself.
    def print(self):

        # DistancesToConcLevels
        print('** DistancesToConcLevels')

        # scalarUdmOutputs
        self.scalarUdmOutputs.print()

        # weather
        self.weather.print()

        for item in self.dispersionRecords:
            item.print()


        # substrate
        self.substrate.print()

        for item in self.dispersionOutputConfigs:
            item.print()


        # material
        self.material.print()

        # dispersionParameters
        self.dispersionParameters.print()

        # concUsed
        for item in self.concUsed:
            print('{0}'.format(item))

        # distances
        for item in self.distances:
            print('{0}'.format(item))

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a distances to conc levels calculation.
class DistancesToConcLevelsCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Concentrations of interest
        self.concUsed = []

        # Distances to concentration of interest
        self.distances = []

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Concentrations of interest
        if data['concUsed'] != None:
            for dataItem in data['concUsed']:
                self.concUsed.append(float(dataItem))

        # Distances to concentration of interest
        if data['distances'] != None:
            for dataItem in data['distances']:
                self.distances.append(float(dataItem))

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a jet fire calculation.
class JetFireCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Material with post-discharge composition
        self.material = Material()

        # Discharge / source term definition
        self.dischargeRecords = list[DischargeRecord]()

        # Number of discharge records
        self.dischargeRecordCount = 0

        # Discharge / source term definition
        self.dischargeResult = DischargeResult()

        # Weather
        self.weather = Weather()

        # Substrate
        self.substrate = Substrate()

        # Flammable parameters
        self.flammableParameters = FlammableParameters()


# Jet fire calculation class.
class JetFireCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Material with post-discharge composition
        self.material = Material()

        # Discharge / source term definition
        self.dischargeRecords = list[DischargeRecord]()


        # Discharge / source term definition
        self.dischargeResult = DischargeResult()

        # Weather
        self.weather = Weather()

        # Substrate
        self.substrate = Substrate()

        # Flammable parameters
        self.flammableParameters = FlammableParameters()

        # Calculation outputs.
        # Flame scalar results
        self.flameResult = FlameResult()

        # Array of jet fire flame records
        self.flameRecords = list[FlameRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # JetFire calculation run method.
    def run(self) -> ResultCode:

        # Create the jet fire request.
        jetFireCalculationRequest = JetFireCalculationRequest()

        # Initialise the member properties.

        jetFireCalculationRequest.material = self.material
        jetFireCalculationRequest.dischargeRecords = self.dischargeRecords
        jetFireCalculationRequest.dischargeRecordCount = len(self.dischargeRecords)
        jetFireCalculationRequest.dischargeResult = self.dischargeResult
        jetFireCalculationRequest.weather = self.weather
        jetFireCalculationRequest.substrate = self.substrate
        jetFireCalculationRequest.flammableParameters = self.flammableParameters

        requestJson = jsons.dumps(jetFireCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatejetfire?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            jetFireCalculationResponse = JetFireCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                jetFireCalculationResponse.initialiseFromDictionary(json)

                self.flameResult = jetFireCalculationResponse.flameResult
                self.flameRecords = jetFireCalculationResponse.flameRecords
                self.resultCode = jetFireCalculationResponse.resultCode
                self.messages = jetFireCalculationResponse.messages
                self.calculationElapsedTime = jetFireCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the JetFire calculation object to print itself.
    def print(self):

        # JetFire
        print('** JetFire')

        # material
        self.material.print()

        for item in self.dischargeRecords:
            item.print()


        # dischargeResult
        self.dischargeResult.print()

        # weather
        self.weather.print()

        # substrate
        self.substrate.print()

        # flammableParameters
        self.flammableParameters.print()

        # flameResult
        self.flameResult.print()

        for flameRecord in self.flameRecords:
            flameRecord.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a jet fire calculation.
class JetFireCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Flame scalar results
        self.flameResult = FlameResult()

        # Array of jet fire flame records
        self.flameRecords = list[FlameRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Flame scalar results
        self.flameResult.initialiseFromDictionary(data['flameResult'])

        # Array of jet fire flame records
        if data['flameRecords'] != None:
            for dataItem in data['flameRecords']:
                flameRecord = FlameRecord()
                flameRecord.initialiseFromDictionary(dataItem)
                self.flameRecords.append(flameRecord)

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a convert composition mole to mass calculation.
class ConvertCompositionMoleToMassCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Mixture to have composition converted
        self.mixture = Material()

        # Input composition of mixture in mole basis
        self.compositionMoles = []

        # Number of components in mixture
        self.compositionMolesCount = 0


# Convert composition mole to mass calculation class.
class ConvertCompositionMoleToMassCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Mixture to have composition converted
        self.mixture = Material()

        # Input composition of mixture in mole basis
        self.compositionMoles = []

        # Number of components in mixture
        self.compositionMolesCount = 0

        # Calculation outputs.
        # Output composition of mixture in mass basis
        self.compositionMass = []

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # ConvertCompositionMoleToMass calculation run method.
    def run(self) -> ResultCode:

        # Create the convert composition mole to mass request.
        convertCompositionMoleToMassCalculationRequest = ConvertCompositionMoleToMassCalculationRequest()

        # Initialise the member properties.

        convertCompositionMoleToMassCalculationRequest.mixture = self.mixture
        convertCompositionMoleToMassCalculationRequest.compositionMoles = self.compositionMoles
        convertCompositionMoleToMassCalculationRequest.compositionMolesCount = self.compositionMolesCount

        requestJson = jsons.dumps(convertCompositionMoleToMassCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculateconvertcompositionmoletomass?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            convertCompositionMoleToMassCalculationResponse = ConvertCompositionMoleToMassCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                convertCompositionMoleToMassCalculationResponse.initialiseFromDictionary(json)

                self.compositionMass = convertCompositionMoleToMassCalculationResponse.compositionMass
                self.resultCode = convertCompositionMoleToMassCalculationResponse.resultCode
                self.messages = convertCompositionMoleToMassCalculationResponse.messages
                self.calculationElapsedTime = convertCompositionMoleToMassCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the ConvertCompositionMoleToMass calculation object to print itself.
    def print(self):

        # ConvertCompositionMoleToMass
        print('** ConvertCompositionMoleToMass')

        # mixture
        self.mixture.print()

        for item in self.compositionMoles:
            print('{0}\t{1}'.format('Composition moles', item))


        # compositionMass
        for item in self.compositionMass:
            print('{0}'.format(item))

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a convert composition mole to mass calculation.
class ConvertCompositionMoleToMassCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Output composition of mixture in mass basis
        self.compositionMass = []

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Output composition of mixture in mass basis
        if data['compositionMass'] != None:
            for dataItem in data['compositionMass']:
                self.compositionMass.append(float(dataItem))

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a fireball calculation.
class FireballCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Material with post-discharge composition
        self.material = Material()

        # The thermodynamic conditions
        self.state = State()

        # Discharge / source term definition
        self.dischargeRecords = list[DischargeRecord]()

        # Number of discharge records
        self.dischargeRecordCount = 0

        # Discharge / source term definition
        self.dischargeResult = DischargeResult()

        # Weather
        self.weather = Weather()


# Fireball calculation class.
class FireballCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Material with post-discharge composition
        self.material = Material()

        # The thermodynamic conditions
        self.state = State()

        # Discharge / source term definition
        self.dischargeRecords = list[DischargeRecord]()


        # Discharge / source term definition
        self.dischargeResult = DischargeResult()

        # Weather
        self.weather = Weather()

        # Calculation outputs.
        # Flame scalar result
        self.flameResult = FlameResult()

        # Array of fireball flame records
        self.flameRecords = list[FlameRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # Fireball calculation run method.
    def run(self) -> ResultCode:

        # Create the fireball request.
        fireballCalculationRequest = FireballCalculationRequest()

        # Initialise the member properties.

        fireballCalculationRequest.material = self.material
        fireballCalculationRequest.state = self.state
        fireballCalculationRequest.dischargeRecords = self.dischargeRecords
        fireballCalculationRequest.dischargeRecordCount = len(self.dischargeRecords)
        fireballCalculationRequest.dischargeResult = self.dischargeResult
        fireballCalculationRequest.weather = self.weather

        requestJson = jsons.dumps(fireballCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatefireball?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            fireballCalculationResponse = FireballCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                fireballCalculationResponse.initialiseFromDictionary(json)

                self.flameResult = fireballCalculationResponse.flameResult
                self.flameRecords = fireballCalculationResponse.flameRecords
                self.resultCode = fireballCalculationResponse.resultCode
                self.messages = fireballCalculationResponse.messages
                self.calculationElapsedTime = fireballCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the Fireball calculation object to print itself.
    def print(self):

        # Fireball
        print('** Fireball')

        # material
        self.material.print()

        # state
        self.state.print()

        for item in self.dischargeRecords:
            item.print()


        # dischargeResult
        self.dischargeResult.print()

        # weather
        self.weather.print()

        # flameResult
        self.flameResult.print()

        for flameRecord in self.flameRecords:
            flameRecord.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a fireball calculation.
class FireballCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Flame scalar result
        self.flameResult = FlameResult()

        # Array of fireball flame records
        self.flameRecords = list[FlameRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Flame scalar result
        self.flameResult.initialiseFromDictionary(data['flameResult'])

        # Array of fireball flame records
        if data['flameRecords'] != None:
            for dataItem in data['flameRecords']:
                flameRecord = FlameRecord()
                flameRecord.initialiseFromDictionary(dataItem)
                self.flameRecords.append(flameRecord)

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a properties dippr p t calculation.
class PropertiesDipprPTCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Composition (5 max as using spreadsheet entry point)
        self.material = Material()

        # Range of temperatures and pressures to be considered
        self.range = PTRange()


# Properties dippr p t calculation class.
class PropertiesDipprPTCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Composition (5 max as using spreadsheet entry point)
        self.material = Material()

        # Range of temperatures and pressures to be considered
        self.range = PTRange()

        # Calculation outputs.
        # Set of property result arrays at individial PT values
        self.result = PropertiesDipprPT1()

        # Set of property result arrays at individial PT values
        self.result2 = PropertiesDipprPT2()

        # Set of property result arrays at individial PT values
        self.result3 = PropertiesDipprPT3()

        # Response code
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # PropertiesDipprPT calculation run method.
    def run(self) -> ResultCode:

        # Create the properties dippr p t request.
        propertiesDipprPTCalculationRequest = PropertiesDipprPTCalculationRequest()

        # Initialise the member properties.

        propertiesDipprPTCalculationRequest.material = self.material
        propertiesDipprPTCalculationRequest.range = self.range

        requestJson = jsons.dumps(propertiesDipprPTCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatepropertiesdipprpt?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            propertiesDipprPTCalculationResponse = PropertiesDipprPTCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                propertiesDipprPTCalculationResponse.initialiseFromDictionary(json)

                self.result = propertiesDipprPTCalculationResponse.result
                self.result2 = propertiesDipprPTCalculationResponse.result2
                self.result3 = propertiesDipprPTCalculationResponse.result3
                self.resultCode = propertiesDipprPTCalculationResponse.resultCode
                self.messages = propertiesDipprPTCalculationResponse.messages
                self.calculationElapsedTime = propertiesDipprPTCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the PropertiesDipprPT calculation object to print itself.
    def print(self):

        # PropertiesDipprPT
        print('** PropertiesDipprPT')

        # material
        self.material.print()

        # range
        self.range.print()

        # result
        self.result.print()

        # result2
        self.result2.print()

        # result3
        self.result3.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a properties dippr p t calculation.
class PropertiesDipprPTCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Set of property result arrays at individial PT values
        self.result = PropertiesDipprPT1()

        # Set of property result arrays at individial PT values
        self.result2 = PropertiesDipprPT2()

        # Set of property result arrays at individial PT values
        self.result3 = PropertiesDipprPT3()

        # Response code
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Set of property result arrays at individial PT values
        self.result.initialiseFromDictionary(data['result'])

        # Set of property result arrays at individial PT values
        self.result2.initialiseFromDictionary(data['result2'])

        # Set of property result arrays at individial PT values
        self.result3.initialiseFromDictionary(data['result3'])

        # Response code
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a flare stack designer calculation.
class FlareStackDesignerCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Flare stack asset
        self.flareStack = FlareStack()

        # Data that defines the design requirements
        self.flareStackConstraint = Constraint()

        # Weather
        self.weather = Weather()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # Substrate data
        self.substrate = Substrate()

        # Flammable parameters
        self.flammableParameters = FlammableParameters()

        # Defines the flammable results of interest
        self.flammableOutputConfig = FlammableOutputConfig()


# Flare stack designer calculation class.
class FlareStackDesignerCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Flare stack asset
        self.flareStack = FlareStack()

        # Data that defines the design requirements
        self.flareStackConstraint = Constraint()

        # Weather
        self.weather = Weather()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # Substrate data
        self.substrate = Substrate()

        # Flammable parameters
        self.flammableParameters = FlammableParameters()

        # Defines the flammable results of interest
        self.flammableOutputConfig = FlammableOutputConfig()

        # Calculation outputs.
        # Value of design variable that satisfies the design target
        self.designSolution = 0.0

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # FlareStackDesigner calculation run method.
    def run(self) -> ResultCode:

        # Create the flare stack designer request.
        flareStackDesignerCalculationRequest = FlareStackDesignerCalculationRequest()

        # Initialise the member properties.

        flareStackDesignerCalculationRequest.flareStack = self.flareStack
        flareStackDesignerCalculationRequest.flareStackConstraint = self.flareStackConstraint
        flareStackDesignerCalculationRequest.weather = self.weather
        flareStackDesignerCalculationRequest.dischargeParameters = self.dischargeParameters
        flareStackDesignerCalculationRequest.substrate = self.substrate
        flareStackDesignerCalculationRequest.flammableParameters = self.flammableParameters
        flareStackDesignerCalculationRequest.flammableOutputConfig = self.flammableOutputConfig

        requestJson = jsons.dumps(flareStackDesignerCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculateflarestackdesigner?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            flareStackDesignerCalculationResponse = FlareStackDesignerCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                flareStackDesignerCalculationResponse.initialiseFromDictionary(json)

                self.designSolution = flareStackDesignerCalculationResponse.designSolution
                self.resultCode = flareStackDesignerCalculationResponse.resultCode
                self.messages = flareStackDesignerCalculationResponse.messages
                self.calculationElapsedTime = flareStackDesignerCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the FlareStackDesigner calculation object to print itself.
    def print(self):

        # FlareStackDesigner
        print('** FlareStackDesigner')

        # flareStack
        self.flareStack.print()

        # flareStackConstraint
        self.flareStackConstraint.print()

        # weather
        self.weather.print()

        # dischargeParameters
        self.dischargeParameters.print()

        # substrate
        self.substrate.print()

        # flammableParameters
        self.flammableParameters.print()

        # flammableOutputConfig
        self.flammableOutputConfig.print()

        # designSolution
        print('{0}\t{1}'.format('Design solution', self.designSolution))

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a flare stack designer calculation.
class FlareStackDesignerCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Value of design variable that satisfies the design target
        self.designSolution = 0.0

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Value of design variable that satisfies the design target
        self.designSolution = float(data['designSolution'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a lethality distance calculation.
class LethalityDistanceCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Material with post-discharge composition
        self.material = Material()

        # UDM scalar outputs
        self.scalarUdmOutputs = ScalarUdmOutputs()

        # Weather
        self.weather = Weather()

        # Dispersion definition
        self.dispersionRecords = list[DispersionRecord]()

        # Number of dispersion records
        self.dispersionRecordCount = 0

        # The dispersing surface
        self.substrate = Substrate()

        # Dispersion view configuration
        self.dispersionOutputConfig = DispersionOutputConfig()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()


# Lethality distance calculation class.
class LethalityDistanceCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Material with post-discharge composition
        self.material = Material()

        # UDM scalar outputs
        self.scalarUdmOutputs = ScalarUdmOutputs()

        # Weather
        self.weather = Weather()

        # Dispersion definition
        self.dispersionRecords = list[DispersionRecord]()


        # The dispersing surface
        self.substrate = Substrate()

        # Dispersion view configuration
        self.dispersionOutputConfig = DispersionOutputConfig()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Calculation outputs.
        # Array of toxic results
        self.toxicRecords = list[ToxicRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # LethalityDistance calculation run method.
    def run(self) -> ResultCode:

        # Create the lethality distance request.
        lethalityDistanceCalculationRequest = LethalityDistanceCalculationRequest()

        # Initialise the member properties.

        lethalityDistanceCalculationRequest.material = self.material
        lethalityDistanceCalculationRequest.scalarUdmOutputs = self.scalarUdmOutputs
        lethalityDistanceCalculationRequest.weather = self.weather
        lethalityDistanceCalculationRequest.dispersionRecords = self.dispersionRecords
        lethalityDistanceCalculationRequest.dispersionRecordCount = len(self.dispersionRecords)
        lethalityDistanceCalculationRequest.substrate = self.substrate
        lethalityDistanceCalculationRequest.dispersionOutputConfig = self.dispersionOutputConfig
        lethalityDistanceCalculationRequest.dispersionParameters = self.dispersionParameters

        requestJson = jsons.dumps(lethalityDistanceCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatelethalitydistance?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            lethalityDistanceCalculationResponse = LethalityDistanceCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                lethalityDistanceCalculationResponse.initialiseFromDictionary(json)

                self.toxicRecords = lethalityDistanceCalculationResponse.toxicRecords
                self.resultCode = lethalityDistanceCalculationResponse.resultCode
                self.messages = lethalityDistanceCalculationResponse.messages
                self.calculationElapsedTime = lethalityDistanceCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the LethalityDistance calculation object to print itself.
    def print(self):

        # LethalityDistance
        print('** LethalityDistance')

        # material
        self.material.print()

        # scalarUdmOutputs
        self.scalarUdmOutputs.print()

        # weather
        self.weather.print()

        for item in self.dispersionRecords:
            item.print()


        # substrate
        self.substrate.print()

        # dispersionOutputConfig
        self.dispersionOutputConfig.print()

        # dispersionParameters
        self.dispersionParameters.print()

        for toxicRecord in self.toxicRecords:
            toxicRecord.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a lethality distance calculation.
class LethalityDistanceCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Array of toxic results
        self.toxicRecords = list[ToxicRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Array of toxic results
        if data['toxicRecords'] != None:
            for dataItem in data['toxicRecords']:
                toxicRecord = ToxicRecord()
                toxicRecord.initialiseFromDictionary(dataItem)
                self.toxicRecords.append(toxicRecord)

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a dispersion calculation.
class DispersionCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Material with post-discharge composition
        self.material = Material()

        # The dispersing surface
        self.substrate = Substrate()

        # Discharge / source term definition
        self.dischargeResult = DischargeResult()

        # Discharge / source term definition
        self.dischargeRecords = list[DischargeRecord]()

        # Number of discharge records
        self.dischargeRecordCount = 0

        # Weather
        self.weather = Weather()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Concentration at which the dispersion calculations will terminate (v/v fraction)
        self.endPointConcentration = 0.0


# Dispersion calculation class.
class DispersionCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Material with post-discharge composition
        self.material = Material()

        # The dispersing surface
        self.substrate = Substrate()

        # Discharge / source term definition
        self.dischargeResult = DischargeResult()

        # Discharge / source term definition
        self.dischargeRecords = list[DischargeRecord]()


        # Weather
        self.weather = Weather()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Concentration at which the dispersion calculations will terminate (v/v fraction)
        self.endPointConcentration = 0.0

        # Calculation outputs.
        # UDM scalar outputs
        self.scalarUdmOutputs = ScalarUdmOutputs()

        # Array of Dispersion records
        self.dispersionRecords = list[DispersionRecord]()

        # Array of Pool records
        self.poolRecords = list[PoolRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # Dispersion calculation run method.
    def run(self) -> ResultCode:

        # Create the dispersion request.
        dispersionCalculationRequest = DispersionCalculationRequest()

        # Initialise the member properties.

        dispersionCalculationRequest.material = self.material
        dispersionCalculationRequest.substrate = self.substrate
        dispersionCalculationRequest.dischargeResult = self.dischargeResult
        dispersionCalculationRequest.dischargeRecords = self.dischargeRecords
        dispersionCalculationRequest.dischargeRecordCount = len(self.dischargeRecords)
        dispersionCalculationRequest.weather = self.weather
        dispersionCalculationRequest.dispersionParameters = self.dispersionParameters
        dispersionCalculationRequest.endPointConcentration = self.endPointConcentration

        requestJson = jsons.dumps(dispersionCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatedispersion?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            dispersionCalculationResponse = DispersionCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                dispersionCalculationResponse.initialiseFromDictionary(json)

                self.scalarUdmOutputs = dispersionCalculationResponse.scalarUdmOutputs
                self.dispersionRecords = dispersionCalculationResponse.dispersionRecords
                self.poolRecords = dispersionCalculationResponse.poolRecords
                self.resultCode = dispersionCalculationResponse.resultCode
                self.messages = dispersionCalculationResponse.messages
                self.calculationElapsedTime = dispersionCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the Dispersion calculation object to print itself.
    def print(self):

        # Dispersion
        print('** Dispersion')

        # material
        self.material.print()

        # substrate
        self.substrate.print()

        # dischargeResult
        self.dischargeResult.print()

        for item in self.dischargeRecords:
            item.print()


        # weather
        self.weather.print()

        # dispersionParameters
        self.dispersionParameters.print()

        print(self.endPointConcentration)
        print('{0}\t{1}'.format('End point concentration', self.endPointConcentration))

        # scalarUdmOutputs
        self.scalarUdmOutputs.print()

        for dispersionRecord in self.dispersionRecords:
            dispersionRecord.print()

        for poolRecord in self.poolRecords:
            poolRecord.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a dispersion calculation.
class DispersionCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # UDM scalar outputs
        self.scalarUdmOutputs = ScalarUdmOutputs()

        # Array of Dispersion records
        self.dispersionRecords = list[DispersionRecord]()

        # Array of Pool records
        self.poolRecords = list[PoolRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # UDM scalar outputs
        self.scalarUdmOutputs.initialiseFromDictionary(data['scalarUdmOutputs'])

        # Array of Dispersion records
        if data['dispersionRecords'] != None:
            for dataItem in data['dispersionRecords']:
                dispersionRecord = DispersionRecord()
                dispersionRecord.initialiseFromDictionary(dataItem)
                self.dispersionRecords.append(dispersionRecord)

        # Array of Pool records
        if data['poolRecords'] != None:
            for dataItem in data['poolRecords']:
                poolRecord = PoolRecord()
                poolRecord.initialiseFromDictionary(dataItem)
                self.poolRecords.append(poolRecord)

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a set u d s for linked run calculation.
class SetUDSForLinkedRunCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Vessel material
        self.material = Material()

        # Duration of the release
        self.releaseDuration = 0.0

        # Phase to be release
        self.phaseRelease = Phase.VAPOUR

        # Final temperature
        self.finalTemperature = 0.0

        # Final liquid fraction
        self.liquidFraction = 0.0

        # Mass flow rate
        self.massFlow = 0.0

        # Final velocity
        self.finalVelocity = 0.0

        # Droplet diameter
        self.dropletDiameter = 0.0

        # Pre-dilution air rate
        self.preDilutionAirRate = 0.0

        # Release elevation
        self.releaseElevation = 0.0

        # Release angle
        self.releaseAngle = 0.0


# Set u d s for linked run calculation class.
class SetUDSForLinkedRunCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Vessel material
        self.material = Material()

        # Duration of the release
        self.releaseDuration = 0.0

        # Phase to be release
        self.phaseRelease = Phase.VAPOUR

        # Final temperature
        self.finalTemperature = 0.0

        # Final liquid fraction
        self.liquidFraction = 0.0

        # Mass flow rate
        self.massFlow = 0.0

        # Final velocity
        self.finalVelocity = 0.0

        # Droplet diameter
        self.dropletDiameter = 0.0

        # Pre-dilution air rate
        self.preDilutionAirRate = 0.0

        # Release elevation
        self.releaseElevation = 0.0

        # Release angle
        self.releaseAngle = 0.0

        # Calculation outputs.
        # Discharge result
        self.dischargeResult = DischargeResult()

        # Discharge records
        self.dischargeRecords = list[DischargeRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # SetUDSForLinkedRun calculation run method.
    def run(self) -> ResultCode:

        # Create the set u d s for linked run request.
        setUDSForLinkedRunCalculationRequest = SetUDSForLinkedRunCalculationRequest()

        # Initialise the member properties.

        setUDSForLinkedRunCalculationRequest.material = self.material
        setUDSForLinkedRunCalculationRequest.releaseDuration = self.releaseDuration
        setUDSForLinkedRunCalculationRequest.phaseRelease = self.phaseRelease
        setUDSForLinkedRunCalculationRequest.finalTemperature = self.finalTemperature
        setUDSForLinkedRunCalculationRequest.liquidFraction = self.liquidFraction
        setUDSForLinkedRunCalculationRequest.massFlow = self.massFlow
        setUDSForLinkedRunCalculationRequest.finalVelocity = self.finalVelocity
        setUDSForLinkedRunCalculationRequest.dropletDiameter = self.dropletDiameter
        setUDSForLinkedRunCalculationRequest.preDilutionAirRate = self.preDilutionAirRate
        setUDSForLinkedRunCalculationRequest.releaseElevation = self.releaseElevation
        setUDSForLinkedRunCalculationRequest.releaseAngle = self.releaseAngle

        requestJson = jsons.dumps(setUDSForLinkedRunCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatesetudsforlinkedrun?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            setUDSForLinkedRunCalculationResponse = SetUDSForLinkedRunCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                setUDSForLinkedRunCalculationResponse.initialiseFromDictionary(json)

                self.dischargeResult = setUDSForLinkedRunCalculationResponse.dischargeResult
                self.dischargeRecords = setUDSForLinkedRunCalculationResponse.dischargeRecords
                self.resultCode = setUDSForLinkedRunCalculationResponse.resultCode
                self.messages = setUDSForLinkedRunCalculationResponse.messages
                self.calculationElapsedTime = setUDSForLinkedRunCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the SetUDSForLinkedRun calculation object to print itself.
    def print(self):

        # SetUDSForLinkedRun
        print('** SetUDSForLinkedRun')

        # material
        self.material.print()

        print(self.releaseDuration)
        print('{0}\t{1}'.format('Release duration', self.releaseDuration))

        print(self.phaseRelease)
        print('{0}\t{1}'.format('Phase release', self.phaseRelease))

        print(self.finalTemperature)
        print('{0}\t{1}'.format('Final temperature', self.finalTemperature))

        print(self.liquidFraction)
        print('{0}\t{1}'.format('Liquid fraction', self.liquidFraction))

        print(self.massFlow)
        print('{0}\t{1}'.format('Mass flow', self.massFlow))

        print(self.finalVelocity)
        print('{0}\t{1}'.format('Final velocity', self.finalVelocity))

        print(self.dropletDiameter)
        print('{0}\t{1}'.format('Droplet diameter', self.dropletDiameter))

        print(self.preDilutionAirRate)
        print('{0}\t{1}'.format('Pre dilution air rate', self.preDilutionAirRate))

        print(self.releaseElevation)
        print('{0}\t{1}'.format('Release elevation', self.releaseElevation))

        print(self.releaseAngle)
        print('{0}\t{1}'.format('Release angle', self.releaseAngle))

        # dischargeResult
        self.dischargeResult.print()

        for dischargeRecord in self.dischargeRecords:
            dischargeRecord.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a set u d s for linked run calculation.
class SetUDSForLinkedRunCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Discharge result
        self.dischargeResult = DischargeResult()

        # Discharge records
        self.dischargeRecords = list[DischargeRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Discharge result
        self.dischargeResult.initialiseFromDictionary(data['dischargeResult'])

        # Discharge records
        if data['dischargeRecords'] != None:
            for dataItem in data['dischargeRecords']:
                dischargeRecord = DischargeRecord()
                dischargeRecord.initialiseFromDictionary(dataItem)
                self.dischargeRecords.append(dischargeRecord)

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a concentration at point calculation.
class ConcentrationAtPointCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # UDM scalar outputs
        self.scalarUdmOutputs = ScalarUdmOutputs()

        # Weather
        self.weather = Weather()

        # Dispersion definition
        self.dispersionRecords = list[DispersionRecord]()

        # Number of dispersion records
        self.dispersionRecordCount = 0

        # The dispersing surface
        self.substrate = Substrate()

        # Dispersion view configuration
        self.dispersionOutputConfig = DispersionOutputConfig()

        # Material with post-discharge composition
        self.material = Material()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()


# Concentration at point calculation class.
class ConcentrationAtPointCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # UDM scalar outputs
        self.scalarUdmOutputs = ScalarUdmOutputs()

        # Weather
        self.weather = Weather()

        # Dispersion definition
        self.dispersionRecords = list[DispersionRecord]()


        # The dispersing surface
        self.substrate = Substrate()

        # Dispersion view configuration
        self.dispersionOutputConfig = DispersionOutputConfig()

        # Material with post-discharge composition
        self.material = Material()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Calculation outputs.
        # Concentration at a position of interest
        self.concentration = 0.0

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # ConcentrationAtPoint calculation run method.
    def run(self) -> ResultCode:

        # Create the concentration at point request.
        concentrationAtPointCalculationRequest = ConcentrationAtPointCalculationRequest()

        # Initialise the member properties.

        concentrationAtPointCalculationRequest.scalarUdmOutputs = self.scalarUdmOutputs
        concentrationAtPointCalculationRequest.weather = self.weather
        concentrationAtPointCalculationRequest.dispersionRecords = self.dispersionRecords
        concentrationAtPointCalculationRequest.dispersionRecordCount = len(self.dispersionRecords)
        concentrationAtPointCalculationRequest.substrate = self.substrate
        concentrationAtPointCalculationRequest.dispersionOutputConfig = self.dispersionOutputConfig
        concentrationAtPointCalculationRequest.material = self.material
        concentrationAtPointCalculationRequest.dispersionParameters = self.dispersionParameters

        requestJson = jsons.dumps(concentrationAtPointCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculateconcentrationatpoint?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            concentrationAtPointCalculationResponse = ConcentrationAtPointCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                concentrationAtPointCalculationResponse.initialiseFromDictionary(json)

                self.concentration = concentrationAtPointCalculationResponse.concentration
                self.resultCode = concentrationAtPointCalculationResponse.resultCode
                self.messages = concentrationAtPointCalculationResponse.messages
                self.calculationElapsedTime = concentrationAtPointCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the ConcentrationAtPoint calculation object to print itself.
    def print(self):

        # ConcentrationAtPoint
        print('** ConcentrationAtPoint')

        # scalarUdmOutputs
        self.scalarUdmOutputs.print()

        # weather
        self.weather.print()

        for item in self.dispersionRecords:
            item.print()


        # substrate
        self.substrate.print()

        # dispersionOutputConfig
        self.dispersionOutputConfig.print()

        # material
        self.material.print()

        # dispersionParameters
        self.dispersionParameters.print()

        # concentration
        print('{0}\t{1}'.format('Concentration', self.concentration))

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a concentration at point calculation.
class ConcentrationAtPointCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Concentration at a position of interest
        self.concentration = 0.0

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Concentration at a position of interest
        self.concentration = float(data['concentration'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a vessel state calculation.
class VesselStateCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # User-defined input material, pure component or mixture (max 20 components)
        self.material = Material()

        # Describes the fluid pressure, temperature, liquid fraction
        self.materialState = State()


# Vessel state calculation class.
class VesselStateCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # User-defined input material, pure component or mixture (max 20 components)
        self.material = Material()

        # Describes the fluid pressure, temperature, liquid fraction
        self.materialState = State()

        # Calculation outputs.
        # Describes the vessel storage conditions (Pure gas, Stratified Two-Phase or Pressurised liquid)
        self.vesselConditions = VesselConditions.PURE_GAS

        # Describes the fluid pressure, temperature and liquid fraction after the flash calculation
        self.outputState = State()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # VesselState calculation run method.
    def run(self) -> ResultCode:

        # Create the vessel state request.
        vesselStateCalculationRequest = VesselStateCalculationRequest()

        # Initialise the member properties.

        vesselStateCalculationRequest.material = self.material
        vesselStateCalculationRequest.materialState = self.materialState

        requestJson = jsons.dumps(vesselStateCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatevesselstate?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            vesselStateCalculationResponse = VesselStateCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                vesselStateCalculationResponse.initialiseFromDictionary(json)

                self.vesselConditions = vesselStateCalculationResponse.vesselConditions
                self.outputState = vesselStateCalculationResponse.outputState
                self.resultCode = vesselStateCalculationResponse.resultCode
                self.messages = vesselStateCalculationResponse.messages
                self.calculationElapsedTime = vesselStateCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the VesselState calculation object to print itself.
    def print(self):

        # VesselState
        print('** VesselState')

        # material
        self.material.print()

        # materialState
        self.materialState.print()

        # vesselConditions
        print('{0}\t{1}'.format('Vessel conditions', self.vesselConditions))

        # outputState
        self.outputState.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a vessel state calculation.
class VesselStateCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Describes the vessel storage conditions (Pure gas, Stratified Two-Phase or Pressurised liquid)
        self.vesselConditions = VesselConditions.PURE_GAS

        # Describes the fluid pressure, temperature and liquid fraction after the flash calculation
        self.outputState = State()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Describes the vessel storage conditions (Pure gas, Stratified Two-Phase or Pressurised liquid)
        self.vesselConditions = VesselConditions(data['vesselConditions'])

        # Describes the fluid pressure, temperature and liquid fraction after the flash calculation
        self.outputState.initialiseFromDictionary(data['outputState'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a distance to radiation calculation.
class DistanceToRadiationCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Scalar flame results
        self.flameResult = FlameResult()

        # Flame definition
        self.flameRecords = list[FlameRecord]()

        # Number of flame records
        self.flameRecordCount = 0

        # Weather
        self.weather = Weather()

        # Flammable parameters
        self.flammableParameters = FlammableParameters()

        # Settings of flammable contours view
        self.flammableOutputConfig = FlammableOutputConfig()


# Distance to radiation calculation class.
class DistanceToRadiationCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Scalar flame results
        self.flameResult = FlameResult()

        # Flame definition
        self.flameRecords = list[FlameRecord]()


        # Weather
        self.weather = Weather()

        # Flammable parameters
        self.flammableParameters = FlammableParameters()

        # Settings of flammable contours view
        self.flammableOutputConfig = FlammableOutputConfig()

        # Calculation outputs.
        # Distance to radiation level
        self.distance = 0.0

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # DistanceToRadiation calculation run method.
    def run(self) -> ResultCode:

        # Create the distance to radiation request.
        distanceToRadiationCalculationRequest = DistanceToRadiationCalculationRequest()

        # Initialise the member properties.

        distanceToRadiationCalculationRequest.flameResult = self.flameResult
        distanceToRadiationCalculationRequest.flameRecords = self.flameRecords
        distanceToRadiationCalculationRequest.flameRecordCount = len(self.flameRecords)
        distanceToRadiationCalculationRequest.weather = self.weather
        distanceToRadiationCalculationRequest.flammableParameters = self.flammableParameters
        distanceToRadiationCalculationRequest.flammableOutputConfig = self.flammableOutputConfig

        requestJson = jsons.dumps(distanceToRadiationCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatedistancetoradiation?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            distanceToRadiationCalculationResponse = DistanceToRadiationCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                distanceToRadiationCalculationResponse.initialiseFromDictionary(json)

                self.distance = distanceToRadiationCalculationResponse.distance
                self.resultCode = distanceToRadiationCalculationResponse.resultCode
                self.messages = distanceToRadiationCalculationResponse.messages
                self.calculationElapsedTime = distanceToRadiationCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the DistanceToRadiation calculation object to print itself.
    def print(self):

        # DistanceToRadiation
        print('** DistanceToRadiation')

        # flameResult
        self.flameResult.print()

        for item in self.flameRecords:
            item.print()


        # weather
        self.weather.print()

        # flammableParameters
        self.flammableParameters.print()

        # flammableOutputConfig
        self.flammableOutputConfig.print()

        # distance
        print('{0}\t{1}'.format('Distance', self.distance))

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a distance to radiation calculation.
class DistanceToRadiationCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Distance to radiation level
        self.distance = 0.0

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Distance to radiation level
        self.distance = float(data['distance'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a convert composition mass to mole calculation.
class ConvertCompositionMassToMoleCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Mixture to have composition converted
        self.mixture = Material()

        # Input composition of mixture in mass basis
        self.compositionMass = []

        # Number of components in mixture
        self.compositionMassCount = 0


# Convert composition mass to mole calculation class.
class ConvertCompositionMassToMoleCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Mixture to have composition converted
        self.mixture = Material()

        # Input composition of mixture in mass basis
        self.compositionMass = []

        # Number of components in mixture
        self.compositionMassCount = 0

        # Calculation outputs.
        # Output composition of mixture in mole basis
        self.compositionMole = []

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # ConvertCompositionMassToMole calculation run method.
    def run(self) -> ResultCode:

        # Create the convert composition mass to mole request.
        convertCompositionMassToMoleCalculationRequest = ConvertCompositionMassToMoleCalculationRequest()

        # Initialise the member properties.

        convertCompositionMassToMoleCalculationRequest.mixture = self.mixture
        convertCompositionMassToMoleCalculationRequest.compositionMass = self.compositionMass
        convertCompositionMassToMoleCalculationRequest.compositionMassCount = self.compositionMassCount

        requestJson = jsons.dumps(convertCompositionMassToMoleCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculateconvertcompositionmasstomole?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            convertCompositionMassToMoleCalculationResponse = ConvertCompositionMassToMoleCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                convertCompositionMassToMoleCalculationResponse.initialiseFromDictionary(json)

                self.compositionMole = convertCompositionMassToMoleCalculationResponse.compositionMole
                self.resultCode = convertCompositionMassToMoleCalculationResponse.resultCode
                self.messages = convertCompositionMassToMoleCalculationResponse.messages
                self.calculationElapsedTime = convertCompositionMassToMoleCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the ConvertCompositionMassToMole calculation object to print itself.
    def print(self):

        # ConvertCompositionMassToMole
        print('** ConvertCompositionMassToMole')

        # mixture
        self.mixture.print()

        for item in self.compositionMass:
            print('{0}\t{1}'.format('Composition mass', item))


        # compositionMole
        for item in self.compositionMole:
            print('{0}'.format(item))

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a convert composition mass to mole calculation.
class ConvertCompositionMassToMoleCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Output composition of mixture in mole basis
        self.compositionMole = []

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Output composition of mixture in mole basis
        if data['compositionMole'] != None:
            for dataItem in data['compositionMole']:
                self.compositionMole.append(float(dataItem))

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a long pipe breach calculation.
class LongPipeBreachCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Pipe equipment item
        self.pipe = Pipe()

        # Long pipeline scenario
        self.pipeBreach = PipeBreach()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()


# Long pipe breach calculation class.
class LongPipeBreachCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Pipe equipment item
        self.pipe = Pipe()

        # Long pipeline scenario
        self.pipeBreach = PipeBreach()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # Calculation outputs.
        # Composition of the released material (indentical to storage composition - using PC mode)
        self.exitMaterial = Material()

        # Scalar discharge results
        self.dischargeResult = DischargeResult()

        # Array of discharge records
        self.dischargeRecords = list[DischargeRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # LongPipeBreach calculation run method.
    def run(self) -> ResultCode:

        # Create the long pipe breach request.
        longPipeBreachCalculationRequest = LongPipeBreachCalculationRequest()

        # Initialise the member properties.

        longPipeBreachCalculationRequest.pipe = self.pipe
        longPipeBreachCalculationRequest.pipeBreach = self.pipeBreach
        longPipeBreachCalculationRequest.dischargeParameters = self.dischargeParameters

        requestJson = jsons.dumps(longPipeBreachCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatelongpipebreach?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            longPipeBreachCalculationResponse = LongPipeBreachCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                longPipeBreachCalculationResponse.initialiseFromDictionary(json)

                self.exitMaterial = longPipeBreachCalculationResponse.exitMaterial
                self.dischargeResult = longPipeBreachCalculationResponse.dischargeResult
                self.dischargeRecords = longPipeBreachCalculationResponse.dischargeRecords
                self.resultCode = longPipeBreachCalculationResponse.resultCode
                self.messages = longPipeBreachCalculationResponse.messages
                self.calculationElapsedTime = longPipeBreachCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the LongPipeBreach calculation object to print itself.
    def print(self):

        # LongPipeBreach
        print('** LongPipeBreach')

        # pipe
        self.pipe.print()

        # pipeBreach
        self.pipeBreach.print()

        # dischargeParameters
        self.dischargeParameters.print()

        # exitMaterial
        self.exitMaterial.print()

        # dischargeResult
        self.dischargeResult.print()

        for dischargeRecord in self.dischargeRecords:
            dischargeRecord.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a long pipe breach calculation.
class LongPipeBreachCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Composition of the released material (indentical to storage composition - using PC mode)
        self.exitMaterial = Material()

        # Scalar discharge results
        self.dischargeResult = DischargeResult()

        # Array of discharge records
        self.dischargeRecords = list[DischargeRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Composition of the released material (indentical to storage composition - using PC mode)
        self.exitMaterial.initialiseFromDictionary(data['exitMaterial'])

        # Scalar discharge results
        self.dischargeResult.initialiseFromDictionary(data['dischargeResult'])

        # Array of discharge records
        if data['dischargeRecords'] != None:
            for dataItem in data['dischargeRecords']:
                dischargeRecord = DischargeRecord()
                dischargeRecord.initialiseFromDictionary(dataItem)
                self.dischargeRecords.append(dischargeRecord)

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a vessel leak linked run calculation.
class VesselLeakLinkedRunCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Vessel definition
        self.vessel = Vessel()

        # Leak scenario
        self.leak = Leak()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # The dispersing surface
        self.substrate = Substrate()

        # Weather definition
        self.weather = Weather()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Concentration at which the dispersion calculations will terminate (v/v fraction)
        self.endPointConcentration = 0.0

        # Fire model parameters
        self.flammableParameters = FlammableParameters()

        # Explosion parameters
        self.explosionParameters = ExplosionParameters()

        # Flammable concentration levels (LFL fraction, LFL, UFL)
        self.dispersionFlamOutputConfigs = list[DispersionOutputConfig]()

        # Number of flammable concentration levels (LFL fraction, LFL, UFL)
        self.dispersionFlamOutputConfigCount = 0

        # Toxic concentration levels (concentration of interest)
        self.dispersionToxicOutputConfigs = list[DispersionOutputConfig]()

        # Number of toxic concentration levels (concentration of interest)
        self.dispersionToxicOutputConfigCount = 0

        # Radiation levels
        self.flammableOutputConfigs = list[FlammableOutputConfig]()

        # Number of radiation levels
        self.flammableOutputConfigCount = 0

        # Overpressure levels
        self.explosionOutputConfigs = list[ExplosionOutputConfig]()

        # Number of overpressure levels
        self.explosionOutputConfigCount = 0

        # Explosion confined volumes
        self.explosionConfinedVolumes = list[ExplosionConfinedVolume]()

        # Number of confined explosion sources
        self.explosionConfinedVolumeCount = 0


# Vessel leak linked run calculation class.
class VesselLeakLinkedRunCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Vessel definition
        self.vessel = Vessel()

        # Leak scenario
        self.leak = Leak()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # The dispersing surface
        self.substrate = Substrate()

        # Weather definition
        self.weather = Weather()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Concentration at which the dispersion calculations will terminate (v/v fraction)
        self.endPointConcentration = 0.0

        # Fire model parameters
        self.flammableParameters = FlammableParameters()

        # Explosion parameters
        self.explosionParameters = ExplosionParameters()

        # Flammable concentration levels (LFL fraction, LFL, UFL)
        self.dispersionFlamOutputConfigs = list[DispersionOutputConfig]()


        # Toxic concentration levels (concentration of interest)
        self.dispersionToxicOutputConfigs = list[DispersionOutputConfig]()


        # Radiation levels
        self.flammableOutputConfigs = list[FlammableOutputConfig]()


        # Overpressure levels
        self.explosionOutputConfigs = list[ExplosionOutputConfig]()


        # Explosion confined volumes
        self.explosionConfinedVolumes = list[ExplosionConfinedVolume]()


        # Calculation outputs.
        # Discharge data for table
        self.dischargeRecord = DischargeRecord()

        # Distances to jet fire radiation levels
        self.distancesToJetFireRadiation = []

        # Ellipses to jet fire radiation levels
        self.jetContourPoints = list[LocalPosition]()

        # Number of contour points for jet fire ellipses per radiation level
        self.nJetCountourPoints = []

        # Areas of jet fire ellipses
        self.areaEllipseJet = []

        # Distances to concentration levels (LFL fraction, LFL and UFL)
        self.distancesToFlamConcentration = []

        # Concentration levels (LFL fraction, LFL and UFL)
        self.flamConcentrationsUsed = []

        # Maximum concentration footprints at given concentration levels (LFL fraction, LFL and UFL)
        self.flamConcContourPoints = list[LocalPosition]()

        # Number of contour points per concentration level (LFL fraction, LFL and UFL)
        self.nFlamConcCountourPoints = []

        # Areas of maximum concentration footprints (LFL fraction, LFL and UFL)
        self.areaFootprintFlamConc = []

        # Distances to pool fire radiation levels
        self.distancesToPoolFireRadiation = []

        # Ellipses to pool fire radiation levels
        self.poolContourPoints = list[LocalPosition]()

        # Number of contour points for pool fire ellipses per radiation level
        self.nPoolCountourPoints = []

        # Areas of pool fire ellipses
        self.areaEllipsePool = []

        # Explosion overpressure results
        self.explosionOverpressureResults = list[ExplosionOverpressureResult]()

        # Distance to concentration of interest (using toxic averaging time)
        self.distancesToToxicConcentration = []

        # Concentration of interest
        self.toxicConcentrationUsed = []

        # Maximum concentration footprint to concentration of interest (using toxic averaging time)
        self.toxicConcContourPoints = list[LocalPosition]()

        # Number of contour points for maximum concentration footprint to concentration of interest
        self.nToxicConcCountourPoints = []

        # Area of maximum concentration footprints to concentration of interest (using toxic averaging time)
        self.areaFootprintToxicConc = []

        # Flame results for jet fire
        self.jetFireFlameResult = FlameResult()

        # Flame results for pool fire
        self.poolFireFlameResult = PoolFireFlameResult()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # VesselLeakLinkedRun calculation run method.
    def run(self) -> ResultCode:

        # Create the vessel leak linked run request.
        vesselLeakLinkedRunCalculationRequest = VesselLeakLinkedRunCalculationRequest()

        # Initialise the member properties.

        vesselLeakLinkedRunCalculationRequest.vessel = self.vessel
        vesselLeakLinkedRunCalculationRequest.leak = self.leak
        vesselLeakLinkedRunCalculationRequest.dischargeParameters = self.dischargeParameters
        vesselLeakLinkedRunCalculationRequest.substrate = self.substrate
        vesselLeakLinkedRunCalculationRequest.weather = self.weather
        vesselLeakLinkedRunCalculationRequest.dispersionParameters = self.dispersionParameters
        vesselLeakLinkedRunCalculationRequest.endPointConcentration = self.endPointConcentration
        vesselLeakLinkedRunCalculationRequest.flammableParameters = self.flammableParameters
        vesselLeakLinkedRunCalculationRequest.explosionParameters = self.explosionParameters
        vesselLeakLinkedRunCalculationRequest.dispersionFlamOutputConfigs = self.dispersionFlamOutputConfigs
        vesselLeakLinkedRunCalculationRequest.dispersionFlamOutputConfigCount = len(self.dispersionFlamOutputConfigs)
        vesselLeakLinkedRunCalculationRequest.dispersionToxicOutputConfigs = self.dispersionToxicOutputConfigs
        vesselLeakLinkedRunCalculationRequest.dispersionToxicOutputConfigCount = len(self.dispersionToxicOutputConfigs)
        vesselLeakLinkedRunCalculationRequest.flammableOutputConfigs = self.flammableOutputConfigs
        vesselLeakLinkedRunCalculationRequest.flammableOutputConfigCount = len(self.flammableOutputConfigs)
        vesselLeakLinkedRunCalculationRequest.explosionOutputConfigs = self.explosionOutputConfigs
        vesselLeakLinkedRunCalculationRequest.explosionOutputConfigCount = len(self.explosionOutputConfigs)
        vesselLeakLinkedRunCalculationRequest.explosionConfinedVolumes = self.explosionConfinedVolumes
        vesselLeakLinkedRunCalculationRequest.explosionConfinedVolumeCount = len(self.explosionConfinedVolumes)

        requestJson = jsons.dumps(vesselLeakLinkedRunCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatevesselleaklinkedrun?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            vesselLeakLinkedRunCalculationResponse = VesselLeakLinkedRunCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                vesselLeakLinkedRunCalculationResponse.initialiseFromDictionary(json)

                self.dischargeRecord = vesselLeakLinkedRunCalculationResponse.dischargeRecord
                self.distancesToJetFireRadiation = vesselLeakLinkedRunCalculationResponse.distancesToJetFireRadiation
                self.jetContourPoints = vesselLeakLinkedRunCalculationResponse.jetContourPoints
                self.nJetCountourPoints = vesselLeakLinkedRunCalculationResponse.nJetCountourPoints
                self.areaEllipseJet = vesselLeakLinkedRunCalculationResponse.areaEllipseJet
                self.distancesToFlamConcentration = vesselLeakLinkedRunCalculationResponse.distancesToFlamConcentration
                self.flamConcentrationsUsed = vesselLeakLinkedRunCalculationResponse.flamConcentrationsUsed
                self.flamConcContourPoints = vesselLeakLinkedRunCalculationResponse.flamConcContourPoints
                self.nFlamConcCountourPoints = vesselLeakLinkedRunCalculationResponse.nFlamConcCountourPoints
                self.areaFootprintFlamConc = vesselLeakLinkedRunCalculationResponse.areaFootprintFlamConc
                self.distancesToPoolFireRadiation = vesselLeakLinkedRunCalculationResponse.distancesToPoolFireRadiation
                self.poolContourPoints = vesselLeakLinkedRunCalculationResponse.poolContourPoints
                self.nPoolCountourPoints = vesselLeakLinkedRunCalculationResponse.nPoolCountourPoints
                self.areaEllipsePool = vesselLeakLinkedRunCalculationResponse.areaEllipsePool
                self.explosionOverpressureResults = vesselLeakLinkedRunCalculationResponse.explosionOverpressureResults
                self.distancesToToxicConcentration = vesselLeakLinkedRunCalculationResponse.distancesToToxicConcentration
                self.toxicConcentrationUsed = vesselLeakLinkedRunCalculationResponse.toxicConcentrationUsed
                self.toxicConcContourPoints = vesselLeakLinkedRunCalculationResponse.toxicConcContourPoints
                self.nToxicConcCountourPoints = vesselLeakLinkedRunCalculationResponse.nToxicConcCountourPoints
                self.areaFootprintToxicConc = vesselLeakLinkedRunCalculationResponse.areaFootprintToxicConc
                self.jetFireFlameResult = vesselLeakLinkedRunCalculationResponse.jetFireFlameResult
                self.poolFireFlameResult = vesselLeakLinkedRunCalculationResponse.poolFireFlameResult
                self.resultCode = vesselLeakLinkedRunCalculationResponse.resultCode
                self.messages = vesselLeakLinkedRunCalculationResponse.messages
                self.calculationElapsedTime = vesselLeakLinkedRunCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the VesselLeakLinkedRun calculation object to print itself.
    def print(self):

        # VesselLeakLinkedRun
        print('** VesselLeakLinkedRun')

        # vessel
        self.vessel.print()

        # leak
        self.leak.print()

        # dischargeParameters
        self.dischargeParameters.print()

        # substrate
        self.substrate.print()

        # weather
        self.weather.print()

        # dispersionParameters
        self.dispersionParameters.print()

        print(self.endPointConcentration)
        print('{0}\t{1}'.format('End point concentration', self.endPointConcentration))

        # flammableParameters
        self.flammableParameters.print()

        # explosionParameters
        self.explosionParameters.print()

        for item in self.dispersionFlamOutputConfigs:
            item.print()


        for item in self.dispersionToxicOutputConfigs:
            item.print()


        for item in self.flammableOutputConfigs:
            item.print()


        for item in self.explosionOutputConfigs:
            item.print()


        for item in self.explosionConfinedVolumes:
            item.print()


        # dischargeRecord
        self.dischargeRecord.print()

        # distancesToJetFireRadiation
        for item in self.distancesToJetFireRadiation:
            print('{0}'.format(item))

        for jetContourPoint in self.jetContourPoints:
            jetContourPoint.print()

        # nJetCountourPoints
        for item in self.nJetCountourPoints:
            print('{0}'.format(item))

        # areaEllipseJet
        for item in self.areaEllipseJet:
            print('{0}'.format(item))

        # distancesToFlamConcentration
        for item in self.distancesToFlamConcentration:
            print('{0}'.format(item))

        # flamConcentrationsUsed
        for item in self.flamConcentrationsUsed:
            print('{0}'.format(item))

        for flamConcContourPoint in self.flamConcContourPoints:
            flamConcContourPoint.print()

        # nFlamConcCountourPoints
        for item in self.nFlamConcCountourPoints:
            print('{0}'.format(item))

        # areaFootprintFlamConc
        for item in self.areaFootprintFlamConc:
            print('{0}'.format(item))

        # distancesToPoolFireRadiation
        for item in self.distancesToPoolFireRadiation:
            print('{0}'.format(item))

        for poolContourPoint in self.poolContourPoints:
            poolContourPoint.print()

        # nPoolCountourPoints
        for item in self.nPoolCountourPoints:
            print('{0}'.format(item))

        # areaEllipsePool
        for item in self.areaEllipsePool:
            print('{0}'.format(item))

        # explosionOverpressureResults
        for item in self.explosionOverpressureResults:
            item.print()

        # distancesToToxicConcentration
        for item in self.distancesToToxicConcentration:
            print('{0}'.format(item))

        # toxicConcentrationUsed
        for item in self.toxicConcentrationUsed:
            print('{0}'.format(item))

        for toxicConcContourPoint in self.toxicConcContourPoints:
            toxicConcContourPoint.print()

        # nToxicConcCountourPoints
        for item in self.nToxicConcCountourPoints:
            print('{0}'.format(item))

        # areaFootprintToxicConc
        for item in self.areaFootprintToxicConc:
            print('{0}'.format(item))

        # jetFireFlameResult
        self.jetFireFlameResult.print()

        # poolFireFlameResult
        self.poolFireFlameResult.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a vessel leak linked run calculation.
class VesselLeakLinkedRunCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Discharge data for table
        self.dischargeRecord = DischargeRecord()

        # Distances to jet fire radiation levels
        self.distancesToJetFireRadiation = []

        # Ellipses to jet fire radiation levels
        self.jetContourPoints = list[LocalPosition]()

        # Number of contour points for jet fire ellipses per radiation level
        self.nJetCountourPoints = []

        # Areas of jet fire ellipses
        self.areaEllipseJet = []

        # Distances to concentration levels (LFL fraction, LFL and UFL)
        self.distancesToFlamConcentration = []

        # Concentration levels (LFL fraction, LFL and UFL)
        self.flamConcentrationsUsed = []

        # Maximum concentration footprints at given concentration levels (LFL fraction, LFL and UFL)
        self.flamConcContourPoints = list[LocalPosition]()

        # Number of contour points per concentration level (LFL fraction, LFL and UFL)
        self.nFlamConcCountourPoints = []

        # Areas of maximum concentration footprints (LFL fraction, LFL and UFL)
        self.areaFootprintFlamConc = []

        # Distances to pool fire radiation levels
        self.distancesToPoolFireRadiation = []

        # Ellipses to pool fire radiation levels
        self.poolContourPoints = list[LocalPosition]()

        # Number of contour points for pool fire ellipses per radiation level
        self.nPoolCountourPoints = []

        # Areas of pool fire ellipses
        self.areaEllipsePool = []

        # Explosion overpressure results
        self.explosionOverpressureResults = list[ExplosionOverpressureResult]()

        # Distance to concentration of interest (using toxic averaging time)
        self.distancesToToxicConcentration = []

        # Concentration of interest
        self.toxicConcentrationUsed = []

        # Maximum concentration footprint to concentration of interest (using toxic averaging time)
        self.toxicConcContourPoints = list[LocalPosition]()

        # Number of contour points for maximum concentration footprint to concentration of interest
        self.nToxicConcCountourPoints = []

        # Area of maximum concentration footprints to concentration of interest (using toxic averaging time)
        self.areaFootprintToxicConc = []

        # Flame results for jet fire
        self.jetFireFlameResult = FlameResult()

        # Flame results for pool fire
        self.poolFireFlameResult = PoolFireFlameResult()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Discharge data for table
        self.dischargeRecord.initialiseFromDictionary(data['dischargeRecord'])

        # Distances to jet fire radiation levels
        if data['distancesToJetFireRadiation'] != None:
            for dataItem in data['distancesToJetFireRadiation']:
                self.distancesToJetFireRadiation.append(float(dataItem))

        # Ellipses to jet fire radiation levels
        if data['jetContourPoints'] != None:
            for dataItem in data['jetContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.jetContourPoints.append(localPosition)

        # Number of contour points for jet fire ellipses per radiation level
        if data['nJetCountourPoints'] != None:
            for dataItem in data['nJetCountourPoints']:
                self.nJetCountourPoints.append(int(dataItem))

        # Areas of jet fire ellipses
        if data['areaEllipseJet'] != None:
            for dataItem in data['areaEllipseJet']:
                self.areaEllipseJet.append(float(dataItem))

        # Distances to concentration levels (LFL fraction, LFL and UFL)
        if data['distancesToFlamConcentration'] != None:
            for dataItem in data['distancesToFlamConcentration']:
                self.distancesToFlamConcentration.append(float(dataItem))

        # Concentration levels (LFL fraction, LFL and UFL)
        if data['flamConcentrationsUsed'] != None:
            for dataItem in data['flamConcentrationsUsed']:
                self.flamConcentrationsUsed.append(float(dataItem))

        # Maximum concentration footprints at given concentration levels (LFL fraction, LFL and UFL)
        if data['flamConcContourPoints'] != None:
            for dataItem in data['flamConcContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.flamConcContourPoints.append(localPosition)

        # Number of contour points per concentration level (LFL fraction, LFL and UFL)
        if data['nFlamConcCountourPoints'] != None:
            for dataItem in data['nFlamConcCountourPoints']:
                self.nFlamConcCountourPoints.append(int(dataItem))

        # Areas of maximum concentration footprints (LFL fraction, LFL and UFL)
        if data['areaFootprintFlamConc'] != None:
            for dataItem in data['areaFootprintFlamConc']:
                self.areaFootprintFlamConc.append(float(dataItem))

        # Distances to pool fire radiation levels
        if data['distancesToPoolFireRadiation'] != None:
            for dataItem in data['distancesToPoolFireRadiation']:
                self.distancesToPoolFireRadiation.append(float(dataItem))

        # Ellipses to pool fire radiation levels
        if data['poolContourPoints'] != None:
            for dataItem in data['poolContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.poolContourPoints.append(localPosition)

        # Number of contour points for pool fire ellipses per radiation level
        if data['nPoolCountourPoints'] != None:
            for dataItem in data['nPoolCountourPoints']:
                self.nPoolCountourPoints.append(int(dataItem))

        # Areas of pool fire ellipses
        if data['areaEllipsePool'] != None:
            for dataItem in data['areaEllipsePool']:
                self.areaEllipsePool.append(float(dataItem))

        # Explosion overpressure results
        if data['explosionOverpressureResults'] != None:
            for dataItem in data['explosionOverpressureResults']:
                explosionOverpressureResult = ExplosionOverpressureResult()
                explosionOverpressureResult.initialiseFromDictionary(dataItem)
                self.explosionOverpressureResults.append(explosionOverpressureResult)

        # Distance to concentration of interest (using toxic averaging time)
        if data['distancesToToxicConcentration'] != None:
            for dataItem in data['distancesToToxicConcentration']:
                self.distancesToToxicConcentration.append(float(dataItem))

        # Concentration of interest
        if data['toxicConcentrationUsed'] != None:
            for dataItem in data['toxicConcentrationUsed']:
                self.toxicConcentrationUsed.append(float(dataItem))

        # Maximum concentration footprint to concentration of interest (using toxic averaging time)
        if data['toxicConcContourPoints'] != None:
            for dataItem in data['toxicConcContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.toxicConcContourPoints.append(localPosition)

        # Number of contour points for maximum concentration footprint to concentration of interest
        if data['nToxicConcCountourPoints'] != None:
            for dataItem in data['nToxicConcCountourPoints']:
                self.nToxicConcCountourPoints.append(int(dataItem))

        # Area of maximum concentration footprints to concentration of interest (using toxic averaging time)
        if data['areaFootprintToxicConc'] != None:
            for dataItem in data['areaFootprintToxicConc']:
                self.areaFootprintToxicConc.append(float(dataItem))

        # Flame results for jet fire
        self.jetFireFlameResult.initialiseFromDictionary(data['jetFireFlameResult'])

        # Flame results for pool fire
        self.poolFireFlameResult.initialiseFromDictionary(data['poolFireFlameResult'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a set phase to release for leak scenario calculation.
class SetPhaseToReleaseForLeakScenarioCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Requested fluid phase to release
        self.phaseToRelease = Phase.VAPOUR

        # Release point elevation above ground
        self.releaseElevation = 0.0

        # Vessel definition input
        self.vessel = Vessel()


# Set phase to release for leak scenario calculation class.
class SetPhaseToReleaseForLeakScenarioCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Requested fluid phase to release
        self.phaseToRelease = Phase.VAPOUR

        # Release point elevation above ground
        self.releaseElevation = 0.0

        # Vessel definition input
        self.vessel = Vessel()

        # Calculation outputs.
        # Updated z-coordinate of vessel to accommodate requested phase to release
        self.zCoordUpdated = 0.0

        # Updated hole height fraction to accommodate requested phase to release
        self.holeHeightFractionUpdated = 0.0

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # SetPhaseToReleaseForLeakScenario calculation run method.
    def run(self) -> ResultCode:

        # Create the set phase to release for leak scenario request.
        setPhaseToReleaseForLeakScenarioCalculationRequest = SetPhaseToReleaseForLeakScenarioCalculationRequest()

        # Initialise the member properties.

        setPhaseToReleaseForLeakScenarioCalculationRequest.phaseToRelease = self.phaseToRelease
        setPhaseToReleaseForLeakScenarioCalculationRequest.releaseElevation = self.releaseElevation
        setPhaseToReleaseForLeakScenarioCalculationRequest.vessel = self.vessel

        requestJson = jsons.dumps(setPhaseToReleaseForLeakScenarioCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'utilities/setphasetoreleaseforleakscenario?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            setPhaseToReleaseForLeakScenarioCalculationResponse = SetPhaseToReleaseForLeakScenarioCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                setPhaseToReleaseForLeakScenarioCalculationResponse.initialiseFromDictionary(json)

                self.zCoordUpdated = setPhaseToReleaseForLeakScenarioCalculationResponse.zCoordUpdated
                self.holeHeightFractionUpdated = setPhaseToReleaseForLeakScenarioCalculationResponse.holeHeightFractionUpdated
                self.resultCode = setPhaseToReleaseForLeakScenarioCalculationResponse.resultCode
                self.messages = setPhaseToReleaseForLeakScenarioCalculationResponse.messages
                self.calculationElapsedTime = setPhaseToReleaseForLeakScenarioCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the SetPhaseToReleaseForLeakScenario calculation object to print itself.
    def print(self):

        # SetPhaseToReleaseForLeakScenario
        print('** SetPhaseToReleaseForLeakScenario')

        print(self.phaseToRelease)
        print('{0}\t{1}'.format('Phase to release', self.phaseToRelease))

        print(self.releaseElevation)
        print('{0}\t{1}'.format('Release elevation', self.releaseElevation))

        # vessel
        self.vessel.print()

        # zCoordUpdated
        print('{0}\t{1}'.format('Z coord updated', self.zCoordUpdated))

        # holeHeightFractionUpdated
        print('{0}\t{1}'.format('Hole height fraction updated', self.holeHeightFractionUpdated))

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a set phase to release for leak scenario calculation.
class SetPhaseToReleaseForLeakScenarioCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Updated z-coordinate of vessel to accommodate requested phase to release
        self.zCoordUpdated = 0.0

        # Updated hole height fraction to accommodate requested phase to release
        self.holeHeightFractionUpdated = 0.0

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Updated z-coordinate of vessel to accommodate requested phase to release
        self.zCoordUpdated = float(data['zCoordUpdated'])

        # Updated hole height fraction to accommodate requested phase to release
        self.holeHeightFractionUpdated = float(data['holeHeightFractionUpdated'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a vessel leak flammable linked run h2 calculation.
class VesselLeakFlammableLinkedRunH2CalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Vessel definition
        self.vessel = Vessel()

        # Leak scenario
        self.leak = Leak()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # The dispersing surface
        self.substrate = Substrate()

        # Weather definition
        self.weather = Weather()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Concentration at which the dispersion calculations will terminate (v/v fraction)
        self.endPointConcentration = 0.0

        # Fire model parameters
        self.flammableParameters = FlammableParameters()

        # Explosion parameters
        self.explosionParameters = ExplosionParameters()

        # Concentration levels
        self.dispersionOutputConfigs = list[DispersionOutputConfig]()

        # Number of concentration levels
        self.dispersionOutputConfigCount = 0

        # Radiation levels
        self.flammableOutputConfigs = list[FlammableOutputConfig]()

        # Number of radiation levels
        self.flammableOutputConfigCount = 0

        # Overpressure levels
        self.explosionOutputConfigs = list[ExplosionOutputConfig]()

        # Number of overpressure levels
        self.explosionOutputConfigCount = 0

        # Explosion confined volumes
        self.explosionConfinedVolumes = list[ExplosionConfinedVolume]()

        # Number of confined explosion sources
        self.explosionConfinedVolumeCount = 0


# Vessel leak flammable linked run h2 calculation class.
class VesselLeakFlammableLinkedRunH2Calculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Vessel definition
        self.vessel = Vessel()

        # Leak scenario
        self.leak = Leak()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # The dispersing surface
        self.substrate = Substrate()

        # Weather definition
        self.weather = Weather()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Concentration at which the dispersion calculations will terminate (v/v fraction)
        self.endPointConcentration = 0.0

        # Fire model parameters
        self.flammableParameters = FlammableParameters()

        # Explosion parameters
        self.explosionParameters = ExplosionParameters()

        # Concentration levels
        self.dispersionOutputConfigs = list[DispersionOutputConfig]()


        # Radiation levels
        self.flammableOutputConfigs = list[FlammableOutputConfig]()


        # Overpressure levels
        self.explosionOutputConfigs = list[ExplosionOutputConfig]()


        # Explosion confined volumes
        self.explosionConfinedVolumes = list[ExplosionConfinedVolume]()


        # Calculation outputs.
        # Discharge data for table
        self.dischargeRecord = DischargeRecord()

        # Description for entry point parameter exitMaterial not found.
        self.exitMaterial = Material()

        # Description for entry point parameter dischargeResult not found.
        self.dischargeResult = DischargeResult()

        # Distances to jet fire radiation levels
        self.distancesToJetFireRadiation = []

        # Ellipses to jet fire radiation levels
        self.jetContourPoints = list[LocalPosition]()

        # Number of contour points for jet fire ellipses per radiation level
        self.nJetCountourPoints = []

        # Areas of jet fire ellipses
        self.areaEllipseJet = []

        # Distances to concentration levels
        self.distancesToConcentration = []

        # Concentration levels
        self.concentrationsUsed = []

        # Maximum concentration footprints at given concentration levels
        self.concContourPoints = list[LocalPosition]()

        # Number of contour points per concentration level
        self.nConcCountourPoints = []

        # Areas of maximum concentration footprints
        self.areaFootprintConc = []

        # Distances to pool fire radiation levels
        self.distancesToPoolFireRadiation = []

        # Ellipses to pool fire radiation levels
        self.poolContourPoints = list[LocalPosition]()

        # Number of contour points for pool fire ellipses per radiation level
        self.nPoolCountourPoints = []

        # Areas of pool fire ellipses
        self.areaEllipsePool = []

        # Explosion overpressure results
        self.explosionOverpressureResults = list[ExplosionOverpressureResult]()

        # Flame results for jet fire
        self.jetFireFlameResult = FlameResult()

        # Flame results for pool fire
        self.poolFireFlameResult = PoolFireFlameResult()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # VesselLeakFlammableLinkedRunH2 calculation run method.
    def run(self) -> ResultCode:

        # Create the vessel leak flammable linked run h2 request.
        vesselLeakFlammableLinkedRunH2CalculationRequest = VesselLeakFlammableLinkedRunH2CalculationRequest()

        # Initialise the member properties.

        vesselLeakFlammableLinkedRunH2CalculationRequest.vessel = self.vessel
        vesselLeakFlammableLinkedRunH2CalculationRequest.leak = self.leak
        vesselLeakFlammableLinkedRunH2CalculationRequest.dischargeParameters = self.dischargeParameters
        vesselLeakFlammableLinkedRunH2CalculationRequest.substrate = self.substrate
        vesselLeakFlammableLinkedRunH2CalculationRequest.weather = self.weather
        vesselLeakFlammableLinkedRunH2CalculationRequest.dispersionParameters = self.dispersionParameters
        vesselLeakFlammableLinkedRunH2CalculationRequest.endPointConcentration = self.endPointConcentration
        vesselLeakFlammableLinkedRunH2CalculationRequest.flammableParameters = self.flammableParameters
        vesselLeakFlammableLinkedRunH2CalculationRequest.explosionParameters = self.explosionParameters
        vesselLeakFlammableLinkedRunH2CalculationRequest.dispersionOutputConfigs = self.dispersionOutputConfigs
        vesselLeakFlammableLinkedRunH2CalculationRequest.dispersionOutputConfigCount = len(self.dispersionOutputConfigs)
        vesselLeakFlammableLinkedRunH2CalculationRequest.flammableOutputConfigs = self.flammableOutputConfigs
        vesselLeakFlammableLinkedRunH2CalculationRequest.flammableOutputConfigCount = len(self.flammableOutputConfigs)
        vesselLeakFlammableLinkedRunH2CalculationRequest.explosionOutputConfigs = self.explosionOutputConfigs
        vesselLeakFlammableLinkedRunH2CalculationRequest.explosionOutputConfigCount = len(self.explosionOutputConfigs)
        vesselLeakFlammableLinkedRunH2CalculationRequest.explosionConfinedVolumes = self.explosionConfinedVolumes
        vesselLeakFlammableLinkedRunH2CalculationRequest.explosionConfinedVolumeCount = len(self.explosionConfinedVolumes)

        requestJson = jsons.dumps(vesselLeakFlammableLinkedRunH2CalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatevesselleakflammablelinkedrunh2?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            vesselLeakFlammableLinkedRunH2CalculationResponse = VesselLeakFlammableLinkedRunH2CalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                vesselLeakFlammableLinkedRunH2CalculationResponse.initialiseFromDictionary(json)

                self.dischargeRecord = vesselLeakFlammableLinkedRunH2CalculationResponse.dischargeRecord
                self.exitMaterial = vesselLeakFlammableLinkedRunH2CalculationResponse.exitMaterial
                self.dischargeResult = vesselLeakFlammableLinkedRunH2CalculationResponse.dischargeResult
                self.distancesToJetFireRadiation = vesselLeakFlammableLinkedRunH2CalculationResponse.distancesToJetFireRadiation
                self.jetContourPoints = vesselLeakFlammableLinkedRunH2CalculationResponse.jetContourPoints
                self.nJetCountourPoints = vesselLeakFlammableLinkedRunH2CalculationResponse.nJetCountourPoints
                self.areaEllipseJet = vesselLeakFlammableLinkedRunH2CalculationResponse.areaEllipseJet
                self.distancesToConcentration = vesselLeakFlammableLinkedRunH2CalculationResponse.distancesToConcentration
                self.concentrationsUsed = vesselLeakFlammableLinkedRunH2CalculationResponse.concentrationsUsed
                self.concContourPoints = vesselLeakFlammableLinkedRunH2CalculationResponse.concContourPoints
                self.nConcCountourPoints = vesselLeakFlammableLinkedRunH2CalculationResponse.nConcCountourPoints
                self.areaFootprintConc = vesselLeakFlammableLinkedRunH2CalculationResponse.areaFootprintConc
                self.distancesToPoolFireRadiation = vesselLeakFlammableLinkedRunH2CalculationResponse.distancesToPoolFireRadiation
                self.poolContourPoints = vesselLeakFlammableLinkedRunH2CalculationResponse.poolContourPoints
                self.nPoolCountourPoints = vesselLeakFlammableLinkedRunH2CalculationResponse.nPoolCountourPoints
                self.areaEllipsePool = vesselLeakFlammableLinkedRunH2CalculationResponse.areaEllipsePool
                self.explosionOverpressureResults = vesselLeakFlammableLinkedRunH2CalculationResponse.explosionOverpressureResults
                self.jetFireFlameResult = vesselLeakFlammableLinkedRunH2CalculationResponse.jetFireFlameResult
                self.poolFireFlameResult = vesselLeakFlammableLinkedRunH2CalculationResponse.poolFireFlameResult
                self.resultCode = vesselLeakFlammableLinkedRunH2CalculationResponse.resultCode
                self.messages = vesselLeakFlammableLinkedRunH2CalculationResponse.messages
                self.calculationElapsedTime = vesselLeakFlammableLinkedRunH2CalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the VesselLeakFlammableLinkedRunH2 calculation object to print itself.
    def print(self):

        # VesselLeakFlammableLinkedRunH2
        print('** VesselLeakFlammableLinkedRunH2')

        # vessel
        self.vessel.print()

        # leak
        self.leak.print()

        # dischargeParameters
        self.dischargeParameters.print()

        # substrate
        self.substrate.print()

        # weather
        self.weather.print()

        # dispersionParameters
        self.dispersionParameters.print()

        print(self.endPointConcentration)
        print('{0}\t{1}'.format('End point concentration', self.endPointConcentration))

        # flammableParameters
        self.flammableParameters.print()

        # explosionParameters
        self.explosionParameters.print()

        for item in self.dispersionOutputConfigs:
            item.print()


        for item in self.flammableOutputConfigs:
            item.print()


        for item in self.explosionOutputConfigs:
            item.print()


        for item in self.explosionConfinedVolumes:
            item.print()


        # dischargeRecord
        self.dischargeRecord.print()

        # exitMaterial
        self.exitMaterial.print()

        # dischargeResult
        self.dischargeResult.print()

        # distancesToJetFireRadiation
        for item in self.distancesToJetFireRadiation:
            print('{0}'.format(item))

        for jetContourPoint in self.jetContourPoints:
            jetContourPoint.print()

        # nJetCountourPoints
        for item in self.nJetCountourPoints:
            print('{0}'.format(item))

        # areaEllipseJet
        for item in self.areaEllipseJet:
            print('{0}'.format(item))

        # distancesToConcentration
        for item in self.distancesToConcentration:
            print('{0}'.format(item))

        # concentrationsUsed
        for item in self.concentrationsUsed:
            print('{0}'.format(item))

        for concContourPoint in self.concContourPoints:
            concContourPoint.print()

        # nConcCountourPoints
        for item in self.nConcCountourPoints:
            print('{0}'.format(item))

        # areaFootprintConc
        for item in self.areaFootprintConc:
            print('{0}'.format(item))

        # distancesToPoolFireRadiation
        for item in self.distancesToPoolFireRadiation:
            print('{0}'.format(item))

        for poolContourPoint in self.poolContourPoints:
            poolContourPoint.print()

        # nPoolCountourPoints
        for item in self.nPoolCountourPoints:
            print('{0}'.format(item))

        # areaEllipsePool
        for item in self.areaEllipsePool:
            print('{0}'.format(item))

        # explosionOverpressureResults
        for item in self.explosionOverpressureResults:
            item.print()

        # jetFireFlameResult
        self.jetFireFlameResult.print()

        # poolFireFlameResult
        self.poolFireFlameResult.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a vessel leak flammable linked run h2 calculation.
class VesselLeakFlammableLinkedRunH2CalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Discharge data for table
        self.dischargeRecord = DischargeRecord()

        # Description for entry point parameter exitMaterial not found.
        self.exitMaterial = Material()

        # Description for entry point parameter dischargeResult not found.
        self.dischargeResult = DischargeResult()

        # Distances to jet fire radiation levels
        self.distancesToJetFireRadiation = []

        # Ellipses to jet fire radiation levels
        self.jetContourPoints = list[LocalPosition]()

        # Number of contour points for jet fire ellipses per radiation level
        self.nJetCountourPoints = []

        # Areas of jet fire ellipses
        self.areaEllipseJet = []

        # Distances to concentration levels
        self.distancesToConcentration = []

        # Concentration levels
        self.concentrationsUsed = []

        # Maximum concentration footprints at given concentration levels
        self.concContourPoints = list[LocalPosition]()

        # Number of contour points per concentration level
        self.nConcCountourPoints = []

        # Areas of maximum concentration footprints
        self.areaFootprintConc = []

        # Distances to pool fire radiation levels
        self.distancesToPoolFireRadiation = []

        # Ellipses to pool fire radiation levels
        self.poolContourPoints = list[LocalPosition]()

        # Number of contour points for pool fire ellipses per radiation level
        self.nPoolCountourPoints = []

        # Areas of pool fire ellipses
        self.areaEllipsePool = []

        # Explosion overpressure results
        self.explosionOverpressureResults = list[ExplosionOverpressureResult]()

        # Flame results for jet fire
        self.jetFireFlameResult = FlameResult()

        # Flame results for pool fire
        self.poolFireFlameResult = PoolFireFlameResult()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Discharge data for table
        self.dischargeRecord.initialiseFromDictionary(data['dischargeRecord'])

        # Description for entry point parameter exitMaterial not found.
        self.exitMaterial.initialiseFromDictionary(data['exitMaterial'])

        # Description for entry point parameter dischargeResult not found.
        self.dischargeResult.initialiseFromDictionary(data['dischargeResult'])

        # Distances to jet fire radiation levels
        if data['distancesToJetFireRadiation'] != None:
            for dataItem in data['distancesToJetFireRadiation']:
                self.distancesToJetFireRadiation.append(float(dataItem))

        # Ellipses to jet fire radiation levels
        if data['jetContourPoints'] != None:
            for dataItem in data['jetContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.jetContourPoints.append(localPosition)

        # Number of contour points for jet fire ellipses per radiation level
        if data['nJetCountourPoints'] != None:
            for dataItem in data['nJetCountourPoints']:
                self.nJetCountourPoints.append(int(dataItem))

        # Areas of jet fire ellipses
        if data['areaEllipseJet'] != None:
            for dataItem in data['areaEllipseJet']:
                self.areaEllipseJet.append(float(dataItem))

        # Distances to concentration levels
        if data['distancesToConcentration'] != None:
            for dataItem in data['distancesToConcentration']:
                self.distancesToConcentration.append(float(dataItem))

        # Concentration levels
        if data['concentrationsUsed'] != None:
            for dataItem in data['concentrationsUsed']:
                self.concentrationsUsed.append(float(dataItem))

        # Maximum concentration footprints at given concentration levels
        if data['concContourPoints'] != None:
            for dataItem in data['concContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.concContourPoints.append(localPosition)

        # Number of contour points per concentration level
        if data['nConcCountourPoints'] != None:
            for dataItem in data['nConcCountourPoints']:
                self.nConcCountourPoints.append(int(dataItem))

        # Areas of maximum concentration footprints
        if data['areaFootprintConc'] != None:
            for dataItem in data['areaFootprintConc']:
                self.areaFootprintConc.append(float(dataItem))

        # Distances to pool fire radiation levels
        if data['distancesToPoolFireRadiation'] != None:
            for dataItem in data['distancesToPoolFireRadiation']:
                self.distancesToPoolFireRadiation.append(float(dataItem))

        # Ellipses to pool fire radiation levels
        if data['poolContourPoints'] != None:
            for dataItem in data['poolContourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.poolContourPoints.append(localPosition)

        # Number of contour points for pool fire ellipses per radiation level
        if data['nPoolCountourPoints'] != None:
            for dataItem in data['nPoolCountourPoints']:
                self.nPoolCountourPoints.append(int(dataItem))

        # Areas of pool fire ellipses
        if data['areaEllipsePool'] != None:
            for dataItem in data['areaEllipsePool']:
                self.areaEllipsePool.append(float(dataItem))

        # Explosion overpressure results
        if data['explosionOverpressureResults'] != None:
            for dataItem in data['explosionOverpressureResults']:
                explosionOverpressureResult = ExplosionOverpressureResult()
                explosionOverpressureResult.initialiseFromDictionary(dataItem)
                self.explosionOverpressureResults.append(explosionOverpressureResult)

        # Flame results for jet fire
        self.jetFireFlameResult.initialiseFromDictionary(data['jetFireFlameResult'])

        # Flame results for pool fire
        self.poolFireFlameResult.initialiseFromDictionary(data['poolFireFlameResult'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a load mass inventory vessel for leak scenario calculation.
class LoadMassInventoryVesselForLeakScenarioCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Vessel material
        self.material = Material()

        # Total vessel mass inventory
        self.mass = 0.0

        # Vessel pressure in absolute scale
        self.pressure = 0.0

        # Vessel temperature
        self.temperature = 0.0

        # Leak hole size
        self.holeSize = 0.0

        # Release elevation
        self.releaseElevation = 0.0

        # Release angle
        self.releaseAngle = 0.0


# Load mass inventory vessel for leak scenario calculation class.
class LoadMassInventoryVesselForLeakScenarioCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Vessel material
        self.material = Material()

        # Total vessel mass inventory
        self.mass = 0.0

        # Vessel pressure in absolute scale
        self.pressure = 0.0

        # Vessel temperature
        self.temperature = 0.0

        # Leak hole size
        self.holeSize = 0.0

        # Release elevation
        self.releaseElevation = 0.0

        # Release angle
        self.releaseAngle = 0.0

        # Calculation outputs.
        # Vessel definition
        self.vessel = Vessel()

        # Leak scenario
        self.leak = Leak()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # LoadMassInventoryVesselForLeakScenario calculation run method.
    def run(self) -> ResultCode:

        # Create the load mass inventory vessel for leak scenario request.
        loadMassInventoryVesselForLeakScenarioCalculationRequest = LoadMassInventoryVesselForLeakScenarioCalculationRequest()

        # Initialise the member properties.

        loadMassInventoryVesselForLeakScenarioCalculationRequest.material = self.material
        loadMassInventoryVesselForLeakScenarioCalculationRequest.mass = self.mass
        loadMassInventoryVesselForLeakScenarioCalculationRequest.pressure = self.pressure
        loadMassInventoryVesselForLeakScenarioCalculationRequest.temperature = self.temperature
        loadMassInventoryVesselForLeakScenarioCalculationRequest.holeSize = self.holeSize
        loadMassInventoryVesselForLeakScenarioCalculationRequest.releaseElevation = self.releaseElevation
        loadMassInventoryVesselForLeakScenarioCalculationRequest.releaseAngle = self.releaseAngle

        requestJson = jsons.dumps(loadMassInventoryVesselForLeakScenarioCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'utilities/loadmassinventoryvesselforleakscenario?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            loadMassInventoryVesselForLeakScenarioCalculationResponse = LoadMassInventoryVesselForLeakScenarioCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                loadMassInventoryVesselForLeakScenarioCalculationResponse.initialiseFromDictionary(json)

                self.vessel = loadMassInventoryVesselForLeakScenarioCalculationResponse.vessel
                self.leak = loadMassInventoryVesselForLeakScenarioCalculationResponse.leak
                self.resultCode = loadMassInventoryVesselForLeakScenarioCalculationResponse.resultCode
                self.messages = loadMassInventoryVesselForLeakScenarioCalculationResponse.messages
                self.calculationElapsedTime = loadMassInventoryVesselForLeakScenarioCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the LoadMassInventoryVesselForLeakScenario calculation object to print itself.
    def print(self):

        # LoadMassInventoryVesselForLeakScenario
        print('** LoadMassInventoryVesselForLeakScenario')

        # material
        self.material.print()

        print(self.mass)
        print('{0}\t{1}'.format('Mass', self.mass))

        print(self.pressure)
        print('{0}\t{1}'.format('Pressure', self.pressure))

        print(self.temperature)
        print('{0}\t{1}'.format('Temperature', self.temperature))

        print(self.holeSize)
        print('{0}\t{1}'.format('Hole size', self.holeSize))

        print(self.releaseElevation)
        print('{0}\t{1}'.format('Release elevation', self.releaseElevation))

        print(self.releaseAngle)
        print('{0}\t{1}'.format('Release angle', self.releaseAngle))

        # vessel
        self.vessel.print()

        # leak
        self.leak.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a load mass inventory vessel for leak scenario calculation.
class LoadMassInventoryVesselForLeakScenarioCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Vessel definition
        self.vessel = Vessel()

        # Leak scenario
        self.leak = Leak()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Vessel definition
        self.vessel.initialiseFromDictionary(data['vessel'])

        # Leak scenario
        self.leak.initialiseFromDictionary(data['leak'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a max distance to conc calculation.
class MaxDistanceToConcCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # UDM scalar outputs
        self.scalarUdmOutputs = ScalarUdmOutputs()

        # Weather
        self.weather = Weather()

        # Dispersion definition
        self.dispersionRecords = list[DispersionRecord]()

        # Number of dispersion records
        self.dispersionRecordCount = 0

        # The dispersing surface
        self.substrate = Substrate()

        # Dispersion view configuration
        self.dispersionOutputConfig = DispersionOutputConfig()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Material with post-discharge composition
        self.material = Material()


# Max distance to conc calculation class.
class MaxDistanceToConcCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # UDM scalar outputs
        self.scalarUdmOutputs = ScalarUdmOutputs()

        # Weather
        self.weather = Weather()

        # Dispersion definition
        self.dispersionRecords = list[DispersionRecord]()


        # The dispersing surface
        self.substrate = Substrate()

        # Dispersion view configuration
        self.dispersionOutputConfig = DispersionOutputConfig()

        # Dispersion parameters
        self.dispersionParameters = DispersionParameters()

        # Material with post-discharge composition
        self.material = Material()

        # Calculation outputs.
        # Concentration of interest
        self.concUsed = 0.0

        # Maximum distance to concentration of interest
        self.distance = 0.0

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # MaxDistanceToConc calculation run method.
    def run(self) -> ResultCode:

        # Create the max distance to conc request.
        maxDistanceToConcCalculationRequest = MaxDistanceToConcCalculationRequest()

        # Initialise the member properties.

        maxDistanceToConcCalculationRequest.scalarUdmOutputs = self.scalarUdmOutputs
        maxDistanceToConcCalculationRequest.weather = self.weather
        maxDistanceToConcCalculationRequest.dispersionRecords = self.dispersionRecords
        maxDistanceToConcCalculationRequest.dispersionRecordCount = len(self.dispersionRecords)
        maxDistanceToConcCalculationRequest.substrate = self.substrate
        maxDistanceToConcCalculationRequest.dispersionOutputConfig = self.dispersionOutputConfig
        maxDistanceToConcCalculationRequest.dispersionParameters = self.dispersionParameters
        maxDistanceToConcCalculationRequest.material = self.material

        requestJson = jsons.dumps(maxDistanceToConcCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatemaxdistancetoconc?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            maxDistanceToConcCalculationResponse = MaxDistanceToConcCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                maxDistanceToConcCalculationResponse.initialiseFromDictionary(json)

                self.concUsed = maxDistanceToConcCalculationResponse.concUsed
                self.distance = maxDistanceToConcCalculationResponse.distance
                self.resultCode = maxDistanceToConcCalculationResponse.resultCode
                self.messages = maxDistanceToConcCalculationResponse.messages
                self.calculationElapsedTime = maxDistanceToConcCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the MaxDistanceToConc calculation object to print itself.
    def print(self):

        # MaxDistanceToConc
        print('** MaxDistanceToConc')

        # scalarUdmOutputs
        self.scalarUdmOutputs.print()

        # weather
        self.weather.print()

        for item in self.dispersionRecords:
            item.print()


        # substrate
        self.substrate.print()

        # dispersionOutputConfig
        self.dispersionOutputConfig.print()

        # dispersionParameters
        self.dispersionParameters.print()

        # material
        self.material.print()

        # concUsed
        print('{0}\t{1}'.format('Conc used', self.concUsed))

        # distance
        print('{0}\t{1}'.format('Distance', self.distance))

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a max distance to conc calculation.
class MaxDistanceToConcCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Concentration of interest
        self.concUsed = 0.0

        # Maximum distance to concentration of interest
        self.distance = 0.0

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Concentration of interest
        self.concUsed = float(data['concUsed'])

        # Maximum distance to concentration of interest
        self.distance = float(data['distance'])

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a vessel catastrophic rupture calculation.
class VesselCatastrophicRuptureCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Vessel (pressurised or atmospheric)
        self.vessel = Vessel()

        # Catastrophic rupture failure case
        self.catastrophicRupture = CatastrophicRupture()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()


# Vessel catastrophic rupture calculation class.
class VesselCatastrophicRuptureCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Vessel (pressurised or atmospheric)
        self.vessel = Vessel()

        # Catastrophic rupture failure case
        self.catastrophicRupture = CatastrophicRupture()

        # Discharge parameters
        self.dischargeParameters = DischargeParameters()

        # Calculation outputs.
        # Composition of the released material (indentical to storage composition)
        self.exitMaterial = Material()

        # Scalar discharge results
        self.dischargeResult = DischargeResult()

        # Array of discharge record
        self.dischargeRecords = list[DischargeRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # VesselCatastrophicRupture calculation run method.
    def run(self) -> ResultCode:

        # Create the vessel catastrophic rupture request.
        vesselCatastrophicRuptureCalculationRequest = VesselCatastrophicRuptureCalculationRequest()

        # Initialise the member properties.

        vesselCatastrophicRuptureCalculationRequest.vessel = self.vessel
        vesselCatastrophicRuptureCalculationRequest.catastrophicRupture = self.catastrophicRupture
        vesselCatastrophicRuptureCalculationRequest.dischargeParameters = self.dischargeParameters

        requestJson = jsons.dumps(vesselCatastrophicRuptureCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculatevesselcatastrophicrupture?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            vesselCatastrophicRuptureCalculationResponse = VesselCatastrophicRuptureCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                vesselCatastrophicRuptureCalculationResponse.initialiseFromDictionary(json)

                self.exitMaterial = vesselCatastrophicRuptureCalculationResponse.exitMaterial
                self.dischargeResult = vesselCatastrophicRuptureCalculationResponse.dischargeResult
                self.dischargeRecords = vesselCatastrophicRuptureCalculationResponse.dischargeRecords
                self.resultCode = vesselCatastrophicRuptureCalculationResponse.resultCode
                self.messages = vesselCatastrophicRuptureCalculationResponse.messages
                self.calculationElapsedTime = vesselCatastrophicRuptureCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the VesselCatastrophicRupture calculation object to print itself.
    def print(self):

        # VesselCatastrophicRupture
        print('** VesselCatastrophicRupture')

        # vessel
        self.vessel.print()

        # catastrophicRupture
        self.catastrophicRupture.print()

        # dischargeParameters
        self.dischargeParameters.print()

        # exitMaterial
        self.exitMaterial.print()

        # dischargeResult
        self.dischargeResult.print()

        for dischargeRecord in self.dischargeRecords:
            dischargeRecord.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a vessel catastrophic rupture calculation.
class VesselCatastrophicRuptureCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Composition of the released material (indentical to storage composition)
        self.exitMaterial = Material()

        # Scalar discharge results
        self.dischargeResult = DischargeResult()

        # Array of discharge record
        self.dischargeRecords = list[DischargeRecord]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Composition of the released material (indentical to storage composition)
        self.exitMaterial.initialiseFromDictionary(data['exitMaterial'])

        # Scalar discharge results
        self.dischargeResult.initialiseFromDictionary(data['dischargeResult'])

        # Array of discharge record
        if data['dischargeRecords'] != None:
            for dataItem in data['dischargeRecords']:
                dischargeRecord = DischargeRecord()
                dischargeRecord.initialiseFromDictionary(dataItem)
                self.dischargeRecords.append(dischargeRecord)

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


# Request object for a radiation contour calculation.
class RadiationContourCalculationRequest(object):

    # Constructor.
    def __init__(self):

        # Scalar flame results
        self.flameResult = FlameResult()

        # Flame definition
        self.flameRecords = list[FlameRecord]()

        # Number of flame records
        self.flameRecordCount = 0

        # Weather
        self.weather = Weather()

        # Flammable parameters
        self.flammableParameters = FlammableParameters()

        # Settings of flammable contours view
        self.flammableOutputConfig = FlammableOutputConfig()


# Radiation contour calculation class.
class RadiationContourCalculation(Calculation):

    # Constructor.
    def __init__(self):

        Calculation.__init__(self)

        # Calculation inputs.

        # Scalar flame results
        self.flameResult = FlameResult()

        # Flame definition
        self.flameRecords = list[FlameRecord]()


        # Weather
        self.weather = Weather()

        # Flammable parameters
        self.flammableParameters = FlammableParameters()

        # Settings of flammable contours view
        self.flammableOutputConfig = FlammableOutputConfig()

        # Calculation outputs.
        # Array of contour points
        self.contourPoints = list[LocalPosition]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0

    # RadiationContour calculation run method.
    def run(self) -> ResultCode:

        # Create the radiation contour request.
        radiationContourCalculationRequest = RadiationContourCalculationRequest()

        # Initialise the member properties.

        radiationContourCalculationRequest.flameResult = self.flameResult
        radiationContourCalculationRequest.flameRecords = self.flameRecords
        radiationContourCalculationRequest.flameRecordCount = len(self.flameRecords)
        radiationContourCalculationRequest.weather = self.weather
        radiationContourCalculationRequest.flammableParameters = self.flammableParameters
        radiationContourCalculationRequest.flammableOutputConfig = self.flammableOutputConfig

        requestJson = jsons.dumps(radiationContourCalculationRequest, use_enum_name=False)

        url = getAnalyticsApiTarget() + 'calculateradiationcontour?clientId=' + getClientAliasId()

        self.resultCode = ResultCode.UNEXPECTED_APPLICATION_ERROR

        response = Calculation.post_request(self, url, requestJson, getAccessToken())

        if response.ok:

            json = jsons.loads(response.text)
            self.resultCode = ResultCode(json['resultCode'])

            radiationContourCalculationResponse = RadiationContourCalculationResponse()

            if (self.resultCode == ResultCode.SUCCESS):

                radiationContourCalculationResponse.initialiseFromDictionary(json)

                self.contourPoints = radiationContourCalculationResponse.contourPoints
                self.resultCode = radiationContourCalculationResponse.resultCode
                self.messages = radiationContourCalculationResponse.messages
                self.calculationElapsedTime = radiationContourCalculationResponse.calculationElapsedTime

            else:

                for message in json['messages']:
                    self.messages.append(message)

        else:

            try:

                json = jsons.loads(response.text)
                self.resultCode = ResultCode(json['resultCode'])

                for message in json['messages']:
                    self.messages.append(message)

            except:
                self.messages.append("No additional error information available")

            self.messages.append("%s (Status code: %3d)" % (response.reason, response.status_code))

        return self.resultCode


    # Utility method to get the RadiationContour calculation object to print itself.
    def print(self):

        # RadiationContour
        print('** RadiationContour')

        # flameResult
        self.flameResult.print()

        for item in self.flameRecords:
            item.print()


        # weather
        self.weather.print()

        # flammableParameters
        self.flammableParameters.print()

        # flammableOutputConfig
        self.flammableOutputConfig.print()

        for contourPoint in self.contourPoints:
            contourPoint.print()

        # resultCode
        print('{0}\t{1}'.format('Result code', self.resultCode))

        # Messages
        for item in self.messages:
            print('{0}'.format(item))

        # CalculationElapsedTime
        print('{0}\t{1}'.format('Calculation elapsed time', self.calculationElapsedTime))

# Response object for a radiation contour calculation.
class RadiationContourCalculationResponse(object):

    # Constructor.
    def __init__(self):

        # Array of contour points
        self.contourPoints = list[LocalPosition]()

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode.SUCCESS

        # Messages generated by the calculation.
        self.messages = []

        # Time taken to run the calculation.
        self.calculationElapsedTime = 0.0


    # Initialise response with data from a dictionary.
    def initialiseFromDictionary(self, data: dict):

        # Array of contour points
        if data['contourPoints'] != None:
            for dataItem in data['contourPoints']:
                localPosition = LocalPosition()
                localPosition.initialiseFromDictionary(dataItem)
                self.contourPoints.append(localPosition)

        # Error code (0 = OK, < 0 data input error, > 0 execution error)
        self.resultCode = ResultCode(data['resultCode'])

        # Messages generated by the calculation.
        if data['messages'] != None:
            for dataItem in data['messages']:
                self.messages.append(dataItem)

        # Time taken to run the calculation.
        self.calculationElapsedTime = float(data['calculationElapsedTime'])


