Author Topic: Not Able to Print a Variable While Looping Over Frames  (Read 1487 times)

jatink

  • Newbie
  • *
  • Posts: 24
Not Able to Print a Variable While Looping Over Frames
« on: October 06, 2018, 01:09:24 AM »
Dear All,

I'm trying to find out maximum Z coordinate in my dump file and then print it which I ultimatly want to write to a text file. I'm following snippets given at "https://ovito.org/manual/python/modules/ovito_io.html" for looping over multiple frames which looks likes below:

import ovito
print("Hello, this is OVITO %i.%i.%i" % ovito.version)

from ovito.io import *

node = import_file("/Users/kashyap/Google_Drive/NJIT/graphene_h2o/redo/angle_6/variable_gap/1_h2o/main/stress/dry/200000/dump_*.cfg")
frames = node.source.num_frames
print("The total number of dump frames are:",frames)

for frame in range(node.source.num_frames):
   node.compute(frame)
   coordinates = node.output.particle_properties.position.array
   zl = max(coordinates[:,2])
   print("The highest z-coordinate in reference frame is:",zl)



But all it's printing is the variable value only processed for the first frame for number of times equal to number of frames in that directory as below:

Hello, this is OVITO 3.0.0
The total number of dump frames are: 11
The highest z-coordinate in reference frame is: 17.81900825664
The highest z-coordinate in reference frame is: 17.81900825664
The highest z-coordinate in reference frame is: 17.81900825664
The highest z-coordinate in reference frame is: 17.81900825664
The highest z-coordinate in reference frame is: 17.81900825664
The highest z-coordinate in reference frame is: 17.81900825664
The highest z-coordinate in reference frame is: 17.81900825664
The highest z-coordinate in reference frame is: 17.81900825664
The highest z-coordinate in reference frame is: 17.81900825664
The highest z-coordinate in reference frame is: 17.81900825664
The highest z-coordinate in reference frame is: 17.81900825664


Can anybody please help me to understand why the new dump files are not being loaded instead it's just repeating the variable value evaluated for first frame.
Thank you.


Alexander Stukowski

  • Administrator
  • Hero Member
  • *****
  • Posts: 512
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #1 on: October 06, 2018, 12:59:55 PM »
Dear jatink,

The ObjectNode.output field has been deprecated in Ovito 3.0.0. It's still there for some limited backward compatibility, but It only reflects the output of the data pipeline at frame 0 of the loaded simulation sequence.

Instead of

Code: [Select]
node.compute(frame)
coordinates = node.output.particle_properties.position.array

You should now use

Code: [Select]
data = node.compute(frame)
coordinates = data.particles["Position"]

-alex
« Last Edit: October 06, 2018, 01:02:05 PM by Alexander Stukowski »

jatink

  • Newbie
  • *
  • Posts: 24
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #2 on: October 07, 2018, 08:09:04 AM »
Hello Alexander,

Thanks for your informative reply. It solved the error. Additionally, can you please help me with following error in which I'm trying to write a newly computed property(High_Z) which is the highest Z component in every single frame to a text file with the frame number.

import ovito
print("Hello, this is OVITO %i.%i.%i" % ovito.version)

from ovito.io import *
from ovito.modifiers import *

node = import_file("/Users/kashyap/Google_Drive/NJIT/graphene_h2o/redo/angle_6/variable_gap/1_h2o/main/stress/dry/200000/dump_*.cfg")
frames = node.source.num_frames
print("The total number of dump frames are:",frames)


for frame in range(node.source.num_frames):
   data = node.compute(frame)
   coordinates = data.particles["Position"]
   modifier = ComputePropertyModifier()
   modifier.output_property = "High_Z"
   modifier.expressions = ["max(Position.Z)"]

   export_file(node, "potenergy.txt", "txt", columns = ["Frame", "High_Z"])



Error

