class

Chem::Spatial::Grid

Inherits Indexable / Enumerable / Iterable / Reference / Object

TODO: add support for non-cubic grids (use cell instead of bounds?) - i to coords: origin.x + (i / nx) * cell.a - coords to i: ? TODO: implement functionality from vmd's volmap

Constructors

[](ni : Int, nj : Int, nk : Int) : self
Source
atom_distance(structure : Structure, dim : Dimensions, bounds : Parallelepiped | Nil = nil) : self
Source
atom_distance_like(other : self | Info, structure : Structure) : self

Returns a grid filled with the distances to the nearest atom. It will have the same bounds and points as other.

structure = Structure.read "path/to/file"
info = Grid::Info.new Parallelepiped[1.5, 2.135, 6.12], {10, 10, 10}
grid = Grid.atom_distance structure, info.dim, info.bounds
Grid.atom_distance_like(info, structure) == grid # => true
Source
build(info : Info, source_file : String | Path | Nil = nil, & : Pointer(Float64), Int32 -> ) : self

Creates a new Grid with info and yields a buffer to be filled.

This method is unsafe, but it is usually used to initialize the buffer in a linear fashion, e.g., reading values from a file.

Grid.build(Grid.info("/path/to/file")) do |buffer, size|
  size.times do |i|
    buffer[i] = read_value
  end
end
Source
build(dim : Dimensions, bounds : Parallelepiped, source_file : String | Path | Nil = nil, & : Pointer(Float64), Int32 -> ) : self
Source
empty_like(other : self | Info) : self

Returns a zero-filled grid with the same bounds and points as other.

grid = Grid.from_dx "/path/to/grid"
other = Grid.empty_like grid
other.bounds == grid.bounds # => true
other.dim == grid.dim       # => true
other.to_a.minmax           # => {0.0, 0.0}
Source
fill_like(other : self | Info, value : Number) : self

Returns a grid with the same bounds and points as other filled with value.

grid = Grid.from_dx "/path/to/grid"
other = Grid.fill_like grid, 2345.123
other.bounds == grid.bounds # => true
other.dim == grid.dim       # => true
other.to_a.minmax           # => {2345.123, 2345.123}
Source
from_chgcar(input : IO | Path | String) : self

Returns the grid encoded in input using the Chem::VASP::Chgcar file format. Arguments are forwarded to Chem::VASP::Chgcar::Reader.open.

Source
from_cube(input : IO | Path | String) : self

Returns the grid encoded in input using the Chem::Cube file format. Arguments are forwarded to Chem::Cube::Reader.open.

Source
from_dx(input : IO | Path | String) : self

Returns the grid encoded in input using the Chem::DX file format. Arguments are forwarded to Chem::DX::Reader.open.

Source
from_io(io : IO, format : IO::ByteFormat) : self

Reads a grid from io in the given format. See also: IO#read_bytes. Raises IO::EOFError if there is missing data.

Source
from_locpot(input : IO | Path | String) : self

Returns the grid encoded in input using the Chem::VASP::Locpot file format. Arguments are forwarded to Chem::VASP::Locpot::Reader.open.

Source
new(dim : Dimensions, bounds : Parallelepiped, source_file : String | Path | Nil = nil)
Source
new(dim : Dimensions, bounds : Parallelepiped, initial_value : Float64, source_file : String | Path | Nil = nil)
Source
new(dim : Dimensions, bounds : Parallelepiped, source_file : String | Path | Nil = nil, &block : Location -> Number)
Source
read(input : IO | Path | String, format : Chem::Format | String) : self

Returns the grid encoded in the specified file using format. Raises ArgumentError if format has required arguments or cannot read Chem::Spatial::Grid.

The supported file formats are Chem::Cube, Chem::DX, Chem::VASP::Chgcar, Chem::VASP::Locpot. Use the .from_* methods to customize how the object is decoded in the corresponding file format if possible.

Source
read(path : Path | String) : self

Returns the grid encoded in the specified file. The file format is chosen based on the filename (see Chem::Format#from_filename). Raises ArgumentError if the file format cannot be determined.

The supported file formats are the following:

  • Chem::Cube (.cube)
  • Chem::DX (.dx)
  • Chem::VASP::Chgcar (CHGCAR)
  • Chem::VASP::Locpot (LOCPOT)

Use the .from_* methods to customize how the object is decoded in the corresponding file format if possible.

Source
vdw_mask(structure : Structure, dim : Dimensions, bounds : Parallelepiped | Nil = nil, delta : Float64 = 0.02) : self

TODO: add more tests FIXME: check delta calculation (grid.resolution.min / 2 shouldn't be enough?)

Source
vdw_mask_like(other : self | Info, structure : Structure, delta : Float64 = 0.02) : self

Returns a grid mask with the points at the vdW spheres set to 1. It will have the same bounds and points as other.

structure = Structure.read "path/to/file"
info = Grid::Info.new Parallelepiped[5.213, 6.823, 10.352], {20, 25, 40}
grid = Grid.vdw_mask structure, info.dim, info.bounds
Grid.vdw_mask_like(info, structure) == grid # => true
Source

Instance methods

*(rhs : Number) : self
Source
*(rhs : self) : self
Source
+(rhs : Number) : self
Source
+(rhs : self) : self
Source
-(rhs : Number) : self
Source
-(rhs : self) : self
Source
/(rhs : Number) : self
Source
/(rhs : self) : self
Source
==(rhs : self) : Bool

Returns true if this reference is the same as other. Invokes same?.

Source
[](*args, **options) : Float64
Source
[]=(i : Int, j : Int, k : Int, value : Float64) : Float64
Source
[]=(i : Int, value : Float64) : Float64
Source
[]=(loc : Location, value : Float64) : Float64
Source
[]?(i : Int, j : Int, k : Int) : Float64 | Nil
Source
[]?(loc : Location) : Float64 | Nil
Source
[]?(vec : Vec3) : Float64 | Nil

TODO: add interpolation (check ARBInterp)

Source
bounds
Source
coords_at(*args, **options) : Vec3
Source
coords_at?(i : Int, j : Int, k : Int) : Vec3 | Nil
Source
coords_at?(i : Int) : Vec3 | Nil
Source
coords_at?(loc : Location) : Vec3 | Nil
Source
dup

Returns a shallow copy of this object.

This allocates a new object and copies the contents of self into it.

Source
each_axial_slice(axis : Int, reuse : Bool | Array(Float64) = false, & : Array(Float64) -> ) : Nil

Iterates over slices along axis. Axis is specified as an integer: 0-2 refer to the direction of the first, second or third basis vector, respectively.

grid = Grid.new({2, 3, 2}, Parallelepiped[1, 1, 1]) { |i, j, k| i * 6 + j * 2 + k }
grid.to_a # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
slices = [] of Array(Float64)
grid.each_axial_slice(axis: 1) { |slice| slices << slice }
slices # => [[0, 1, 6, 7], [2, 3, 8, 9], [4, 5, 10, 11]]

When using read-only slices, one can specify the reuse option to prevent many memory allocations:

  • If reuse is an Array, this array will be reused.
  • If reuse is true, the method will create a new array and reuse it.
  • If reuse is false (default), a new array is created and yielded on each iteration.
Source
each_coords
Source
each_loc(vec : Vec3, cutoff : Number, & : Location, Float64 -> ) : Nil
Source
each_loc
Source
each_with_coords
Source
each_with_loc
Source
includes?(*args, **options)
Source
includes?(*args, **options, &)
Source
index(loc : Location) : Int32 | Nil
Source
index(vec : Vec3) : Int32 | Nil
Source
index!(*args, **options) : Int32
Source
loc_at(*args, **options) : Location
Source
loc_at?(i : Int) : Location | Nil
Source
loc_at?(vec : Vec3) : Location | Nil
Source
map

Returns an Array with the results of running the block against each element of the collection.

[1, 2, 3].map { |i| i * 10 } # => [10, 20, 30]
Source
map!
Source
map_with_coords
Source
map_with_coords!
Source
map_with_index

Like map, but the block gets passed both the element and its index.

["Alice", "Bob"].map_with_index { |name, i| "User ##{i}: #{name}" }
# => ["User #0: Alice", "User #1: Bob"]

Accepts an optional offset parameter, which tells it to start counting from there.

Source
map_with_index!
Source
map_with_loc
Source
map_with_loc!
Source
mask

Returns a grid mask. Elements for which the passed block returns true are set to 1, otherwise 0.

Grid masks are very useful to deal with multiple grids, and when points are to be selected based on one grid only.

grid = Grid.new({2, 2, 2}, Parallelepiped[10, 10, 10]) { |i, j, k| i + j + k }
grid.to_a              # => [0, 1, 1, 2, 1, 2, 2, 3]
grid.mask(&.>(1)).to_a # => [0, 0, 0, 1, 0, 1, 1, 1]
grid.to_a              # => [0, 1, 1, 2, 1, 2, 2, 3]
Source
mask(value : Number, delta : Number) : self

Returns a grid mask. Elements for which (value - ele).abs <= delta returns true are set to 1, otherwise 0.

Grid masks are very useful to deal with multiple grids, and when points are to be selected based on one grid only.

grid = Grid.new({2, 2, 3}, Parallelepiped[1, 1, 1]) { |i, j, k| (i + 1) * (j + 1) * (k + 1) / 5 }
grid.to_a              # => [0.2, 0.4, 0.6, 0.4, 0.8, 1.2, 0.4, 0.8, 1.2, 0.8, 1.6, 2.4]
grid.mask(1, 0.5).to_a # => [0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0]
grid.to_a              # => [0.2, 0.4, 0.6, 0.4, 0.8, 1.2, 0.4, 0.8, 1.2, 0.8, 1.6, 2.4]
Source
mask(pattern) : self

Returns a grid mask. Elements for which pattern === element returns true are set to 1, otherwise 0.

Grid masks are very useful to deal with multiple grids, and when points are to be selected based on one grid only.

grid = Grid.new({2, 2, 3}, Parallelepiped[1, 1, 1]) { |i, j, k| (i + 1) * (j + 1) * (k + 1) }
grid.to_a              # => [1, 2, 3, 2, 4, 6, 2, 4, 6, 4, 8, 12]
grid.mask(2..4.5).to_a # => [0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0]
grid.to_a              # => [1, 2, 3, 2, 4, 6, 2, 4, 6, 4, 8, 12]
Source
mask!

Masks a grid by the passed block. Elements for which the passed block returns false are set to 0.

Optimized version of creating a mask and applying it to the same grid, but avoids creating intermediate grids. This is equivalent to grid = grid * grid.mask { ... }.

grid = Grid.new({2, 2, 2}, Parallelepiped[10, 10, 10]) { |i, j, k| i + j + k }
grid.to_a # => [0, 1, 1, 2, 1, 2, 2, 3]
grid.mask! &.>(1)
grid.to_a # => [0, 0, 0, 2, 0, 2, 2, 3]
Source
mask!(value : Number, delta : Number) : self

Masks a grid by value+/-delta. Elements for which (value - ele).abs > delta returns true are set to 0.

Optimized version of creating a mask and applying it to the same grid, but avoids creating intermediate grids. This is equivalent to grid = grid * grid.mask(value, delta)

grid = Grid.new({2, 2, 3}, Parallelepiped[1, 1, 1]) { |i, j, k| (i + j + k) / 5 }
grid.to_a # => [0.0, 0.2, 0.4, 0.2, 0.4, 0.6, 0.2, 0.4, 0.6, 0.4, 0.6, 0.8]
grid.mask! 0.5, 0.1
grid.to_a # => [0.0, 0.0, 0.4, 0.0, 0.4, 0.6, 0.0, 0.4, 0.6, 0.4, 0.6, 0.0]
Source
mask!(pattern) : self

Masks a grid by pattern. Elements for which pattern === element returns false are set to 0.

Optimized version of creating a mask and applying it to the same grid, but avoids creating intermediate grids. This is equivalent to grid = grid * grid.mask(pattern)

grid = Grid.new({2, 2, 3}, Parallelepiped[1, 1, 1]) { |i, j, k| (i + 1) * (j + 1) * (k + 1) }
grid.to_a # => [1, 2, 3, 2, 4, 6, 2, 4, 6, 4, 8, 12]
grid.mask! 2..4.5
grid.to_a # => [0, 2, 3, 2, 4, 0, 2, 4, 0, 4, 0, 0]
Source
mask_by_coords

Returns a grid mask. Coordinates for which the passed block returns true are set to 1, otherwise 0.

Grid masks are very useful to deal with multiple grids, and when points are to be selected based on one grid only.

grid = Grid.new({2, 2, 2}, Parallelepiped[10, 10, 10]) { |i, j, k| i * 4 + j * 2 + k }
grid.to_a                           # => [0, 1, 2, 3, 4, 5, 6, 7]
grid.mask_by_coords(&.x.==(0)).to_a # => [1, 1, 1, 1, 0, 0, 0, 0]
grid.to_a                           # => [0, 1, 2, 3, 4, 5, 6, 7]
Source
mask_by_coords!

Masks a grid by coordinates. Coordinates for which the passed block returns false are set to 0.

Optimized version of creating a mask and applying it to the same grid, but avoids creating intermediate grids. This is equivalent to grid = grid * grid.mask_by_coords { ... }

grid = Grid.new({2, 2, 2}, Parallelepiped[5, 5, 5]) { |i, j, k| i * 4 + j * 2 + k }
grid.to_a # => [0, 1, 2, 3, 4, 5, 6, 7]
grid.mask_by_coords! { |vec| vec.y == 5 }
grid.to_a # => [0, 0, 2, 3, 0, 0, 6, 7]
Source
mask_by_index

Returns a grid mask. Indexes for which the passed block returns true are set to 1, otherwise 0.

Grid masks are very useful to deal with multiple grids, and when points are to be selected based on one grid only.

grid = Grid.new({2, 2, 2}, Parallelepiped[10, 10, 10]) { |i, j, k| i * 4 + j * 2 + k }
grid.to_a                       # => [0, 1, 2, 3, 4, 5, 6, 7]
grid.mask_by_index(&.>(4)).to_a # => [0, 0, 0, 0, 0, 1, 1, 1]
grid.to_a                       # => [0, 1, 2, 3, 4, 5, 6, 7]
Source
mask_by_index!

Masks a grid by index. Indexes for which the passed block returns false are set to 0.

Optimized version of creating a mask and applying it to the same grid, but avoids creating intermediate grids. This is equivalent to grid = grid * grid.mask_by_index { ... }

grid = Grid.new({2, 2, 2}, Parallelepiped[1, 1, 1]) { |i, j, k| i * 4 + j * 2 + k }
grid.to_a # => [0, 1, 2, 3, 4, 5, 6, 7]
grid.mask_by_index! &.<(3)
grid.to_a # => [0, 1, 2, 0, 0, 0, 0, 0]
Source
mask_by_loc

Returns a grid mask. Locations for which the passed block returns true are set to 1, otherwise 0.

Grid masks are very useful to deal with multiple grids, and when points are to be selected based on one grid only.

grid = Grid.new({2, 2, 2}, Parallelepiped[10, 10, 10]) { |i, j, k| i * 4 + j * 2 + k }
grid.to_a                                  # => [0, 1, 2, 3, 4, 5, 6, 7]
grid.mask_by_loc { |i, j, k| k == 1 }.to_a # => [0, 1, 0, 1, 0, 1, 0, 1]
grid.to_a                                  # => [0, 1, 2, 3, 4, 5, 6, 7]
Source
mask_by_loc!

Masks a grid by location. Locations for which the passed block returns false are set to 0.

Optimized version of creating a mask and applying it to the same grid, but avoids creating intermediate grids. This is equivalent to grid = grid * grid.mask_by_loc { ... }

grid = Grid.new({2, 2, 2}, Parallelepiped[1, 1, 1]) { |i, j, k| i * 4 + j * 2 + k }
grid.to_a # => [0, 1, 2, 3, 4, 5, 6, 7]
grid.mask_by_loc! { |(i, j, k)| i == 1 }
grid.to_a # => [0, 0, 0, 0, 4, 5, 6, 7]
Source
mean(axis : Int) : Array(Float64)

Returns the arithmetic mean along axis. Axis is specified as an integer: 0-2 refer to the direction of the first, second or third basis vector, respectively.

Raises IndexError is axis is out of bounds.

grid = Grid.new({2, 3, 4}, Parallelepiped[1, 1, 1]) { |i, j, k| i * 12 + j * 4 + k }
grid.mean(axis: 0) # => [5.5, 17.5]
grid.mean(axis: 1) # => [7.5, 11.5, 15.5]
grid.mean(axis: 2) # => [10, 11, 12, 13]
grid.mean(axis: 3) # raises IndexError
Source
mean

Returns the arithmetic mean of the grid elements.

grid = Grid.new({2, 3, 4}, Parallelepiped[1, 1, 1]) { |i, j, k| i * 12 + j * 4 + k }
grid.mean # => 11.5
Source
mean_with_coords(axis : Int) : Array(Tuple(Float64, Float64))

Returns the arithmetic mean along axis with its coordinates. Axis is specified as an integer: 0-2 refer to the direction of the first, second or third basis vector, respectively.

Raises IndexError is axis is out of bounds.

grid = Grid.new({2, 3, 5}, Parallelepiped[1, 1, 1]) { |i, j, k| i * 12 + j * 4 + k }
grid.mean(axis: 1) # => [{9.5, 0.0}, {14.5, 0.5}, {19.5, 1.0}]
Source
origin(*args, **options)
Source
origin(*args, **options, &)
Source
resolution
Source
size

Returns the number of elements in this container.

Source
source_file
Source
step(di : Int, dj : Int, dk : Int) : self
Source
step(n : Int) : self
Source
to_a

Returns an Array with all the elements in the collection.

(1..5).to_a # => [1, 2, 3, 4, 5]
Source
to_chgcar(output : IO | Path | String, structure : Structure) : Nil

Writes the grid to output using the Chem::VASP::Chgcar file format. Arguments are fowarded to Chem::VASP::Chgcar::Writer.open.

Source
to_chgcar(structure : Structure) : String

Returns a string representation of the grid using the Chem::VASP::Chgcar file format. Arguments are fowarded to Chem::VASP::Chgcar::Writer.open.

Source
to_cube(output : IO | Path | String, atoms : AtomCollection) : Nil

Writes the grid to output using the Chem::Cube file format. Arguments are fowarded to Chem::Cube::Writer.open.

Source
to_cube(atoms : AtomCollection) : String

Returns a string representation of the grid using the Chem::Cube file format. Arguments are fowarded to Chem::Cube::Writer.open.

Source
to_dx(output : IO | Path | String) : Nil

Writes the grid to output using the Chem::DX file format. Arguments are fowarded to Chem::DX::Writer.open.

Source
to_dx

Returns a string representation of the grid using the Chem::DX file format. Arguments are fowarded to Chem::DX::Writer.open.

Source
to_io(io : IO, format : IO::ByteFormat = :system_endian) : Nil

Writes the binary representation of the grid to io in the given format. See also IO#write_bytes. Raises ArgumentError is the encoding is not UTF-8.

Source
to_locpot(output : IO | Path | String, structure : Structure) : Nil

Writes the grid to output using the Chem::VASP::Locpot file format. Arguments are fowarded to Chem::VASP::Locpot::Writer.open.

Source
to_locpot(structure : Structure) : String

Returns a string representation of the grid using the Chem::VASP::Locpot file format. Arguments are fowarded to Chem::VASP::Locpot::Writer.open.

Source
to_unsafe
Source
unsafe_fetch(index : Int) : Float64

Returns the element at the given index, without doing any bounds check.

Indexable makes sure to invoke this method with index in 0...size, so converting negative indices to positive ones is not needed here.

Clients never invoke this method directly. Instead, they access elements with #[](index) and #[]?(index).

This method should only be directly invoked if you are absolutely sure the index is in bounds, to avoid a bounds check for a small boost of performance.

Source
unsafe_fetch(loc : Location) : Float64
Source
volume(*args, **options)
Source
volume(*args, **options, &)
Source
write(output : IO | Path | String, format : Chem::Format | String) : Nil

Writes the grid to output using format. Raises ArgumentError if format has required arguments or cannot write Chem::Spatial::Grid.

The supported file formats are Chem::DX. Use the #to_* methods to customize how the object is written in the corresponding file format if possible.

Source
write(path : Path | String) : Nil

Writes the grid to the specified file. The file format is chosen based on the filename (see Chem::Format#from_filename). Raises ArgumentError if the file format cannot be determined.

The supported file formats are the following:

  • Chem::DX (.dx)

Use the #to_* methods to customize how the object is written in the corresponding file format if possible.

Source

Nested types