1
0
Fork 0
sattools/src/detect.c

1145 lines
25 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "qfits.h"
#include <wcslib/cel.h>
#include <cpgplot.h>
#include <getopt.h>
#include <gsl/gsl_rng.h>
#define LIM 192
#define NMAX 256
#define D2R M_PI/180.0
#define R2D 180.0/M_PI
struct fourframe
{
char filename[64];
int naxis1, naxis2, naxis3, nframes;
float *zavg, *zstd, *zmax, *znum, *ztrk, *zsig;
int *mask;
double ra0, de0;
float x0, y0;
float a[3], b[3], xrms, yrms;
double mjd;
float *dt, exptime;
char nfd[32];
int cospar;
};
struct observation
{
int satno, cospar;
char desig[16], conditions, behavior, catalog[32], comment[LIM];
double mjd, ra, de;
float terr, perr, tmid;
char nfd[32], pos[32];
int epoch, type;
char iod_line[80];
float x[3], y[3], t[3], dxdt, dydt, drdt;
int state;
};
struct point
{
float x, y, t;
int flag;
};
struct fourframe read_fits (char *filename);
void forward (double ra0, double de0, double ra, double de, double *x,
double *y);
void reverse (double ra0, double de0, double x, double y, double *ra,
double *de);
// Linear least squares fit
float
linear_fit (float x[], float y[], float w[], int n, float a[], float sa[])
{
int i;
float sum, sumx, sumy, sumxx, sumxy;
float d, chi2, covar, r;
// Compute sums
sum = sumx = sumy = sumxx = sumxy = 0.;
for (i = 0; i < n; i++)
{
sum += w[i];
sumx += x[i] * w[i];
sumy += y[i] * w[i];
sumxx += x[i] * x[i] * w[i];
sumxy += x[i] * y[i] * w[i];
}
d = sum * sumxx - sumx * sumx;
// Parameters
a[0] = (sumxx * sumy - sumx * sumxy) / d;
a[1] = (sum * sumxy - sumx * sumy) / d;
// Uncertainties
sa[0] = sqrt (sumxx / d);
sa[1] = sqrt (sum / d);
// Chi squared
for (i = 0, chi2 = 0.0; i < n; i++)
chi2 += pow (y[i] - a[0] - a[1] * x[i], 2);
// Covariance
covar = -sumx / d;
// Correlation coefficient
r = -sumx / sqrt (sum * sumxx);
return chi2;
}
// Compute Julian Day from Date
double
date2mjd (int year, int month, double day)
{
int a, b;
double jd;
if (month < 3)
{
year--;
month += 12;
}
a = floor (year / 100.);
b = 2. - a + floor (a / 4.);
if (year < 1582)
b = 0;
if (year == 1582 && month < 10)
b = 0;
if (year == 1582 && month == 10 && day <= 4)
b = 0;
jd =
floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b -
1524.5;
return jd - 2400000.5;
}
// nfd2mjd
double
nfd2mjd (char *date)
{
int year, month, day, hour, min;
double mjd, dday;
float sec;
sscanf (date, "'%04d-%02d-%02dT%02d:%02d:%f'", &year, &month, &day, &hour,
&min, &sec);
dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0;
mjd = date2mjd (year, month, dday);
return mjd;
}
// Compute Date from Julian Day
void
mjd2date (double mjd, char *date)
{
double f, jd, dday;
int z, alpha, a, b, c, d, e;
double year, month, day, hour, min;
double sec, x, fsec;
jd = mjd + 2400000.5;
jd += 0.5;
z = floor (jd);
f = fmod (jd, 1.);
if (z < 2299161)
a = z;
else
{
alpha = floor ((z - 1867216.25) / 36524.25);
a = z + 1 + alpha - floor (alpha / 4.);
}
b = a + 1524;
c = floor ((b - 122.1) / 365.25);
d = floor (365.25 * c);
e = floor ((b - d) / 30.6001);
dday = b - d - floor (30.6001 * e) + f;
if (e < 14)
month = e - 1;
else
month = e - 13;
if (month > 2)
year = c - 4716;
else
year = c - 4715;
day = (int) floor (dday);
x = 24.0 * (dday - day);
x = 3600. * fabs (x);
sec = fmod (x, 60.);
x = (x - sec) / 60.;
min = fmod (x, 60.);
x = (x - min) / 60.;
hour = x;
fsec = 1000.0 * (sec - floor (sec));
sprintf (date, "%04d%02d%02d%02d%02d%02.0f%03.0f", (int) year, (int) month,
(int) day, (int) hour, (int) min, floor (sec), fsec);
return;
}
// MJD to DOY
double
mjd2doy (double mjd, int *yr)
{
int year, month, k = 2;
int day;
double doy;
char nfd[32];
mjd2date (mjd, nfd);
sscanf (nfd, "%04d", &year);
sscanf (nfd + 4, "%02d", &month);
sscanf (nfd + 6, "%02d", &day);
if (year % 4 == 0 && year % 400 != 0)
k = 1;
doy =
floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30;
*yr = year;
return doy;
}
// Convert Decimal into Sexagesimal
void
dec2s (double x, char *s, int type)
{
int i;
double sec, deg, min, fmin;
char sign;
sign = (x < 0 ? '-' : '+');
x = 60. * fabs (x);
min = fmod (x, 60.);
x = (x - min) / 60.;
// deg=fmod(x,60.);
deg = x;
if (type == 0)
fmin = 1000.0 * (min - floor (min));
else
fmin = 100.0 * (min - floor (min));
if (type == 0)
sprintf (s, "%02.0f%02.0f%03.0f", deg, floor (min), fmin);
else
sprintf (s, "%c%02.0f%02.0f%02.0f", sign, deg, floor (min), fmin);
return;
}
// Reduce point
void
reduce_point (struct observation *obs, struct fourframe img, float tmid,
float x, float y)
{
int iframe, k;
double ra, de, rx, ry;
float dx, dy, dt;
double mjd;
char nfd[32], sra[15], sde[15];
// Transform position
dx = x - img.x0;
dy = y - img.y0;
rx = img.a[0] + img.a[1] * dx + img.a[2] * dy;
ry = img.b[0] + img.b[1] * dx + img.b[2] * dy;
reverse (img.ra0, img.de0, rx, ry, &ra, &de);
dec2s (ra / 15.0, sra, 0);
dec2s (de, sde, 1);
// Get time
k = (int) x + img.naxis1 * (int) y;
iframe = (int) img.znum[k];
if (tmid < 0.0)
dt = img.dt[iframe];
else
dt = tmid;
mjd = nfd2mjd (img.nfd) + (double) dt / 86400.0;
mjd2date (mjd, nfd);
// Copy
strcpy (obs->nfd, nfd);
sprintf (obs->pos, "%s%s", sra, sde);
return;
}
void
fit (struct observation *obs, struct fourframe ff, struct point *p, int np,
int flag)
{
int i, j, k, l, n, m;
float *t, *dt, *x, *y, *w;
float tmin, tmax, tmid;
float chi2x, chi2y, ax[2], sax[2], ay[2], say[2];
float dx, dy, dr, rmsx, rmsy;
// Count number of points
for (i = 0, n = 0; i < np; i++)
if (p[i].flag == flag)
n++;
// Allocate
t = (float *) malloc (sizeof (float) * n);
dt = (float *) malloc (sizeof (float) * n);
x = (float *) malloc (sizeof (float) * n);
y = (float *) malloc (sizeof (float) * n);
w = (float *) malloc (sizeof (float) * n);
// Fill
for (i = 0, l = 0; i < np; i++)
{
if (p[i].flag == flag)
{
x[l] = p[i].x;
y[l] = p[i].y;
w[l] = 1.0;
t[l] = p[i].t;
l++;
}
}
// Find limits in time
for (i = 0; i < n; i++)
{
if (i == 0)
{
tmin = t[i];
tmax = t[i];
}
else
{
if (t[i] < tmin)
tmin = t[i];
if (t[i] > tmax)
tmax = t[i];
}
}
tmid = 0.5 * (tmin + tmax);
// Shift in time
for (i = 0; i < n; i++)
dt[i] = t[i] - tmid;
// Fit x-pixel position
chi2x = linear_fit (dt, x, w, n, ax, sax);
// Fit x-pixel position
chi2y = linear_fit (dt, y, w, n, ay, say);
// Compute rms
for (i = 0, rmsx = 0.0, rmsy = 0.0; i < n; i++)
{
rmsx += pow (x[i] - (ax[0] + ax[1] * dt[i]), 2);
rmsy += pow (y[i] - (ay[0] + ay[1] * dt[i]), 2);
}
rmsx = sqrt (rmsx / (float) (n - 1));
rmsy = sqrt (rmsy / (float) (n - 1));
obs->x[0] = ax[0];
obs->y[0] = ay[0];
obs->t[0] = tmid;
obs->x[1] = ax[0] + ax[1] * (tmin - tmid);
obs->y[1] = ay[0] + ay[1] * (tmin - tmid);
obs->t[1] = tmin;
obs->x[2] = ax[0] + ax[1] * (tmax - tmid);
obs->y[2] = ay[0] + ay[1] * (tmax - tmid);
obs->t[2] = tmax;
obs->state = 1;
obs->dxdt = (obs->x[2] - obs->x[1]) / (obs->t[2] - obs->t[1]);
obs->dydt = (obs->y[2] - obs->y[1]) / (obs->t[2] - obs->t[1]);
obs->drdt = sqrt (obs->dxdt * obs->dxdt + obs->dydt * obs->dydt);
// Reduce point
reduce_point (obs, ff, tmid, ax[0], ay[0]);
// Free
free (t);
free (dt);
free (x);
free (y);
return;
}
void
format_iod_line (struct observation *obs)
{
int mt, xt, mp, xp;
char string[10];
// Time format
sprintf (string, "%7.1e", obs->terr);
mt = string[0] - '0';
xt = atoi (string + 4) + 8;
// Position format
if (obs->type == 2)
{
sprintf (string, "%7.1e", obs->perr);
mp = string[0] - '0';
xp = atoi (string + 4) + 8;
}
else
{
printf ("Position format not implemented!\n");
}
sprintf (obs->iod_line,
"%05d %c%c %-6s %04d %c %-17s %d%d %d%d %-14s %d%d %c", obs->satno,
obs->desig[0], obs->desig[1], obs->desig + 2, obs->cospar,
obs->conditions, obs->nfd, mt, xt, obs->type, obs->epoch, obs->pos,
mp, xp, obs->behavior);
return;
}
// Read a line of maximum length int lim from file FILE into string s
int
fgetline (FILE * file, char *s, int lim)
{
int c, i = 0;
while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n')
s[i++] = c;
if (c == '\t')
c = ' ';
if (c == '\n')
s[i++] = c;
s[i] = '\0';
return i;
}
void
find_designation (int satno0, char *desig0)
{
FILE *file;
int satno;
char desig[16];
char *env, filename[128];
// Environment variables
env = getenv ("ST_DATADIR");
sprintf (filename, "%s/data/desig.txt", env);
file = fopen (filename, "r");
if (file == NULL)
{
fprintf (stderr, "Designation file not found!\n");
exit (0);
}
while (!feof (file))
{
fscanf (file, "%d %s", &satno, desig);
if (satno == satno0)
{
strcpy (desig0, desig);
break;
}
}
fclose (file);
return;
}
void
identify_observation (struct observation *obs, char *fileroot, float drmin,
float amin)
{
FILE *file;
float x0, y0, x1, y1, x, y, texp;
double mjd;
int satno, flag = 0, i;
char nfd[32], filename[LIM], line[LIM], catalog[LIM];
float dx, dy, dr, dxdt, dydt, drdt, angle, dp;
// Open ID file
sprintf (filename, "%s.id", fileroot);
file = fopen (filename, "r");
if (file == NULL)
{
fprintf (stderr, "ID file %s not found\n", filename);
return;
}
while (fgetline (file, line, LIM) > 0)
{
sscanf (line, "%s %f %f %f %f %f %d %s", nfd, &x0, &y0, &x1, &y1, &texp,
&satno, catalog);
// Predicted pixel rates
dxdt = (x1 - x0) / texp;
dydt = (y1 - y0) / texp;
drdt = sqrt (dxdt * dxdt + dydt * dydt);
x = x0 + dxdt * obs->t[0];
y = y0 + dydt * obs->t[0];
// Compare
dx = x - obs->x[0];
dy = y - obs->y[0];
dr = sqrt (dx * dx + dy * dy);
dp = (dxdt * obs->dxdt + dydt * obs->dydt) / (obs->drdt * drdt);
if (dp <= 1.0)
angle = acos (dp) * R2D;
else
angle = 0.0;
// Identify
if (dr < drmin && angle < amin)
{
obs->satno = satno;
if (strstr (catalog, "classfd.tle") != NULL)
strcpy (obs->catalog, "classfd");
if (strstr (catalog, "inttles.tle") != NULL)
strcpy (obs->catalog, "classfd");
else if (strstr (catalog, "catalog.tle") != NULL)
strcpy (obs->catalog, "catalog");
}
}
fclose (file);
return;
}
void
write_observation (struct observation obs)
{
FILE *file;
char filename[LIM];
sprintf (filename, "%s.dat", obs.catalog);
file = fopen (filename, "a");
fprintf (file, "%s\n%s\n", obs.comment, obs.iod_line);
fclose (file);
return;
}
void
overlay_predictions (char *fitsfile, struct fourframe ff)
{
float x0, y0, x1, y1, texp;
int satno, isch;
char filename[LIM], line[LIM], nfd[32], catalog[LIM], text[8];
FILE *file;
float t, x, y;
cpgqci (&isch);
sprintf (filename, "%s.id", fitsfile);
// Open ID file
file = fopen (filename, "r");
if (file == NULL)
{
fprintf (stderr, "ID file %s not found\n", filename);
return;
}
while (fgetline (file, line, LIM) > 0)
{
sscanf (line, "%s %f %f %f %f %f %d %s", nfd, &x0, &y0, &x1, &y1, &texp,
&satno, catalog);
if (strstr (catalog, "classfd") != NULL)
cpgsci (4);
else if (strstr (catalog, "catalog") != NULL)
cpgsci (0);
else if (strstr (catalog, "inttles") != NULL)
cpgsci (3);
else if (strstr (catalog, "jsc") != NULL)
cpgsci (5);
cpgpt1 (x0, y0, 17);
cpgmove (x0, y0);
cpgdraw (x1, y1);
// plot text
cpgsch (0.65);
sprintf (text, " %05d", satno);
for (t = 0.0; t < 1.0; t += 0.1)
{
x = x0 + (x1 - x0) * t;
y = y0 + (y1 - y0) * t;
if (x > 0.0 && y > 0.0 && x < ff.naxis1 && y < ff.naxis2)
{
cpgtext (x, y, text);
break;
}
}
cpgsch (1.0);
cpgsci (isch);
}
fclose (file);
return;
}
void
accumulate (float *z, int nx, int ny, int nz, int *mask, int bx, int by,
int bz, int nsel, int *zsel)
{
int ix, iy, iz;
int jx, jy, jz, k;
int mx, my, mz;
int *c, npoints = 0;
// New dimensions
mx = nx / bx;
my = ny / by;
mz = nz / bz;
// Allocate and zero
c = (int *) malloc (sizeof (int) * mx * my * mz);
for (ix = 0; ix < mx * my * mz; ix++)
c[ix] = 0;
// Accumulate
for (ix = 0; ix < nx; ix++)
{
for (iy = 0; iy < ny; iy++)
{
iz = (int) z[ix + nx * iy];
jx = ix / bx;
jy = iy / by;
jz = iz / bz;
k = jx + mx * (jy + my * jz);
if (mask[ix + nx * iy] == 1)
c[k]++;
}
}
// Apply mask
for (ix = 0; ix < nx; ix++)
{
for (iy = 0; iy < ny; iy++)
{
iz = (int) z[ix + nx * iy];
jx = ix / bx;
jy = iy / by;
jz = iz / bz;
k = jx + mx * (jy + my * jz);
if (c[k] > nsel)
zsel[ix + nx * iy]++;
}
}
free (c);
return;
}
// RANSAC line finding
void
ransac (struct point *p, int np, float drmin)
{
int i = 0, j, k, l, m, n, mmax;
const gsl_rng_type *T;
gsl_rng *r;
int i0, i1, i0max, i1max;
float ax, bx, ay, by;
float dx, dy, dr;
// Set up randomizer
gsl_rng_env_setup ();
T = gsl_rng_default;
r = gsl_rng_alloc (T);
// Loop over number of lines
for (i = 1; i <= 4; i++)
{
// Number of iterations
for (l = 0, mmax = 0; l < 10000; l++)
{
// Get random end points
for (;;)
{
i0 = (int) (np * gsl_rng_uniform (r));
if (p[i0].flag == 0)
break;
}
for (;;)
{
i1 = (int) (np * gsl_rng_uniform (r));
if (p[i1].flag == 0)
break;
}
// Linear model
ax = (p[i1].x - p[i0].x) / (p[i1].t - p[i0].t);
bx = p[i0].x - ax * p[i0].t;
ay = (p[i1].y - p[i0].y) / (p[i1].t - p[i0].t);
by = p[i0].y - ay * p[i0].t;
// Find matches
for (k = 0, m = 0; k < np; k++)
{
dx = bx + ax * p[k].t - p[k].x;
dy = by + ay * p[k].t - p[k].y;
dr = sqrt (dx * dx + dy * dy);
if (dr < drmin && p[k].flag == 0)
m++;
}
// Store
if (m > mmax)
{
mmax = m;
i0max = i0;
i1max = i1;
}
}
// Linear model
ax = (p[i1max].x - p[i0max].x) / (p[i1max].t - p[i0max].t);
bx = p[i0max].x - ax * p[i0max].t;
ay = (p[i1max].y - p[i0max].y) / (p[i1max].t - p[i0max].t);
by = p[i0max].y - ay * p[i0max].t;
// Find matches
for (k = 0; k < np; k++)
{
dx = bx + ax * p[k].t - p[k].x;
dy = by + ay * p[k].t - p[k].y;
dr = sqrt (dx * dx + dy * dy);
if (dr < drmin && p[k].flag == 0)
p[k].flag = i;
}
// Available points
for (k = 0, m = 0; k < np; k++)
if (p[k].flag == 0)
m++;
if (m == 0)
break;
}
return;
}
int
main (int argc, char *argv[])
{
int i, j, k, l, m, n, flag = 0, np, nline;
struct fourframe ff;
char *env, *fitsfile;
float tr[] = { -0.5, 1.0, 0.0, -0.5, 0.0, 1.0 };
float heat_l[] = { 0.0, 0.2, 0.4, 0.6, 1.0 };
float heat_r[] = { 0.0, 0.5, 1.0, 1.0, 1.0 };
float heat_g[] = { 0.0, 0.0, 0.5, 1.0, 1.0 };
float heat_b[] = { 0.0, 0.0, 0.0, 0.3, 1.0 };
char filename[LIM], text[128], catalog[128];
float sigma = 5.0;
struct point *p;
struct observation obs;
int arg = 0, satno, plot = 0;
FILE *file;
float zmin, zmax;
int *zsel;
float theta, r;
float drmin = 10, rmin = 20, amin = 5.0;
int mmin = 100;
double mjd, doy;
int year;
// Decode options
if (argc > 1)
{
while ((arg = getopt (argc, argv, "f:s:R:r:a:pn:")) != -1)
{
switch (arg)
{
case 'f':
fitsfile = optarg;
break;
case 'p':
plot = 1;
break;
case 's':
sigma = atof (optarg);
break;
case 'R':
drmin = atof (optarg);
break;
case 'r':
rmin = atof (optarg);
break;
case 'n':
mmin = atoi (optarg);
break;
default:
return 0;
break;
}
}
}
else
{
return 0;
}
printf ("# Processing %s\n", fitsfile);
// Read
ff = read_fits (fitsfile);
// Fill mask
if (ff.naxis1 == 720 && ff.naxis2 == 576)
{
for (i = 0; i < ff.naxis1; i++)
{
for (j = 0; j < ff.naxis2; j++)
{
k = i + ff.naxis1 * j;
if (i < 10 || i > ff.naxis1 - 12 || j > ff.naxis2 - 1 || j < 1)
ff.mask[k] = 0;
}
}
}
// Allocate accumulation array
zsel = (int *) malloc (sizeof (int) * ff.naxis1 * ff.naxis2);
for (i = 0; i < ff.naxis1 * ff.naxis2; i++)
zsel[i] = 0;
// Accumulate
if (ff.nframes == 250)
{
// accumulate(ff.znum,ff.naxis1,ff.naxis2,ff.nframes,ff.mask,2,2,10,2,zsel);
accumulate (ff.znum, ff.naxis1, ff.naxis2, ff.nframes, ff.mask, 4, 4,
10, 8, zsel);
}
else if (ff.nframes == 256)
{
// accumulate(ff.znum,ff.naxis1,ff.naxis2,ff.nframes,ff.mask,2,2,8,2,zsel);
accumulate (ff.znum, ff.naxis1, ff.naxis2, ff.nframes, ff.mask, 4, 4,
16, 6, zsel);
}
// Apply mask
for (i = 0; i < ff.naxis1 * ff.naxis2; i++)
if (zsel[i] == 0)
ff.zmax[i] = 0.0;
// Plot
if (plot == 1)
{
cpgopen ("/xs");
cpgpap (0., 1.0);
cpgsvp (0.1, 0.95, 0.1, 0.8);
cpgsch (0.8);
sprintf (text, "UT Date: %.23s COSPAR ID: %04d", ff.nfd + 1,
ff.cospar);
cpgmtxt ("T", 6.0, 0.0, 0.0, text);
sprintf (text, "R.A.: %10.5f (%4.1f'') Decl.: %10.5f (%4.1f'')", ff.ra0,
ff.xrms, ff.de0, ff.yrms);
cpgmtxt ("T", 4.8, 0.0, 0.0, text);
sprintf (text,
"FoV: %.2f\\(2218)x%.2f\\(2218) Scale: %.2f''x%.2f'' pix\\u-1\\d",
ff.naxis1 * sqrt (ff.a[1] * ff.a[1] +
ff.b[1] * ff.b[1]) / 3600.0,
ff.naxis2 * sqrt (ff.a[2] * ff.a[2] +
ff.b[2] * ff.b[2]) / 3600.0,
sqrt (ff.a[1] * ff.a[1] + ff.b[1] * ff.b[1]),
sqrt (ff.a[2] * ff.a[2] + ff.b[2] * ff.b[2]));
cpgmtxt ("T", 3.6, 0.0, 0.0, text);
cpgsch (1.0);
cpgctab (heat_l, heat_r, heat_g, heat_b, 5, 1.0, 0.5);
cpgwnad (0.0, (float) ff.naxis1, 0.0, (float) ff.naxis2);
zmin = 0.0;
zmax = 100.0;
cpgimag (ff.zmax, ff.naxis1, ff.naxis2, 1, ff.naxis1, 1, ff.naxis2,
zmin, zmax, tr);
cpgbox ("BCTSNI", 0., 0, "BCTSNI", 0., 0);
cpgstbg (1);
overlay_predictions (fitsfile, ff);
}
// Count
for (i = 0, np = 0; i < ff.naxis1 * ff.naxis2; i++)
if (zsel[i] > 0)
np++;
// Skip if no points
if (np == 0)
return 0;
// Skip if too many points
if (np > 0.1 * ff.naxis1 * ff.naxis2)
return 0;
// Allocate points
p = (struct point *) malloc (sizeof (struct point) * np);
// Fill
for (i = 0, l = 0; i < ff.naxis1; i++)
{
for (j = 0; j < ff.naxis2; j++)
{
k = i + ff.naxis1 * j;
if (zsel[k] > 0)
{
p[l].x = (float) i;
p[l].y = (float) j;
p[l].t = ff.dt[(int) ff.znum[k]];
p[l].flag = 0;
l++;
}
}
}
// Random Sample Consensus line finding
ransac (p, np, drmin);
// Fit lines
for (l = 1; l <= 4; l++)
{
// Default observation
env = getenv ("ST_COSPAR");
obs.satno = 99999;
strcpy (obs.catalog, "unidentified");
strcpy (obs.desig, "99999U");
obs.cospar = atoi (env);
obs.conditions = 'G';
strcpy (obs.nfd, "YYYYMMDDHHMMSSsss");
obs.terr = 0.1;
strcpy (obs.pos, "HHMMmmm+DDMMmm");
strcpy (obs.iod_line, "");
obs.perr = 0.3;
obs.epoch = 5;
obs.type = 2;
obs.behavior = ' ';
obs.state = 0;
// Count points
for (i = 0, m = 0; i < np; i++)
if (p[i].flag == l)
m++;
if (m == 0)
continue;
if (m <= mmin)
continue;
// Fit observation
fit (&obs, ff, p, np, l);
// Identify observation
identify_observation (&obs, fitsfile, rmin, amin);
// Find designation
if (obs.satno != 99999)
{
find_designation (obs.satno, obs.desig);
}
else
{
mjd = nfd2mjd (ff.nfd);
doy = mjd2doy (mjd, &year);
sprintf (obs.desig, "%02d%03.0lfA", year - 2000, doy + 500);
}
// Format observation
format_iod_line (&obs);
// Open file
if (flag == 0)
{
sprintf (filename, "%s.det", fitsfile);
file = fopen (filename, "w");
flag = 1;
}
// Comment
fprintf (file, "# %s : line %d, %d points\n", fitsfile, l, m);
fprintf (file,
"# %7.2f %7.2f %5.2f %7.2f %7.2f %5.2f %7.2f %7.2f %5.2f\n",
obs.x[0], obs.y[0], obs.t[0], obs.x[1], obs.y[1], obs.t[1],
obs.x[2], obs.y[2], obs.t[2]);
fprintf (file, "# %s\n", obs.catalog);
fprintf (file, "%s\n", obs.iod_line);
printf ("# %s : line %d, %d points\n", fitsfile, l, m);
printf ("%s\n", obs.iod_line);
// Plot observation
if (plot == 1)
{
cpgsci (5);
sprintf (text, " %d: %05d", l, obs.satno);
cpgsch (0.65);
cpgtext (obs.x[0], obs.y[0], text);
cpgsch (1.0);
cpgpt1 (obs.x[0], obs.y[0], 4);
cpgmove (obs.x[1], obs.y[1]);
cpgdraw (obs.x[2], obs.y[2]);
cpgsci (1);
}
}
if (plot == 1)
cpgend ();
// Close file
if (flag == 1)
fclose (file);
// Free
free (ff.zavg);
free (ff.zstd);
free (ff.zmax);
free (ff.znum);
free (ff.zsig);
free (ff.dt);
free (ff.mask);
free (zsel);
free (p);
return 0;
}
// Read fits fourframe
struct fourframe
read_fits (char *filename)
{
int i, j, k, l, m;
qfitsloader ql;
char key[FITS_LINESZ + 1];
char val[FITS_LINESZ + 1];
struct fourframe img;
// Copy filename
strcpy (img.filename, filename);
// Image size
img.naxis1 = atoi (qfits_query_hdr (filename, "NAXIS1"));
img.naxis2 = atoi (qfits_query_hdr (filename, "NAXIS2"));
img.naxis3 = atoi (qfits_query_hdr (filename, "NAXIS3"));
// MJD
img.mjd = (double) atof (qfits_query_hdr (filename, "MJD-OBS"));
strcpy (img.nfd, qfits_query_hdr (filename, "DATE-OBS"));
// COSPAR ID
img.cospar = atoi (qfits_query_hdr (filename, "COSPAR"));
// Transformation
img.mjd = atof (qfits_query_hdr (filename, "MJD-OBS"));
img.ra0 = atof (qfits_query_hdr (filename, "CRVAL1"));
img.de0 = atof (qfits_query_hdr (filename, "CRVAL2"));
img.x0 = atof (qfits_query_hdr (filename, "CRPIX1"));
img.y0 = atof (qfits_query_hdr (filename, "CRPIX2"));
img.a[0] = 0.0;
img.a[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_1"));
img.a[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_2"));
img.b[0] = 0.0;
img.b[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_1"));
img.b[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_2"));
img.xrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES1"));
img.yrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES2"));
img.exptime = atof (qfits_query_hdr (filename, "EXPTIME"));
img.nframes = atoi (qfits_query_hdr (filename, "NFRAMES"));
// Timestamps
img.dt = (float *) malloc (sizeof (float) * img.nframes);
for (i = 0; i < img.nframes; i++)
{
sprintf (key, "DT%04d", i);
img.dt[i] = atof (qfits_query_hdr (filename, key));
}
// Allocate image memory
img.zavg = (float *) malloc (sizeof (float) * img.naxis1 * img.naxis2);
img.zstd = (float *) malloc (sizeof (float) * img.naxis1 * img.naxis2);
img.zmax = (float *) malloc (sizeof (float) * img.naxis1 * img.naxis2);
img.znum = (float *) malloc (sizeof (float) * img.naxis1 * img.naxis2);
img.zsig = (float *) malloc (sizeof (float) * img.naxis1 * img.naxis2);
if (img.naxis3 == 5)
img.ztrk = (float *) malloc (sizeof (float) * img.naxis1 * img.naxis2);
img.mask = (int *) malloc (sizeof (int) * img.naxis1 * img.naxis2);
// Set mask
for (i = 0; i < img.naxis1 * img.naxis2; i++)
img.mask[i] = 1;
// Set parameters
ql.xtnum = 0;
ql.ptype = PTYPE_FLOAT;
ql.filename = filename;
// Loop over planes
for (k = 0; k < img.naxis3; k++)
{
ql.pnum = k;
// Initialize load
if (qfitsloader_init (&ql) != 0)
printf ("Error initializing data loading\n");
// Test load
if (qfits_loadpix (&ql) != 0)
printf ("Error loading actual data\n");
// Fill z array
for (i = 0, l = 0; i < img.naxis1; i++)
{
for (j = 0; j < img.naxis2; j++)
{
if (k == 1)
img.zstd[l] = ql.fbuf[l];
if (k == 2)
img.zmax[l] = ql.fbuf[l];
if (k == 3)
img.znum[l] = ql.fbuf[l];
if (img.naxis3 == 5)
{
if (k == 0)
img.ztrk[l] = ql.fbuf[l];
if (k == 4)
img.zavg[l] = ql.fbuf[l];
}
else
{
if (k == 0)
img.zavg[l] = ql.fbuf[l];
}
l++;
}
}
}
for (i = 0; i < img.naxis1 * img.naxis2; i++)
img.zsig[i] = (img.zmax[i] - img.zavg[i]) / img.zstd[i];
return img;
}