def test_wcs (self): img = Image.fromFile(os.path.join(self.base, "teste-com-wcs.fits"), fix=False) world = img.worldAt(0,0) print "world value at pixel 0,0:", world print "pixel value at world %s:" % world, img.pixelAt(world) print "world value at center pix %s:" % str(img.center()), img.worldAt(img.center()) assert world.ra.D != None assert world.dec.D != None img = Image.fromFile(os.path.join(self.base, "teste-sem-wcs.fits"), fix=False) assert_raises(WCSNotFoundException, img.worldAt, 0, 0)
def test_wcs(self): img = Image.fromFile(os.path.join(self.base, "teste-com-wcs.fits"), fix=False) world = img.worldAt(0, 0) print "world value at pixel 0,0:", world print "pixel value at world %s:" % world, img.pixelAt(world) print "world value at center pix %s:" % str(img.center()), img.worldAt( img.center()) assert world.ra.D != None assert world.dec.D != None img = Image.fromFile(os.path.join(self.base, "teste-sem-wcs.fits"), fix=False) assert_raises(WCSNotFoundException, img.worldAt, 0, 0)
def _takeImage(self): cam = self.getCam() if self.filter: filter = self.getFilter() filter.setFilter(self.filter) self.imageRequest["filename"] = os.path.basename(ImageUtil.makeFilename("align-$DATE")) frames = cam.expose(self.imageRequest) if frames: image = frames[0] image_path = image.filename() if not os.path.exists(image_path): # If image is on a remote server, donwload it. # If remote is windows, image_path will be c:\...\image.fits, so use ntpath instead of os.path. if ':\\' in image_path: modpath = ntpath else: modpath = os.path image_path = ImageUtil.makeFilename(os.path.join(getImageServer(self.getManager()).defaultNightDir(), modpath.basename(image_path))) t0 = time.time() self.log.debug('Downloading image from server to %s' % image_path) if not ImageUtil.download(image, image_path): raise ChimeraException('Error downloading image %s from %s' % (image_path, image.http())) self.log.debug('Finished download. Took %3.2f seconds' % (time.time() - t0)) image = Image.fromFile(image_path) return image #image_path #, image else: raise Exception("Could not take an image")
def _findStars(self, frame_path): frame = Image.fromFile(frame_path) config = {} config['PIXEL_SCALE'] = 0 # use WCS info config['BACK_TYPE'] = "AUTO" # CCD saturation level in ADUs. s = self.getCam()["ccd_saturation_level"] if s is not None: # If there is no ccd_saturation_level on the config, use the default. config['SATUR_LEVEL'] = s # improve speed with higher threshold config['DETECT_THRESH'] = 3.0 # no output, please config['VERBOSE_TYPE'] = "QUIET" # our "star" dict entry will contain all this members config['PARAMETERS_LIST'] = ["NUMBER", "XWIN_IMAGE", "YWIN_IMAGE", "FLUX_BEST", "FWHM_IMAGE", "FLAGS"] aux_fname = os.path.join(SYSTEM_CONFIG_DIRECTORY, self.currentRun, os.path.splitext(os.path.basename(frame_path))[0]) catalogName = aux_fname + ".catalog" configName = aux_fname + ".config" return frame.extract(config, saveCatalog=catalogName, saveConfig=configName)
def _takeImage(self): if self._debugging: pass try: frame = self._debug_images[self._debug_image] self._debug_image += 1 img = Image.fromFile(frame) srv = getImageServer(self.getManager()) return srv.register(img) except IndexError: raise ChimeraException("Cannot find debug images") self.imageRequest["filename"] = os.path.join(SYSTEM_CONFIG_DIRECTORY, self.currentRun, "autoguider.fits") cam = self.getCam() if self.filter: filter = self.getFilter() filter.setFilter(self.filter) frame = cam.expose(self.imageRequest) if frame: return frame[0] else: raise Exception("Error taking image.")
def _findStars(self, frame_path): frame = Image.fromFile(frame_path) config = {} config["PIXEL_SCALE"] = 0 # use WCS info config["BACK_TYPE"] = "AUTO" # CCD saturation level in ADUs. s = self.getCam()["ccd_saturation_level"] if s is not None: # If there is no ccd_saturation_level on the config, use the default. config["SATUR_LEVEL"] = s # improve speed with higher threshold config["DETECT_THRESH"] = 3.0 # no output, please config["VERBOSE_TYPE"] = "QUIET" # our "star" dict entry will contain all this members config["PARAMETERS_LIST"] = ["NUMBER", "XWIN_IMAGE", "YWIN_IMAGE", "FLUX_BEST", "FWHM_IMAGE", "FLAGS"] aux_fname = os.path.join( SYSTEM_CONFIG_DIRECTORY, self.currentRun, os.path.splitext(os.path.basename(frame_path))[0] ) catalogName = aux_fname + ".catalog" configName = aux_fname + ".config" return frame.extract(config, saveCatalog=catalogName, saveConfig=configName)
def _takeImage(self): if self._debugging: try: frame = self._debug_images[self._debug_image] self._debug_image += 1 img = Image.fromFile(frame) srv = getImageServer(self.getManager()) return srv.register(img) except IndexError: raise ChimeraException("Cannot find debug images") self.imageRequest["filename"] = os.path.join(SYSTEM_CONFIG_DIRECTORY, self.currentRun, "focus-$DATE.fits") cam = self.getCam() if self.filter: filter = self.getFilter() filter.setFilter(self.filter) frame = cam.expose(self.imageRequest) if frame: return frame[0] else: raise Exception("Error taking image.")
def test_headers (self): img = Image.fromFile(os.path.join(self.base, "teste-sem-wcs.fits"), fix=False) print() for k, v in list(img.items()): print(k,v, type(v))
def test_create (self): img = Image.create(N.zeros((100,100)), filename="autogen-teste.fits") assert os.path.exists(img.filename()) assert img.width() == 100 assert img.height() == 100 os.unlink(img.filename())
def test_headers (self): img = Image.fromFile(os.path.join(self.base, "teste-sem-wcs.fits"), fix=False) print for k, v in img.items(): print k,v, type(v)
def ui(): self.exposureProgress.set_fraction(1.0) self.exposureProgress.set_text("readout and save complete ...") url = image.http() imageFileName = urllib.urlretrieve( url, filename=os.path.basename(image.filename()))[0] imageFile = Image.fromFile(imageFileName) self.module.imageViewer.newImage(imageFile)
def _saveImage(self, imageRequest, imageData, extra): (mode, binning, top, left, width, height) = self._getReadoutModeInfo(imageRequest["binning"], imageRequest["window"]) binFactor = extra.get("binning_factor", 1.0) pix_w, pix_h = self.getPixelSize() focal_length = self["telescope_focal_length"] scale_x = binFactor * (((180 / pi) / focal_length) * (pix_w * 0.001)) scale_y = binFactor * (((180 / pi) / focal_length) * (pix_h * 0.001)) full_width, full_height = self.getPhysicalSize() CRPIX1 = ((int(full_width / 2.0)) - left) - 1 CRPIX2 = ((int(full_height / 2.0)) - top) - 1 t0 = time.time() img = Image.create(imageData, imageRequest) img += [ ('DATE-OBS', ImageUtil.formatDate( extra.get("frame_start_time", dt.datetime.utcnow())), 'Date exposure started'), ('CCD-TEMP', extra.get("frame_temperature", -275.0), 'CCD Temperature at Exposure Start [deg. C]'), ("EXPTIME", float(imageRequest['exptime']) or -1, "exposure time in seconds"), ('IMAGETYP', imageRequest['type'].strip(), 'Image type'), ('SHUTTER', str(imageRequest['shutter']), 'Requested shutter state'), ("CRPIX1", CRPIX1, "coordinate system reference pixel"), ("CRPIX2", CRPIX2, "coordinate system reference pixel"), ("CD1_1", scale_x, "transformation matrix element (1,1)"), ("CD1_2", 0.0, "transformation matrix element (1,2)"), ("CD2_1", 0.0, "transformation matrix element (2,1)"), ("CD2_2", scale_y, "transformation matrix element (2,2)"), ('CAMERA', str(self['camera_model']), 'Camera Model'), ('CCD', str(self['ccd_model']), 'CCD Model'), ('CCD_DIMX', self.getPhysicalSize()[0], 'CCD X Dimension Size'), ('CCD_DIMY', self.getPhysicalSize()[1], 'CCD Y Dimension Size'), ('CCDPXSZX', self.getPixelSize()[0], 'CCD X Pixel Size [micrometer]'), ('CCDPXSZY', self.getPixelSize()[1], 'CCD Y Pixel Size [micrometer]') ] # register image on ImageServer server = getImageServer(self.getManager()) proxy = server.register(img) # and finally compress the image img.compress(multiprocess=True) return proxy
def ui(): self.exposureProgress.set_fraction(1.0) self.exposureProgress.set_text("readout and save complete ...") url = image.http() imageFileName = urllib.urlretrieve(url, filename=os.path.basename( image.filename()))[0] imageFile = Image.fromFile(imageFileName) self.module.imageViewer.newImage(imageFile)
def test_wcs (self): img = Image.fromFile(os.path.join(self.base, "teste-com-wcs.fits"), fix=False) world = img.worldAt(0,0) print("world value at pixel 0,0:", world) print("pixel value at world %s:" % world, img.pixelAt(world)) print("world value at center pix %s:" % str(img.center()), img.worldAt(img.center())) assert world.ra.D != None assert world.dec.D != None
def test_wcs(self): for f in ["teste-com-wcs.fits", "teste-sem-wcs.fits"]: img = Image.fromFile(os.path.join(self.base, f), fix=False) print f world = img.worldAt(0, 0) print "world value at pixel 0,0:", world print "pixel value at world %s:" % world, img.pixelAt(world) print "world value at center pix %s:" % str( img.center()), img.worldAt(img.center()) print
def _saveImage(self, imageRequest, imageData, extra): (mode, binning, top, left, width, height) = self._getReadoutModeInfo( imageRequest["binning"], imageRequest["window"] ) binFactor = extra.get("binning_factor", 1.0) pix_w, pix_h = self.getPixelSize() focal_length = self["telescope_focal_length"] scale_x = binFactor * (((180 / pi) / focal_length) * (pix_w * 0.001)) scale_y = binFactor * (((180 / pi) / focal_length) * (pix_h * 0.001)) full_width, full_height = self.getPhysicalSize() CRPIX1 = ((int(full_width / 2.0)) - left) - 1 CRPIX2 = ((int(full_height / 2.0)) - top) - 1 t0 = time.time() img = Image.create(imageData, imageRequest) img += [ ( "DATE-OBS", ImageUtil.formatDate(extra.get("frame_start_time", dt.datetime.utcnow())), "Date exposure started", ), ("CCD-TEMP", extra.get("frame_temperature", -275.0), "CCD Temperature at Exposure Start [deg. C]"), ("EXPTIME", float(imageRequest["exptime"]) or -1, "exposure time in seconds"), ("IMAGETYP", imageRequest["type"].strip(), "Image type"), ("SHUTTER", str(imageRequest["shutter"]), "Requested shutter state"), ("CRPIX1", CRPIX1, "coordinate system reference pixel"), ("CRPIX2", CRPIX2, "coordinate system reference pixel"), ("CD1_1", scale_x, "transformation matrix element (1,1)"), ("CD1_2", 0.0, "transformation matrix element (1,2)"), ("CD2_1", 0.0, "transformation matrix element (2,1)"), ("CD2_2", scale_y, "transformation matrix element (2,2)"), ("CAMERA", str(self["camera_model"]), "Camera Model"), ("CCD", str(self["ccd_model"]), "CCD Model"), ("CCD_DIMX", self.getPhysicalSize()[0], "CCD X Dimension Size"), ("CCD_DIMY", self.getPhysicalSize()[1], "CCD Y Dimension Size"), ("CCDPXSZX", self.getPixelSize()[0], "CCD X Pixel Size [micrometer]"), ("CCDPXSZY", self.getPixelSize()[1], "CCD Y Pixel Size [micrometer]"), ] # register image on ImageServer server = getImageServer(self.getManager()) proxy = server.register(img) # and finally compress the image img.compress(multiprocess=True) return proxy
def _takeImage(self): if self._debugging: try: frame = self._debug_images[self._debug_image] self._debug_image += 1 img = Image.fromFile(frame) srv = getImageServer(self.getManager()) return srv.register(img) except IndexError: raise ChimeraException("Cannot find debug images") self.imageRequest["filename"] = os.path.basename( ImageUtil.makeFilename("focus-$DATE")) cam = self.getCam() if self.filter: filter = self.getFilter() filter.setFilter(self.filter) frames = cam.expose(self.imageRequest) if frames: image = frames[0] image_path = image.filename() if not os.path.exists( image_path ): # If image is on a remote server, donwload it. # If remote is windows, image_path will be c:\...\image.fits, so use ntpath instead of os.path. if ':\\' in image_path: modpath = ntpath else: modpath = os.path image_path = ImageUtil.makeFilename( os.path.join( getImageServer(self.getManager()).defaultNightDir(), modpath.basename(image_path))) t0 = time.time() self.log.debug('Downloading image from server to %s' % image_path) if not ImageUtil.download(image, image_path): raise ChimeraException( 'Error downloading image %s from %s' % (image_path, image.http())) self.log.debug('Finished download. Took %3.2f seconds' % (time.time() - t0)) return image_path, image else: raise Exception("Could not take an image")
def test_extractor (self): for f in ["teste-com-wcs.fits", "teste-sem-wcs.fits"]: img = Image.fromFile(os.path.join(self.base, f), fix=False) stars = img.extract() print() print("Found %d star(s) on image %s, showing first 10:" % (len(stars), img.filename)) for star in stars[:10]: print(star["NUMBER"], star["XWIN_IMAGE"], star["YWIN_IMAGE"], star["FLUX_BEST"])
def _loadImageDir(self, dir): filesToLoad = [] if os.path.exists(dir): # build files list for root, dirs, files in os.walk(dir): filesToLoad += [os.path.join(dir, root, f) for f in files if f.endswith(".fits")] for file in filesToLoad: self.log.debug('Loading %s' % file) self.register(Image.fromFile(file))
def test_extractor (self): for f in ["teste-com-wcs.fits", "teste-sem-wcs.fits"]: img = Image.fromFile(os.path.join(self.base, f), fix=False) stars = img.extract() print print "Found %d star(s) on image %s, showing first 10:" % (len(stars), img.filename) for star in stars[:10]: print star["NUMBER"], star["XWIN_IMAGE"], star["YWIN_IMAGE"], star["FLUX_BEST"]
def add_image_to_queue(imagepath): """Adds a single image to the image queue for processing Does not start processing function""" global image_queue pathname, filename = os.path.split(imagepath) pathname = pathname + "/" basefilename, file_xtn = os.path.splitext(filename) # *** enforce .fits extension if (file_xtn != ".fits"): return # *** check whether the file exists or not if (os.path.exists(imagepath) == False): return image = Image.fromFile(imagepath) AstrometryNet.image_queue.append(image)
def _saveImage(self, imageRequest, imageData, extras=None): if extras is not None: self.extra_header_info = extras imageRequest.headers += self.getMetadata(imageRequest) img = Image.create(imageData, imageRequest) # register image on ImageServer server = getImageServer(self.getManager()) proxy = server.register(img) # and finally compress the image if asked if imageRequest['compress_format'].lower() != 'no': img.compress(format=imageRequest['compress_format'], multiprocess=True) return proxy
def _takeImage(self): if self._debugging: try: frame = self._debug_images[self._debug_image] self._debug_image += 1 img = Image.fromFile(frame) srv = getImageServer(self.getManager()) return srv.register(img) except IndexError: raise ChimeraException("Cannot find debug images") self.imageRequest["filename"] = os.path.basename(ImageUtil.makeFilename("focus-$DATE")) cam = self.getCam() if self.filter: filter = self.getFilter() filter.setFilter(self.filter) frames = cam.expose(self.imageRequest) if frames: image = frames[0] image_path = image.filename() if not os.path.exists(image_path): # If image is on a remote server, donwload it. # If remote is windows, image_path will be c:\...\image.fits, so use ntpath instead of os.path. if ":\\" in image_path: modpath = ntpath else: modpath = os.path image_path = ImageUtil.makeFilename( os.path.join(getImageServer(self.getManager()).defaultNightDir(), modpath.basename(image_path)) ) t0 = time.time() self.log.debug("Downloading image from server to %s" % image_path) if not ImageUtil.download(image, image_path): raise ChimeraException("Error downloading image %s from %s" % (image_path, image.http())) self.log.debug("Finished download. Took %3.2f seconds" % (time.time() - t0)) return image_path, image else: raise Exception("Could not take an image")
def test_extractor(self): for f in ["teste-com-wcs.fits", "teste-sem-wcs.fits"]: try: img = Image.fromFile(os.path.join(self.base, f), fix=False) stars = img.extract() print print "Found %d star(s) on image %s, showing first 10:" % ( len(stars), img.filename) for star in stars[:10]: print star["NUMBER"], star["XWIN_IMAGE"], star[ "YWIN_IMAGE"], star["FLUX_BEST"] except SExtractorException: print "You don't have SExtractor... try to install it before"
def test_create (self): img = Image.create(N.zeros((100,100)), filename="autogen-teste.fits") print img.width, img.height
def _saveImage(self, imageRequest, imageData, extra): (mode, binning, top, left, width, height) = self._getReadoutModeInfo(imageRequest["binning"], imageRequest["window"]) binFactor = extra.get("binning_factor", 1.0) pix_w, pix_h = self.getPixelSize() img = Image.create(imageData, imageRequest) if self["telescope_focal_length"] is not None: # If there is no telescope_focal_length defined, don't store WCS focal_length = self["telescope_focal_length"] scale_x = binFactor * (((180 / pi) / focal_length) * (pix_w * 0.001)) scale_y = binFactor * (((180 / pi) / focal_length) * (pix_h * 0.001)) full_width, full_height = self.getPhysicalSize() CRPIX1 = ((int(full_width / 2.0)) - left) - 1 CRPIX2 = ((int(full_height / 2.0)) - top) - 1 # Adding WCS coordinates according to FITS standard. # Quick sheet: http://www.astro.iag.usp.br/~moser/notes/GAi_FITSimgs.html # http://adsabs.harvard.edu/abs/2002A%26A...395.1061G # http://adsabs.harvard.edu/abs/2002A%26A...395.1077C img += [("CRPIX1", CRPIX1, "coordinate system reference pixel"), ("CRPIX2", CRPIX2, "coordinate system reference pixel"), ("CD1_1", scale_x * cos(self["rotation"]*pi/180.), "transformation matrix element (1,1)"), ("CD1_2", -scale_y * sin(self["rotation"]*pi/180.), "transformation matrix element (1,2)"), ("CD2_1", scale_x * sin(self["rotation"]*pi/180.), "transformation matrix element (2,1)"), ("CD2_2", scale_y * cos(self["rotation"]*pi/180.), "transformation matrix element (2,2)")] img += [('DATE-OBS', ImageUtil.formatDate( extra.get("frame_start_time", dt.datetime.utcnow())), 'Date exposure started'), ('CCD-TEMP', extra.get("frame_temperature", -275.0), 'CCD Temperature at Exposure Start [deg. C]'), ("EXPTIME", float(imageRequest['exptime']) or -1, "exposure time in seconds"), ('IMAGETYP', imageRequest['type'].strip(), 'Image type'), ('SHUTTER', str(imageRequest['shutter']), 'Requested shutter state'), ('INSTRUME', str(self['camera_model']), 'Name of instrument'), ('CCD', str(self['ccd_model']), 'CCD Model'), ('CCD_DIMX', self.getPhysicalSize() [0], 'CCD X Dimension Size'), ('CCD_DIMY', self.getPhysicalSize() [1], 'CCD Y Dimension Size'), ('CCDPXSZX', self.getPixelSize()[0], 'CCD X Pixel Size [micrometer]'), ('CCDPXSZY', self.getPixelSize()[1], 'CCD Y Pixel Size [micrometer]')] # register image on ImageServer server = getImageServer(self.getManager()) proxy = server.register(img) # and finally compress the image if asked if imageRequest['compress_format'].lower() != 'no': img.compress(format=imageRequest['compress_format'], multiprocess=True) return proxy
def solveField(fullfilename, findstarmethod="astrometry.net"): """ @param: fullfilename entire path to image @type: str @param: findstarmethod (astrometry.net, sex) @type: str Does astrometry to image=fullfilename Uses either astrometry.net or sex(tractor) as its star finder """ pathname, filename = os.path.split(fullfilename) pathname = pathname + "/" basefilename,file_xtn = os.path.splitext(filename) # *** enforce .fits extension if (file_xtn != ".fits"): raise ValueError("File extension must be .fits it was = %s\n" %file_xtn) # *** check whether the file exists or not if ( os.path.exists(fullfilename) == False ): raise IOError("You selected image %s It does not exist\n" %fullfilename) # version 0.23 changed behavior of --overwrite # I need to specify an output filename with -o outfilename = basefilename + "-out" image = Image.fromFile(fullfilename) try: ra = image["CRVAL1"] # expects to see this in image except: raise AstrometryNetException("Need CRVAL1 and CRVAL2 and CD1_1 on header") try: dec = image["CRVAL2"] except: raise AstrometryNetException("Need CRVAL1 and CRVAL2 and CD1_1 on header") width = image["NAXIS1"] height = image["NAXIS2"] radius = 5.0 * abs(image["CD1_1"]) * width if findstarmethod == "astrometry.net": #line = "solve-field --guess-scale %s --overwrite -o %s" %(fullfilename, outfilename) line = "solve-field %s --overwrite -o %s --ra %f --dec %f --radius %f" %(fullfilename, outfilename, ra, dec, radius) print line elif findstarmethod == "sex": sexoutfilename = pathname + outfilename + ".xyls" line = "solve-field %s --overwrite -o %s --x-column X_IMAGE --y-column Y_IMAGE --sort-column MAG_ISO --sort-ascending --width %d --height %d --ra %f --dec %f --radius %f" %(sexoutfilename, outfilename, width, height, ra, dec, radius) print "Sextractor command line %s" %line # using --guess-scale # line = "solve-field %s --overwrite -o %s --x-column X_IMAGE --y-column Y_IMAGE --sort-column MAG_ISO --sort-ascending --width %d --height %d --guess-scale" %(sexoutfilename, outfilename, width, height) sex = SExtractor() sex.config['BACK_TYPE'] = "AUTO" sex.config['DETECT_THRESH'] = 3.0 sex.config['DETECT_MINAREA'] = 18.0 sex.config['VERBOSE_TYPE'] = "QUIET" sex.config['CATALOG_TYPE'] = "FITS_1.0" #sex.config['CATALOG_TYPE'] = "ASCII" sex.config['CATALOG_NAME'] = sexoutfilename sex.config['PARAMETERS_LIST'] = ["X_IMAGE","Y_IMAGE","MAG_ISO"] sex.run(fullfilename) else: log.error("Unknown option used in astrometry.net") # when there is a solution astrometry.net creates a file with .solved # added as extension. is_solved = pathname + outfilename + ".solved" # if it is already there, make sure to delete it if ( os.path.exists(is_solved)): os.remove(is_solved) solve = Popen(line.split()) # ,env=os.environ) solve.wait() # if solution failed, there will be no file .solved if ( os.path.exists(is_solved) == False ): raise NoSolutionAstrometryNetException("Astrometry.net could not find a solution for image: %s %s" %(fullfilename, is_solved)) # wcs_imgname will be the old fits file with the new header # wcs_solution is the solve-field solution file wcs_imgname = pathname + outfilename + "-wcs" + ".fits" wcs_solution = pathname + outfilename + ".wcs" shutil.copyfile(wcs_solution,wcs_solution+".fits") if ( os.path.exists(wcs_imgname) == True ): iraf.imdelete(wcs_imgname) # create a separate image with new header iraf.artdata() iraf.imcopy(fullfilename,wcs_imgname) iraf.mkheader(images=wcs_imgname,headers=wcs_solution+".fits", append="no",verbose="no",mode="al") return(wcs_imgname)
pix = self.make_dark( (self["ccd_height"], self["ccd_width"]), N.float, imageRequest['exptime']) self.log.debug("Making flat...") pix += self.make_flat( (self["ccd_height"], self["ccd_width"]), N.float) except Exception, e: self.log.warning("MakekFlat error: " + str(e)) #Last resort if nothing else could make a picture if (pix == None): pix = N.zeros((100, 100), dtype=N.int32) imageRequest.fetchPostHeaders(self.getManager()) img = Image.create(pix, imageRequest) # update image request imageRequest["filename"] = img.filename() img += [('DATE-OBS', ImageUtil.formatDate( dt.datetime.fromtimestamp(self.__lastFrameStart)))] server = getImageServer(self.getManager()) proxy = server.register(img) self.readoutComplete(proxy) return proxy
def path_2_image(fullfilename): """Create a Chimera image object from a path name""" print " creating image from file name" image = Image.fromFile(fullfilename) return image
def pointVerify(self): """ Checks telescope pointing Checks the pointing. If telescope coordinates - image coordinates > tolerance move the scope take a new image test again do this while ntrials < max_trials Returns True if centering was succesful False if not """ # take an image and read its coordinates off the header try: image_name = self._takeImage() # for testing purposes uncomment line below and specify some image except: self.log.error("Can't take image") raise image = Image.fromFile(image_name) # Image defined in util ra_img_center = image["CRVAL1"] # expects to see this in image dec_img_center = image["CRVAL2"] currentImageCenter = Position.fromRaDec(Coord.fromD(ra_img_center), Coord.fromD(dec_img_center)) tel = self.getTel() # analyze the previous image using # AstrometryNet defined in util try: wcs_name = AstrometryNet.solveField(image.filename, findstarmethod="sex") except (NoSolutionAstronomyNetException): # why can't I select this exception? # # there was no solution to this field. # send the telescope back to checkPointing # if that fails, clouds or telescope problem # an exception will be raised there self.log.error("No WCS solution") if not self.checkedpointing: if checkPointing() == True: self.checkedpointing = True tel.slewToRaDec(currentImageCenter) try: pointVerify() return True except CanSetScopeButNotThisField: pass # let the caller decide whether we go to next # field or stay on this with no verification else: self.checkedpointing = False raise CanSetScopeButNotThisField( "Able to set scope, but unable to verify this field %s" % (currentImageCenter)) wcs = Image.fromFile(wcs_name) ra_wcs_center = wcs["CRVAL1"] + (wcs["NAXIS1"] / 2.0 - wcs["CRPIX1"]) * wcs["CD1_1"] dec_wcs_center = wcs["CRVAL2"] + (wcs["NAXIS2"] / 2.0 - wcs["CRPIX2"]) * wcs["CD2_2"] currentWCS = Position.fromRaDec(Coord.fromD(ra_wcs_center), Coord.fromD(dec_wcs_center)) # save the position of first trial: if (self.ntrials == 0): initialPosition = Position.fromRaDec(Coord.fromD(ra_img_center), Coord.fromD(dec_img_center)) initialWCS = Position.fromRaDec(currentWCS.ra, currentWCS.dec) # write down the two positions for later use in mount models if (self.ntrials == 0): logstr = "Pointing Info for Mount Model: %s %s %s" % ( image["DATE-OBS"], initialPosition, currentWCS) self.log.info(logstr) delta_ra = ra_img_center - ra_wcs_center delta_dec = dec_img_center - dec_wcs_center self.log.debug("%s %s" % (delta_ra, delta_dec)) self.log.debug("%s %s" % (ra_img_center, ra_wcs_center)) self.log.debug("%s %s" % (dec_img_center, dec_wcs_center)) # *** need to do real logging here logstr = "%s %f %f %f %f %f %f" % (image["DATE-OBS"], ra_img_center, dec_img_center, ra_wcs_center, dec_wcs_center, delta_ra, delta_dec) self.log.debug(logstr) if (delta_ra > self["tolra"]) or (delta_dec > self["toldec"]): print "Telescope not there yet." print "Trying again" self.ntrials += 1 if (self.ntrials > self["max_trials"]): self.ntrials = 0 raise CantPointScopeException( "Scope does not point with a precision of %f (RA) or %f (DEC) after %d trials\n" % self["tolra"] % self["toldec"] % self["max_trials"]) tel.moveOffset(delta_ra, delta_dec) self.pointVerify() else: # if we got here, we were succesfull reset trials counter self.ntrials = 0 # and save final position # write down the two positions for later use in mount models logstr = "Pointing: final solution %s %s %s" % ( image["DATE-OBS"], currentImageCenter, currentWCS) self.log.info(logstr) return (True)
def test_create(self): img = Image.create(N.zeros((100, 100)), filename="autogen-teste.fits") print img.width, img.height
class PointVerify(ChimeraObject, IPointVerify): """ Verifies telescope pointing. There are two ways of doing this: - verify the field the scope has been pointed to - choose a field (from a list of certified fields) and try verification """ # normal constructor # initialize the relevant variables def __init__(self): ChimeraObject.__init__(self) self.ntrials = 0 # number times we try to center on a field self.nfields = 0 # number of fields we try to center on self.checkedpointing = False # True = Standard field is verified self.currentField = 0 # counts fields tried to verify #def __start__ (self): #self.pointVerify() #self.checkPointing() #return True def getTel(self): return self.getManager().getProxy(self["telescope"]) def getCam(self): return self.getManager().getProxy(self["camera"]) def getFilter(self): return self.getManager().getProxy(self["filterwheel"]) def _takeImage(self): cam = self.getCam() frames = cam.expose(exptime=self["exptime"], frames=1, shutter=Shutter.OPEN, filename="pointverify-$DATE") if frames: return frames[0] else: raise Exception("Could not take an image") def pointVerify(self): """ Checks telescope pointing Checks the pointing. If abs ( telescope coordinates - image coordinates ) > tolerance move the scope take a new image test again do this while ntrials < max_trials Returns True if centering was succesful False if not """ # take an image and read its coordinates off the header image = None try: image = self._takeImage() print "image name %s", image.filename() except: self.log.error("Can't take image") raise ra_img_center = image["CRVAL1"] # expects to see this in image dec_img_center = image["CRVAL2"] currentImageCenter = Position.fromRaDec(Coord.fromD(ra_img_center), Coord.fromD(dec_img_center)) tel = self.getTel() # analyze the previous image using # AstrometryNet defined in util try: wcs_name = AstrometryNet.solveField(image.filename(), findstarmethod="sex") except NoSolutionAstrometryNetException, e: raise e # why can't I select this exception? # # there was no solution to this field. # send the telescope back to checkPointing # if that fails, clouds or telescope problem # an exception will be raised there #self.log.error("No WCS solution") #if not self.checkedpointing: # self.nfields += 1 # self.currentField += 1 # if self.nfields <= self["max_fields"] and self.checkPointing() == True: # self.checkedpointing = True # tel.slewToRaDec(currentImageCenter) # try: # self.pointVerify() # return True # except CanSetScopeButNotThisField: # raise # # else: # self.checkedpointing = False # self.currentField = 0 # raise Exception("max fields") # #else: # self.checkedpointing = False # raise CanSetScopeButNotThisField("Able to set scope, but unable to verify this field %s" %(currentImageCenter)) wcs = Image.fromFile(wcs_name) ra_wcs_center = wcs["CRVAL1"] + (wcs["NAXIS1"] / 2.0 - wcs["CRPIX1"]) * wcs["CD1_1"] dec_wcs_center = wcs["CRVAL2"] + (wcs["NAXIS2"] / 2.0 - wcs["CRPIX2"]) * wcs["CD2_2"] currentWCS = Position.fromRaDec(Coord.fromD(ra_wcs_center), Coord.fromD(dec_wcs_center)) # save the position of first trial: if (self.ntrials == 0): initialPosition = Position.fromRaDec(Coord.fromD(ra_img_center), Coord.fromD(dec_img_center)) initialWCS = Position.fromRaDec(currentWCS.ra, currentWCS.dec) # write down the two positions for later use in mount models if (self.ntrials == 0): site = self.getManager().getProxy("/Site/0") logstr = "Pointing Info for Mount Model: %s %s %s %s %s" % ( site.LST(), site.MJD(), image["DATE-OBS"], initialPosition, currentWCS) self.log.info(logstr) delta_ra = ra_img_center - ra_wcs_center delta_dec = dec_img_center - dec_wcs_center self.log.debug("delta_ra: %s delta_dec: %s" % (delta_ra, delta_dec)) self.log.debug("ra_img_center: %s ra_wcs_center: %s" % (ra_img_center, ra_wcs_center)) self.log.debug("dec_img_center: %s dec_wcs_center: %s" % (dec_img_center, dec_wcs_center)) # *** need to do real logging here logstr = "%s %f %f %f %f %f %f" % (image["DATE-OBS"], ra_img_center, dec_img_center, ra_wcs_center, dec_wcs_center, delta_ra, delta_dec) self.log.debug(logstr) if (fabs(delta_ra) > self["tolra"]) or (fabs(delta_dec) > self["toldec"]): print "Telescope not there yet." print "Trying again" self.ntrials += 1 if (self.ntrials > self["max_trials"]): self.ntrials = 0 raise CantPointScopeException( "Scope does not point with a precision of %f (RA) or %f (DEC) after %d trials\n" % (self["tolra"], self["toldec"], self["max_trials"])) time.sleep(5) tel.moveOffset(Coord.fromD(delta_ra).AS, Coord.fromD(delta_dec).AS, rate=SlewRate.CENTER) self.pointVerify() else: # if we got here, we were succesfull, reset trials counter self.ntrials = 0 self.currentField = 0 # and save final position # write down the two positions for later use in mount models logstr = "Pointing: final solution %s %s %s" % ( image["DATE-OBS"], currentImageCenter, currentWCS) #self.log.debug("Synchronizing telescope on %s" % currentWCS) #tel.syncRaDec(currentWCS) # *** should we sync the scope ??? # maybe there should be an option of syncing or not # the first pointing in the night should sync I believe # subsequent pointings should not. # another idea is to sync if the delta_coords at first trial were larger than some value self.log.info(logstr) return (True)
def run_stats(self, proxy, status): if status == CameraStatus.OK and proxy["IMAGETYP"].upper().rstrip() == "OBJECT" and \ proxy["SHUTTER"].upper().rstrip() == "OPEN": self.log.debug('%s [status:%s]@[%s]' % (proxy.filename(), status, proxy.http())) image_path = proxy.filename() if not os.path.exists( image_path ): # If image is on a remote server, donwload it. # If remote is windows, image_path will be c:\...\image.fits, so use ntpath instead of os.path. if ':\\' in image_path: modpath = ntpath else: modpath = os.path image_path = ImageUtil.makeFilename( os.path.join( getImageServer(self.getManager()).defaultNightDir(), modpath.basename(image_path))) t0 = time.time() self.log.debug('Downloading image from server to %s' % image_path) if not ImageUtil.download(proxy, image_path): raise ChimeraException( 'Error downloading image %s from %s' % (image_path, image.http())) self.log.debug('Finished download. Took %3.2f seconds' % (time.time() - t0)) img = Image.fromFile(image_path) else: img = Image.fromFile(image_path) tmpfile = mktemp() p = self._sex_params p.update({"CATALOG_NAME": mktemp()}) extract = img.extract(p) # os.unlink(tmpfile) # else: # extract = proxy.extract(self.sex_params) if len(extract ) > 0: # Only go ahead if at least one object was detected # stats = np.array( # [[data["CLASS_STAR"], data["FLAGS"], data["FWHM_IMAGE"], data["BACKGROUND"]] for data in # extract]) stats = np.array([[ data["NUMBER"], data["X_IMAGE"], data["Y_IMAGE"], data["XWIN_IMAGE"], data["YWIN_IMAGE"], data["ALPHA_J2000"], data["DELTA_J2000"], data["MAG_AUTO"], data["FLUX_AUTO"], data["BACKGROUND"], data["FWHM_IMAGE"], data["FLAGS"], data["CLASS_STAR"], ] for data in extract]) mask = np.bitwise_and(stats[:, 12] > 0.8, stats[:, 11] == 0) fff = "CLEAR" if "FILTER" in proxy.keys(): fff = proxy["FILTER"] # fff = "R" session = Session() try: log = ImageStatistics( date_obs=datetime.datetime.strptime( proxy["DATE-OBS"], "%Y-%m-%dT%H:%M:%S.%f"), filename=proxy.filename(), filter=fff, fwhm_avg=np.average(stats[:, 10][mask]), fwhm_std=np.std(stats[:, 10][mask]), background=np.average(stats[:, 9][mask]), npts=mask.sum(), exptime=proxy["EXPTIME"]) session.add(log) session.flush() session.refresh(log) # Now add stars to the star catalog # Todo: Solve astrometry cat = [] mag_sort = np.argsort(stats[:, 7])[:self['max_stars_catalog']] for data in stats[mag_sort]: cat.append( ImageCatalog( image_statistics_id=log.id, NUMBER=data[0], X_IMAGE=data[1], Y_IMAGE=data[2], XWIN_IMAGE=data[3], YWIN_IMAGE=data[4], ALPHA_J2000=data[5], DELTA_J2000=data[6], MAG_AUTO=data[7], FLUX_AUTO=data[8], BACKGROUND=data[9], FWHM_IMAGE=data[10], FLAGS=data[11], CLASS_STAR=data[12], )) session.add_all(cat) finally: session.commit() # self.stats.append(s) # print "fwhm stats:", s # self.stats[-1] else: self.log.debug( 'Image %s not good for statistics. [status:%s]@[%s]' % (proxy.filename(), status, proxy.http()))
pass # will never happen! imageRequest.addPostHeaders(self.getManager()) binFactor = self._binning_factors[binning] scale_x = binFactor * (((180 / pi) / cam["telescope_focal_length"]) * (self.getPixelSize()[0] * 0.001)) scale_y = binFactor * (((180 / pi) / cam["telescope_focal_length"]) * (self.getPixelSize()[1] * 0.001)) fullsize = self.drv.readoutModes[self.ccd][0] CRPIX1 = ((int(fullsize.width / 2)) - left) - 1 CRPIX2 = ((int(fullsize.height / 2)) - top) - 1 img = Image.create(img, imageRequest) img += [('DATE-OBS', ImageUtil.formatDate(self.lastFrameStartTime), 'Date exposure started'), ('CCD-TEMP', self.lastFrameTemp, 'CCD Temperature at Exposure Start [deg. C]'), ("EXPTIME", float(imageRequest['exptime']) or -1, "exposure time in seconds"), ('IMAGETYP', imageRequest['type'].strip(), 'Image type'), ('SHUTTER', str(imageRequest['shutter']), 'Requested shutter state'), ("CRPIX1", CRPIX1, "coordinate system reference pixel"), ("CRPIX2", CRPIX2, "coordinate system reference pixel"), ("CD1_1", scale_x, "transformation matrix element (1,1)"), ("CD1_2", 0.0, "transformation matrix element (1,2)"), ("CD2_1", 0.0, "transformation matrix element (2,1)"),
def solveField(fullfilename, findstarmethod="astrometry.net"): """ @param: fullfilename entire path to image @type: str @param: findstarmethod (astrometry.net, sex) @type: str Does astrometry to image=fullfilename Uses either astrometry.net or sex(tractor) as its star finder """ pathname, filename = os.path.split(fullfilename) pathname = pathname + "/" basefilename, file_xtn = os.path.splitext(filename) # *** enforce .fits extension if file_xtn != ".fits": raise ValueError("File extension must be .fits it was = %s\n" % file_xtn) # *** check whether the file exists or not if os.path.exists(fullfilename) == False: raise IOError("You selected image %s It does not exist\n" % fullfilename) # version 0.23 changed behavior of --overwrite # I need to specify an output filename with -o outfilename = basefilename + "-out" image = Image.fromFile(fullfilename) try: ra = image["CRVAL1"] # expects to see this in image except: raise AstrometryNetException("Need CRVAL1 and CRVAL2 and CD1_1 on header") try: dec = image["CRVAL2"] except: raise AstrometryNetException("Need CRVAL1 and CRVAL2 and CD1_1 on header") width = image["NAXIS1"] height = image["NAXIS2"] radius = 10.0 * abs(image["CD1_1"]) * width wcs_filename = pathname + outfilename + ".wcs" if findstarmethod == "astrometry.net": line = "solve-field %s --no-plots --overwrite -o %s --ra %f --dec %f --radius %f" % ( fullfilename, outfilename, ra, dec, radius) elif findstarmethod == "sex": sexoutfilename = pathname + outfilename + ".xyls" line = "solve-field %s --no-plots --overwrite -o %s --x-column X_IMAGE --y-column Y_IMAGE " \ "--sort-column MAG_ISO --sort-ascending --width %d --height %d --ra %f --dec %f --radius %f" % ( sexoutfilename, outfilename, width, height, ra, dec, radius) sex = SExtractor() sex.config['BACK_TYPE'] = "AUTO" sex.config['DETECT_THRESH'] = 3.0 sex.config['DETECT_MINAREA'] = 18.0 sex.config['VERBOSE_TYPE'] = "QUIET" sex.config['CATALOG_TYPE'] = "FITS_1.0" sex.config['CATALOG_NAME'] = sexoutfilename sex.config['PARAMETERS_LIST'] = ["X_IMAGE", "Y_IMAGE", "MAG_ISO"] sex.run(fullfilename) else: log.error("Unknown option used in astrometry.net") # when there is a solution astrometry.net creates a file with .solved # added as extension. is_solved = pathname + outfilename + ".solved" # if it is already there, make sure to delete it if os.path.exists(is_solved): os.remove(is_solved) log.debug("SOLVE %s" % line) # *** it would be nice to add a test here to check # whether astrometrynet is running OK, if not raise a new exception # like AstrometryNetInstallProblem log.debug('Starting solve-field...') t0 = time.time() solve = Popen(line.split()) # ,env=os.environ) solve.wait() log.debug('Solve field finished. Took %3.2f sec' % (time.time() - t0)) # if solution failed, there will be no file .solved if (os.path.exists(is_solved) == False): raise NoSolutionAstrometryNetException( "Astrometry.net could not find a solution for image: %s %s" % (fullfilename, is_solved)) return wcs_filename
def solveField(fullfilename, findstarmethod="astrometry.net"): """ @param: fullfilename entire path to image @type: str @param: findstarmethod (astrometry.net, sex) @type: str Does astrometry to image=fullfilename Uses either astrometry.net or sex(tractor) as its star finder """ pathname, filename = os.path.split(fullfilename) pathname = pathname + "/" basefilename, file_xtn = os.path.splitext(filename) # *** enforce .fits extension if (file_xtn != ".fits"): raise ValueError( "File extension must be .fits it was = %s\n" % file_xtn) # *** check whether the file exists or not if (os.path.exists(fullfilename) == False): raise IOError( "You selected image %s It does not exist\n" % fullfilename) # version 0.23 changed behavior of --overwrite # I need to specify an output filename with -o outfilename = basefilename + "-out" image = Image.fromFile(fullfilename) try: ra = image["CRVAL1"] # expects to see this in image except: raise AstrometryNetException( "Need CRVAL1 and CRVAL2 and CD1_1 on header") try: dec = image["CRVAL2"] except: raise AstrometryNetException( "Need CRVAL1 and CRVAL2 and CD1_1 on header") width = image["NAXIS1"] height = image["NAXIS2"] radius = 5.0 * abs(image["CD1_1"]) * width if findstarmethod == "astrometry.net": line = "solve-field %s -d 10,20,30,40,50,60,70,80,90,100 --overwrite -o %s --ra %f --dec %f --radius %f" % ( fullfilename, outfilename, ra, dec, radius) elif findstarmethod == "sex": sexoutfilename = pathname + outfilename + ".xyls" line = "solve-field %s -d 10,20,30,40,50,60,70,80,90,100 --overwrite -o %s --x-column X_IMAGE --y-column Y_IMAGE --sort-column MAG_ISO --sort-ascending --width %d --height %d --ra %f --dec %f --radius %f" % ( sexoutfilename, outfilename, width, height, ra, dec, radius) # line = "solve-field %s --overwrite -o %s --x-column X_IMAGE --y-column Y_IMAGE --sort-column MAG_ISO --sort-ascending --width %d --height %d" %(sexoutfilename, outfilename,width, height) # could use --guess-scale for unreliable mounts: # line = "solve-field %s --overwrite -o %s --x-column X_IMAGE --y-column Y_IMAGE --sort-column MAG_ISO --sort-ascending --width %d --height %d --guess-scale" %(sexoutfilename, outfilename, width, height) sex = SExtractor() sex.config['BACK_TYPE'] = "AUTO" sex.config['DETECT_THRESH'] = 3.0 sex.config['DETECT_MINAREA'] = 18.0 sex.config['VERBOSE_TYPE'] = "QUIET" sex.config['CATALOG_TYPE'] = "FITS_1.0" #sex.config['CATALOG_TYPE'] = "ASCII" sex.config['CATALOG_NAME'] = sexoutfilename sex.config['PARAMETERS_LIST'] = ["X_IMAGE", "Y_IMAGE", "MAG_ISO"] sex.run(fullfilename) else: log.error("Unknown option used in astrometry.net") # when there is a solution astrometry.net creates a file with .solved # added as extension. is_solved = pathname + outfilename + ".solved" # if it is already there, make sure to delete it if (os.path.exists(is_solved)): os.remove(is_solved) print "SOLVE", line # *** it would be nice to add a test here to check # whether astrometrynet is running OK, if not raise a new exception # like AstrometryNetInstallProblem solve = Popen(line.split()) # ,env=os.environ) solve.wait() # if solution failed, there will be no file .solved if (os.path.exists(is_solved) == False): raise NoSolutionAstrometryNetException( "Astrometry.net could not find a solution for image: %s %s" % (fullfilename, is_solved)) # wcs_imgname will be the old fits file with the new header # wcs_solution is the solve-field solution file wcs_imgname = pathname + outfilename + "-wcs" + ".fits" wcs_solution = pathname + outfilename + ".wcs" shutil.copyfile(wcs_solution, wcs_solution + ".fits") if (os.path.exists(wcs_imgname) == True): iraf.imdelete(wcs_imgname) # create a separate image with new header iraf.artdata() iraf.imcopy(fullfilename, wcs_imgname) iraf.hedit(wcs_imgname, "CD1_1,CD1_2,CD2_1,CD2_2,CRPIX1,CRPIX2,CRVAL1,CRVAL2,RA,DEC,ALT,AZ", add="no", addonly="no", delete="yes", verify="no", show="no", update="yes") iraf.mkheader(images=wcs_imgname, headers=wcs_solution + ".fits", append="yes", verbose="no", mode="al") return(wcs_imgname)