Hello, this is OVITO 3.0.0
The total number of dump frames are: 11
The highest z-coordinate in reference frame is: 17.81900825664
Traceback (most recent call last):
  File "ovito1.py", line 31, in <module>
    export_file(node, "potenergy.txt", "txt", columns = ["Frame", "High_Z"])
  File "/Applications/Ovito.app/Contents/MacOS/Ovito.App/Contents/MacOS/../Resources/python/ovito/io/export_file.py", line 177, in export_file
    if not exporter.export_nodes(ovito.task_manager):
RuntimeError: The global attribute 'High_Z' to be exported is not available at animation frame 0.
ERROR: The Python script 'ovito1.py' has exited with an error.



Can you please give me a hint why I'm getting this error.

Thank you.
« Last Edit: October 07, 2018, 08:10:56 AM by jatink »

Alexander Stukowski

  • Administrator
  • Hero Member
  • *****
  • Posts: 512
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #3 on: October 07, 2018, 04:47:55 PM »
Note that in Ovito the term "property" typically refers to local per-atom information, whereas the term "attribute" refers to a global value, i.e. information not related to individual particles. You would like to calculate an attribute from the local per-atom information and export it to a file.

The ComputePropertyModifier is not the right tool for that as it can only compute new per-atom properties. When calling export_file() with the "txt" output format, Ovito expects you to specify a list of attributes to export. However, "High_Z" computed by the ComputePropertyModifer will be a particle property, not a global attribute. That's why you see the error.

You need to write a user-defined modifier in Python instead. Here is a draft for a script. Note that I cannot test it myself, because I am on vacation without access to a computer running Ovito:

Code: [Select]
import numpy
node = import_file(...)
def compute_max_z(frame, input, output):
    output.attributes["High_Z"] = numpy.max(input.particles["Position"][:,2])
node.modifiers.append(PythonScriptModifier(function=compute_max_z))
export_file(node, "max_z.txt", "txt", columns=["Frame", "High_Z"], multiple_frames = True)

A for-loop is not needed in this simple case, because export_file() will automatically step through the animation frames thanks to the multiple_frames=True option. The system will evaluate the data pipeline for every animation frame. As part of a pipeline evaluation, the compute_max_z() function will be invoked by the system, which computes the maximum of the z-component of the "Position" particle property, storing the result in a new output attribute with the name "High_Z".

jatink

  • Newbie
  • *
  • Posts: 24
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #4 on: October 07, 2018, 07:53:53 PM »
Hello Alexander,

Thanks a lot for your quick reply with detailed explanation for the algorithm. It's working without any problem. And thanks to your algorithm explanation, now I'm feeling more comfortable with OVITO python interface. I used below code:

import ovito
print("Hello, this is OVITO %i.%i.%i" % ovito.version)

from ovito.io import *
from ovito.modifiers import *


import numpy
node = import_file("/Users/kashyap/Google_Drive/NJIT/graphene_h2o/redo/angle_6/variable_gap/1_h2o/main/stress/dry/200000/dump_*.cfg")
def compute_max_z(frame, input, output):
    output.attributes["High_Z"] = numpy.max(input.particles["Position"][:,2])
node.modifiers.append(PythonScriptModifier(function=compute_max_z))
export_file(node, "max_z.txt", "txt", columns=["Frame", "High_Z"], multiple_frames = True)
~


And just to confirm
"def compute_max_z(frame, input, output):
 output.attributes["High_Z"] = numpy.max(input.particles["Position"][:,2])"
 is the piece which is converting local particle property to global attribute, correct?

And "node.modifiers.append(PythonScriptModifier(function=compute_max_z))" is the piece which is calling our user-defined modifier into OVITO, correct?

And one last thing I want to do in this code is, I want to print number of oxygen atoms in every simulation frame next to High_Z column in text out put file so that I can plot High_Z Vs. # Oxygen atoms in matlab. Any hint to do it will be much appreciated.

Thanks  a lot!
« Last Edit: October 07, 2018, 08:01:22 PM by jatink »

Alexander Stukowski

  • Administrator
  • Hero Member
  • *****
  • Posts: 512
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #5 on: October 08, 2018, 03:44:34 PM »
Jatink,
Answer to your 1st question is a yes. And the append() instruction adds the user-defined modifier function to the data pipeline. This is similar to what happens when you insert a modifier in the graphical user interface of Ovito. All the modifier functions in the current pipeline get called by the system to process the input data and compute the resulting output data.

