[AstroPy] Moving Ahead with Raw Image Conversion

Wayne Watson sierra_mtnview at sbcglobal.net
Tue Apr 14 13:40:13 EDT 2009


Yes, that's true, but I was trying to express the confusion over leaving 
the pyfits manual lingering in numarray-land.

Jim Vickroy wrote:
> 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
>>>
>>>
>>>
>>>     
>>
>>   
>

-- 
           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)
 




More information about the AstroPy mailing list