00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <math.h>
00040 #include "astro.h"
00041
00042 static void Cckerly(double *u, double s);
00043 static double Ccintdly(double *f, int nx, int ny, double x, double y);
00044 static double Linintdly(double *f, int nx, int ny, double x, double y);
00045
00046
00047 void Cckerly(double *u, double s)
00048 {
00049 double s2, s3;
00050
00051 s2= s * s;
00052 s3= s2 * s;
00053 u[0] = s2 - 0.5 * (s3 + s);
00054 u[1] = 1.5*s3 - 2.5*s2 + 1.0;
00055 u[2] = -1.5*s3 + 2.0*s2 + 0.5*s;
00056 u[3] = 0.5 * (s3 - s2);
00057 }
00058
00059
00060 double Ccintdly(double *f, int nx, int ny, double x, double y)
00061 {
00062 double ux[4], uy[4];
00063
00064 double sum;
00065
00066 int ix, iy, ix1, iy1, i, j;
00067
00068 if (x < 1. || x >= (double)(nx-2) ||
00069 y < 1. || y >= (double)(ny-2))
00070 return 0.0;
00071
00072 ix = (int)x;
00073 iy = (int)y;
00074 Cckerly(ux, x - (double)ix);
00075 Cckerly(uy, y - (double)iy);
00076
00077 ix1 = ix - 1;
00078 iy1 = iy - 1;
00079 sum = 0.;
00080 for (i = 0; i < 4; i++)
00081 for (j = 0; j < 4; j++)
00082 sum = sum + f[(iy1+i) * nx + ix1 + j] * uy[i] * ux[j];
00083 return sum;
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 double Linintdly(double *f, int nx, int ny, double x, double y)
00101 {
00102 double p0, p1, q0, q1;
00103 int ilow, jlow;
00104 double *fptr;
00105 double u;
00106
00107 ilow = (int)floor(x);
00108 jlow = (int)floor(y);
00109 if (ilow < 0) ilow = 0;
00110 if (ilow+1 >= nx) ilow -= 1;
00111 if (jlow < 0) jlow = 0;
00112 if (jlow+1 >= ny) jlow -= 1;
00113 p1 = x - ilow;
00114 p0 = 1.0 - p1;
00115 q1 = y - jlow;
00116 q0 = 1.0 - q1;
00117
00118
00119 u = 0.0;
00120 fptr = f + jlow*nx + ilow;
00121 u += p0 * q0 * *fptr++;
00122 u += p1 * q0 * *fptr;
00123 fptr += nx - 1;
00124 u += p0 * q1 * *fptr++;
00125 u += p1 * q1 * *fptr;
00126 return u;
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 int Obs2heliodb(
00151 float *V,
00152
00153 float *U,
00154
00155 int xpixels,
00156 int ypixels,
00157 double x0,
00158 double y0,
00159 double BZero,
00160 double P,
00161
00162 double S,
00163 double rsun,
00164 double Rmax,
00165
00166 int interpolation,
00167 int cols,
00168 int rows,
00169 double Lmin,
00170 double Ldelta,
00171 double Ladjust,
00172 double sinBdelta,
00173
00174 double smajor,
00175 double sminor,
00176 double sangle,
00177 double xscale,
00178 double yscale,
00179 const char *orientation,
00180
00181 int mag_correction,
00182 int velocity_correction,
00183 double obs_vr,
00184 double obs_vw,
00185 double obs_vn,
00186 double vsign,
00187 int NaN_beyond_rmax,
00188 int carrStretch,
00189 const LIBASTRO_Dist_t *distpars,
00190 float diffrotA,
00191 float diffrotB,
00192 float diffrotC,
00193 LIBASTRO_RotRate_t *rRates,
00194 int size)
00195 {
00196
00197 double xtmp, ytmp;
00198 float u;
00199
00200
00201 double sinBbase;
00202 double sinB0, cosB0;
00203 double sinB, cosB;
00204 double sinL, cosL;
00205 double sinP, cosP;
00206 double cosrho;
00207 double sinp_sinrho;
00208 double cosp_sinrho;
00209 double rp;
00210 double x, y;
00211 double Rmax2;
00212
00213
00214 double sinS, cosS, sinS2, cosS2, sinScosS;
00215 double stretch_xx, stretch_xy, stretch_yx, stretch_yy;
00216
00217
00218 int orient_xx, orient_xy, orient_yx, orient_yy;
00219 int swap, ewflip, nsflip;
00220
00221
00222 double combo_xx, combo_xy, combo_yx, combo_yy;
00223
00224
00225 int row, col;
00226 double L;
00227
00228
00229
00230 double mu;
00231 double v_rotation;
00232 double v_limbshift;
00233
00234
00235 const double v_lat = 0.0;
00236 const double v_equator = 1974.1;
00237 const double rotation_coef_a2 = -0.121;
00238 const double rotation_coef_a4 = -0.178;
00239 const double limbshift_coef_a0 = -166.;
00240 const double limbshift_coef_a1 = -139.;
00241 const double limbshift_coef_a2 = 700.;
00242
00243 const int kMaxCols = 6072;
00244 const double kOmegaCarr = (360 / 27.27527);
00245 const double kRadsPerDegree = M_PI/180.;
00246
00247
00248 double savedDeltaL[kMaxCols];
00249 double savedsinL[kMaxCols];
00250 double savedcosL[kMaxCols];
00251 double cB0sB, cB0cB, sB0sB, sB0cB;
00252 double sinB2;
00253 int rowoffset;
00254 double omegaLat;
00255 double deltaLAdj;
00256
00257
00258 long i;
00259 double *vdp;
00260 float *vp;
00261
00262 double *VD;
00263 VD=(double *)(malloc(xpixels*ypixels*sizeof(double)));
00264 vdp=VD;
00265 vp=V;
00266
00267
00268
00269
00270 for (i=0;i<xpixels*ypixels;i++) *vdp++=(double)*vp++;
00271
00272 if (cols > kMaxCols)
00273 {
00274 return kLIBASTRO_DimensionMismatch;
00275 }
00276
00277 if (rows%2) return kLIBASTRO_CantDoOddNumLats;
00278
00279 if (interpolation != kLIBASTRO_InterCubic && interpolation != kLIBASTRO_InterBilinear)
00280 {
00281 return kLIBASTRO_UnsupportedInterp;
00282 }
00283
00284 if ((mag_correction < kLIBASTRO_MCORLevel0) || (mag_correction > kLIBASTRO_MCORLevel1))
00285 return kLIBASTRO_UnsupportedMCOR;
00286
00287 if ((velocity_correction < kLIBASTRO_VCORSignOnly) || (velocity_correction > kLIBASTRO_VCORLevel2))
00288 return kLIBASTRO_UnsupportedVCOR;
00289
00290
00291
00292 sinBbase = 0.5-rows/2;
00293 sinS = sin(sangle); cosS = cos(sangle);
00294 sinS2 = sinS*sinS; cosS2 = cosS*cosS; sinScosS = sinS*cosS;
00295 stretch_xx = smajor*cosS2 + sminor*sinS2;
00296 stretch_xy = stretch_yx = (smajor - sminor)*sinScosS;
00297 stretch_yy = smajor*sinS2 + sminor*cosS2;
00298
00299 swap = (orientation[0]!=orientation[2]);
00300 ewflip = (orientation[1]=='W'); nsflip = (orientation[0]=='N');
00301 orient_xx = orient_yy = !swap; orient_xy = orient_yx = swap;
00302 if(ewflip) {orient_xx=-orient_xx; orient_yx=-orient_yx;}
00303 if(nsflip) {orient_xy=-orient_xy; orient_yy=-orient_yy;}
00304
00305 combo_xx = rsun*(orient_xx*stretch_xx+orient_xy*stretch_yx)/xscale;
00306 combo_xy = rsun*(orient_xx*stretch_xy+orient_xy*stretch_yy)/xscale;
00307 combo_yx = rsun*(orient_yx*stretch_xx+orient_yy*stretch_yx)/yscale;
00308 combo_yy = rsun*(orient_yx*stretch_xy+orient_yy*stretch_yy)/yscale;
00309
00310 sinB0 = sin(BZero);
00311 cosB0 = sqrt(1.0 - sinB0*sinB0);
00312 sinP = sin(P);
00313 cosP = cos(P);
00314 Rmax2 = Rmax * Rmax;
00315
00316 for (col = 0; col < cols; col++) {
00317 savedDeltaL[col] = (L = Ldelta*col + Lmin - Ladjust);
00318 savedsinL[col] = (sinL = sin(L));
00319 savedcosL[col] = sqrt(1.0 - sinL*sinL);
00320 }
00321
00322
00323
00324 for (row = 0; row < rows; row++) {
00325 rowoffset = row*cols;
00326 sinB = sinBdelta*(sinBbase + row);
00327 sinB2 = sinB*sinB;
00328 cosB = sqrt(1.0 - sinB2);
00329 sB0sB = sinB0*sinB;
00330 sB0cB = sinB0*cosB;
00331 cB0sB = cosB0*sinB;
00332 cB0cB = cosB0*cosB;
00333 omegaLat = diffrotA + diffrotB * sinB2 + diffrotC * sinB2 * sinB2;
00334
00335
00336 if (rRates && row < size)
00337 {
00338 rRates[row].lat = asin(sinB);
00339 rRates[row].r = 14.562 + (diffrotB * sinB2) + (diffrotC * sinB2 * sinB2);
00340 }
00341
00342 v_rotation = v_equator*(1.0+sinB2*(rotation_coef_a2+sinB2*rotation_coef_a4));
00343
00344 for (col = 0; col < cols; col++) {
00345
00346 if (carrStretch == 0)
00347 {
00348 sinL = savedsinL[col];
00349 cosL = savedcosL[col];
00350 }
00351 else
00352 {
00353
00354
00355
00356
00357
00358
00359 deltaLAdj = savedDeltaL[col] * omegaLat / kOmegaCarr;
00360 sinL = sin(deltaLAdj);
00361 cosL = cos(deltaLAdj);
00362 }
00363
00364 sinp_sinrho = sinL*cosB;
00365 cosp_sinrho = cB0sB - sB0cB*cosL;
00366 cosrho = sB0sB + cB0cB*cosL;
00367 rp = 1.0 / (1.0 - S * cosrho);
00368 x = rp * (sinp_sinrho*cosP - cosp_sinrho*sinP);
00369 y = rp * (cosp_sinrho*cosP + sinp_sinrho*sinP);
00370
00371
00372 if ((x*x + y*y) >= Rmax2)
00373 {
00374 *(U + rowoffset + col) = (NaN_beyond_rmax) ? DRMS_MISSING_FLOAT : (float)0.0;
00375 continue;
00376 }
00377
00378 xtmp = combo_xx*x + combo_xy*y;
00379 ytmp = combo_yx*x + combo_yy*y;
00380 x = xtmp + x0;
00381 y = ytmp + y0;
00382
00383
00384 Distort(x, y, rsun, +1, &x, &y, distpars);
00385
00386
00387
00388
00389
00390 if (interpolation == kLIBASTRO_InterCubic)
00391 {
00392 u = (float)(vsign * Ccintdly (VD,xpixels,ypixels,x,y));
00393 }
00394 else if (interpolation == kLIBASTRO_InterBilinear)
00395 {
00396 u = (float)(vsign * Linintdly (VD,xpixels,ypixels,x,y));
00397 }
00398
00399 if (mag_correction == kLIBASTRO_MCORLevel1)
00400 u = (float)(u * (sB0sB+cB0cB) / cosrho);
00401
00402 if (velocity_correction > kLIBASTRO_VCORSignOnly)
00403 {
00404 mu = 1.0 - cosrho;
00405 v_limbshift = limbshift_coef_a0 + mu*(limbshift_coef_a1 + mu*limbshift_coef_a2);
00406
00407 if (velocity_correction == kLIBASTRO_VCORLevel1) rp=1.0;
00408 u = (float)((u + v_limbshift)/rp + v_rotation*cosB*sinL*cosB0 - (sB0cB - cosL*cB0sB)*v_lat
00409 + obs_vr/rp - S*(obs_vw*sinp_sinrho + obs_vn*cosp_sinrho));
00410
00411 if (velocity_correction == kLIBASTRO_VCORLevel2) u = (float)(cosB*cosL*u/(cosrho-S));
00412 }
00413
00414
00415 *(U + rowoffset + col) = u;
00416 }
00417 }
00418 free(VD);
00419 return kLIBASTRO_Success;
00420 }