There are several ways of counting the O-atoms. In the present case it's easiest to extend our user defined modifier function to emit a second global attribute:

Code: [Select]
def compute_max_z(frame, input, output):
    output.attributes["High_Z"] = numpy.max(input.particles["Position"][:,2])
    output.attributes["Ocount"] = numpy.count_nonzero(input.particles["Particle Type"] == 2)

Replace the literal "2" in this code, which I just used as an example, with the atom type ID for O atoms.

jatink

  • Newbie
  • *
  • Posts: 24
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #6 on: October 08, 2018, 09:50:56 PM »
Thanks Alexander. It's working completely fine. Can you please help me in the main project I'm working on. In our project, I have a system in which a body of water is sandwitched between the two graphene layers as you can see in the picture. After the system is relaxed a wrinkle is generated(height along Z axis) in the upper graphene layer to accomodate the presence of the water-body. Since we have constrained the movement of lower graphene layer, wrinkle is moving along the length of the sheet(x-axis) while we're deleting some number of water molecules after some random number of steps untill water-body is completely deleted. Now I have to find out the velocity of the wrinkle in the graphene sheet, and plot it against number of water molecules. I'm getting confused whether can I use the built-in displacement vector feature of the OVITO or not. Since the wrinkle is behaving like a wave i.e. whenever wrinkle moves it do not actually moves the atoms but instead energy gets tranferred from one atom to the other. Is it possible to find out the displacement vector between two DIFFERENT atoms in adjacent frames (commong thing will be those atoms will be having highest Z coordinate in their corresponding frame) or we have to just go with more basic algorithm in which we will find out the x coordinates of the atoms having highest Z coordinates in two adjacent frames and dividing the difference in x coordinates by timestep to get the velocity and then loop it from very first frame to the last frame so that we can a have a continuous plot showing the velocity fluctuations against the number of water molecules.

I know we can accomplish this task by other methods as well i.e. LAMMPS etc. but since we are planning to adopt OVITO python scripting in our future projects extensively so this will be our preferred option which will also serve us as our learning curve of the code as well. Can you please help me to build the algorithm to accomplish above task, and it will definitely guide me for my future projects as well.

Thanks a lot!
« Last Edit: October 08, 2018, 09:57:30 PM by jatink »

Alexander Stukowski

  • Administrator
  • Hero Member
  • *****
  • Posts: 512
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #7 on: October 09, 2018, 12:41:48 AM »
Dear Jatink,

I am glad I was able to help a bit.

I am currently on vacation though, that's why I can provide only very limited support at the moment. WHat you described sounds like a more complicated problem that I cannot address before I return to Germany (in a week from now).

Maybe my colleague Constanze will be able to provide you some support in the meantime -or other users in this forum. In general, however, I suggest you contact us directly if you are interested in a scientific collaboration, receiving direct technical support and/or more in-depth training on Ovito's analysis and scripting capabilities.

-alex

jatink

  • Newbie
  • *
  • Posts: 24
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #8 on: October 15, 2018, 07:04:36 PM »
Alex,

I'll be waiting for your or other user's reply to the problem mentioned above.

Over the course of last few days, I've meet with my principal investigator to narrow down the possibilities of the sceintific collaborations. And it turns out that it will be best if we can do that instead of depending upon the forum primarily. I'll contact your team very soon about our current and/or future projects based on what's the result of this thread comes out to be.

Thanks a lot!
 

Constanze Kalcher

  • Administrator
  • Full Member
  • *****
  • Posts: 119
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #9 on: October 16, 2018, 02:03:59 PM »
Dear jatink,

we are looking forward to you contacting us directly. But in the meantime here's an idea of how you could track the x-coordinate of the particle with the highest z-coordinate as a function of simulation time. As you already noted, the Displacement vectors modifier is not the right tool to achieve this.
However, here's how you could adapt your python script: Use numpy.argmax() to find the index of the particle with the highest z-coordinate and use that index to look up its x-coordinate.
Code: [Select]
import numpy
node = import_file(...)

