def realtime_image_view(request, image_id=0, size=0, type='jpeg'): filename = RealtimeImages.objects.filter(id=image_id) if filename: object = RealtimeObjects.objects.get(id=filename[0].object_id) filename = filename[0].filename else: return HttpResponse("Image unavailable") filename = posixpath.join(settings.BASE, filename) filename = fix_remote_path(filename, object.channel_id) if type == 'jpeg': image, xsize, ysize = fitsimage.FitsReadData(filename) img = fitsimage.FitsImageFromData(image, xsize, ysize, contrast="percentile", contrast_opts={'max_percent': 99.5}, scale="linear") if size: img.thumbnail((size, size), resample=fitsimage.Image.ANTIALIAS) # now what? response = HttpResponse(content_type="image/jpeg") img.save(response, "JPEG", quality=95) elif type == 'fits': response = HttpResponse(FileWrapper(file(filename)), content_type='application/octet-stream') response[ 'Content-Disposition'] = 'attachment; filename=' + os.path.split( filename)[-1] response['Content-Length'] = os.path.getsize(filename) return response
def survey_image_download(request, id=0, ra=0, dec=0, sr=0.1, size=200, plot_objects=True): image = Images.objects.get(id=id) filename = image.filename filename = fix_remote_path(filename, image.channel_id) header = pyfits.getheader(filename, -1) wcs = pywcs.WCS(header) x, y = wcs.all_world2pix(float(ra), float(dec), 0) pixscale = np.hypot(wcs.wcs.cd[0, 0], wcs.wcs.cd[0, 1]) cutsize = max(10, float(sr) / pixscale) process = subprocess.Popen([ "./crop", filename, "-", "x0=%d" % np.round(x), "y0=%d" % np.round(y), "width=%d" % np.round(2 * cutsize), "height=%d" % np.round(2 * cutsize) ], stdout=subprocess.PIPE) content = process.communicate()[0] response = HttpResponse(content, content_type='application/octet-stream') response[ 'Content-Disposition'] = 'attachment; filename=crop_' + os.path.split( filename)[-1] response['Content-Length'] = len(content) return response
def raw_dir(request, dir='', channel=0): base = fix_remote_path(settings.BASE_RAW, channel_id=channel) fits = get_index(posixpath.join(base, dir)) has_index = True if not fits: fits = [ f for f in os.listdir(posixpath.join(base, dir)) if os.path.isfile(posixpath.join(base, dir, f)) and re.match('^.*\.fits$', f) ] fits = [{'path': path, 'filter': None} for path in sorted(fits)] has_index = False stat = os.statvfs(base) s_free = stat.f_bavail * stat.f_frsize s_total = stat.f_blocks * stat.f_frsize context = { 'raw_dir': fits, 'dir': dir, 'base': posixpath.join(base, dir), 'free': s_free, 'total': s_total, 'has_index': has_index, 'channel': channel if channel else 0 } return TemplateResponse(request, 'raw_list.html', context=context)
def realtime_object_animation(request, object_id=0): object = RealtimeObjects.objects.get(id=object_id) images = RealtimeImages.objects.filter(object=object_id)[:1] if request.method == 'GET': channel_id = int(request.GET.get('channel_id', 0)) else: channel_id = 0 if images: dirname = posixpath.split(images[0].filename)[0] dirname = posixpath.join(settings.BASE, dirname) dirname = fix_remote_path(dirname, object.channel_id) if channel_id: filename = glob.glob( posixpath.join(dirname, "channels", "%d_*" % channel_id, "animation.gif")) if filename: filename = filename[0] print filename else: filename = posixpath.join(dirname, "animation.gif") # with open(filename) as f: # string = f.read() response = HttpResponse(FileWrapper(file(filename)), content_type='image/gif') response['Content-Length'] = os.path.getsize(filename) else: response = HttpResponse("Animation unavailable") return response
def raw_slice(request, filename='', channel=0): base = fix_remote_path(settings.BASE_RAW, channel_id=channel) fits = pyfits.open(posixpath.join(base, filename)) d = fits[0].data h, w = fits[0].shape y0 = int(h / 2) x0 = int(w / 2) fig = Figure(facecolor='white', figsize=(800 / 72, 600 / 72)) ax = fig.add_subplot(211) ax.plot(d[y0], drawstyle='steps') ax.set_xlabel("X") ax.set_ylabel("Value") ax.set_title("Horizontal and Vertical Slices at the Center") ax.set_ylim(min(0, np.min(d[y0])), np.max(d[y0])) ax.set_xlim(0, w) ax = fig.add_subplot(212) ax.plot(d[:, x0], drawstyle='steps') ax.set_xlabel("Y") ax.set_ylabel("Value") #ax.set_title("Vertical Slice") ax.set_ylim(min(0, np.min(d[:, x0])), np.max(d[:, x0])) ax.set_xlim(0, h) canvas = FigureCanvas(fig) response = HttpResponse(content_type='image/png') canvas.print_png(response) return response
def image_histogram(request, id, base=settings.BASE): image_obj = Images.objects.get(id=id) filename = Images.objects.get(id=id).filename filename = posixpath.join(base, filename) filename = fix_remote_path(filename, image_obj.channel_id) fits = pyfits.open(filename) d = fits[-1].data.flatten() fig = Figure(facecolor='white', figsize=(800 / 72, 600 / 72)) ax = fig.add_subplot(111) if d.max() - d.min() > 10: ax.hist(d, bins=d.max() - d.min(), histtype='step', log=True) else: ax.hist(d, bins=1000, histtype='step', log=True) ax.set_xlabel("Value") ax.set_ylabel("") ax.set_title("Histogram: %s" % (filename)) # ax.set_xlim(0, width) # ax.set_ylim(height, 0) canvas = FigureCanvas(fig) response = HttpResponse(content_type='image/png') canvas.print_png(response) return response
def image_details(request, id=0): image = Images.objects.get(id=id) context = {'image': image} if image.type != 'flat' and image.type != 'dark': context['flat'] = find_image(image.time, 'superflat', image.channel_id) context['flat_id'] = find_image_id(image.time, 'superflat', image.channel_id) context['dark'] = find_image(image.time, 'dark', image.channel_id) context['dark_id'] = find_image_id(image.time, 'dark', image.channel_id) try: # Try to read original FITS keywords with comments filename = posixpath.join(settings.BASE, image.filename) filename = fix_remote_path(filename, image.channel_id) hdr = pyfits.getheader(filename, -1) ignored_keywords = ['COMMENT', 'SIMPLE', 'BZERO', 'BSCALE', 'EXTEND'] keywords = [{ 'key': k, 'value': repr(hdr[k]), 'comment': hdr.comments[k] } for k in hdr.keys() if k not in ignored_keywords] context['keywords'] = keywords except: pass return TemplateResponse(request, 'image.html', context=context)
def raw_view(request, filename='', channel=0, size=0, processed=False, type='jpeg'): base = fix_remote_path(settings.BASE_RAW, channel_id=channel) fullname = posixpath.join(base, filename) image = pyfits.getdata(fullname, -1) header = pyfits.getheader(fullname, -1) time = postprocess.get_time_from_filename(posixpath.split(filename)[-1]) if processed: darkname = find_image(time, 'dark', channel) darkname = fix_remote_path(darkname, channel) if posixpath.exists(darkname): dark = pyfits.getdata(darkname, -1) image -= dark if type == 'jpeg': img = fitsimage.FitsImageFromData(image, image.shape[1], image.shape[0], contrast="percentile", contrast_opts={'max_percent': 99.9}, scale="linear") if size: img.thumbnail((size, size)) #, resample=fitsimage.Image.ANTIALIAS) # now what? response = HttpResponse(content_type="image/jpeg") img.save(response, "JPEG", quality=95) elif type == 'fits': response = HttpResponse(FileWrapper( file(posixpath.join(base, filename))), content_type='application/octet-stream') response[ 'Content-Disposition'] = 'attachment; filename=' + os.path.split( filename)[-1] response['Content-Length'] = os.path.getsize( posixpath.join(base, filename)) return response
def raw_list(request, channel=0): context = {} if settings.CHANNEL_ID > 0 or channel > 0: base = fix_remote_path(settings.BASE_RAW, channel_id=channel) dirs = [ d for d in os.listdir(base) if os.path.isdir(posixpath.join(base, d)) and re.match('^\d{8}_\d{6}$', d) ] raws = [] prev_time = None for path in sorted(dirs, reverse=True): index = get_index(posixpath.join(base, path)) length = len(index) is_new = False if index: first = index[0] last = index[-1] # Is the time delay between last file and current one large enough? if prev_time and prev_time - get_time_from_filename( last['path']) > datetime.timedelta(seconds=1): is_new = True prev_time = get_time_from_filename(first['path']) else: first = None raws.append({ 'path': path, 'first': first, 'length': length, 'is_new': is_new }) stat = os.statvfs(base) s_free = stat.f_bavail * stat.f_frsize s_total = stat.f_blocks * stat.f_frsize context['raw_list'] = raws context['base'] = base context['free'] = s_free context['total'] = s_total context['channel_list'] = range(1, settings.NCHANNELS + 1) context['channel'] = int(channel) if channel else 0 return TemplateResponse(request, 'raw_list.html', context=context)
def image_download(request, id, size=800, base=settings.BASE): image_obj = Images.objects.get(id=id) filename = Images.objects.get(id=id).filename filename = posixpath.join(base, filename) filename = fix_remote_path(filename, image_obj.channel_id) response = HttpResponse(FileWrapper(file(filename)), content_type='application/octet-stream') response['Content-Disposition'] = 'attachment; filename=' + os.path.split( filename)[-1] response['Content-Length'] = os.path.getsize(filename) return response
def scheduler_target_rgb_image(request, id=0): base = posixpath.join("/tmp/fweb/targets", str(id)) try: os.makedirs(base) except: pass rgbname = posixpath.join(base, "rgb.jpg") if not posixpath.isfile(rgbname): # No cached file try: target = SchedulerTargets.objects.get(id=id) images = Images.objects.raw( "select *,get_filter_name(filter) as filter_string from images where keywords->'TARGET UUID'='%s' and q3c_radial_query(ra0, dec0, %s, %s, 2.0) order by channel_id" % (target.uuid, target.ra, target.dec)) files_b, files_v, files_r = [], [], [] for image in images: filename = posixpath.join(settings.BASE, image.filename) filename = fix_remote_path(filename, image.channel_id) if image.filter_string == 'B': files_b.append(filename) if image.filter_string == 'V': files_v.append(filename) if image.filter_string == 'R': files_r.append(filename) if len(files_b) and len(files_v) and len(files_r): print files_b[0], files_v[0], files_r[0] coadd_rgb(name_blue=files_b[0], name_green=files_v[0], name_red=files_r[0], out=rgbname) except: pass if not posixpath.isfile(rgbname): return HttpResponse("Can't create RGB image for target %s" % str(id)) response = HttpResponse(FileWrapper(file(rgbname)), content_type='image/jpeg') response['Content-Length'] = posixpath.getsize(rgbname) return response
def image_slice(request, id, base=settings.BASE): image_obj = Images.objects.get(id=id) filename = Images.objects.get(id=id).filename filename = posixpath.join(base, filename) filename = fix_remote_path(filename, image_obj.channel_id) fits = pyfits.open(filename) fits = pyfits.open(posixpath.join(base, filename)) d = fits[-1].data h, w = fits[-1].shape y0 = int(h / 2) x0 = int(w / 2) fig = Figure(facecolor='white', figsize=(800 / 72, 600 / 72)) ax = fig.add_subplot(211) ax.plot(d[y0], drawstyle='steps') ax.set_xlabel("X") ax.set_ylabel("Value") ax.set_title("Horizontal and Vertical Slices at the Center") if not request.GET.get('nozero', 0): ax.set_ylim(min(0, np.min(d[y0])), np.max(d[y0])) ax.set_xlim(0, w) ax = fig.add_subplot(212) ax.plot(d[:, x0], drawstyle='steps') ax.set_xlabel("Y") ax.set_ylabel("Value") #ax.set_title("Vertical Slice") if not request.GET.get('nozero', 0): ax.set_ylim(min(0, np.min(d[:, x0])), np.max(d[:, x0])) ax.set_xlim(0, h) canvas = FigureCanvas(fig) response = HttpResponse(content_type='image/png') canvas.print_png(response) return response
def raw_histogram(request, filename='', channel=0): base = fix_remote_path(settings.BASE_RAW, channel_id=channel) fits = pyfits.open(posixpath.join(base, filename)) d = fits[0].data.flatten() fig = Figure(facecolor='white', figsize=(800 / 72, 600 / 72)) ax = fig.add_subplot(111) ax.hist(d, bins=d.max() - d.min(), histtype='step', log=True) ax.set_xlabel("Value") ax.set_ylabel("") ax.set_title("Histogram: %s" % (filename)) # ax.set_xlim(0, width) # ax.set_ylim(height, 0) canvas = FigureCanvas(fig) response = HttpResponse(content_type='image/png') canvas.print_png(response) return response
def raw_info(request, filename='', channel=0): base = fix_remote_path(settings.BASE_RAW, channel_id=channel) fits = pyfits.open(posixpath.join(base, filename)) time = postprocess.get_time_from_filename(posixpath.split(filename)[-1]) hdr = fits[0].header ignored_keywords = ['COMMENT', 'SIMPLE', 'BZERO', 'BSCALE', 'EXTEND'] keywords = [{ 'key': k, 'value': repr(hdr[k]), 'comment': hdr.comments[k] } for k in hdr.keys() if k not in ignored_keywords] fits.close() context = { 'filename': filename, 'keywords': keywords, 'channel': channel if channel else 0, 'time': time } avg = Images.objects.filter(type='avg', channel_id=channel, time__lt=time).order_by('-time').first() survey = Images.objects.filter(type='survey', channel_id=channel, time__lt=time).order_by('-time').first() dark = Images.objects.filter(type='dark', channel_id=channel, time__lt=time).order_by('-time').first() if dark: context['dark'] = dark if avg: context['avg'] = avg if survey and (time - survey.time).total_seconds() < 20 * 60: context['survey'] = survey return TemplateResponse(request, 'raw_info.html', context=context)
def survey_image(request, id=0, ra=0, dec=0, sr=0.1, size=300, plot_objects=True): image = Images.objects.get(id=id) filename = image.filename filename = fix_remote_path(filename, image.channel_id) imdata = pyfits.getdata(filename, -1) header = pyfits.getheader(filename, -1) wcs = pywcs.WCS(header) x, y = wcs.all_world2pix(float(ra), float(dec), 0) pixscale = np.hypot(wcs.wcs.cd[0, 0], wcs.wcs.cd[0, 1]) cutsize = max(10, float(sr) / pixscale) #imdata2,x0,y0 = crop_image(imdata, x, y, cutsize) if plot_objects: objects = survey.get_objects_from_file(filename) else: objects = None fig = Figure(facecolor='white', dpi=72, figsize=(size * 1.0 / 72, size * 1.0 / 72)) ax = fig.add_axes([0, 0, 1, 1]) ax.axis('off') # if x > -cutsize and x <= imdata.shape[1] + cutsize and y > -cutsize and y <= imdata.shape[0] + cutsize: # limits = np.percentile(imdata2, [0.5, 99.0]) # ax.imshow(imdata2, cmap='hot', origin='lower', interpolation='nearest', vmin=limits[0], vmax=limits[1]) # if x < cutsize: # ax.set_xlim(x - cutsize, x + cutsize - 1) # if x >= imdata.shape[1] - cutsize: # ax.set_xlim(0, 2*cutsize - 1) # if y < cutsize: # ax.set_ylim(y - cutsize, y + cutsize - 1) # if y >= imdata.shape[0] - cutsize: # ax.set_ylim(0, 2*cutsize - 1) y1, x1 = np.mgrid[0:imdata.shape[0], 0:imdata.shape[1]] idx = (x1 >= x - cutsize) & (x1 <= x + cutsize) & (y1 >= y - cutsize) & ( y1 <= y + cutsize) idx = idx & (x1 > 0) & (y1 > 0) & (x1 < imdata.shape[1] - 1) & ( y1 < imdata.shape[0] - 1) if len(imdata[idx]): limits = np.percentile(imdata[idx], [0.5, 99.0]) ax.imshow(imdata, cmap='hot', origin='lower', interpolation='nearest', vmin=limits[0], vmax=limits[1]) ax.set_xlim(x - cutsize, x + cutsize) ax.set_ylim(y - cutsize, y + cutsize) if objects: ax.autoscale(False) ax.scatter(objects['x'], objects['y'], c='blue') if request.method == 'GET': if request.GET.has_key('ra0') and request.GET.has_key('dec0'): ra0 = float(request.GET.get('ra0', 0)) dec0 = float(request.GET.get('dec0', 0)) sr0 = float(request.GET.get('sr0', 0.01)) x0, y0 = wcs.all_world2pix(float(ra0), float(dec0), 0) psr0 = float(sr0) / pixscale ax.add_patch( Ellipse(xy=[x0, y0], width=2 * psr0, height=2 * psr0, edgecolor='green', fc='None', lw=2)) response = HttpResponse(content_type="image/png") canvas = FigureCanvas(fig) canvas.print_png(response, bbox_inches='tight') return response
def image_processed(request, id, size=800, base=settings.BASE, raw=False, format='jpeg', pmin=0.5, pmax=97): if request.method == 'GET': pmin = float(request.GET.get('pmin', pmin)) pmax = float(request.GET.get('pmax', pmax)) image_obj = Images.objects.get(id=id) filename = image_obj.filename filename = posixpath.join(base, filename) filename = fix_remote_path(filename, image_obj.channel_id) data = pyfits.getdata(filename, -1).astype(np.float64) header = pyfits.getheader(filename, -1) np.seterr(divide='ignore') if not raw and image_obj.type not in [ 'coadd', 'dark', 'mdark', 'flat', 'flat_11', 'bgflat', 'skyflat', 'skyflat_11', 'superflat' ]: darkname = find_image(image_obj.time, 'dark', image_obj.channel_id) darkname = fix_remote_path(darkname, image_obj.channel_id) is_flat = False if request.method == 'GET' and request.GET.has_key('linearize'): calib = Calibrator(shutter=int(image_obj.keywords['SHUTTER']), channel_id=image_obj.channel_id) data, header = calib.calibrate(data, header) darkname = None is_flat = True if darkname and posixpath.exists(darkname): dark = pyfits.getdata(darkname, -1) # if image_obj.type == 'avg' and np.median(data) < np.median(dark): # # AVG image affected by off-by-one error (summed over 99 frames instead of 100, but divided by 100) # data *= 100.0/99.0 data -= dark is_flat = True if is_flat: flatname = find_image(image_obj.time, 'superflat', image_obj.channel_id) flatname = fix_remote_path(flatname, image_obj.channel_id) if flatname and posixpath.exists(flatname): flat = pyfits.getdata(flatname, -1) flat[np.isnan(flat)] = np.median(flat[~np.isnan(flat)]) data *= np.mean(flat) / flat if raw and request.method == 'GET' and request.GET.has_key('linearize'): calib = Calibrator(shutter=int(image_obj.keywords['SHUTTER']), channel_id=image_obj.channel_id) data, header = calib.calibrate(data, header) if format == 'jpeg': img = fitsimage.FitsImageFromData(data, data.shape[1], data.shape[0], contrast="percentile", contrast_opts={ 'min_percent': pmin, 'max_percent': pmax }, scale="linear") if size: img.thumbnail((size, size), resample=fitsimage.Image.ANTIALIAS) # now what? response = HttpResponse(content_type="image/jpeg") img.save(response, "JPEG", quality=95) return response elif format == 'fits': newname = posixpath.splitext( posixpath.split(filename)[-1])[0] + '.processed.fits' obj = StringIO.StringIO() pyfits.writeto(obj, data, header=header, clobber=True) response = HttpResponse(obj.getvalue(), content_type='application/octet-stream') response['Content-Disposition'] = 'attachment; filename=' + newname return response
def realtime_object_details(request, object_id=0): if request.method == 'POST': assert_permission(request, 'fweb.modify_data') message = "" action = request.POST.get('action') r = None if action in [ 'process', 'process_1s', 'process_5s', 'process_10s', 'preview' ]: object = RealtimeObjects.objects.get(id=object_id) if action == 'process_1s': deltat = 1 elif action == 'process_5s': deltat = 5 elif action == 'process_10s': deltat = 10 else: deltat = 0 if action == 'preview': preview = True else: preview = False r = favor2_celery.processObjects.apply_async(kwargs={ 'id': object_id, 'deltat': deltat, 'reprocess': True, 'preview': preview }, queue="channel%d" % object.channel_id) elif action == 'delete' or action == 'delete_and_next': object = RealtimeObjects.objects.get(id=object_id) night = object.night state = object.state.name realtime_object_delete(id=object_id) next_state = request.POST.get('next_state') if action == 'delete' or not next_state: return redirect('/realtime/night/%s/%s' % (night, state)) else: return redirect('realtime_object', object_id=int(next_state)) elif action == 'comment-delete': for c in RealtimeComments.objects.filter(object_id=object_id): c.delete() elif action == 'comment': comment = request.POST.get('comment').strip() c, _ = RealtimeComments.objects.get_or_create(object_id=object_id) if comment: c.comment = comment c.save() else: c.delete() elif action == 'change_state': new_state = request.POST.get('new_state').strip() if new_state: realtime_object_change_state(object_id, new_state) elif action == 'change_state_particle': realtime_object_change_state(object_id, 'particle') elif action == 'change_state_misc': realtime_object_change_state(object_id, 'misc') if r: # Redirect to the task page return redirect('tasks_task', id=r.id) else: # Redirect to the same view, but with no POST args. We can't display messages with it! return redirect('realtime_object', object_id=object_id) object = RealtimeObjects.objects.annotate( nrecords=Count('realtimerecords')).get(id=object_id) context = {'object': object} next = RealtimeObjects.objects.filter(night=object.night).filter( id__lt=object.id).order_by('-time_start').order_by('-id').first() next_state = RealtimeObjects.objects.filter( night=object.night, state=object.state, id__lt=object.id).order_by('-time_start').order_by('-id').first() if next: context['next'] = next.id if next_state: context['next_state'] = next_state.id prev = RealtimeObjects.objects.filter(night=object.night).filter( id__gt=object.id).order_by('time_start').order_by('id').first() prev_state = RealtimeObjects.objects.filter( night=object.night, state=object.state, id__gt=object.id).order_by('time_start').order_by('id').first() if prev: context['prev'] = prev.id if prev_state: context['prev_state'] = prev_state.id images = RealtimeImages.objects.filter( object_id=object_id).order_by('time') if not images: records = RealtimeRecords.objects.filter( object_id=object_id).order_by('time') images = [{'record': r, 'time': r.time} for r in records] context['processed'] = False else: context['processed'] = True comments = RealtimeComments.objects.filter(object_id=object_id) if comments: context['comment'] = comments[0] if object.params.has_key('related'): related = object.params['related'].split() context['related'] = related avg = Images.objects.filter(type='avg').filter( channel_id=object.channel_id).filter( time__gt=object.time_start).order_by('time').first() if avg: context['avg_id'] = avg.id #context['avg_id'] = find_image_id(object.time_start, 'avg', object.channel_id) if object.channel_id: # Try to get direct links to RAW files raw_base = fix_remote_path(settings.BASE_RAW, channel_id=object.channel_id) raw_dirs = [ d for d in os.listdir(raw_base) if os.path.isdir(posixpath.join(raw_base, d)) and re.match('^\d{8}_\d{6}$', d) ] raw_dirs.sort() i0 = max( 0, bisect.bisect_right( raw_dirs, get_dirname(object.time_start - datetime.timedelta(seconds=1))) - 1) i1 = bisect.bisect_right( raw_dirs, get_dirname(object.time_end + datetime.timedelta(seconds=1))) - 1 raw_dirs = raw_dirs[i0:i1 + 1] for image in images: raw = None if raw_dirs: time = image['time'] if type(image) == dict else image.time filename = get_filename(time) for dir in raw_dirs: idx = get_index(posixpath.join(raw_base, dir)) for i in idx: if i['path'] == filename: raw = posixpath.join(dir, i['path']) break if raw: break if type(image) == dict: image['raw'] = raw else: image.raw = raw context['images'] = images return TemplateResponse(request, 'realtime_object.html', context=context)
def survey_dbg_image(request, id=0, size=900, cat='pickles'): if request.method == 'GET': if request.GET.has_key('cat'): cat = request.GET.get('cat') image_obj = Images.objects.get(id=id) filename = fix_remote_path(image_obj.filename, image_obj.channel_id) darkname = find_image(image_obj.time, 'dark', image_obj.channel_id) darkname = fix_remote_path(darkname, image_obj.channel_id) flatname = find_image(image_obj.time, 'flat', image_obj.channel_id) flatname = fix_remote_path(flatname, image_obj.channel_id) data = pyfits.getdata(filename, -1) header = pyfits.getheader(filename, -1) # Prepare if posixpath.exists(darkname): dark = pyfits.getdata(darkname, -1) data -= dark if posixpath.exists(flatname): flat = pyfits.getdata(flatname, -1) data *= np.mean(flat) / flat # Calibrate obj = survey.get_objects_from_file(filename, simple=False, filter=True) wcs = pywcs.WCS(header) ra0, dec0, sr0 = survey.get_frame_center(header=header, wcs=wcs) print filename, '-', ra0, dec0, sr0 favor2 = Favor2() if cat == 'apass': cat = favor2.get_stars(ra0, dec0, sr0, catalog='apass', limit=600000, extra=[ "g<14 and g>8.5", "b<20 and v<20 and r<20 and i<20 and g<20", "var = 0", "gerr>0 and rerr>0 and ierr>0" ]) else: cat = favor2.get_stars(ra0, dec0, sr0, catalog='pickles', limit=200000, extra=["var = 0", "rank=1"]) print "%d objects, %d stars" % (len(obj['ra']), len(cat['ra'])) survey.fix_distortion(obj, cat, header=header) Y, YY, corr, oidx = survey.calibrate_objects(obj, cat, sr=10. / 3600, retval='all') # Plot dpi = 72 figsize = (size / dpi, size * 4 * 0.6 / dpi) fig = Figure(facecolor='white', figsize=figsize, tight_layout=True) # 1 ax = fig.add_subplot(411) limits = np.percentile(data, [0.5, 99.5]) i = ax.imshow(data, origin='lower', cmap='hot', interpolation='nearest', vmin=limits[0], vmax=limits[1]) fig.colorbar(i) ax.set_title( "%d / %s / ch=%d at %s" % (image_obj.id, image_obj.type, image_obj.channel_id, image_obj.time)) # 2 ax = fig.add_subplot(412) gmag0, bins, binloc = griddata(obj['x'][oidx], obj['y'][oidx], Y, binsize=100) limits = np.percentile(gmag0[np.isfinite(gmag0)], [0.5, 95.5]) i = ax.imshow(gmag0, origin='lower', extent=[0, header['NAXIS1'], 0, header['NAXIS2']], interpolation='nearest', vmin=limits[0], vmax=limits[1]) fig.colorbar(i) ax.autoscale(False) ax.plot(obj['x'][oidx], obj['y'][oidx], 'b.', alpha=0.3) ax.set_title("Actual zero point") # 3 ax = fig.add_subplot(413) gmag0, bins, binloc = griddata(obj['x'][oidx], obj['y'][oidx], YY, binsize=100) #limits = np.percentile(gmag0[np.isfinite(gmag0)], [0.5, 95.5]) i = ax.imshow(gmag0, origin='lower', extent=[0, header['NAXIS1'], 0, header['NAXIS2']], interpolation='nearest', vmin=limits[0], vmax=limits[1]) fig.colorbar(i) ax.autoscale(False) ax.plot(obj['x'][oidx], obj['y'][oidx], 'b.', alpha=0.3) ax.set_title("Fitted zero point") # 4 ax = fig.add_subplot(414) gmag0, bins, binloc = griddata(obj['x'][oidx], obj['y'][oidx], Y - YY, binsize=100) limits = np.percentile(gmag0[np.isfinite(gmag0)], [0.5, 95.5]) i = ax.imshow(gmag0, origin='lower', extent=[0, header['NAXIS1'], 0, header['NAXIS2']], interpolation='nearest', vmin=limits[0], vmax=limits[1]) fig.colorbar(i) ax.autoscale(False) ax.plot(obj['x'][oidx], obj['y'][oidx], 'b.', alpha=0.3) ax.set_title("Zero point residuals. std=%g" % np.std(Y - YY)) canvas = FigureCanvas(fig) response = HttpResponse(content_type='image/png') canvas.print_png(response) return response