class AcquisitionImage(object): def __init__(self, filename, mosmask=None, mdfdir=None): self.ad = AstroData(filename) self.mosmask = mosmask self.mdfdir = mdfdir # Determine extension nsci = len(self.ad) debug("...nsci = ", nsci) if nsci > 1: l_sci_ext = 1 else: l_sci_ext = 0 debug("...using extension [" + str(l_sci_ext) + "]") overscan_dv = self.ad[l_sci_ext].overscan_section() if self.is_mos_mode(): self.box_coords = parse_box_coords(self, self.get_mdf_filename()) self.box_mosaic = BoxMosaic(self, self.box_coords) self.scidata = self.box_mosaic.get_science_data() elif self.is_new_gmosn_ccd(): # tile the 2 center parts of the new GMOS image self.scidata = gmultiamp(self.ad) elif not overscan_dv.is_none(): # remove the overscan so we don't have to take it into account when guessing the slit location self.scidata = subtract_overscan(self.ad[l_sci_ext]) # it still affects the center of rotation however ox1, ox2, oy1, oy2 = overscan_dv.as_list() correction = np.array([ox2 - ox1, 0]) center = self.get_binned_data_center() - correction self.fieldcenter = center * self.detector_y_bin() else: self.scidata = self.ad[l_sci_ext].data @cache def instrument(self): return str(self.ad.instrument()) def is_new_gmosn_ccd(self): header = self.ad.phu.header if "DETECTOR" not in header: return False if header["DETECTOR"] == "GMOS + e2v DD CCD42-90": return True return False def get_science_data(self): assert self.scidata is not None return self.scidata @cache def unbinned_pixel_scale(self): return float(self.ad.pixel_scale()) / self.detector_y_bin() @cache def binned_pixel_scale(self): return float(self.ad.pixel_scale()) def _check_binning(self): if int(self.ad.detector_x_bin()) != int(self.ad.detector_y_bin()): error("ERROR: incorrect binning!") error("Sorry about that, better luck next time.") sys.exit(1) @cache def detector_x_bin(self): self._check_binning() return int(self.ad.detector_x_bin()) @cache def detector_y_bin(self): self._check_binning() return int(self.ad.detector_y_bin()) @cache def program_id(self): return str(self.ad.program_id()) @cache def observation_id(self): return str(self.ad.observation_id()) @cache def saturation_level(self): dv = self.ad.saturation_level() return min(dv.as_list()) @cache def focal_plane_mask(self): return str(self.ad.focal_plane_mask()) @cache def grating(self): return str(self.ad.grating()) def get_detector_size(self): # mos mode acquisitions don't necessarily have the entire # field of view in their data sections, so we have to rely on # other tricks to figure out the center of rotation. detsize = self.ad.phu_get_key_value("DETSIZE") xmin, xdim, ymin, ydim = extract_dimensions(detsize) # adjust for chip gaps nccds = int(self.ad.phu_get_key_value("NCCDS")) xdim += ((nccds - 1) * _obtain_unbinned_arraygap(self.ad)) # adjust for un-illuminated pixels if self.is_gmos(): ydim -= 36 # magic number that should be replaced with a lookup table later return xdim, ydim def get_field_center(self): """ The center of rotation in pixels. """ if hasattr(self, "fieldcenter"): return self.fieldcenter if self.is_mos_mode(): xdim, ydim = self.get_detector_size() return np.array([float(xdim) / 2.0, float(ydim) / 2.0]) return self.get_data_center() def get_data_center(self): ydim, xdim = self.get_science_data().shape return np.array([float(xdim) / 2.0, float(ydim) / 2.0]) * self.detector_y_bin() def get_binned_data_center(self): return self.get_data_center() / self.detector_y_bin() def set_goal_center(self, center): self.goal_center = np.array(center) def get_goal_center(self): default = self.get_data_center() return getattr(self, "goal_center", default) def set_binned_custom_center(self, center): self.set_binned_goal_center(center) self.custom_center = True def has_custom_center(self): return getattr(self, "custom_center", False) def get_binned_goal_center(self): return self.get_goal_center() / self.detector_y_bin() def set_binned_goal_center(self, center): center = np.array(center) * self.detector_y_bin() self.set_goal_center(center) def get_mask_width(self): debug("...finding slit dimensions...") slitxbin = self.detector_x_bin() slitybin = self.detector_y_bin() debug("...slit image binning = ", slitxbin, " x ", slitybin) if slitxbin > 1 or slitybin > 1: warning("! WARNING: Slit image is binned " + slitxbin + " x " + slitybin) slitmask = self.focal_plane_mask() return float(slitmask.replace("arcsec", "")) def get_mask_width_in_pixels(self): return self.get_mask_width() / self.unbinned_pixel_scale() def get_slit_size_in_pixels(self): xsize = self.get_mask_width_in_pixels() ysize = self.get_science_data().shape[0] return xsize, ysize def get_expected_slit_tilt(self): if self.is_gmos(): return 0.0 error("Instrument is not supported, need to know an expected slit tilt") sys.exit(1) @property def phu(self): return self.ad.phu @property def filename(self): return self.ad.filename def get_program_id_parts(self): gemprgid = str(self.ad.program_id()) parts = gemprgid.split("-") if len(parts) != 4: msg = "Cannot parse program id '%s'" % gemprgid error(msg) raise ValueError(msg) observatory, semester, prgtype, queuenum = parts return observatory, semester, prgtype, int(queuenum) def get_semester(self): """ Return something in the form of '2006B' """ observatory, semester, prgtype, queuenum = self.get_program_id_parts() return semester def get_observatory_prefix(self): """ Return something in the form of 'GN' """ observatory, semester, prgtype, queuenum = self.get_program_id_parts() return observatory def is_mos_mode(self): return self.mosmask is not None or self.has_mos_mask() @cache def has_mos_mask(self): if not self.is_gmos() and not self.is_f2(): return False maskname = self.focal_plane_mask() if ("Q" in maskname or # Queue program "C" in maskname or # Classical program "D" in maskname or # DD program "V" in maskname): # SV program xbin = self.detector_x_bin() ybin = self.detector_y_bin() if xbin != 1 or ybin != 1: error ("MOS acquisition image binning must be 1x1, found %ix%i binning." % (xbin, ybin)) clean() return True return False def has_mask_in_beam(self): maskname = self.focal_plane_mask().lower() if "imag" in maskname: return False slitmask = self.focal_plane_mask() if self.is_gmos() and "arcsec" in slitmask: return True if self.is_gnirs() and "arcsec" in slitmask: acqmir = slitimage_ad.phu.header["ACQMIR"] debug("...acqmir = ", acqmir) if acqmir == "In": return True if self.is_niri() and "cam" not in slitmask: return True if self.is_f2() and "slit" in slitmask: return True if self.is_f2() and "mos" in slitmask: return True return self.has_mos_mask() def get_mdf_filename(self): if hasattr(self, "mdffile"): return self.mdffile self.mdffile = self._get_mdf_filename() return self.mdffile def _get_mdf_filename(self): if self.mosmask is not None: mdffile = self.mosmask # Expand the MOS mask number if is_number(self.mosmask): observatory, semester, prgtype, queuenum = self.get_program_id_parts() mdffile = "%s%s%s%03i-%02i" % (observatory, semester, prgtype, queuenum, int(self.mosmask)) debug("...mosmask =", mdffile) else: mdffile = self.focal_plane_mask() mdffile = fits_filename(mdffile) #----------------------------------------------------------------------- # Start searching around willy nilly for the MDF file if os.path.exists(mdffile): return mdffile # note, the order in which directories are added to this list gives priority dirs = [] if self.mdfdir is not None: dirs.append(self.mdfdir) dname = os.path.dirname(self.filename) if dname and dname != ".": dirs.append(dname) dirs.append(os.getcwd()) # search through semester directories as well semester_dir = self.get_observatory_prefix() + self.get_semester() directories_to_search = [] for dname in dirs: directories_to_search.append(dname) dname = os.path.join(dname, semester_dir) directories_to_search.append(dname) # now search through the directories for dname in directories_to_search: fname = os.path.join(dname, mdffile) debug("...trying", fname) if os.path.exists(fname): return fname raise ValueError("Unable to find MDF file named '%s'" % mdffile) def get_num_mos_boxes(self): return self.box_mosaic.get_num_mos_boxes() def get_mos_boxes(self): return self.box_mosaic.get_boxes() def get_mos_box_borders(self): for border in self.box_mosaic.get_box_borders(): yield border @cache def get_min_slitsize(self): mdffile_ad = AstroData(self.get_mdf_filename()) xsize = Ellipsis ysize = Ellipsis for row in mdffile_ad["MDF"].data: # select the alignment boxes, designated by priority 0 if row["priority"] not in ["1", "2", "3"]: continue xsize = min(xsize, row["slitsize_x"]) ysize = min(ysize, row["slitsize_y"]) return xsize, ysize def get_extensions(self): for ext in self.ad: yield ext def _get_lazy_detector_section_finder(self): if not hasattr(self, "detsec_finder"): self.detsec_finder = DetectorSectionFinder(self) return self.detsec_finder def get_box_size(self): return self._get_lazy_detector_section_finder().get_box_size() def find_detector_section(self, point): return self._get_lazy_detector_section_finder().find_detector_section(point) def get_full_field_of_view(self): return self._get_lazy_detector_section_finder().get_full_field_of_view() def is_altair(self): aofold = self.ad.phu.header["AOFOLD"] if aofold == "IN": return True return False def is_south_port(self): inportnum = int(self.ad.phu.header["INPORT"]) if inportnum == 1: return True return False def is_type(self, typename): return self.ad.is_type(typename) def is_gmos(self): return self.is_type("GMOS") def is_gmosn(self): return self.is_type("GMOS_N") def is_gmoss(self): return self.is_type("GMOS_S") def is_gnirs(self): return self.is_type("GNIRS") def is_f2(self): return self.is_type("F2") def is_nifs(self): return self.is_type("NIFS") def is_niri(self): return self.is_type("NIRI")
import sys sys.path.append("/opt/gemini_python") from astrodata import AstroData import urllib2, urllib # This is a GMOS_N imaging science dataset ad = AstroData("/home/callen/SVN-AD/gemini_python/test_data/calsearch/N20110531S0114.fits") desc_dict = {'instrument':ad.instrument().for_db(), 'observation_type': ad.observation_type().for_db(), 'data_label':ad.data_label().for_db(), 'detector_x_bin':ad.detector_x_bin().for_db(), 'detector_y_bin':ad.detector_y_bin().for_db(), 'read_speed_setting':ad.read_speed_setting().for_db(), 'gain_setting':ad.gain_setting().for_db(), 'amp_read_area':ad.amp_read_area().for_db(), 'ut_datetime':ad.ut_datetime().for_db(), 'exposure_time':ad.exposure_time().for_db(), 'object': ad.object().for_db(), 'filter_name':ad.filter_name().for_db(), 'focal_plane_mask':ad.focal_plane_mask().for_db(), } print repr(desc_dict) type_list = ad.types ad.close() sequence = [('descriptors', desc_dict), ('types', type_list)] postdata = urllib.urlencode(sequence) #postdata = urllib.urlencode({"hello":1.})
from astrodata import AstroData ad = AstroData("../../../test_data/recipedata/N20091027S0141.fits") # this is a developer script, the way it works is you can set a small bank of variables # to various descriptor return values (ones that return DescriptorValues!) # and a series of automated printouts can help you inspect the value and probe its # behavior ad.descriptorFormat = "as_dict" g = ad.detector_x_bin() h = ad.detector_x_bin() i = ad.detector_x_bin() j = ad.detector_x_bin(format="as_dict") dvsnames = ["g","h","i","j"] dvs = [] for dvname in dvsnames: dv = eval(dvname) dv.myname = dvname dvs.append(dv) for dv in dvs: print 'dv "%s" (%s)' % ( dv.myname,dv.name) print dv.info() import math print "using DescriptorValue as a float" a = math.sin(h) print "math.sin(h) =",a
import sys, os from astrodata import AstroData from astrodata import Errors import re ad = AstroData("../../../test_data/recipedata/N20090703S0163.fits") ybin = ad.detector_y_bin() xbin = ad.detector_x_bin() disp = ad.disperser() descripts = ["airmass", "amp_read_area", "azimuth", "camera", "cass_rotator_pa", "central_wavelength", "coadds", "data_label", "data_section", "dec", "decker", "detector_section", "detector_x_bin", "detector_y_bin", "disperser", "dispersion", "dispersion_axis", "elevation", "exposure_time", "filter_name", "focal_plane_mask", "gain", "gain_setting", "grating", "instrument", "local_time", "mdf_row_id", "nod_count", "nod_pixels", "non_linear_level", "object", "observation_class", "observation_epoch", "observation_id", "observation_type", "pixel_scale", "prism", "program_id", "pupil_mask", "qa_state", "ra", "raw_bg", "raw_cc", "raw_iq", "raw_wv", "read_mode", "read_noise", "read_speed_setting", "saturation_level", "slit", "telescope", "ut_date", "ut_datetime", "ut_time", "wavefront_sensor", "wavelength_reference_pixel", "well_depth_setting", "x_offset", "y_offset"] descripts = ["detector_x_bin","exposure_time", "raw_cc"] if True: ops = ["+","-","*","/","//", "%", "**", "<<",">>", "^", "<", "<=", ">",">=","==",] #ops = ["<", "<=", ">",">=","==",] exprs = [] operands = ["'hello'", 10., 10]