def compute_max_z(frame, input, output):
    #Find the index of the particle with the highest z-coordinate and look up its x-coordinate                                                                                                                                                                     
    positions = input.particles["Position"]
    output.attributes["x_coord"] = positions[ np.argmax(positions[:,2]) ][0]
export_file(node, "max_z.txt", "txt", columns=["Frame", "x_coord"], multiple_frames = True)

This gives you the x-coordinate of the maximum of your "wrinkle" as a function of simulation time. You could then use that data to fit the velocity. Let me know if that was what you had in mind.

-Constanze


jatink

  • Newbie
  • *
  • Posts: 24
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #10 on: October 24, 2018, 10:58:03 PM »
Hi Constanze,

That worked perfectly well. Can please help me to solve the below error:

import ovito
Hello, this is OVITO 3.0.0
ERROR: Failed to open input file: Too many open files
Traceback (most recent call last):
  File "ovito4.py", line 13, in compute_max_z
  File "/Applications/Ovito.app/Contents/MacOS/Ovito.App/Contents/MacOS/../Resources/python/ovito/data/particles/particles_view.py", line 46, in __getitem__
KeyError: "The DataCollection does not contain a particle property with the name 'Position'."


P.S: When I do the ulimit it shows unlimited.

Thanks.

Alexander Stukowski

  • Administrator
  • Hero Member
  • *****
  • Posts: 512
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #11 on: October 25, 2018, 12:52:19 AM »
Dear jatink,

Could you please attach the script file ('ovito4.py') so we can see the entire code. This would be helpful to understand where this error comes from.

Thanks.

-Alex

jatink

  • Newbie
  • *
  • Posts: 24
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #12 on: October 25, 2018, 01:55:29 AM »
Dear Alex,


Here is the full script which works for most of the cases:

import ovito
print("Hello, this is OVITO %i.%i.%i" % ovito.version)

from ovito.io import *
from ovito.modifiers import *

import numpy
node = import_file("sftp://jk435@kong.njit.edu:/research/ddlab/jk435/MD_LAMMPS_ddlab/TEST/water_gr/water_btw_gr/redo/angle_16/variable_gap/3_h2o/main/stress/cont_merge/dry/dump_*.cfg")

def compute_max_z(frame, input, output):

    #Find the index of the particle with the highest z-coordinate and look up its x-coordinate
    positions = input.particles["Position"]
    output.attributes["x_coord"] = positions[ numpy.argmax(positions[:,2]) ][0]
    output.attributes["Ocount"] = numpy.count_nonzero(input.particles["Particle Type"] == 2)

node.modifiers.append(PythonScriptModifier(function=compute_max_z))
export_file(node, "max_z2.txt", "txt", columns=["Ocount", "x_coord"], multiple_frames = True)
« Last Edit: October 25, 2018, 02:27:11 AM by jatink »

Alexander Stukowski

  • Administrator
  • Hero Member
  • *****
  • Posts: 512
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #13 on: October 25, 2018, 02:45:25 AM »
Thank you.
Are you processing a large number of CFG files? The error message ("ERROR: Failed to open input file: Too many open files") suggests that Ovito reaches some sort of resource limit, which might be a bug in the software. I am wondering if it makes a difference whether you load the data files via SFTP protocol or from a local filesystem, like you did before.

Alexander Stukowski

  • Administrator
  • Hero Member
  • *****
  • Posts: 512
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #14 on: October 25, 2018, 03:47:36 AM »
It's likely that the error only occurs for files fetched via SFTP, but I cannot promise that it doesn't also occur for files stored locally.

I would be interested in knowing how many files you are processing and after how many the error occurs. You can find out by adding a print statement to your modifier function to print the current frame being processed:

Code: [Select]
def compute_max_z(frame, input, output):
    print(frame)
    ....

As a workaround, you could process the frame sequence in chunks. Call ovitos several time to process one chunk at a time and then combine the generated output files into one using a text editor. The export_file() function allows you to specify a (sub-)range of frames to process. Let's say the error occurs only after 1000 frames have been processed succesfully, then you can limit the script to frames 0-999:

