# Compute property modifer does not work correctly when using Python script

Quote from zhen ZHANG on December 27, 2020, 1:22 pmDear Ovito developers,

I found when using compute property modifier in Python script, the line

`mod.expressions[0] = "XXX"`

always returns zero. For example, by adding the following lines to my script I only get "smoothed_d2min" corresponding to the result of`mod.neighbor_expressions`

. This problem does not exist when using the GUI for the same operations.# Compute property: mod = ComputePropertyModifier() mod.expressions[0] = 'NonaffineSquaredDisplacement/(NumNeighbors+1)' mod.output_property = 'smoothed_d2min' mod.cutoff_radius = 5.0 mod.neighbor_expressions = ['NonaffineSquaredDisplacement/(NumNeighbors+1)'] pipeline.modifiers.append(mod) #----------------------------Please see if this is the case for the version 3.3.5 pro, or I made mistake somewhere. Thank you.

Best regards,

Zhen

Dear Ovito developers,

I found when using compute property modifier in Python script, the line `mod.expressions[0] = "XXX"`

always returns zero. For example, by adding the following lines to my script I only get "smoothed_d2min" corresponding to the result of `mod.neighbor_expressions`

. This problem does not exist when using the GUI for the same operations.

# Compute property: mod = ComputePropertyModifier() mod.expressions[0] = 'NonaffineSquaredDisplacement/(NumNeighbors+1)' mod.output_property = 'smoothed_d2min' mod.cutoff_radius = 5.0 mod.neighbor_expressions = ['NonaffineSquaredDisplacement/(NumNeighbors+1)'] pipeline.modifiers.append(mod) #----------------------------

Please see if this is the case for the version 3.3.5 pro, or I made mistake somewhere. Thank you.

Best regards,

Zhen

Quote from Alexander Stukowski on December 28, 2020, 9:35 amDear Zhen,

As you have already noticed, the following assignment to the expression field has seemingly no effect:

>>> mod = ComputePropertyModifier() >>> mod.expressions[0] = 'NonaffineSquaredDisplacement/(NumNeighbors+1)' >>> print(mod.expressions) ['0']The value of

`mod.expressions`

did not change! Unfortunately, you have tripped over one of the little weaknesses of the Python bindings of OVITO here, which lead to this strange behavior. The problem is that the Python expression`mod.expressions`

returns anew copyof the list of strings stored in the modifier every time it is being evaluated. Changes made to this copy of the list, e.g. replacing the entry at index 0 with a new string, like in your code, modifies only the returned copy of the list but not the internal state of the modifier (which is a C++ object)!For the changes to take effect, you would have to write the modified string list back into the modifier:

>>> expr = mod.expressions >>> expr[0] = 'NonaffineSquaredDisplacement/(NumNeighbors+1)' >>> mod.expressions = expr >>> print(mod.expressions) ['NonaffineSquaredDisplacement/(NumNeighbors+1)']Of course, the same can be achieved with a direct assignment of a new string list:

mod.expressions = ['NonaffineSquaredDisplacement/(NumNeighbors+1)']The underlying reason for this strange behavior is the fact that all OVITO objects such as modifiers are actually C++ objects and not native Python objects. You cannot access or manipulate the internal state of these objects directly. Access is only possible through the property fields they expose, which typically return copies of the internal data after it has been converted to a Python representation.

I'll see if this particular pitfall can be resolved in the future. I guess the best way to prevent this pitfall would be to let

`ComputePropertyModifier.expressions`

return a Pythontupleinstead of alist.Tuples are read-only, thus preventing any attempts to modify the tuple's entries from the outset.

Dear Zhen,

As you have already noticed, the following assignment to the expression field has seemingly no effect:

>>> mod = ComputePropertyModifier() >>> mod.expressions[0] = 'NonaffineSquaredDisplacement/(NumNeighbors+1)' >>> print(mod.expressions) ['0']

The value of `mod.expressions`

did not change! Unfortunately, you have tripped over one of the little weaknesses of the Python bindings of OVITO here, which lead to this strange behavior. The problem is that the Python expression `mod.expressions`

returns a **new copy** of the list of strings stored in the modifier every time it is being evaluated. Changes made to this copy of the list, e.g. replacing the entry at index 0 with a new string, like in your code, modifies only the returned copy of the list but not the internal state of the modifier (which is a C++ object)!

For the changes to take effect, you would have to write the modified string list back into the modifier:

>>> expr = mod.expressions >>> expr[0] = 'NonaffineSquaredDisplacement/(NumNeighbors+1)' >>> mod.expressions = expr >>> print(mod.expressions) ['NonaffineSquaredDisplacement/(NumNeighbors+1)']

Of course, the same can be achieved with a direct assignment of a new string list:

mod.expressions = ['NonaffineSquaredDisplacement/(NumNeighbors+1)']

The underlying reason for this strange behavior is the fact that all OVITO objects such as modifiers are actually C++ objects and not native Python objects. You cannot access or manipulate the internal state of these objects directly. Access is only possible through the property fields they expose, which typically return copies of the internal data after it has been converted to a Python representation.

I'll see if this particular pitfall can be resolved in the future. I guess the best way to prevent this pitfall would be to let `ComputePropertyModifier.expressions`

return a Python *tuple* instead of a *list.* Tuples are read-only, thus preventing any attempts to modify the tuple's entries from the outset.

Quote from zhen ZHANG on December 28, 2020, 10:25 amDear Alexander,

Thank you for your detailed explanation and the solutions. Actually I used the Python script generated from the ovito GUI. So it would be great if the solutions to this pitfall can be automatically implemented in the future.

Best regards,

Zhen

Dear Alexander,

Thank you for your detailed explanation and the solutions. Actually I used the Python script generated from the ovito GUI. So it would be great if the solutions to this pitfall can be automatically implemented in the future.

Best regards,

Zhen

Quote from Alexander Stukowski on December 28, 2020, 10:27 amI see, then the code generator needs to be changed as well to not produce this kind of statements. Thanks for letting me know.

I see, then the code generator needs to be changed as well to not produce this kind of statements. Thanks for letting me know.