VarianAPIs / PyESAPI

Python interface to Eclipse Scripting API

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

GetEditableParameters for IonBeam plans

chrisrose100 opened this issue · comments

Using the GetEditableParameters method on IonBeam plans only returns parameters which are associated with Photon beam plans rather than IonBeam plans

Applying the same method in C#, to the same plan, returns the correct parameters such as the raw spot list, etc (as expected).

I apologize for the inconvenience. The solution is to create a DLL with a C# static method wrapping GetEditableParameters to return the editable parameters type explicitly. Then import the DLL with pyesapi.clr (which is interface to pythonnet). I have an example somewhere, I'll try to find it and paste it here.

If you could find an example that would be brilliant. thanks.

DLL code

namespace ProtonHelperNS
{
  public static class ProtonHelper
  {
    public static IonBeamParameters GetEditableIonBeamParameters(IonBeam iBeam)
    {
            return (iBeam.GetEditableParameters() as IonBeamParameters); // soo casted
    }
  }
}

PyESAPI code

# ...

# path to compiled proton helper DLL:
sys.path.append(r'C:\\Users\\Varian\\Documents\\Eclipse Scripting API\\Projects\\ProtonHelper\\bin\\debug')
pyesapi.clr.AddReference('ProtonHelper')
from ProtonHelperNS import ProtonHelper

#...

editable_params = ProtonHelper.GetEditableIonBeamParameters(beam)

Note, I ran into an issue with .NET Framework 4.6.1 (target for next release of Eclipse). The namespace should be different than the DLL name, otherwise, import will fail (name collision perhaps). See here: https://github.com/pythonnet/pythonnet/wiki/How-to-call-a-dynamic-library

I've edited examples above.

The elegant solution was found using reflection (in C# reflection can do literally anything). The issue was the function was overloaded due to IonBeam basing off of Beam class and pythonnet called the base method (there is a bigger issue here related to how methods are differentiated by their input parameter types only in pythonnet, so when there are no input parameters, there is ambiguity... I personally think the output type should also be used to differentiate the method). Technically, the "override" modifier should have been set on the GetEditableIonBeamParameters method in IonBeam class (ESAPI source). Anyway, here is the fix, I'll roll this into PyESAPI proper sooner or later:

import pyesapi
import atexit
def get_editable_IonBeamParameters(beam):
    for mi in beam.GetType().GetMethods():
        if mi.ReturnType.ToString() == 'VMS.TPS.Common.Model.API.IonBeamParameters':
            return mi.Invoke(beam,[])
pyesapi.IonBeam.GetEditableIonBeamParameters = get_editable_IonBeamParameters  # monkey patch like a boss
if not 'app' in locals():
    app = pyesapi.CustomScriptExecutable.CreateApplication('python_demo')
    atexit.register(app.Dispose);