Code: [Select]
export_file(node, "max_z2.part1.txt", "txt", columns=["Ocount", "x_coord"], start_frame = 0, end_frame = 999, multiple_frames = True)

jatink

  • Newbie
  • *
  • Posts: 24
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #15 on: November 08, 2018, 05:25:20 PM »
Hi Alex,

I was not able to see your reply until now without realizing the thread got extended to the 2nd page and I kept checking only that part of the thread which become first page after my last reply. Anyways, one workaround worked for me as follows: Since I'm using iterm2 on a mac so I restarted the terminal just in a hope doing so will free-up default memory of the terminal. And it worked! And then I batched process all of my jobs in that way i.e. restarting the terminal before running code and it worked just fine! So I think the bug may not be in OVITO.

Thanks a lot for your help in the project.
Hope to work with you in future again.


« Last Edit: November 09, 2018, 04:43:56 PM by jatink »

Alexander Stukowski

  • Administrator
  • Hero Member
  • *****
  • Posts: 512
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #16 on: November 08, 2018, 05:46:20 PM »
Thanks for letting us know that you were able to solve the problem.

Yeah, additional pages are easy to miss in the forum. I'm sorry about that. I just bumbed up the maximum number of posts per page to 30 to reduce the likeliness of additional pages showing up.

ad

  • Newbie
  • *
  • Posts: 20
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #17 on: November 08, 2018, 05:50:51 PM »
Do I need to modify script if filetype is XYZ. I am trying to compute the same as discussed above but getting following error in OVITO GUI Python script:

Hello, this is OVITO 2.9.0
The Python script has exited with an error.
Traceback (most recent call last):
  File "<string>", line 9, in <module>
  File "/Applications/Ovito.app/Contents/MacOS/../Resources/python/ovito/io/__init__.py", line 119, in import_file
    if not node.wait(signalError = True):
  File "/Applications/Ovito.app/Contents/MacOS/../Resources/python/ovito/__init__.py", line 173, in _ObjectNode_wait
    raise RuntimeError("Data pipeline evaluation failed with the following error: %s" % state.status.text)
RuntimeError: Data pipeline evaluation failed with the following error: No file column has been mapped to the particle position property.

Thanks,

-ad

Alexander Stukowski

  • Administrator
  • Hero Member
  • *****
  • Posts: 512
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #18 on: November 08, 2018, 09:55:22 PM »
ad,

When loading a legacy-type XYZ file, you need to tell Ovito what the meaning of the file columns is. This is done using the "columns" keyword parameter. See the section on "File columns" here.

For example:

Code: [Select]
node = import_file("file.xyz", columns=["Particle Identifier", "Particle Type", "Position.X", "Position.Y", "Position.Z"])

The error occurred, because Ovito didn't now where to take the data for the "Position" particle property from. Particles must have a "Position" property, filled with the data from three columns of the input file.

-Alex

ad

  • Newbie
  • *
  • Posts: 20
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #19 on: November 12, 2018, 05:52:28 AM »
Hello

import ovito
print("Hello, this is OVITO %i.%i.%i" % ovito.version)

from ovito.io import *
from ovito.modifiers import *


import numpy
node = import_file("Users/3sd/test_sim/asd/sige/ge_10_f/1700K/traj-*.xyz", columns=["Particle Type", "Position.X", "Position.Y", "Position.Z"])

def compute_max_z(frame, input, output):
    output.attributes["High_Z"] = numpy.max(input.particles["Position"][:,4])
    node.modifiers.append(PythonScriptModifier(function=compute_max_z))
print(compute_max_z)
export_file(node, "max_z.txt", "txt", columns=["Frame", "High_Z"], multiple_frames = True)

I tried this, I am getting following error

Hello, this is OVITO 2.9.0
<function compute_max_z at 0x126d0ca60>
The Python script has exited with an error.
Traceback (most recent call last):
  File "<string>", line 15, in <module>
  File "/Applications/Ovito.app/Contents/MacOS/../Resources/python/ovito/io/__init__.py", line 305, in export_file
    if not exporter.export_nodes(ovito.task_manager):
