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

Calculate the proportion of certrain atoms in a selection-freezed region


I want to calculate the fraction of full-icosahedral (FI) cluster in a selection-freezed region at different frames. The full-icosahedral cluster has Voronoi index : <0,0,12,0> and only type 1 are considered.

Now i add up the atom type of selected atoms (TYPE==1) to calculated the atoms numbers:

Select = SelectExpressionModifier()

modifier = FreezePropertyModifier(source_property = 'Selection',
destination_property = 'Selection',
freeze_at = 47)

def averaging_strain_tensors(frame, input, output):
# input
Atomictype = input.particle_properties['Particle Type'].array
selection = input.particle_properties['Selection'].array
# calculate
output.attributes['Atom_nums'] = np.sum(Atomictype[selection != 0])

for frame in range(40,50):
print('calculating', frame, 'frame')
Select.expression ='abs(Position.X-275)<15 && abs(Position.Y-90)<15 && ParticleType==1'
#refresh the data
data = node.compute(frame)
a = data.attributes['Atom_nums']

Select.expression ='abs(Position.X-275)<15 && abs(Position.Y-90)<15 && ParticleType==1 \
&& ParticleType==1 &&  voronoiindex3==0 && voronoiindex4==0 && voronoiindex5==12 && voronoiindex6==0'
data = node.compute(frame)
b = data.attributes['Atom_nums']

CCFI= float(b)/float(a)

f.write("{} {} {} {}\n".format(frame,a,b,CCFI))


And then i found i got a constant fraction in every frames, which should not be correct.  I realized this is because i freezed those full-icosahedral  atoms too, but i still don't know how to obtained to correct fraction. Any advices?



Hi Bida,

yes, if you freeze the property "Selection" at frame 47, the fraction of icosahedra will not change in different frames, because the property "Selection" will not be updated in other frames.

Also, I don't understand what you're trying to do with your python script modifier "averaging_strain_tensors". This modifier function will sum up the numeric particle type ids of a selection of atoms. Only in case your selection consists exclusively of particles of type 1, this will be equivalent to the number of atoms in your selection. To get the number of selected atoms it's enough to sum up your particle property "Selection". np.sum(selection)
By the way, the ExpressionSelection modifier automatically creates a global attribute for you that stores the number of selected particles, so you actually don't need to do this.

And I'm wondering, since you never appended this modifier to your pipeline, it shouldn't have any effect at all. The attribute 'Atom_nums' should not exist at all. Maybe this was just a copy and paste mistake?

Just so I understand correctly: You were using the FreezePropertyModifier because you want to analyze the evolution of the fraction of icosahedral atoms among all atoms of particle type 1 that are in this region 'abs(Position.X-275)<15 && abs(Position.Y-90)<15'  in frame 47. Is that correct?
Then you could do the following:

#Select all particles that are in the defined region and have particle type 1
Select = SelectExpressionModifier(expression = 'abs(Position.X-275)<15 && abs(Position.Y-90)<15 && ParticleType==1')
#Freeze this selection at Frame 47 and give the particle property a new name "MySelection"
modifier = FreezePropertyModifier(source_property = 'Selection', destination_property = 'MySelection', freeze_at = 47)
Select2 = SelectExpressionModifier(expression = 'MySelection && VoronoiIndex.3 == 0 && VoronoiIndex.4 == 0 && VoronoiIndex.5 == 12 && MaxFaceOrder == 5')

for frame in range(40,50):
    data = node.compute(frame)
    ico = data.attributes["ExpressionSelection.count.2"]
    n_select = np.sum(data.particles["MySelection"])
    CCFI = ico/n_select
    f.write("{} {} {} {}\n".format(frame,ico,n_select,CCFI))

Note that this this script is meant to be used with the latest developer version.
Does that work for you?




Yes,  the python script modifier should be appened, it is a copy and paste mistake.

Actually, i used  data.attributes['SelectExpression.num_selected'] at first place, and results are not correct. So i try adding up the atomic type.

With the code you provided,  i got error messeage:

KeyError: "Attribute 'ExpressionSelection.count.2' does not exist in data collection."





data.attributes['SelectExpression.num_selected'] at first place, and results are not correct.

Can you explain what you mean by that?  data.attributes['SelectExpression.num_selected'] and numpy.sum(data.particles["Selection"]) yield the same result.

With the code you provided, i got error messeage

Please make sure you really use the latest developer version available here: