The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

PDLx::MaskedData - Automatically synchronize data and valid data masks

VERSION

version 0.06

SYNOPSIS

  use 5.10.0;

  use PDLx::MaskedData;

  $data1 = PDLx::MaskedData->new( sequence(9) );
  say $data1;    # [0 1 2 3 4 5 6 7 8]

  # grab the mask
  $mask = $data1->mask;
  say $mask;    # [1 1 1 1 1 1 1 1 1]


  # create another masked piddle with the same mask
  my $pdl = $data1 + 1;

  $data2 = PDLx::MaskedData->new( $pdl, $mask );

  say $data2;    # [1 2 3 4 5 6 7 8 9]

  # update the mask
  $mask->set( 3, 0 );
  say $mask;     # [1 1 1 0 1 1 1 1 1]

  # and see it propagate
  say $data1;    # [0 1 2 0 4 5 6 7 8]
  say $data2;    # [1 2 3 0 5 6 7 8 9]

  # use bad values for $data1
  $data1->badflag(1);
  # notice that the invalid element is now bad
  say $data1;    # [0 1 2 BAD 4 5 6 7 8]

  # push invalid values upstream to the shared mask
  $data1->data_mask(1);
  $data1->setbadat(0);
  say $data1;    # [BAD 1 2 BAD 4 5 6 7 8]

  # see the mask change
  say $mask;     # [0 1 1 0 1 1 1 1 1]

  # and see the other piddle change
  say $data2;    # [0 2 3 0 5 6 7 8 9]

DESCRIPTION

Typically PDL uses bad values to mark elements in a piddle which contain invalid data. When multiple piddles should have the same elements marked as invalid, a separate mask piddle (whose values are true for valid data and false otherwise) is often used.

PDLx::MaskedData (in concert with PDLx::Mask) simplifies the management of multiple piddles sharing the same mask. PDLx::Mask is the shared mask, and PDLx::MaskedData is a specialized piddle which will dynamically respond to changes in the mask, so that they are always up-to-date.

Additionally, invalid elements in a data piddle may automatically be added to the shared mask, so that there is a consistent view of valid elements across all data piddles.

Details

PDLx::MaskedData is a subclass of PDL which manages a masked piddle. It can be used directly as a piddle, but be careful not to change its contents inadvertently. It should only be manipulated via the provided methods or overloaded operators.

It maintains two views of the data:

  1. the original base data; and

  2. the effective data, which is the base data with an applied mask. The invalid data elements may either be set as bad values, or may be set to any other value (e.g. 0).

INTERNALS

INTERFACE

Methods specific to PDLx::MaskedData

new

  $data = PDLx::MaskedData->new( $base_data );
  $data = PDLx::MaskedData->new( $base_data, $mask );
  $data = PDLx::MaskedData->new( base => $base_data, %options );

Create a masked piddle using the passed data piddle as the base data. It does not copy the passed piddle.

An optional mask may be provided (see below for details). If not provided, one will be created. The newly created object will be subscribed to the mask object;

base

A data piddle. If the piddle has the bad data flag set, masked elements are set to the piddle's bad value. Otherwise masked elements are set to the value of the mask_value option.

mask => scalar | piddle | PDLx::Mask object

An optional initial mask. If it is a piddle, it will be used as a base mask for a new PDLx::Mask object; it will not be copied. If not specified, all data elements are valid.

mask_value => scalar

If the piddle's bad flag is not set, this specifies the value of invalid elements in the effective data. It defaults to 0.

apply_mask => boolean

If true, the mask is applied to the data. This defaults to true. See "EXAMPLES/Secondary Masks" in PDlx::Mask for an application.

data_mask => boolean

If true, any invalid elements in the base data are replicated in the mask. It defaults to false.

base

  $base = $data->base;

This returns the base data. Don't alter the returned piddle!

data

  $pdl = $data->data;
  $pdl = $data->data( $new_data );

Return the effective data, optionally altering the base data. Don't alter the returned piddle!

If passed a piddle, it is copied to the base data and the update method is called.

Note that the $data object can also be used directly without calling this method.

mask

  $mask = $data->mask;

This returns the mask as a PDLx::Mask object.

  $data->mask( $new_mask );

This replaces the mask, detaching $data from the previous mask object. To instead alter the mask object, use the mask object's methods, e.g.:

  $data->mask->mask( $new_mask );

nvalid

  $nvalid_elements = $data->nvalid;

The number of valid elements in the effective data. This is lazily evaluated and cached.

update

  $data->update;

Update the effective data. This should never be required by user code.

If $data->data_mask is true, $data->mask->update is called, otherwise the result of applying the mask to the base data is stored as the effective data.

subscribe

  $data->subscribe;

Subscribe to $data's mask. Usually this is not necessary; see "EXAMPLES/Intermittant Secondary Masks" in PDLx-Mask for why this might be useful.

unsubscribe

  $data->unsubscribe( %options );

Subscribe to $data's mask. Usually this is not necessary; see "EXAMPLES/Intermittant Secondary Masks" in PDLx-Mask for why this might be useful.

Options:

reset_data_storage => boolean

If true (the default), memory used to store the effective data is reclaimed if possible. If $data will be resubscribed to a mask, it's more efficient to not perform this step.

is_subscribed

  $bool = $data->is_subscribed;

Returns true if $data is subscribed to its mask.

Overridden methods

copy

  $pdl = $data->copy;

Returns a copy of the effective data as an ordinary piddle.

inplace

This is a fatal operation.

set_inplace

This is a fatal operation if the passed value is non-zero.

set

   $data->set( $pos, $value);

This updates the base data at position $pos to $value and invokes the update method.

set

   $data->setbadat( $pos );

This sets the base data at position $pos to the bad value and invokes the update method.

dsum

  $data->dsum;

This is a lazily evaluated and cached version of the PDL dsum method.

SUPPORT

Bugs

Please report any bugs or feature requests to bug-pdlx-mask@rt.cpan.org or through the web interface at: https://rt.cpan.org/Public/Dist/Display.html?Name=PDLx-Mask

Source

Source is available at

  https://gitlab.com/djerius/pdlx-mask

and may be cloned from

  https://gitlab.com/djerius/pdlx-mask.git

SEE ALSO

Please see those modules/websites for more information related to this module.

AUTHOR

Diab Jerius <djerius@cpan.org>

COPYRIGHT AND LICENSE

This software is Copyright (c) 2016 by Smithsonian Astrophysical Observatory.

This is free software, licensed under:

  The GNU General Public License, Version 3, June 2007