OpenMPCD
ParticleCollection.py
1 from .Vector3DReal import Vector3DReal
2 
3 import math
4 import numpy
5 import numpy.linalg
6 
7 class ParticleCollection:
8  """
9  Represents the state of a collection of particles.
10  """
11 
12  def __init__(self):
13  """
14  Constructs an empty particle collection.
15  """
16 
17  self.positions = []
18  self.velocities = []
19  self.uniformMass = None
20 
21  self.gyrationTensor = None
22 
23 
24  def setPositionsAndVelocities(self, positions, velocities):
25  """
26  Sets the particle positions and velocities.
27 
28  The given arguments will be copied into an instance-internal store.
29 
30  @throw TypeError
31  Throws if the arguments do not have the types specified in their
32  documentation.
33  @throw ValueError
34  Throws if the `positions` and `velocities` lists do not have
35  equal length.
36 
37  @param[in] positions
38  A list of `Vector3DReal` instances, describing the particle
39  positions.
40  @param[in] velocities
41  A list of `Vector3DReal` instances, describing the particle
42  velocities.
43  """
44 
45  if not isinstance(positions, list):
46  raise TypeError()
47  if not isinstance(velocities, list):
48  raise TypeError()
49 
50 
51  for x in positions:
52  if not isinstance(x, Vector3DReal):
53  raise TypeError()
54  for x in velocities:
55  if not isinstance(x, Vector3DReal):
56  raise TypeError()
57 
58 
59  if len(velocities) != 0:
60  if len(positions) != len(velocities):
61  raise ValueError("Arrays of different length given")
62 
63 
64  import copy
65  self.positions = copy.deepcopy(positions)
66  self.velocities = copy.deepcopy(velocities)
67 
68  self.gyrationTensor = None
69 
70 
71  def setUniformMass(self, mass):
72  """
73  Sets a uniform mass for all particles, including currently stored ones
74  and ones that may be added or altered later.
75 
76  @throw TypeError
77  Throws if `mass` is neither `int` nor `float`.
78  @throw ValueError
79  Throws if `mass` is smaller than `0`.
80 
81  @param[in] mass
82  The particle mass, which must be a non-negative `int` or
83  `float`.
84  """
85 
86  if not isinstance(mass, (int, float)):
87  raise TypeError()
88 
89  if mass < 0:
90  raise ValueError()
91 
92  self.uniformMass = float(mass)
93 
94 
95  def isEmpty(self):
96  """
97  Returns whether this collection contains any particles.
98  """
99 
100  return len(self.positions) == 0
101 
102 
103  def getParticleCount(self):
104  """
105  Returns the number of particles in this collection.
106  """
107 
108  return len(self.positions)
109 
110 
111  def getPositions(self):
112  """
113  Returns a reference to the internal list of position vectors.
114 
115  @warning
116  It is assumed that the returned reference will not be manipulated!
117  """
118 
119  return self.positions
120 
121 
122  def getPosition(self, index):
123  """
124  Returns the position of the particle with the given `index`, as an
125  instance of `Vector3DReal`.
126 
127  @throw IndexError
128  Throws if `index` is negative or `index >= getParticleCount()`.
129  @throw TypeError
130  Throws if `index` is not an `int`.
131 
132  @param[in] index
133  The index of the particle to query, in the range of
134  `[0, getParticleCount() - 1]`.
135  """
136 
137  if not isinstance(index, int):
138  raise TypeError()
139 
140  if index < 0 or index >= self.getParticleCount():
141  raise IndexError()
142 
143  return self.positions[index]
144 
145 
146  def getVelocities(self):
147  """
148  Returns a reference to the internal list of velocity vectors.
149 
150  @warning
151  It is assumed that the returned reference will not be manipulated!
152  """
153 
154  return self.velocities
155 
156 
157  def getVelocity(self, index):
158  """
159  Returns the velocity of the particle with the given `index`, as an
160  instance of `Vector3DReal`
161 
162  @throw IndexError
163  Throws if `index` is negative or `index >= getParticleCount()`.
164  @throw TypeError
165  Throws if `index` is not an `int`.
166 
167  @param[in] index
168  The index of the particle to query, in the range of
169  `[0, getParticleCount() - 1]`.
170  """
171 
172  if not isinstance(index, int):
173  raise TypeError()
174 
175  if index < 0 or index >= self.getParticleCount():
176  raise IndexError()
177 
178  return self.velocities[index]
179 
180 
181  def getMass(self, index):
182  """
183  Returns the mass of the particle with the given `index` as a `float`.
184 
185  @throw IndexError
186  Throws if `index` is negative or `index >= getParticleCount()`.
187  @throw RuntimeError
188  Throws if no mass has been specified for the given particle.
189  @throw TypeError
190  Throws if `index` is not an `int`.
191 
192  @param[in] index
193  The index of the particle to query, in the range of
194  `[0, getParticleCount() - 1]`.
195  """
196 
197  if not isinstance(index, int):
198  raise TypeError()
199 
200  if index < 0 or index >= self.getParticleCount():
201  raise IndexError()
202 
203  if self.uniformMass is None:
204  raise RuntimeError()
205 
206  return self.uniformMass
207 
208 
209  def getMomentum(self, index):
210  """
211  Returns the momentum of the particle with the given `index`, as an
212  instance of `Vector3DReal`
213 
214  @throw IndexError
215  Throws if `index` is negative or `index >= getParticleCount()`.
216  @throw RuntimeError
217  Throws if no mass has been specified for the given particle.
218  @throw TypeError
219  Throws if `index` is not an `int`.
220 
221  @param[in] index
222  The index of the particle to query, in the range of
223  `[0, getParticleCount() - 1]`.
224  """
225 
226  return self.velocities[index] * self.getMass(index)
227 
228 
229  def getCenterOfMass(self):
230  """
231  Returns the center of mass of the particles, as an instance of
232  `Vector3DReal`.
233 
234  @throw RuntimeError
235  Throws if `isEmpty()`.
236  @throw RuntimeError
237  Throws if the mass has not been specified for all particles.
238  """
239 
240  if self.isEmpty():
241  raise RuntimeError()
242 
243  cumulative = Vector3DReal(0, 0, 0)
244  mass = 0.0
245 
246  for index, position in enumerate(self.positions):
247  currentMass = self.getMass(index)
248  mass += currentMass
249  cumulative += position * currentMass
250 
251  centerOfMass = cumulative / mass
252  return centerOfMass
253 
254 
255  def getCenterOfPositions(self):
256  """
257  Returns the unweighted average of all particle positions, as an instance
258  of `Vector3DReal`.
259 
260  @throw RuntimeError
261  Throws if `isEmpty()`.
262  """
263 
264  if self.isEmpty():
265  raise RuntimeError()
266 
267  cumulative = Vector3DReal(0, 0, 0)
268 
269  for position in self.positions:
270  cumulative += position
271 
272  return cumulative / len(self.positions)
273 
274 
275  def getCenterOfMassVelocity(self):
276  """
277  Returns the velocity of the center of mass, as an instance of
278  `Vector3DReal`.
279 
280  @throw RuntimeError
281  Throws if `isEmpty()`.
282  @throw RuntimeError
283  Throws if the mass has not been specified for all particles.
284  """
285 
286  if self.isEmpty():
287  raise RuntimeError()
288 
289  cumulative = Vector3DReal(0, 0, 0)
290  mass = 0
291 
292  for index, velocity in enumerate(self.velocities):
293  currentMass = self.getMass(index)
294  mass += currentMass
295  cumulative += velocity * currentMass
296 
297  centerOfMassVelocity = cumulative / mass
298  return centerOfMassVelocity
299 
300 
301  def rotateAroundNormalizedAxis(self, axis, angle):
302  """
303  Rotates all position and velocity vectors around the given `axis` for
304  the given `angle`.
305 
306  @throw TypeError
307  Throws if one of the arguments is of the wrong type.
308  @throw ValueError
309  Throws if `axis` is not a unit-length vector.
310 
311  @param[in] axis
312  The axis to rotate around, which must have unit length.
313  @param[in] angle
314  The angle to rotate, in radians, as an instance of `float`.
315  """
316 
317  if not isinstance(axis, Vector3DReal):
318  raise TypeError()
319 
320  if not isinstance(angle, float):
321  raise TypeError()
322 
323  if not axis.getLengthSquared() == 1.0:
324  raise ValueError()
325 
326 
327  for position in self.positions:
328  position.rotateAroundNormalizedAxis(axis, angle)
329 
330  for velocity in self.velocities:
331  velocity.rotateAroundNormalizedAxis(axis, angle)
332 
333  self.gyrationTensor = None
334 
335 
336  def shiftToCenterOfMassFrame(self):
337  """
338  Transforms the positions and velocities into the center of mass frame.
339  """
340 
341  centerOfMass = self.getCenterOfMass()
342  centerOfMassVelocity = self.getCenterOfMassVelocity()
343 
344  for index, _ in enumerate(self.positions):
345  self.positions[index] -= centerOfMass
346 
347  for index, _ in enumerate(self.velocities):
348  self.velocities[index] -= centerOfMassVelocity
349 
350  self.gyrationTensor = None
351 
352 
353  def getGyrationTensor(self):
354  """
355  Returns the gyration tensor \f$ S \f$.
356 
357  The returned object is a \f$ 3 \times 3 \f$ symmetric matrix of type
358  `numpy.ndarray`.
359  Given \f$ N \f$ particles with positions \f$ \vec{r}^{(i)} \f$ (in any
360  Cartesian coordinate frame), the \f$ \left( m, n \right) \f$-component
361  of the gyration tensor is defined by
362  \f[
363  S_{mn}
364  =
365  \frac{ 1 }{ 2 N^2 }
366  \sum_{i = 1}^N
367  \sum_{j = 1}^N
368  \left( \vec{r}^{(i)}_m - \vec{r}^{(j)}_m \right)
369  \left( \vec{r}^{(i)}_n - \vec{r}^{(j)}_n \right)
370  \f]
371 
372  @throw ValueError
373  Throws if there are no particles in this instance.
374  """
375 
376  if self.gyrationTensor is not None:
377  return self.gyrationTensor
378 
379  if self.isEmpty():
380  raise ValueError()
381 
382 
383  S = numpy.zeros((3, 3))
384 
385  for r1 in self.positions:
386  for r2 in self.positions:
387  for m in range(0, 3):
388  for n in range(m, 3):
389  S[m][n] += (r1[m] - r2[m]) * (r1[n] - r2[n])
390 
391  factor = 1.0 / (2 * self.getParticleCount() * self.getParticleCount())
392  for m in range(0, 3):
393  for n in range(m, 3):
394  S[m][n] *= factor
395 
396  S[1][0] = S[0][1]
397  S[2][0] = S[0][2]
398  S[2][1] = S[1][2]
399 
400  self.gyrationTensor = S
401  return S
402 
403 
404  def getMomentOfInertiaTensor(self):
405  centerOfMass = self.getCenterOfMass()
406  if centerOfMass.getLengthSquared() > 1e-20:
407  raise ValueError(
408  "The center of mass has to be at the origin! " +
409  "Instead, it squared distance to the origin is: " +
410  str(centerOfMass.getLengthSquared()))
411 
412  Ixx = 0.0
413  Ixy = 0.0
414  Ixz = 0.0
415  Iyy = 0.0
416  Iyz = 0.0
417  Izz = 0.0
418 
419  for index, position in enumerate(self.positions):
420  x = position.getX()
421  y = position.getY()
422  z = position.getZ()
423  mass = self.getMass(index)
424 
425  Ixx += mass * (y * y + z * z)
426  Ixy += -mass * x * y
427  Ixz += -mass * x * z
428  Iyy += mass * (x * x + z * z)
429  Iyz += -mass * y * z
430  Izz += mass * (x * x + y * y)
431 
432  I = numpy.array([
433  [Ixx, Ixy, Ixz],
434  [Ixy, Iyy, Iyz],
435  [Ixz, Iyz, Izz]])
436 
437  return I
438 
439  def getTotalAngularMomentumVector(self):
440  L = Vector3DReal(0, 0, 0)
441 
442  for index, position in enumerate(self.positions):
443  L += position.cross(self.getMomentum(index))
444 
445  return L
446 
447  def getRotationFrequencyVector(self):
448  I = self.getMomentOfInertiaTensor()
450  L = numpy.array([L.getX(), L.getY(), L.getZ()])
451  omega = numpy.linalg.inv(I).dot(L)
452  return Vector3DReal(omega[0], omega[1], omega[2])
453 
454 
456  """
457  Returns the eigenvalues \f$ \lambda_x^2 \f$, \f$ \lambda_y^2 \f$, and
458  \f$ \lambda_z^2 \f$ of the gyration tensor (as returned by
459  `getGyrationTensor`). The eigenvalues are arranged such that
460  \f$ \lambda_x^2 \le \lambda_y^2 \le \lambda_y^z \f$.
461 
462  The eigenvalues are real and of type `numpy.float64`, and returned as
463  the elements of a list.
464  """
465 
466  S = self.getGyrationTensor()
467  eigenvalues, _ = numpy.linalg.eig(S)
468 
469  x, y, z = numpy.sort(eigenvalues)
470 
471  if not (numpy.isreal(x) and numpy.isreal(y) and numpy.isreal(z)):
472  raise ValueError("Unexpected")
473 
474  return [x, y, z]
475 
476 
478  """
479  Returns the eigenvalues and eigenvectors of the gyration tensor (as
480  returned by `getGyrationTensor`).
481 
482  The returned object is a list, with each element being a list of first
483  the eigenvalue, and second the associated eigenvector. The tuples are
484  sorted by the value of the eigenvalue, smallest first.
485 
486  The eigenvalues are real and of type `numpy.float64`, and the
487  eigenvectors are of type `numpy.ndarray` with three entries of type
488  `numpy.float64`.
489  """
490 
491  S = self.getGyrationTensor()
492  eigenvalues, eigenvectors = numpy.linalg.eig(S)
493 
494  for eigenvalue in eigenvalues:
495  if not numpy.isreal(eigenvalue):
496  raise ValueError("Unexpected")
497 
498  indices = eigenvalues.argsort()
499 
500  ret = []
501  for index in indices:
502  ret.append([eigenvalues[index], eigenvectors[:, index]])
503 
504  return ret
505 
506 
507  def getRadiusOfGyrationSquared(self):
508  """
509  Returns the sum of the eigenvalues of the gyration tensor, as returned
510  by `getGyrationTensorPrincipalMoments`
511  """
512 
513  x, y, z = self.getGyrationTensorPrincipalMoments()
514 
515  return x + y + z
516 
517  def getRadiusOfGyration(self):
518  """
519  Returns the radius of gyration \f$ R_g \f$, i.e. the square root of the
520  result of `getRadiusOfGyrationSquared`.
521  """
522 
523  return math.sqrt(self.getRadiusOfGyrationSquared())
524 
525  def getAsphericity(self):
526  """
527  Returns the asphericity \f$ b \f$, i.e.
528  \f[
529  \lambda_z^2 - \frac{1}{2} \left( \lambda_x^2 + \lambda_y^2 \right)
530  \f]
531  where \f$ \lambda_z^2 \f$ is the largest eigenvalue of the gyration
532  tensor, and \f$ \lambda_x^2 \f$ and \f$ \lambda_y^2 \f$ are the two
533  smallest eigenvalues.
534  """
535 
536  x, y, z = self.getGyrationTensorPrincipalMoments()
537 
538  return z - 0.5 * (x + y)
539 
540  def getAcylindricity(self):
541  """
542  Returns the acylindricity \f$ c \f$, i.e.
543  \f[
544  \lambda_y^2 - \lambda_x^2
545  \f]
546  where \f$ \lambda_x^2 \f$ is the smallest eigenvalue of the gyration
547  tensor, \f$ \lambda_z^2 \f$ is the largest eigenvalue, and
548  \f$ \lambda_y^2 \f$ is the one in between.
549  """
550 
551  x, y, _ = self.getGyrationTensorPrincipalMoments()
552 
553  return y - x
554 
555  def getRelativeShapeAnisotropy(self):
556  """
557  Returns the relative shape anisotropy \f$ \kappa^2 \f$, i.e.
558  \f[
559  \frac{ b^2 + \frac{3}{4} c^2 }{ R_g^4 }
560  \f]
561  where \f$ b \f$ is the asphericity, \f$ c \f$ is the acylindricity, and
562  \f$ R_g \f$ is the radius of gyration.
563  """
564 
565  b = self.getAsphericity()
566  c = self.getAcylindricity()
567  R_g_squared = self.getRadiusOfGyrationSquared()
568 
569  return (b * b + 0.75 * c * c) / (R_g_squared * R_g_squared)
570 
571  def getOrientationAngle(self, axis):
572  """
573  Returns the angle between the given `axis` and the eigenvector of the
574  gyration tensor that corresponds to the largest eigenvalue.
575  """
576 
577  if len(axis) != 3:
578  raise ValueError("")
579 
580  eigenpairs = self.getGyrationTensorEigensystem()
581 
582  return self._getAngleBetweenLines(eigenpairs[2][1], axis)
583 
584  def getOrientationAngles(self, axis):
585  """
586  Returns the angle between the given `axis` and the eigenvectors of the
587  gyration tensor. The returned value is a list, sorted by increasing
588  eigenvalues, of pairs of eigenvalue and corresponding angle.
589  """
590 
591  if len(axis) != 3:
592  raise ValueError("")
593 
594  eigenpairs = self.getGyrationTensorEigensystem()
595 
596  ret = []
597  for eigenpair in eigenpairs:
598  eigenvalue = eigenpair[0]
599  eigenvector = eigenpair[1]
600 
601  angle = self._getAngleBetweenLines(eigenvector, axis)
602 
603  ret.append([eigenvalue, angle])
604 
605  return ret
606 
607 
608 
609  def _getAngleBetweenLines(self, v1, v2):
610  """
611  Returns the angle between two lines, characterized by the given two
612  vectors.
613  """
614 
615  dot = numpy.dot(v1, v2)
616  if dot < 0:
617  dot *= -1
618 
619  len1Squared = numpy.dot(v1, v1)
620  len2Squared = numpy.dot(v2, v2)
621 
622  return numpy.arccos(dot / numpy.sqrt(len1Squared * len2Squared))
623 
624 
625  def __eq__(self, rhs):
626  """
627  The equality operator.
628 
629  Returns whether this instance stores the same particles (i.e. their
630  count, positions, velocities, and masses) as the given `rhs` instance.
631 
632  Having set a different uniform mass in two instances makes them not
633  equal, even if there are no particles.
634 
635  @param[in] rhs The right-hand-side instance to compare to.
636 
637  @return Returns whether the two instances are equal, or `NotImplemented`
638  if the two instances are not of the same type.
639  """
640 
641  if not isinstance(rhs, self.__class__):
642  return NotImplemented
643 
644  if len(self.positions) != len(rhs.positions):
645  return False
646 
647  if self.uniformMass != rhs.uniformMass:
648  return False
649 
650  for index, position in enumerate(self.positions):
651  if position != rhs.positions[index]:
652  return False
653  if self.velocities[index] != rhs.velocities[index]:
654  return False
655 
656  return True
657 
658 
659  def __ne__(self, rhs):
660  """
661  The inequality operator.
662 
663  @param[in] rhs The right-hand-side instance to compare to.
664 
665  @return Returns `NotImplemented` if the two instances are not of the
666  same type, and `not self == rhs` otherwise.
667  """
668 
669  if not isinstance(rhs, self.__class__):
670  return NotImplemented
671 
672  return not self == rhs
MPCDAnalysis.ParticleCollection.ParticleCollection.getAcylindricity
def getAcylindricity(self)
Definition: ParticleCollection.py:573
MPCDAnalysis.ParticleCollection.ParticleCollection.getGyrationTensor
def getGyrationTensor(self)
Definition: ParticleCollection.py:392
MPCDAnalysis.ParticleCollection.ParticleCollection.setPositionsAndVelocities
def setPositionsAndVelocities(self, positions, velocities)
Definition: ParticleCollection.py:46
MPCDAnalysis.ParticleCollection.ParticleCollection.getCenterOfMass
def getCenterOfMass(self)
Definition: ParticleCollection.py:251
MPCDAnalysis.ParticleCollection.ParticleCollection.getMomentum
def getMomentum(self, index)
Definition: ParticleCollection.py:236
MPCDAnalysis.ParticleCollection.ParticleCollection.getOrientationAngles
def getOrientationAngles(self, axis)
Definition: ParticleCollection.py:616
MPCDAnalysis.ParticleCollection.ParticleCollection.getAsphericity
def getAsphericity(self)
Definition: ParticleCollection.py:557
MPCDAnalysis.ParticleCollection.ParticleCollection.getCenterOfMassVelocity
def getCenterOfMassVelocity(self)
Definition: ParticleCollection.py:299
MPCDAnalysis.ParticleCollection.ParticleCollection.positions
positions
Definition: ParticleCollection.py:19
MPCDAnalysis.ParticleCollection.ParticleCollection.getMass
def getMass(self, index)
Definition: ParticleCollection.py:206
MPCDAnalysis.ParticleCollection.ParticleCollection.getVelocities
def getVelocities(self)
Definition: ParticleCollection.py:161
MPCDAnalysis.ParticleCollection.ParticleCollection.getPositions
def getPositions(self)
Definition: ParticleCollection.py:124
MPCDAnalysis.ParticleCollection.ParticleCollection.getMomentOfInertiaTensor
def getMomentOfInertiaTensor(self)
Definition: ParticleCollection.py:422
MPCDAnalysis.ParticleCollection.ParticleCollection.getGyrationTensorPrincipalMoments
def getGyrationTensorPrincipalMoments(self)
Definition: ParticleCollection.py:483
MPCDAnalysis.ParticleCollection.ParticleCollection.getOrientationAngle
def getOrientationAngle(self, axis)
Definition: ParticleCollection.py:601
MPCDAnalysis.Vector3DReal.Vector3DReal
Definition: Vector3DReal.py:7
MPCDAnalysis.ParticleCollection.ParticleCollection.__init__
def __init__(self)
Definition: ParticleCollection.py:17
MPCDAnalysis.ParticleCollection.ParticleCollection.getCenterOfPositions
def getCenterOfPositions(self)
Definition: ParticleCollection.py:276
MPCDAnalysis.ParticleCollection.ParticleCollection.getVelocity
def getVelocity(self, index)
Definition: ParticleCollection.py:180
MPCDAnalysis.ParticleCollection.ParticleCollection.isEmpty
def isEmpty(self)
Definition: ParticleCollection.py:103
MPCDAnalysis.ParticleCollection.ParticleCollection.getRelativeShapeAnisotropy
def getRelativeShapeAnisotropy(self)
Definition: ParticleCollection.py:588
MPCDAnalysis.ParticleCollection.ParticleCollection.shiftToCenterOfMassFrame
def shiftToCenterOfMassFrame(self)
Definition: ParticleCollection.py:356
MPCDAnalysis.ParticleCollection.ParticleCollection.getParticleCount
def getParticleCount(self)
Definition: ParticleCollection.py:112
MPCDAnalysis.ParticleCollection.ParticleCollection.getRadiusOfGyration
def getRadiusOfGyration(self)
Definition: ParticleCollection.py:543
MPCDAnalysis.ParticleCollection.ParticleCollection.getPosition
def getPosition(self, index)
Definition: ParticleCollection.py:143
MPCDAnalysis.ParticleCollection.ParticleCollection.velocities
velocities
Definition: ParticleCollection.py:20
MPCDAnalysis.ParticleCollection.ParticleCollection.getGyrationTensorEigensystem
def getGyrationTensorEigensystem(self)
Definition: ParticleCollection.py:509
MPCDAnalysis.ParticleCollection.ParticleCollection.getRadiusOfGyrationSquared
def getRadiusOfGyrationSquared(self)
Definition: ParticleCollection.py:532
MPCDAnalysis.ParticleCollection.ParticleCollection.setUniformMass
def setUniformMass(self, mass)
Definition: ParticleCollection.py:88
MPCDAnalysis.ParticleCollection.ParticleCollection.getTotalAngularMomentumVector
def getTotalAngularMomentumVector(self)
Definition: ParticleCollection.py:457
MPCDAnalysis.ParticleCollection.ParticleCollection.rotateAroundNormalizedAxis
def rotateAroundNormalizedAxis(self, axis, angle)
Definition: ParticleCollection.py:331
MPCDAnalysis.ParticleCollection.ParticleCollection._getAngleBetweenLines
def _getAngleBetweenLines(self, v1, v2)
Definition: ParticleCollection.py:641
MPCDAnalysis.ParticleCollection.ParticleCollection.gyrationTensor
gyrationTensor
Definition: ParticleCollection.py:23
MPCDAnalysis.ParticleCollection.ParticleCollection.uniformMass
uniformMass
Definition: ParticleCollection.py:21
MPCDAnalysis.ParticleCollection.ParticleCollection.__eq__
def __eq__(self, rhs)
Definition: ParticleCollection.py:668
MPCDAnalysis.ParticleCollection.ParticleCollection.__ne__
def __ne__(self, rhs)
Definition: ParticleCollection.py:697