i have a fits file and i want to add a new header to the fits file.
I've actually added a new fits header but it didn't save it. How to save and add new fits header?
Codes here:
from astropy.io import fits
hdul = fits.open('example.fits.gz')[0]
hdul.header.append('GAIN')
hdul.header['GAIN'] = 0.12
hdul.header.comments['GAIN']="e-/ADU"
print(hdul.header)
Thank in advance
open() opens the FITS file in read-only mode by default. If you want to modify the file in place you need to open it with mode='update'. Also, appending the new header can be done in a single line (as documented in Header.append like:
with open('example.fits', mode='update') as hdul:
hdul[0].header.append(('GAIN', 0.12, 'e-/ADU'))
Or, if you already have a FITS file open in read-only mode, you can write the modified file out to a new file using the writeto method as mentioned here.
One caveat I noticed in your original example is you were opening a gzipped FITS file. I'm not actually sure off the top of my head if that can be modified in 'update' mode, in which case you'll definitely need to write to a new file. I believe it does work, so try it, but I forget how well tested that is.
I don't have the 50 reputation points to comment on #Iguananaut's answer, so I'll leave my comment here: Make sure it is fits.open(). Otherwise, it will give you the following error ValueError: invalid mode: 'update'.
Using #Iguananaut's example, it should be:
with fits.open('example.fits', mode='update') as hdul:
hdul[0].header.append(('GAIN', 0.12, 'e-/ADU'))
Also, using append() will append the same 'new' card for every time you run the code. To prevent this, I suggest a minor adjustment. It will not just add the new card you want, but it will also update that same card if you run the code multiple times, avoiding card multiples.
with fits.open('example.fits', mode='update') as hdul:
hdr = hdul[0].header
hdr['GAIN'] = (0.12, 'e-/ADU')
Related
I looked for what opening a file with fitz do to the file, but didn't find anything. The code is simple:
import fitz
doc = fitz.open('a.pdf')
doc.save('b.pdf')
What I don't understand is why this will change the pdf size. With the file I tried, its size went from 829kb to 854kb.
I am not confortable with this because I would like to change a characteristic of a large number of files and I can't do it before being sure this won't alter them in any sense but in the characteristic I want to change.
BTW, what I want is just set the inner title of a pdf to be equal to the shown name of its file.
import fitz
doc = fitz.open(r'a.pdf')
doc.metadata['title']=None
doc.setMetadata(doc.metadata)
doc.save(r'b.pdf')
Can I asume I won't lose some information in this second example? Why the change in size when I just open and save the file in the first example?
You should check the metadata of the document.
It may have information on modification date, saving date, etc., that could explain the increased size.
I'm still new to python and cannot achieve to make what i'm looking for. I'm using Python 3.7.0
I have one file, called log.csv, containing a log of CANbus messages.
I want to check what is the content of column label Data2 and Data3 when the ID is 348 in column label ID.
If they are both different from "00", I want to make a new string called fault_code with the "Data3+Data2".
Then I want to check on another CSV file where this code string appear, and print the column 6 of this row (label description). But this last part I want to do it only one time per fault_code.
Here is my code:
import csv
CAN_ID = "348"
with open('0.csv') as log:
reader = csv.reader(log,delimiter=',')
for log_row in reader:
if log_row[1] == CAN_ID:
if (log_row[5]+log_row[4]) != "0000":
fault_code = log_row[5]+log_row[4]
with open('Fault_codes.csv') as fault:
readerFC = csv.reader(fault,delimiter=';')
for fault_row in readerFC:
if "0x"+fault_code in readerFC:
print("{fault_row[6]}")
Here is a part of the log.csv file
Timestamp,ID,Data0,Data1,Data2,Data3,Data4,Data5,Data6,Data7,
396774,313,0F,00,28,0A,00,00,C2,FF
396774,314,00,00,06,02,10,00,D8,00
396775,**348**,2C,00,**00,00**,FF,7F,E6,02
and this is a part of faultcode.csv
Level;LED Flashes;UID;FID;Type;Display;Message;Description;RecommendedAction
1;2;1;**0x4481**;Warning;F12001;Handbrake Fault;Handbrake is active;Release handbrake
1;5;1;**0x4541**;Warning;F15001;Fan Fault;blablabla;blablalba
1;5;2;**0x4542**;Warning;F15002;blablabla
Also do you think of a better way to do this task? I've read that Pandas can be very good for large files. As log.csv can have 100'000+ row, it's maybe a better idea to use it. What do you think?
Thank you for your help!
Be careful with your indentation, you get this error because you sometimes you use spaces and other tabs to indent.
As PM 2Ring said, reading 'Fault_codes.csv' everytime you read 1 line of your log is really not efficient.
You should read faultcode once and store the content in RAM (if it fits). You can use pandas to do it, and store the content into a DataFrame. I would do that before reading your logs.
You do not need to store all log.csv lines in RAM. So I'd keep reading it line by line with csv module, do my stuff, write to a new file, and read the next line. No need to use pandas here as it will fill your RAM for nothing.
I already have a fits file written (someone sent it to me) and I want to add a checksum and datasum to the header. The only examples I found with adding a checksum using astropy.io.fits involve building a new fits HDU and verifying it on adding each section to the HDU. Which I could do, but that seems a like it would have a lot more overhead then is needed.
Is there a way to add a checksum and datasum to an existing HDU?
ImageHDU objects have a method called add_checksum(). That should do exactly what you want.
So you could open a FITS file in update mode and then call this and close the file again.
from astropy.io import fits
with fits.open(filename, mode='update') as hdus:
hdus[0].add_checksum() # Fill in the arguments like you need them
The with is preferred because it automatically closes the file when the with context is exited (even if an exception happens) but you could also open and close it without the with:
from astropy.io import fits
hdul = fits.open(filename, mode='update')
hdul[0].add_checksum()
hdul.close()
I'm extracting extensions from a multi-extension FITS file, manipulate the data, and save the data (with the extension's header information) to a new FITS file.
To my knowledge pyfits.writeto() does the task. However, when I give it a data parameter in the form of an array, it gives me the error:
'AttributeError: 'numpy.ndarray' object has no attribute 'lower''
Here is a sample of my code:
'file = 'hst_11166_54_wfc3_ir_f110w_drz.fits'
hdulist = pyfits.open(dir + file)'
sci = hdulist[1].data # science image data
exp = hdulist[5].data # exposure time data
sci = sci*exp # converts electrons/second to electrons
file = 'test_counts.fits'
hdulist.writeto(file,sci,clobber=True)
hdulist.close()
I appreciate any help with this. Thanks in advance.
You're confusing the HDUList.writeto method, and the writeto function.
What you're calling is a method on the HDUList object that is returned when you call pyfits.open. You can think of this object as something like a file handle to your original drizzled FITS file. You can manipulate this object in place and either write it out to a new file or save updates in place (if you open the file in mode='update').
The writeto function on the other hand is not tied to any existing file. It's just a high-level function for writing an array out to a file. In your example you could write your array of electron counts out like:
pyfits.writeto(filename, data)
This will create a single-HDU FITS file with the array data in the PRIMARY HDU.
Do be aware of the admonishment at the top of this section of the docs: http://docs.astropy.org/en/v1.0.3/io/fits/index.html#convenience-functions
The functions like pyfits.writeto are there for convenience in interactive work, but are not recommendable for use in code that will be run repeatedly, as in a script. Instead have a look at these instructions to start.
It is probably because you should use hdulist.writeto(file, clobber=True). There is only one required argument:
https://pythonhosted.org/pyfits/api_docs/api_hdulists.html#pyfits.HDUList.writeto
If you give a second argument, it is used for output_verify which should be a string, not a numpy array. This probably explains your AttributeError ....
I am trying to change the value of a keyword in the header of a FITS file.
Quite simple, this is the code:
import pyfits
hdulist = pyfits.open('test.fits') # open a FITS file
prihdr = hdulist[1].header
print prihdr['AREASCAL']
effarea = prihdr['AREASCAL']/5.
print effarea
prihdr['AREASCAL'] = effarea
print prihdr['AREASCAL']
I print the steps many times to check the values are correct. And they are.
The problem is that, when I check the FITS file afterwards, the keyword value in the header is not changed. Why does this happen?
You are opening the file in read-only mode. This won't prevent you from modifying any of the in-memory objects, but closing or flushing to the file (as suggested in other answers to this question) won't make any changes to the file. You need to open the file in update mode:
hdul = pyfits.open(filename, mode='update')
Or better yet use the with statement:
with pyfits.open(filename, mode='update') as hdul:
# Make changes to the file...
# The changes will be saved and the underlying file object closed when exiting
# the 'with' block
You need to close the file, or explicitly flush it, in order to write the changes back:
hdulist.close()
or
hdulist.flush()
Interestingly, there's a tutorial for that in the astropy tutorials github. Here is the ipython notebook viewer version of that tutorial that explains it all.
Basically, you are noticing that the python instance does not interact with disk instance. You have to save a new file or overwrite the old one explicitly.