openPMD/openPMD-viewer

Particle selection

Opened this issue ยท 13 comments

ts_particles.get_particle() used to work well with selections in the physical space for macroparticle coordinates. With a Python script such as this:

space

I used to plot a selection of all particles within a single mesh cell in the z-direction, where SHIFTZ is the middle of the simulation domain in [m]

sel

All selections which refer to the Cartesian space could be made in physical space and the macroparticle coordinates were returned in [m].

I have just reinstalled openPMDviewer and I see that selection is now done in cells, but also I see a strange grid across the macroparticles.

cells

Is there a way to revert to the old style, or maybe I would need to downgrade? Which version is indicated

ax3l commented

Thanks for reaching out!

I see that selection is now done in cells ...

Just to clarify, where do you see that change? Because select by z takes the particle global position, there is no need to go by cell. It's just the position in meters.

Hi @ax3l The difference can be seen in the code snippets. When the selection is done in the physical space (first example) the array returned is empty. when it is done using cells (second example) it shows the correct slice along the simulation domain. The first example used to work so far but not with this new installation.

SHIFTZ = (CELLSZ/2)*uZspace is the middle of the simulation domain in [m]

ax3l commented

Oh, we think we have an idea what causes this.

@franzpoeschel , you fixed unitSI handling in #363. Is it possible that the unitSI for this PIConGPU data set is off for positions?

In PIConGPU in the past, what I did is add the cell size as unitSI to each position/* and the positionOffset is in cells, where you also add the cell size as unitSI to each positionOffset/* component.

@cbontoiu can you share a single step data set via a dropbox/google drive/etc. link with us? Then I can take a quick look.

Thanks for looking into this. I will upload a snapshot soon. Just now my internet connection is down.

ax3l commented

Thanks! I took a look at the file with

$ bpls -A -l simData_001490.bp
  double    /data/1490/particles/e/position/x/unitSI                          attr   = 2.5e-08
  double    /data/1490/particles/e/position/y/unitSI                          attr   = 2.5e-08
  double    /data/1490/particles/e/position/z/unitSI                          attr   = 2.5e-08
...
  double    /data/1490/particles/e/positionOffset/x/unitSI                    attr   = 2.5e-08
  double    /data/1490/particles/e/positionOffset/y/unitSI                    attr   = 2.5e-08
  double    /data/1490/particles/e/positionOffset/z/unitSI                    attr   = 2.5e-08
...

$ bpls -l simData_001490.bp
...
  float     /data/1490/particles/e/position/x                          {33950341} = 0 / 0
  float     /data/1490/particles/e/position/y                          {33950341} = 0 / 0
  float     /data/1490/particles/e/position/z                          {33950341} = 0 / 0
  int32_t   /data/1490/particles/e/positionOffset/x                    {33950341} = 0 / 0
  int32_t   /data/1490/particles/e/positionOffset/y                    {33950341} = 0 / 0
  int32_t   /data/1490/particles/e/positionOffset/z                    {33950341} = 0 / 0
  float     /data/1490/particles/e/weighting                           {33950341} = 0 / 0

That in general looks good, but from your image I suspect an issue adding positionOffset and position.

@cbontoiu are your cell sizes for the sim in question cubic, same edge length of 2.5e-8m?

ax3l commented

@cbontoiu which version of PIConGPU did you use?
@franzpoeschel are you aware of a bug that was recently fixed with respect to position and positionOffset handling?

On first sight, the logic in openPMD-viewer looks ok, we scale each position and positionOffset with their respective units in get_data since #363 and then add them together here:

# - Return positions, with an offset
if record_comp in ['x', 'y', 'z']:
offset = get_data(species_grp['positionOffset/%s' % record_comp])
data += offset

# - Return positions, with an offset
if component_name in ['x', 'y', 'z']:
offset = get_data(series, species['positionOffset'][component_name])
data += offset

The simulation snapshot provided was obtained with PIConGPU installed about 3 months ago

PIConGPU: 0.7.0-dev
  Build-Type: Release

Third party:
  OS:         Linux-5.15.0-69-generic
  arch:       x86_64
  CXX:        GNU (11.3.0)
  CMake:      3.22.1
  CUDA:       12.0.76
  mallocMC:   2.6.0
  Boost:      1.74.0
  MPI:        
    standard: 3.1
    flavor:   OpenMPI (4.1.4)
  PNGwriter:  0.7.0
  openPMD:    0.14.4
ax3l commented

This assumption could be a bug:

if q.dtype in [ np.float64, np.float32 ]:
# Fill the position of absent particles by NaNs
selected_q = np.where( selected_indices == -1,
np.nan, selected_q)
else:
# The only non-float quantity in openPMD-viewer is particle id
selected_q = self.selected_pid

openPMD does not declare only id to be non-float, data types are up to the user.
Also, the floating point bitness test is unnecessarily narrow.

@ax3l thank you for helping with this issue.
I use openPMD-viewer with conda and Jupyter Lab. What should I do to downgrade it to the latest version, before this bug was introduced?
Many thanks.

ax3l commented

In conda, you can specify the version with openpmd-viewer==1.6.0. Alternatively, you can pin the version with pip the same way to downgrade until this if fixed.

ax3l commented

@cbontoiu are your cell sizes for the sim in question cubic, same edge length of 2.5e-8m each?

Yes they are cubic, 25 nm each side, at least to 3 digits approximation.