RuntimeError: Failed to open output file 'max_z.txt' for writing: Permission denied

Can you please help me out?

-ad

Alexander Stukowski

  • Administrator
  • Hero Member
  • *****
  • Posts: 512
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #20 on: November 12, 2018, 12:05:20 PM »
Ad,

First note that the following code line should not be indented:
Code: [Select]
node.modifiers.append(PythonScriptModifier(function=compute_max_z))
That is because this statement needs to be part of the main program and not the compute_max_z() function.

The error occurs, because you did not specify an absolute path of the output file when calling the export_file() function. Without specifying a path, the function will probably try to write the output file to the root directory of your machine, which is a write-protected location. To avoid the error message, specify a full path for the output file, like you did for the input file when calling import_file().

-Alex

ad

  • Newbie
  • *
  • Posts: 20
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #21 on: November 16, 2018, 09:00:09 PM »
he Python script has exited with an error.
Traceback (most recent call last):
  File "<string>", line 15, in <module>
  File "/Applications/Ovito 2.app/Contents/MacOS/../Resources/python/ovito/io/export_file.py", line 177, in export_file
    exporter.do_export()
RuntimeError: The global attribute 'High_Z' to be exported is not available at animation frame 0.
Hello, this is OVITO 3.0.0

Why it's giving this error still there are atoms in frame 0

Alexander Stukowski

  • Administrator
  • Hero Member
  • *****
  • Posts: 512
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #22 on: November 17, 2018, 07:56:42 PM »
Please attach the script code. Without it, it is hard to tell what went wrong.

ad

  • Newbie
  • *
  • Posts: 20
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #23 on: November 19, 2018, 04:53:06 AM »
Hello Alex,

Code is working fine, I think it was my mistake. But I have a question, if there is binary system, how to get Max. Z co-ordinate for both the particles?
Like Frame Max_Z(particle 1) Max_Z(particle 2)

Alexander Stukowski

  • Administrator
  • Hero Member
  • *****
  • Posts: 512
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #24 on: November 19, 2018, 08:50:58 AM »
I assume you are currently using the following code line to determine the max. z-coordinate of all particles:

Code: [Select]
output.attributes["High_Z"] = numpy.max(input.particles["Position"][:,2])

Here the ':' selects all particles. You can replace it with an index list which selects only particles of a specific type:

Code: [Select]
selection1 = (input.particles["Particle Type"] == 1)
selection2 = (input.particles["Particle Type"] == 2)
output.attributes["High_Z(1)"] = numpy.max(input.particles["Position"][selection1,2])
output.attributes["High_Z(2)"] = numpy.max(input.particles["Position"][selection2,2])

What is being used here is a technique knows as Boolean indexing of a Numpy array. The first two lines generate two selection arrays using Boolean expressions, which refer to the "Particle Type" property. The following two code lines use these selection arrays to filter the "Position" property array.

ad

  • Newbie
  • *
  • Posts: 20
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #25 on: November 21, 2018, 03:08:01 PM »
Thanks Alex,

Some of the frames contains only a single particle type, how will I write other particle as zero if algorithm couldn't find one?(currently it giving error). I have few more questions for the analysis is it possible to contact you personally?


Thanks,
ad

Alexander Stukowski

  • Administrator
  • Hero Member
  • *****
  • Posts: 512
Re: Not Able to Print a Variable While Looping Over Frames
« Reply #26 on: November 21, 2018, 07:27:09 PM »
If the selection set may be empty, because are no particles of type 2, for example, then you have to handle this special case appropriately in the code. The numpy.any() function can be used to test whether the selection set is empty:

Code: [Select]
selection2 = (input.particles["Particle Type"] == 2)
if numpy.any(selection2):
    output.attributes["High_Z(2)"] = numpy.max(input.particles["Position"][selection2,2])
else:
    output.attributes["High_Z(2)"] = 0.0

If you have more questions, I would prefer that you ask them here in the forum. I have only very limited time at the moment to provide technical support for Ovito as my other jobs take up more and more of my time.