Class: RFits::ImageData
- Inherits:
-
Object
- Object
- RFits::ImageData
- Includes:
- Enumerable
- Defined in:
- lib/rfits/rfits.rb
Overview
Represents the actual pixels in a FITS file.
Constant Summary collapse
- BITPIX_IMG_MAP =
{ IO::Proxy::BYTE_IMG => IO::Proxy::TBYTE, IO::Proxy::SHORT_IMG => IO::Proxy::TSHORT, IO::Proxy::LONG_IMG => IO::Proxy::TLONG, IO::Proxy::LONGLONG_IMG => IO::Proxy::TLONGLONG, IO::Proxy::FLOAT_IMG => IO::Proxy::TFLOAT, IO::Proxy::DOUBLE_IMG => IO::Proxy::TDOUBLE, IO::Proxy::SBYTE_IMG => IO::Proxy::TSBYTE, IO::Proxy::USHORT_IMG => IO::Proxy::TUSHORT, IO::Proxy::ULONG_IMG => IO::Proxy::TULONG }
Instance Attribute Summary collapse
-
#image ⇒ Object
readonly
The image the data belongs to.
Instance Method Summary collapse
-
#[](*args) ⇒ Object
An alias for ImageData#pixels, but automatically chooses the datatype for you based on the type of image (i.e. BITPIX).
-
#[]=(*args) ⇒ Object
An alias for ImageData#set_pixels, but automatically chooses the datatype for you based on the type of image (i.e. BITPIX).
-
#column(i) ⇒ Object
Retrieve the ith (where i is zero-based) column of the image array.
-
#each ⇒ Object
Iterate through each pixel in the array.
-
#each_column ⇒ Object
Iterate through each column of pixels in the array.
-
#each_row ⇒ Object
Iterate through each row of pixels in the array.
-
#first ⇒ Object
The first pixel in the image array.
-
#initialize(image) ⇒ ImageData
constructor
Create an ImageData object associated with the specified image.
-
#last ⇒ Object
The last pixel in the image array.
-
#length ⇒ Object
The number of pixels in the image array.
-
#pixels(datatype, *args) ⇒ Object
Retrieve the value of a pixel, or a range of pixels.
-
#row(i) ⇒ Object
Retrieve the ith (where i is zero-based) row of the image array.
-
#set_column(i, vals) ⇒ Object
Set the ith column of a 2D image to the specified pixels.
-
#set_pixels(datatype, *args) ⇒ Object
Set the value of a pixel, or a range of pixels.
-
#set_row(i, vals) ⇒ Object
Set the ith row of a 2D image to the specified pixels.
Constructor Details
#initialize(image) ⇒ ImageData
Create an ImageData object associated with the specified image.
392 393 394 |
# File 'lib/rfits/rfits.rb', line 392 def initialize(image) @image = image end |
Instance Attribute Details
#image ⇒ Object (readonly)
The image the data belongs to.
389 390 391 |
# File 'lib/rfits/rfits.rb', line 389 def image @image end |
Instance Method Details
#[](*args) ⇒ Object
An alias for ImageData#pixels, but automatically chooses the datatype for you based on the type of image (i.e. BITPIX).
398 399 400 |
# File 'lib/rfits/rfits.rb', line 398 def [](*args) self.pixels(BITPIX_IMG_MAP[self.image.bitpix], *args) end |
#[]=(*args) ⇒ Object
An alias for ImageData#set_pixels, but automatically chooses the datatype for you based on the type of image (i.e. BITPIX).
404 405 406 |
# File 'lib/rfits/rfits.rb', line 404 def []=(*args) self.set_pixels(BITPIX_IMG_MAP[self.image.bitpix], *args) end |
#column(i) ⇒ Object
Retrieve the ith (where i is zero-based) column of the image array. Assumes a two-dimensional image.
570 571 572 573 574 575 576 577 |
# File 'lib/rfits/rfits.rb', line 570 def column(i) pixel_list = [] (0...self.image.naxes.first).each do |row| pixel_list << self[i, row] end pixel_list end |
#each ⇒ Object
Iterate through each pixel in the array.
543 544 545 546 547 |
# File 'lib/rfits/rfits.rb', line 543 def each (0...self.length).each do |i| yield self[i] end end |
#each_column ⇒ Object
Iterate through each column of pixels in the array. Assumes a two-dimensional image.
588 589 590 591 592 |
# File 'lib/rfits/rfits.rb', line 588 def each_column (0...self.image.naxes.last).each do |i| yield(self.column(i), i) end end |
#each_row ⇒ Object
Iterate through each row of pixels in the array. Assumes a two-dimensional image.
562 563 564 565 566 |
# File 'lib/rfits/rfits.rb', line 562 def each_row (0...self.image.naxes.last).each do |i| yield(self.row(i), i) end end |
#first ⇒ Object
The first pixel in the image array.
595 596 597 |
# File 'lib/rfits/rfits.rb', line 595 def first self[0] end |
#last ⇒ Object
The last pixel in the image array.
600 601 602 |
# File 'lib/rfits/rfits.rb', line 600 def last self[self.length - 1] end |
#length ⇒ Object
The number of pixels in the image array.
538 539 540 |
# File 'lib/rfits/rfits.rb', line 538 def length self.image.naxes.inject(1){ |product, n| product *= n } end |
#pixels(datatype, *args) ⇒ Object
Retrieve the value of a pixel, or a range of pixels. The value is coerced into an appropriate class according to the datatype provided. Can be used in a number of ways. The simplest plucks the nth pixel from the image array:
image.data.pixels(IO::Proxy::TSHORT, 0) # first pixel in the image (remember zero-based indexing?)
image.data.pixels(IO::Proxy::TSHORT, image.data[image.data.size - 1]) # last pixel in the image
You can also choose a range of contiguous pixels, in which case an array of values is returned:
image.data.pixels(IO::Proxy::TSHORT, 0..10) # retrieve first 10 pixels
or pick the single pixel at a particular coordinate:
image.data.pixels(IO::Proxy::TSHORT, 4, 5)
or equivalently:
image.data.pixels(IO::Proxy::TSHORT, [4, 5])
In addition, you can give an (x,y) coordinate and a number of pixels, assuming the coordinates are zero-based:
image.data.pixels(IO::Proxy::TSHORT, [4, 5], 10) # 10 pixels starting at the point [4, 5]
or get all the pixels between two points:
image.data.pixels(IO::Proxy::TSHORT, [4, 5], [6, 6]) # all the pixels between the points [4, 5] and [6, 6]
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 |
# File 'lib/rfits/rfits.rb', line 434 def pixels(datatype, *args) self.image.reset_position() pixnum = nelem = nil pixel_values = case args.size when 1 # 1 argument if args.first.is_a?(Range) # a range of pixels pixnum = args.first.first.to_i < 0 ? self.length + args.first.first.to_i : args.first.first.to_i + 1 nelem = args.first.exclude_end? ? args.first.last.to_i - args.first.first.to_i + 1: args.first.last.to_i - args.first.first.to_i elsif args.first.is_a?(Fixnum) # the nth pixel pixnum = args.first.to_i < 0 ? self.length + args.first.to_i : args.first.to_i + 1 nelem = 1 elsif args.first.is_a?(Array) # array representing single pixel return(IO::Proxy.fits_read_pix(self.image.file.io, datatype, args.first.collect{ |c| c + 1 }, 1, nil).first.first) else raise ArgumentError, "Argument should be an integer, an integer range, or an array of integers." end IO::Proxy.fits_read_img(self.image.file.io, datatype, pixnum, nelem, nil).first when 2 # 2 arguments if args.first.is_a?(Fixnum) and args.last.is_a?(Fixnum) # the pixel at the coordinate IO::Proxy.fits_read_pix(self.image.file.io, datatype, [args.first.to_i+1, args.last.to_i+1], 1, nil).first elsif args.first.is_a?(Array) and args.last.is_a?(Fixnum) # a starting coordinate + some number of pixels fpixel = args.first.collect{ |p| p + 1 } IO::Proxy.fits_read_pix(self.image.file.io, datatype, fpixel, args.last.to_i, nil).first elsif args.first.is_a?(Array) and args.last.is_a?(Array) # a starting coordinate + ending coordinate fpixel = args.first.collect{ |p| p + 1 } lpixel = args.last.collect{ |p| p + 1 } IO::Proxy.fits_read_subset(self.image.file.io, datatype, fpixel, lpixel, args.first.collect{ |dim| 1 }, nil).first else raise ArgumentError, "Arguments should be two fixnums, an array and a fixnum, or two arrays." end else raise ArgumentError, "Arguments should be an integer, an integer range, an array of integers, two fixnums, an array and a fixnum, or two arrays." end pixel_values.size == 1 ? pixel_values.first : pixel_values end |
#row(i) ⇒ Object
Retrieve the ith (where i is zero-based) row of the image array. Assumes a two-dimensional image.
551 552 553 |
# File 'lib/rfits/rfits.rb', line 551 def row(i) self[[0, i], self.image.naxes.first] end |
#set_column(i, vals) ⇒ Object
Set the ith column of a 2D image to the specified pixels.
580 581 582 583 584 |
# File 'lib/rfits/rfits.rb', line 580 def set_column(i, vals) (0...self.image.naxes.first).each do |row| self[i, row] = vals[row] end end |
#set_pixels(datatype, *args) ⇒ Object
Set the value of a pixel, or a range of pixels. The value is coerced into an appropriate class according to the datatype provided. Can be used in a number of ways. The simplest sets the nth pixel in the image array:
image.data.set_pixels(IO::Proxy::TSHORT, 0, 5) # first pixel in the image is set to 5
You can also set a range of contiguous pixels:
image.data.set_pixels(IO::Proxy::TSHORT, 0..10, [5, 5, 3, 1, 0, 9, 5, 6, 7, 1]) # set first 10 pixels
or set the single pixel at a particular coordinate:
image.data.set_pixels(IO::Proxy::TSHORT, 4, 5, 10) # set pixel at [4, 5] to 10
or equivalently:
image.data.set_pixels(IO::Proxy::TSHORT, [4, 5], 10)
In addition, you can give an (x,y) coordinate and a list of pixels, assuming the coordinates are zero-based:
image.data.set_pixels(IO::Proxy::TSHORT, [4, 5], [1, 2, 3, 4]) # four pixels with values 1, 2, 3, 4 starting at [4, 5]
or set the pixels between two points:
image.data.set_pixels(IO::Proxy::TSHORT, [0, 0], [1, 1], [5, 6, 7, 8]) # set pixels to (5, 6, 7, 8) between [0, 0] and [1, 1]
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 |
# File 'lib/rfits/rfits.rb', line 500 def set_pixels(datatype, *args) self.image.reset_position() val = args.last.is_a?(Array) ? args.last : [args.last] case args.size when 2 if args.first.is_a?(Fixnum) pixnum = args.first.to_i < 0 ? self.length + args.first.to_i : args.first.to_i + 1 IO::Proxy.fits_write_img(self.image.file.io, datatype, pixnum, val.size, val) elsif args.first.is_a?(Range) pixnum = args.first.first.to_i < 0 ? self.length + args.first.first.to_i : args.first.first.to_i + 1 nelem = args.first.exclude_end? ? args.first.last.to_i - args.first.first.to_i + 1: args.first.last.to_i - args.first.first.to_i IO::Proxy.fits_write_img(self.image.file.io, datatype, pixnum, nelem, val) elsif(args.first.is_a?(Array)) IO::Proxy.fits_write_pixnull(self.image.file.io, datatype, args.first.collect{ |c| c + 1 }, val.size, val, nil) else raise ArgumentError, "Selector should be an integer, an integer range, or an array of integers." end when 3 if args.first.is_a?(Fixnum) and args[-2].is_a?(Fixnum) IO::Proxy.fits_write_pixnull(self.image.file.io, datatype, args[0..-2].collect{ |c| c + 1 }, val.size, val, nil) elsif args.first.is_a?(Array) and args[-2].is_a?(Fixnum) IO::Proxy.fits_write_pixnull(self.image.file.io, datatype, args.first.collect{ |c| c + 1 }, args[-2], val, nil) elsif args.first.is_a?(Array) and args[-2].is_a?(Array) IO::Proxy.fits_write_subset(self.image.file.io, datatype, args.first.collect{ |c| c + 1 }, args[1].collect{ |c| c + 1 }, val) else raise ArgumentError, "Selectors should be two fixnums, an array and a fixnum, or two arrays." end else raise ArgumentError, "Selectors should be an integer, an integer range, an array of integers, two fixnums, an array and a fixnum, or two arrays." end end |
#set_row(i, vals) ⇒ Object
Set the ith row of a 2D image to the specified pixels.
556 557 558 |
# File 'lib/rfits/rfits.rb', line 556 def set_row(i, vals) self[[0, i], self.image.naxes.first] = vals end |