diff --git a/python/calibrate.py b/python/calibrate.py new file mode 100644 index 0000000..3125adf --- /dev/null +++ b/python/calibrate.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python + +import os +from astropy.io import fits +import matplotlib.pyplot as plt +import numpy as np +from astropy import wcs +from scipy import optimize + +def residual(a,x,y,z): + return z-(a[0]+a[1]*x+a[2]*y) + +def offsets(ra0,de0,ra,de): + w=wcs.WCS(naxis=2) + w.wcs.crpix=np.array([0.0,0.0]) + w.wcs.crval=np.array([ra0,de0]) + w.wcs.cd=np.array([[1.0/3600.0,0.0],[0.0,1.0/3600.0]]) + w.wcs.ctype=["RA---TAN","DEC--TAN"] + w.wcs.set_pv([(2,1,45.0)]) + + world=np.stack((ra,de),axis=-1) + pix=w.wcs_world2pix(world,1) + return pix[:,0],pix[:,1] + + +def read_pixel_catalog(fname): + d=np.loadtxt(fname) + x,y,mag=d[:,0],d[:,1],d[:,2] + + return x,y,mag + +def read_tycho2_catalog(maxmag=9.0): + hdu=fits.open("/home/bassa/code/python/satellite/astrometry-tycho2/build/tyc2.fits") + + ra=hdu[1].data.field('RA') + de=hdu[1].data.field('DEC') + mag=hdu[1].data.field('MAG_VT') + + c=mag0) & (xc0) & (ycntrkmin: + obs=observation(ff,x,y,t,sig) + + obs.ra,obs.de=pos2rel(ff,obs.x0,obs.y0) + + # Plot + ppgplot.pgopen("/xs") + ppgplot.pgpap(0.0,1.0) + ppgplot.pgsvp(0.1,0.95,0.1,0.8) + + ppgplot.pgsch(0.8) + ppgplot.pgmtxt("T",6.0,0.0,0.0,"UT Date: %.23s COSPAR ID: %04d"%(ff.nfd,ff.site_id)) + ppgplot.pgmtxt("T",4.8,0.0,0.0,"R.A.: %10.5f (%4.1f'') Decl.: %10.5f (%4.1f'')"%(ff.crval[0],3600.0*ff.crres[0],ff.crval[1],3600.0*ff.crres[1])) + ppgplot.pgmtxt("T",3.6,0.0,0.0,"FoV: %.2f\\(2218)x%.2f\\(2218) Scale: %.2f''x%.2f'' pix\\u-1\\d"%(ff.wx,ff.wy,3600.0*ff.sx,3600.0*ff.sy)) + ppgplot.pgmtxt("T",2.4,0.0,0.0,"Stat: %5.1f+-%.1f (%.1f-%.1f)"%(np.mean(ff.zmax),np.std(ff.zmax),ff.vmin,ff.vmax)) + + ppgplot.pgsch(1.0) + ppgplot.pgwnad(0.0,ff.nx,0.0,ff.ny) + ppgplot.pglab("x (pix)","y (pix)"," ") + ppgplot.pgctab(heat_l,heat_r,heat_g,heat_b,5,1.0,0.5) + + ppgplot.pgimag(ff.zmax,ff.nx,ff.ny,0,ff.nx-1,0,ff.ny-1,ff.vmax,ff.vmin,tr) + ppgplot.pgbox("BCTSNI",0.,0,"BCTSNI",0.,0) + + ppgplot.pgsci(3) +# ppgplot.pgpt(x,y,4) + + ppgplot.pgsci(4) + ppgplot.pgpt(np.array([obs.x0]),np.array([obs.y0]),4) + ppgplot.pgmove(obs.xmin,obs.ymin) + ppgplot.pgdraw(obs.xmax,obs.ymax) + + ppgplot.pgend() + + plt.figure() + plt.plot(t,x,'.') + plt.plot(t,y,'.') + plt.plot([obs.tmin,obs.tmax],[obs.xmin,obs.xmax]) + plt.plot([obs.tmin,obs.tmax],[obs.ymin,obs.ymax]) + plt.show() + + # Track and stack + else: + ztrk=ff.track(id.dxdt,id.dydt,0.0) + +# plt.figure(figsize=(15,10)) +# plt.imshow(ztrk,origin='lower') +# plt.scatter(id.x0,id.y0,s=150,edgecolors="y",facecolors="none") +# plt.show() + diff --git a/python/hough.py b/python/hough.py new file mode 100644 index 0000000..fcdc0f3 --- /dev/null +++ b/python/hough.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +from astropy.io import fits +import cv2 +import sys + +hdu=fits.open(sys.argv[1]) + +data=hdu[0].data +zavg,zstd,zmax,znum=data + +zsig=(zmax-zavg)/(zstd+1e-9) + +ny,nx=zsig.shape +tmp=np.zeros(nx*ny*3,dtype='uint8').reshape(ny,nx,3) +tmp[:,:,0]=zmax.astype('uint8') +tmp[:,:,1]=0.1*zmax.astype('uint8') +tmp[:,:,2]=0.1*zmax.astype('uint8') +img=cv2.cvtColor(tmp,cv2.COLOR_BGR2RGB) + +mask=np.array(zsig>5.0,dtype='uint8') +tmp=np.zeros(nx*ny*3,dtype='uint8').reshape(ny,nx,3) +tmp[:,:,0]=255*mask +tmp[:,:,1]=255*mask +tmp[:,:,2]=255*mask + +mat=cv2.cvtColor(tmp,cv2.COLOR_BGR2GRAY) +lines=cv2.HoughLines(mat,1,np.pi/180.0,200) +if lines is not None: + for rho,theta in lines[0]: + a = np.cos(theta) + b = np.sin(theta) + x0 = a*rho + y0 = b*rho + x1 = int(x0 + 1000*(-b)) + y1 = int(y0 + 1000*(a)) + x2 = int(x0 - 1000*(-b)) + y2 = int(y0 - 1000*(a)) + + cv2.line(img,(x1,y1+10),(x2,y2+10),(0,0,255),2) + +minLineLength = 100 +maxLineGap = 10 +lines = cv2.HoughLinesP(mat,1,np.pi/180,100,minLineLength,maxLineGap) +if lines is not None: + for x1,y1,x2,y2 in lines[0]: + cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2) + + cv2.imwrite(sys.argv[1]+'.jpg',img) diff --git a/python/iod.py b/python/iod.py new file mode 100644 index 0000000..609c8bc --- /dev/null +++ b/python/iod.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python + +class iod: + """IOD Observation""" + + def __init__(self,line): + s=line.split() + self.iodline=line + self.norad=int(s[0]) + self.cospar="%s %s"%(s[1],s[2]) + self.site=int(s[3]) + self.conditions=s[4] + self.datestring=s[5] + + + + def __repr__(self): + return "%05d %s %04d %s %s"%(self.norad,self.cospar,self.site,self.conditions,self.datestring) + + +iodlines=["10529 77 112D 4553 G 20120511214446298 17 25 2034286+472232 37 R", + "10529 77 112D 4553 G 20120511214452938 17 25 2038653+454274 37 S", + "23862 96 029D 4553 G 20120511221706217 17 25 2121225+480700 37 S", + "23862 96 029D 4553 G 20120511221726241 17 25 2122590+453398 37 R"] + +obslist=[iod(line) for line in iodlines] + +print(type(obslist),type(obslist[0])) +for obs in obslist: + print(obs) diff --git a/python/plot.py b/python/plot.py new file mode 100644 index 0000000..d1118d7 --- /dev/null +++ b/python/plot.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python +import numpy as np +import sys +from astropy.io import fits +import matplotlib.pyplot as plt +from mpl_toolkits.mplot3d import Axes3D + +fname="2018-02-12T17:39:55.270.fits" + +# Read fits +hdu=fits.open(fname) + +# Read data +data=hdu[0].data +zavg,zstd,zmax,znum=data + +# Read header +ny,nx=zavg.shape +nz=hdu[0].header['NFRAMES'] +dt=[hdu[0].header['DT%04d'%i] for i in range(nz)] + +# Sigma frame +zsig=(zmax-zavg)/(zstd+1e-9) + +# Position +xm,ym=np.meshgrid(np.arange(nx),np.arange(ny)) + +# Selection width +w=10 +sigma=5.0 + +# Selection +c=(zsig>sigma) & (xm>w) & (xmw) & (ym %f %f %f %d %s %s"%(self.nfd,self.x0,self.y0,self.t0,self.x1,self.y1,self.t1,self.norad,self.catalog,self.state) + +class fourframe: + """Four frame class""" + + def __init__(self,fname=None): + if fname==None: + # Initialize empty fourframe + self.nx=0 + self.ny=0 + self.nz=0 + self.mjd=-1 + self.nfd=None + self.zavg=None + self.zstd=None + self.zmax=None + self.znum=None + self.dt=None + self.site_id=0 + self.observer=None + self.texp=0.0 + self.fname=None + self.crpix=np.array([0.0,0.0]) + self.crval=np.array([0.0,0.0]) + self.cd=np.array([[1.0,0.0],[0.0,1.0]]) + self.ctype=["RA---TAN","DEC--TAN"] + self.cunit=np.array(["deg","deg"]) + self.crres=np.array([0.0,0.0]) + else: + # Read FITS file + hdu=fits.open(fname) + + # Read image planes + self.zavg,self.zstd,self.zmax,self.znum=hdu[0].data + + # Frame properties + self.ny,self.nx=self.zavg.shape + self.nz=hdu[0].header['NFRAMES'] + + # Read frame time oselfsets + self.dt=np.array([hdu[0].header['DT%04d'%i] for i in range(self.nz)]) + + # Read header + self.mjd=hdu[0].header['MJD-OBS'] + self.nfd=hdu[0].header['DATE-OBS'] + self.site_id=hdu[0].header['COSPAR'] + self.observer=hdu[0].header['OBSERVER'] + self.texp=hdu[0].header['EXPTIME'] + self.fname=fname + + # Astrometry keywords + self.crpix=np.array([hdu[0].header['CRPIX1'],hdu[0].header['CRPIX2']]) + self.crval=np.array([hdu[0].header['CRVAL1'],hdu[0].header['CRVAL2']]) + self.cd=np.array([[hdu[0].header['CD1_1'],hdu[0].header['CD1_2']], + [hdu[0].header['CD2_1'],hdu[0].header['CD2_2']]]) + self.ctype=[hdu[0].header['CTYPE1'],hdu[0].header['CTYPE2']] + self.cunit=[hdu[0].header['CUNIT1'],hdu[0].header['CUNIT2']] + self.crres=np.array([hdu[0].header['CRRES1'],hdu[0].header['CRRES2']]) + + self.sx=np.sqrt(self.cd[0,0]**2+self.cd[1,0]**2) + self.sy=np.sqrt(self.cd[0,1]**2+self.cd[1,1]**2) + self.wx=self.nx*self.sx + self.wy=self.ny*self.sy + self.vmin=np.mean(self.zmax)-2.0*np.std(self.zmax) + self.vmax=np.mean(self.zmax)+6.0*np.std(self.zmax) + + + def significant(self,sigma,x0,y0,dxdt,dydt,rmin=10.0): + """Extract significant points""" + + # Generate sigma frame + zsig=(self.zmax-self.zavg)/(self.zstd+1e-9) + + # Select + c=(zsig>sigma) + + # Positions + xm,ym=np.meshgrid(np.arange(self.nx),np.arange(self.ny)) + x,y=np.ravel(xm[c]),np.ravel(ym[c]) + inum=np.ravel(self.znum[c]).astype('int') + sig=np.ravel(zsig[c]) + t=np.array([self.dt[i] for i in inum]) + + # Predicted positions + xr=x0+dxdt*t + yr=y0+dydt*t + r=np.sqrt((x-xr)**2+(y-yr)**2) + c=r=0: + i1min,i1max=dx,self.nx-1 + i2min,i2max=0,self.nx-dx-1 + else: + i1min,i1max=0,self.nx+dx-1 + i2min,i2max=-dx,self.nx-1 + if dy>=0: + j1min,j1max=dy,self.ny-1 + j2min,j2max=0,self.ny-dy-1 + else: + j1min,j1max=0,self.ny+dy-1 + j2min,j2max=-dy,self.ny-1 + zsel=np.where(self.znum==i,self.zmax,0.0) + ztrk[j2min:j2max,i2min:i2max]+=zsel[j1min:j1max,i1min:i1max] + + return ztrk + + def __repr__(self): + return "%s %dx%dx%d %s %.3f %d %s"%(self.fname,self.nx,self.ny,self.nz,self.nfd,self.texp,self.site_id,self.observer) + + diff --git a/python/sun.py b/python/sun.py new file mode 100644 index 0000000..4468550 --- /dev/null +++ b/python/sun.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +from astropy.coordinates import SkyCoord,EarthLocation,AltAz,get_sun +from astropy.time import Time +import astropy.units as u +import numpy as np +import matplotlib.pyplot as plt +from scipy import optimize,interpolate + + + +loc=EarthLocation(lat=52.8344*u.deg,lon=6.3785*u.deg,height=10*u.m) +t0=Time.now() +refalt=-6.0 + +# Compute solar position every 10 minutes +t=Time(t0.mjd+np.arange(144)/144.0,format='mjd',scale='utc') +psun=get_sun(t) +hor=psun.transform_to(AltAz(obstime=t,location=loc)) + +# Interpolating function +alt_diff=hor.alt.deg-refalt +f=interpolate.interp1d(t.mjd,alt_diff) + +# Find sunrise/sunset +sign=alt_diff[1:]*alt_diff[:-1] +idx=np.where(sign<0.0)[0] +for i in idx: + # Set + if alt_diff[i]>alt_diff[i+1]: + tset=Time(optimize.bisect(f,t[i].mjd,t[i+1].mjd),format='mjd',scale='utc') + # Rise + else: + trise=Time(optimize.bisect(f,t[i].mjd,t[i+1].mjd),format='mjd',scale='utc') + diff --git a/python/vis.py b/python/vis.py new file mode 100644 index 0000000..5a05209 --- /dev/null +++ b/python/vis.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python +from skyfield.positionlib import ICRF +from skyfield.api import load,Topos + +ts=load.timescale() +t=ts.now() +observer=Topos(latitude_degrees=52.8344,longitude_degrees=6.3785,elevation_m=10.0) +p=ICRF([0.0,0.0,0.0],observer_data=observer,t=t) +q=p.from_altaz(alt_degrees=30.0,az_degrees=30.0) + +print(p,q)