[AstroPy] Moving Ahead with Raw Image Conversion
Jim Vickroy
Jim.Vickroy at noaa.gov
Tue Apr 14 11:35:04 EDT 2009
At the risk of stating the obvious, you should only be using numpy (not
numarray). Numarray was a competing package that pyfits previously
supported. Numarray is deprecated and the recent releases of pyfits
have complete support for numpy.
-- jv
Wayne Watson wrote:
> Howdy, I think I see the ccdsoft problem. I looked at a fit (fits) file
> I produced with my CCD camera using it, and it produces a uint16
> (BITPIX=16). I just made the change you suggested, and the resulting
> file shows BITPIX=8, but CCDSoft liked it. Apparently, it objected to
> the 32 bit image earlier, which probably gave rise to the black image.
> The former way produced a file of 1,204KB, and the current file produced
> sized with the simple replacement produced a file of 304KB. I used
> dtype='uint8' instead of 'B'.
>
> Somewhere along the line I confused myself with the numarray use in the
> FITS manual, and apparently its look-alike notion ( as seen via arange
> and reshape) in numpy. Maybe they are equivalent in every respect. I was
> trying to figure out how to get Python to put together a 'matrix'
> (mathematical sense) to feed it to data, but it looks like reshape is
> the ticket. reshape seems missing from numarray (not mentioned in the
> fits manual), so maybe there is a difference. I'm not sure the pyfits
> manual ever showed how to make a 'matrix' and stuff it into the data
> portion of a FITS header (maybe that's what section 2.2.3 is about,
> which interestingly has the same title as 2.2.2).
>
> I think we are pretty much, successfully, done here. Allowing the meteor
> program I'm adding new features to be able to use FITS will be a very
> useful change. Some exposure to pyfits and numpy helps too from the
> coding aspects. Of course, if I decide to add features that allow FITS
> files into the program, say, for IP (img processing) work, that'll
> require some unraveling of the data part of the fits file for
> PIL/Tinter. Later though.
>
> Thanks for the help.
>
> Peter Erwin wrote:
>
>> Hi Wayne,
>>
>> Anne Archibald pointed out a much more concise and elegant way to read in
>> and convert the raw file, using a function in Numpy. So you could
>> replace the
>> following original code:
>>
>>
>>> # get raw data from .raw file:
>>> raw_file=open('sent_internal.raw','rb')
>>> raw_image=raw_file.read()
>>> raw_file.close()
>>>
>>> # convert raw data to Python list of integers (1-D):
>>> rawim_intarray = []
>>> for x in raw_image:
>>> # convert byte to integer ('B' = treat data as single unsigned byte)
>>> newint = struct.unpack('B', x)[0]
>>> rawim_intarray.append(newint)
>>>
>>> # convert Python list of integers into numpy array of integers (note:
>>> still 1-D at this point)
>>> rawim_numpy = numpy.array(rawim_intarray)
>>>
>> with this:
>>
>> rawim_numpy = numpy.fromfile('sent_internal.raw', dtype='B')
>>
>> [note: dtype='B' is identical to dtype=numpy.uint8, which Anne used in
>> her example]
>>
>> and then continue as before.
>>
>> This has the added benefit of producing a smaller output file (300 KB vs
>> 1.2 MB), since the numpy array is now explicitly in 8-bit-integer form
>> (rather than the 32-bit-integer form that my code created), and so
>> Pyfits will automatically save it as 8-bit integers (you can check this
>> by looking at the header keyword BITPIX).
>>
>>
>> You're right, the raw image is a sequence of (standard) 8-bit bytes.
>> Well, all
>> computer files are streams of bytes; the question is how to interpret
>> them. Since
>> you said earlier that it was supposed to be 8-bit values, the idea is
>> then to
>> interpret each individual byte as an unsigned "integer" value (values
>> from 0 to 255);
>> that's what the "dtype='B'" (or "dtype=numpy.uint8") option passed to
>> numpy.fromfile()
>> does. (My previous code did the same thing, but then assigned each
>> value to a
>> standard Python integer, which is 4 bytes long; perfectly workable,
>> but a bit
>> wasteful!).
>>
>> Anyway, when I do this, I can see an image in DS9 (a circular aperture
>> with ragged
>> edges and an overall horizontal gradient inside the aperture). So I'm
>> pretty sure
>> it's working. (I've attached a jpeg saved from DS9 to show what the
>> image looks like.)
>>
>> I don't think I can help you with this "ccdsoft" program; I'm not
>> familiar with it.
>> If it's a Windows program, then it may expect all FITS files to end in
>> ".fit" instead
>> of ".fits", just because Windows traditionally expects files to have
>> 3-letter extensions.
>>
>>
>> As for overwriting an existing FITS file, try this:
>>
>> hdu.writeto("existing_file_name.fit", clobber=True)
>>
>> cheers,
>>
>> Peter
>>
>>
>>
>> ------------------------------------------------------------------------
>>
>>
>>
>>
>> On Apr 14, 2009, at 6:28 AM, Wayne Watson wrote:
>>
>>
>>> Hi, Peter. It looks like I confused a few people with the hex. I had
>>> removed it, but only after I placed the code in the msg. I was
>>> playing with hex in the event I might need it somehow. int was fine
>>> for my experimental purposes.
>>>
>>> Here's your code with a minor correction. I changed this line:
>>> rawim_numpy_2d = numpy.reshape(rawim_numpy,(480, 640))
>>> The difference is rawmin_numpy.
>>> I added a print at the end, and threw in two lines that attempt to
>>> put header info into the final file. Continuing below the code.
>>>
>>> =====================Start===============
>>> import struct, numpy, pyfits # struct is part of the main Python
>>> library
>>>
>>> # get raw data from .raw file:
>>> raw_file=open('sent_internal.raw','rb')
>>> raw_image=raw_file.read()
>>> raw_file.close()
>>>
>>> # convert raw data to Python list of integers (1-D):
>>> rawim_intarray = []
>>> for x in raw_image:
>>> # convert byte to integer ('B' = treat data as single unsigned byte)
>>> newint = struct.unpack('B', x)[0]
>>> rawim_intarray.append(newint)
>>>
>>> # convert Python list of integers into numpy array of integers (note:
>>> still 1-D at this point)
>>> rawim_numpy = numpy.array(rawim_intarray)
>>>
>>> # reshape numpy array into 2D form, using our knowledge of the
>>> original image's
>>> # x and y sizes (kudos to Megan Sosey for pointing out how to do this)
>>> rawim_numpy_2d = numpy.reshape(rawim_numpy,(480, 640))
>>>
>>> # create Pyfits header-data unit:
>>> hdu = pyfits.PrimaryHDU(rawim_numpy_2d)
>>> hdu.header.update('LATOBS',"32:11:56")
>>> hdu.header.update('LNGOBS',"120:00:00")
>>>
>>> # (make any modifications to the header you might want to... e.g.,
>>> see Megan Sosey's
>>> # email of April 8 for examples)
>>>
>>> # ... and save the data to disk as a FITS file:
>>> hdu.writeto("test.fits")
>>> print "Finished. See test.fits"
>>> ===============End code============
>>>
>>> I'm not sure what the 'byte' stuff is about. It may be that it's not
>>> needed. I think the original 'raw' file is byte oriented--rather than
>>> int or whatever. Anyway, I don't seem to have succeeded in getting
>>> header info into the file. Sort of. If I use DS9, I can see the image
>>> and the fits header with what I coded into it. Here's what I see with
>>> ds9.
>>>
>>> *However, with my ccdsoft program, te image is black and the header
>>> is not the same. Whoops. Interesting. I changed the file to test.fit
>>> instead of test.fits, and the header info is there, but the image is
>>> still black. The dimension are the same, 640x480. I'm attaching
>>> test-ww.fits. I just renamed my test.fits. I think I'll check with
>>> The Bisque (ccdsoft) to see what format they produce and use for the
>>> raw image.
>>> Question. When I execute the program a second time, the
>>> *hdu.writeto("test.fits") *will not write over the old file. Is there
>>> an option to force the write?
>>>
>>> Well, this is all good progress. ** *
>>>
>>> --
>>>
>>> Wayne Watson (Watson Adventures, Prop., Nevada City, CA)
>>>
>>> (121.015 Deg. W, 39.262 Deg. N) GMT-8 hr std. time)
>>> Obz Site: 39° 15' 7" N, 121° 2' 32" W, 2700 feet
>>> All the neutrons, and protons in the human body occupy
>>> a cube whose side is 5.52*10**-6 meters (tiny!). That
>>> adds up to a 150 pound person. It's not a surprise that
>>> we are mostly space. (Calculation by WTW)
>>>
>> =============================================================
>> Peter Erwin Max-Planck-Insitute for Extraterrestrial
>> erwin at mpe.mpg.de Physics, Giessenbachstrasse
>> tel. +49 (0)89 30000 3695 85748 Garching, Germany
>> fax +49 (0)89 30000 3495 http://www.mpe.mpg.de/~erwin
>>
>>
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/astropy/attachments/20090414/bfb2e559/attachment.html>
More information about the AstroPy
mailing list