Forum Navigation
You need to log in to create posts and topics.

Changing atom types

Hi,

I am wondering how can I simply change an atom type after loading a file in python ovito? I am able to change the type id by

data.particles_.particle_types_[...][i] = 3

However, I am not sure how to change the label (for example to H instead of default Type3). Thanks

Hi,

each type has a unique id, a human-readable name and other attributes like color and radius which you can control. This is explained here:

https://www.ovito.org/docs/current/python/modules/ovito_data.php#ovito.data.ParticleType

and in the section "Typed properties" of this manual entry:

https://www.ovito.org/docs/current/python/modules/ovito_data.php#ovito.data.Particles

If you want to add a type name to particle type 3 you can do the following:

types = pipeline.source.data.particles.particle_types
types.type_by_id(3).name = "H"

-Constanze

You may also have a look at the documentation of the FileSource class. It contains another example of how to set the particle type names after importing a simulation file.

Thanks for your response. Actually, I have attempted to do this already but the problem is that after loading a data object and modifying one of the types through let's say the following command, "particle_types" object is not updated. In other words, if we have one type of atom initially and try to modify one of the species, "data.particles_.particle_types_.types" still will show one type atom instead of two. So, I wouldn't be able to assign name or id to the newly specified particle.

data.particles_["Particle Type"][...][i]= 2

Thanks

I see, so after assigning the new particle type property to the particle, you should also add a new ParticleType() object to the types list of the Particle Type property.

from ovito.data import *

def modify(frame, data):
   ptypes =  data.particles_.particle_types_
   #Give particle 100 a new particle type 3
   ptypes[99] = 3  
   #Now add the new type id and name to the types list of the "Particle Type" property
   ptypes.types.append(ParticleType( id = 3, name = "H"))
   
   for type in ptypes.types:
       print (type.id, type.name)

-Constanze

Hi,

I have a follow up question. Could one change the atom types within the gui Ovito? I tried using Python script, however, changing "Particle Type" is not allowed.

Thanks,

Hi,

please make sure you don't forget to use the underscore notation, to make the property array modifiable, see also
https://www.ovito.org/docs/current/python/introduction/data_manipulation.php?#modifying-properties.

#Option 1
data.particles_.particle_types_
#Option 2
data.particles_.["Particle Type_"]

Thanks very much, Constanze. I actually used above commands within python interface before, however, I am trying to find a way to do this in gui Ovito. I assume using Python script modifier, one should be able to do atom type modification but I believe this modification should be operative before passing the ".compute()" command (in other words, directly applied to the pipeline rather than "data" object). Otherwise I'll get the following error:

numpy.asanyarray(self)[idx] = value # Note to users: Write access to a property requires a 'with' Python statement.
ValueError: assignment destination is read-only

Below is the body of my Python script "modifier" within gui Ovito:

from ovito.data import *

def modify(frame, data):
    
    if data.particles != None:
        pt = data.particles_.particle_types_
        pt.types.append(ParticleType(id=2, name='Cu', color=(0.0, 1.0, 0.0)))
        data.particles_["Particle Type_"][1]=2
        for type in pt.types:
            print(type.id)

Thanks,

-Shahriar

The error message suggests that you are using an older version of OVITO, where you needed a "with" python statement to be able to modify a particle property. Note that calling compute() is not necessary when using a python script modifier in the GUI, since the pipeline is automatically evaluated for you when you press the execute button.

Both scripts posted in this thread can be used in the GUI. Updating your OVITO version to the latest version of OVITO Pro will fix the error message.

Do you only want to change the particle type of the second particle (particle index 1), like you did in the script you posted here? If that's the case than you could use a Compute Property Modifier in the GUI with the following settings:

Output property: Particle Type
Expression: ParticleIndex == 1 ? 2 : ParticleType

This will overwrite the particle type property of the second particle in the list (i.e. with index 1) to type 2 and leave it unchanged for all other particles.

Hello Constanze,

I have a follow-up question. I have a system with 6 different Particle Types. In which I wanted to make 3 of them as one particle type and 3 as another particle type. I tried the above method to change the particle type via python script in GUI and compute property.

However, when I exported the system as a  LAMMPS DATA  file it has only Type 0.

So, it would be great if you can help me with this.

Best

Prash

 

 

Hi,

sure, here's how you could change the particle type property of type 1,2,3 particles to 1 and of type 4,5,6 particles to 2. You can copy and paste the following lines of code into a python script modifier in your OVITO Pro desktop application and adapt it to your needs.

from ovito.data import *

def modify(frame: int, data: DataCollection):
    
    original = data.clone()
    types = data.particles_.particle_types_
    old_types= original.particles.particle_types
    types[old_types <= 3] = 1
    types[old_types > 3] = 2

In that particular case, you could also shorten it to:

from ovito.data import *

def modify(frame: int, data: DataCollection):
    types = data.particles_.particle_types_
    types[types <= 3] = 1
    types[types > 3] = 2

Analogous, you could use a Compute property modifier with the following expression:

ParticleType <=3 ? 1:2

 

Thank you, Constanze for the help.

That's exactly what I wanted to do.

But I want to make type 2,4,6 as 1, type 3,5 as 3, and type 1 particle to 3.

So, what's happing is every time in the last line of selection types[types == 1] = 3  it doesn't take the old_types. Instead, it actually taking the updated one. Where I did types[types == 2] = 1. 

Any idea what could be done in this case.

 

Thank you

Best

Prash

Yes, please use the first code example, that I posted. Cloning the original data before modifying it will solve that problem.

Thank you so much, it works. 🙂

Have a nice day

Best

P

Hello Constanze,

I have one more follow-up question.

Is there any possibility we can select atom Type randomly and then change it to other atom Type.

For example in previous code we selected all atom Type <=3 and convert to Type 1.

But does Ovito-pro give flexibility to select randomly with some percentage (say 40%) and then convert it to atom Type 1.

Best

Prash

from ovito.data import *

def modify(frame: int, data: DataCollection):
    
    original = data.clone()
    types = data.particles_.particle_types_
    old_types= original.particles.particle_types
    types[old_types <= 3] = 1
    types[old_types > 3] = 2

 

Hi Prashant,

Yes, since you are using python, you can make use of the random number routines numpy has to offer: https://numpy.org/doc/stable/reference/random/index.html

from ovito.data import *
import numpy

def modify(frame: int, data: DataCollection, nfrac=0.4):
    rng = numpy.random.default_rng()
    types = data.particles_.particle_types_
    types[rng.choice(data.particles.count, int(nfrac*data.particles.count), replace = False)] = 3

-Constanze

 

Hello,

Thank you so much for the reply. I tried to use this but it applies to all the atoms in the simulation box. By any means is it possible to use this python script only for a region in the simulation box.

I selected a region based on some conditions using Expression selection.

Thank you

Yes of course, you can look up the indices of the selected particles and randomly choose particle indices from this subset only, e.g. like this:

from ovito.data import *
import numpy

def modify(frame: int, data: DataCollection, nfrac=0.4):
    
    rng = numpy.random.default_rng()
    selected_indices = numpy.where(data.particles.selection)[0]
    types = data.particles_.particle_types_
    types[rng.choice(selected_indices, int(nfrac*selected_indices.size), replace = False)] = 3

 

 

Thank you so much Constanze.

It works.

新的OVITO微信频道!
New for our users in China: OVITO on WeChat 

Official OVITO WeChat channel operated by Foshan Diesi Technology Co., Ltd.