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
00040
00041 #include <stdlib.h>
00042 #include <math.h>
00043 #include "projection.h"
00044
00045 char *cvsinfo_obs2helio = "cvsinfo: $Header: /home/cvsuser/cvsroot/JSOC/proj/globalhs/libs/projection/obs2helio.c,v 1.3 2014/01/15 19:07:48 tplarson Exp $";
00046
00047 const int kMaxCols = 20000;
00048 const double kOmegaCarr = (360 / 27.27527);
00049 const double kRadsPerDegree = M_PI/180.;
00050
00051 static void Ccker(double *u, double s);
00052 static double Ccintd(double *f, int nx, int ny, double x, double y);
00053 static double Linintd(double *f, int nx, int ny, double x, double y);
00054 static void Distort(double x,
00055 double y,
00056 double rsun,
00057 int sign,
00058 double *xd,
00059 double *yd,
00060 const LIBPROJECTION_Dist_t *distpars);
00061
00062
00063 void Ccker(double *u, double s)
00064 {
00065 double s2, s3;
00066
00067 s2= s * s;
00068 s3= s2 * s;
00069 u[0] = s2 - 0.5 * (s3 + s);
00070 u[1] = 1.5*s3 - 2.5*s2 + 1.0;
00071 u[2] = -1.5*s3 + 2.0*s2 + 0.5*s;
00072 u[3] = 0.5 * (s3 - s2);
00073 }
00074
00075
00076 double Ccintd(double *f, int nx, int ny, double x, double y)
00077 {
00078 double ux[4], uy[4];
00079
00080 double sum;
00081
00082 int ix, iy, ix1, iy1, i, j;
00083
00084 if (x < 1. || x >= (double)(nx-2) ||
00085 y < 1. || y >= (double)(ny-2))
00086 return 0.0;
00087
00088 ix = (int)x;
00089 iy = (int)y;
00090 Ccker(ux, x - (double)ix);
00091 Ccker(uy, y - (double)iy);
00092
00093 ix1 = ix - 1;
00094 iy1 = iy - 1;
00095 sum = 0.;
00096 for (i = 0; i < 4; i++)
00097 for (j = 0; j < 4; j++)
00098 sum = sum + f[(iy1+i) * nx + ix1 + j] * uy[i] * ux[j];
00099 return sum;
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 double Linintd(double *f, int nx, int ny, double x, double y)
00117 {
00118 double p0, p1, q0, q1;
00119 int ilow, jlow;
00120 double *fptr;
00121 double u;
00122
00123 ilow = (int)floor(x);
00124 jlow = (int)floor(y);
00125 if (ilow < 0) ilow = 0;
00126 if (ilow+1 >= nx) ilow -= 1;
00127 if (jlow < 0) jlow = 0;
00128 if (jlow+1 >= ny) jlow -= 1;
00129 p1 = x - ilow;
00130 p0 = 1.0 - p1;
00131 q1 = y - jlow;
00132 q0 = 1.0 - q1;
00133
00134
00135 u = 0.0;
00136 fptr = f + jlow*nx + ilow;
00137 u += p0 * q0 * *fptr++;
00138 u += p1 * q0 * *fptr;
00139 fptr += nx - 1;
00140 u += p0 * q1 * *fptr++;
00141 u += p1 * q1 * *fptr;
00142 return u;
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 int SetDistort(int dist,
00166 double cubic,
00167 double alpha,
00168 double beta,
00169 double feff,
00170 LIBPROJECTION_Dist_t *dOut)
00171 {
00172 int error = 0;
00173
00174 if (dOut != NULL)
00175 {
00176 int status = 0;
00177
00178 dOut->disttype = dist;
00179
00180
00181 if (dOut->disttype != 0)
00182 {
00183 if (dOut->disttype == 1)
00184 {
00185
00186 dOut->xc = 511.5;
00187 dOut->yc = 511.5;
00188 dOut->scale = 1.0;
00189 }
00190 else if (dOut->disttype == 2)
00191 {
00192
00193 dOut->xc = 95.1;
00194 dOut->yc = 95.1;
00195 dOut->scale = 5.0;
00196 }
00197 else
00198 {
00199 error = 1;
00200 }
00201
00202 if (!error)
00203 {
00204 dOut->feff = feff;
00205 dOut->alpha = alpha * kRadsPerDegree;
00206 beta *= kRadsPerDegree;
00207 dOut->cosbeta = cos(beta);
00208 dOut->sinbeta = sin(beta);
00209 dOut->cdist = cubic;
00210
00211
00212
00213
00214
00215
00216 }
00217
00218 }
00219 }
00220 else
00221 {
00222 error = 1;
00223 }
00224
00225 return error;
00226 }
00227
00228
00229 void Distort(double x,
00230 double y,
00231 double rsun,
00232 int sign,
00233 double *xd,
00234 double *yd,
00235 const LIBPROJECTION_Dist_t *distpars)
00236 {
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 double xx,yy,xxl,yyl,x0,y0,x00,y00,x0l,y0l,epsx,epsy,rdist;
00247
00248 if (distpars->disttype == 0)
00249 {
00250 *xd=x;
00251 *yd=y;
00252 return;
00253 }
00254
00255
00256 rsun=rsun*distpars->scale;
00257
00258
00259
00260
00261
00262
00263 x00=distpars->scale*(x-distpars->xc);
00264 y00=distpars->scale*(y-distpars->yc);
00265
00266
00267
00268 rdist=distpars->cdist*(x00*x00+y00*y00-rsun*rsun);
00269
00270 x0=x00+rdist*x00;
00271 y0=y00+rdist*y00;
00272
00273
00274
00275
00276 x0l=x0*distpars->cosbeta+y0*distpars->sinbeta;
00277 y0l=-x0*distpars->sinbeta+y0*distpars->cosbeta;
00278
00279
00280 xxl=x0l*(1.-distpars->alpha*distpars->alpha/4.+y0l/distpars->feff*distpars->alpha);
00281 yyl=y0l*(1.+distpars->alpha*distpars->alpha/4.+y0l/distpars->feff*distpars->alpha) -
00282 rsun*rsun/distpars->feff*distpars->alpha;
00283
00284
00285 xx=xxl*distpars->cosbeta-yyl*distpars->sinbeta;
00286 yy=xxl*distpars->sinbeta+yyl*distpars->cosbeta;
00287
00288
00289
00290 epsx=xx-x00;
00291 epsy=yy-y00;
00292
00293
00294
00295 *xd=x+sign*epsx/distpars->scale;
00296 *yd=y+sign*epsy/distpars->scale;
00297 }
00298
00299 int obs2helio(
00300 float *V,
00301
00302 float *U,
00303 int xpixels,
00304 int ypixels,
00305 double x0,
00306 double y0,
00307 double BZero,
00308 double P,
00309
00310 double S,
00311 double rsun,
00312 double Rmax,
00313 int interpolation,
00314 int cols,
00315 int rows,
00316 double Lmin,
00317 double Ldelta,
00318 double Ladjust,
00319 double sinBdelta,
00320 double smajor,
00321 double sminor,
00322 double sangle,
00323 double xscale,
00324 double yscale,
00325 const char *orientation,
00326 int mag_correction,
00327 int velocity_correction,
00328 double obs_vr,
00329 double obs_vw,
00330 double obs_vn,
00331 double vsign,
00332 int NaN_beyond_rmax,
00333 int carrStretch,
00334 const LIBPROJECTION_Dist_t *distpars,
00335 float diffrotA,
00336 float diffrotB,
00337 float diffrotC,
00338 LIBPROJECTION_RotRate_t *rRates,
00339 int size)
00340 {
00341
00342 double xtmp, ytmp;
00343 float u;
00344
00345
00346 double sinBbase;
00347 double sinB0, cosB0;
00348 double sinB, cosB;
00349 double sinL, cosL;
00350 double sinP, cosP;
00351 double cosrho;
00352 double sinp_sinrho;
00353 double cosp_sinrho;
00354 double rp;
00355 double x, y;
00356 double Rmax2;
00357
00358
00359 double sinS, cosS, sinS2, cosS2, sinScosS;
00360 double stretch_xx, stretch_xy, stretch_yx, stretch_yy;
00361
00362
00363 int orient_xx, orient_xy, orient_yx, orient_yy;
00364 int swap, ewflip, nsflip;
00365
00366
00367 double combo_xx, combo_xy, combo_yx, combo_yy;
00368
00369
00370 int row, col;
00371 double L;
00372
00373
00374 double mu;
00375 double v_rotation;
00376 double v_limbshift;
00377
00378
00379 const double v_lat = 0.0;
00380 const double v_equator = 1974.1;
00381 const double rotation_coef_a2 = -0.121;
00382 const double rotation_coef_a4 = -0.178;
00383 const double limbshift_coef_a0 = -166.;
00384 const double limbshift_coef_a1 = -139.;
00385 const double limbshift_coef_a2 = 700.;
00386
00387
00388 double savedDeltaL[kMaxCols];
00389 double savedsinL[kMaxCols];
00390 double savedcosL[kMaxCols];
00391 double cB0sB, cB0cB, sB0sB, sB0cB;
00392 double sinB2;
00393 int rowoffset;
00394 double omegaLat;
00395 double deltaLAdj;
00396
00397 long i;
00398 double *vdp;
00399 float *vp;
00400
00401 double *VD;
00402 VD=(double *)(malloc(xpixels*ypixels*sizeof(double)));
00403 vdp=VD;
00404 vp=V;
00405 for (i=0;i<xpixels*ypixels;i++) *vdp++=(double)*vp++;
00406
00407 if (cols > kMaxCols)
00408 {
00409 return kLIBPROJECTION_DimensionMismatch;
00410 }
00411
00412 if (rows%2) return kLIBPROJECTION_CantDoOddNumLats;
00413
00414 if (interpolation != kLIBPROJECTION_InterCubic && interpolation != kLIBPROJECTION_InterBilinear)
00415 {
00416 return kLIBPROJECTION_UnsupportedInterp;
00417 }
00418
00419 if ((mag_correction < kLIBPROJECTION_MCORLevel0) || (mag_correction > kLIBPROJECTION_MCORLevel2))
00420 return kLIBPROJECTION_UnsupportedMCOR;
00421
00422 if ((velocity_correction < kLIBPROJECTION_VCORSignOnly) || (velocity_correction > kLIBPROJECTION_VCORLevel2))
00423 return kLIBPROJECTION_UnsupportedVCOR;
00424
00425
00426
00427 sinBbase = 0.5-rows/2;
00428 sinS = sin(sangle); cosS = cos(sangle);
00429 sinS2 = sinS*sinS; cosS2 = cosS*cosS; sinScosS = sinS*cosS;
00430 stretch_xx = smajor*cosS2 + sminor*sinS2;
00431 stretch_xy = stretch_yx = (smajor - sminor)*sinScosS;
00432 stretch_yy = smajor*sinS2 + sminor*cosS2;
00433
00434 swap = (orientation[0]!=orientation[2]);
00435 ewflip = (orientation[1]=='W'); nsflip = (orientation[0]=='N');
00436 orient_xx = orient_yy = !swap; orient_xy = orient_yx = swap;
00437 if(ewflip) {orient_xx=-orient_xx; orient_yx=-orient_yx;}
00438 if(nsflip) {orient_xy=-orient_xy; orient_yy=-orient_yy;}
00439
00440 combo_xx = rsun*(orient_xx*stretch_xx+orient_xy*stretch_yx)/xscale;
00441 combo_xy = rsun*(orient_xx*stretch_xy+orient_xy*stretch_yy)/xscale;
00442 combo_yx = rsun*(orient_yx*stretch_xx+orient_yy*stretch_yx)/yscale;
00443 combo_yy = rsun*(orient_yx*stretch_xy+orient_yy*stretch_yy)/yscale;
00444
00445 sinB0 = sin(BZero);
00446 cosB0 = sqrt(1.0 - sinB0*sinB0);
00447 sinP = sin(P);
00448 cosP = cos(P);
00449 Rmax2 = Rmax * Rmax;
00450
00451 for (col = 0; col < cols; col++) {
00452 savedDeltaL[col] = (L = Ldelta*col + Lmin - Ladjust);
00453 savedsinL[col] = (sinL = sin(L));
00454 savedcosL[col] = sqrt(1.0 - sinL*sinL);
00455 }
00456
00457
00458
00459 for (row = 0; row < rows; row++) {
00460 rowoffset = row*cols;
00461 sinB = sinBdelta*(sinBbase + row);
00462 sinB2 = sinB*sinB;
00463 cosB = sqrt(1.0 - sinB2);
00464 sB0sB = sinB0*sinB;
00465 sB0cB = sinB0*cosB;
00466 cB0sB = cosB0*sinB;
00467 cB0cB = cosB0*cosB;
00468 omegaLat = diffrotA + diffrotB * sinB2 + diffrotC * sinB2 * sinB2;
00469
00470
00471 if (rRates && row < size)
00472 {
00473 rRates[row].lat = asin(sinB);
00474 rRates[row].r = 14.562 + (diffrotB * sinB2) + (diffrotC * sinB2 * sinB2);
00475 }
00476
00477 v_rotation = v_equator*(1.0+sinB2*(rotation_coef_a2+sinB2*rotation_coef_a4));
00478
00479 for (col = 0; col < cols; col++) {
00480
00481 if (carrStretch == 0)
00482 {
00483 sinL = savedsinL[col];
00484 cosL = savedcosL[col];
00485 }
00486 else
00487 {
00488
00489
00490
00491
00492
00493
00494 deltaLAdj = savedDeltaL[col] * omegaLat / kOmegaCarr;
00495 sinL = sin(deltaLAdj);
00496 cosL = cos(deltaLAdj);
00497 }
00498
00499 sinp_sinrho = sinL*cosB;
00500 cosp_sinrho = cB0sB - sB0cB*cosL;
00501 cosrho = sB0sB + cB0cB*cosL;
00502
00503
00504
00505
00506
00507
00508 rp = sqrt(1 - S*S) / (1.0 - S * cosrho);
00509 x = rp * (sinp_sinrho*cosP - cosp_sinrho*sinP);
00510 y = rp * (cosp_sinrho*cosP + sinp_sinrho*sinP);
00511
00512
00513
00514 if ((x*x + y*y) >= Rmax2 || cosrho < S)
00515 {
00516 *(U + rowoffset + col) = (NaN_beyond_rmax) ? NAN : (float)0.0;
00517 continue;
00518 }
00519
00520 xtmp = combo_xx*x + combo_xy*y;
00521 ytmp = combo_yx*x + combo_yy*y;
00522 x = xtmp + x0;
00523 y = ytmp + y0;
00524
00525 Distort(x, y, rsun, +1, &x, &y, distpars);
00526
00527
00528
00529
00530
00531 if (interpolation == kLIBPROJECTION_InterCubic)
00532 {
00533 u = (float)(vsign * Ccintd (VD,xpixels,ypixels,x,y));
00534 }
00535 else if (interpolation == kLIBPROJECTION_InterBilinear)
00536 {
00537 u = (float)(vsign * Linintd (VD,xpixels,ypixels,x,y));
00538 }
00539
00540 if (mag_correction == kLIBPROJECTION_MCORLevel1)
00541 u = (float)(u * (sB0sB+cB0cB) / cosrho);
00542
00543 if (mag_correction == kLIBPROJECTION_MCORLevel2)
00544 u = (float)(u / cosrho);
00545
00546 if (velocity_correction > kLIBPROJECTION_VCORSignOnly)
00547 {
00548 mu = 1.0 - cosrho;
00549 v_limbshift = limbshift_coef_a0 + mu*(limbshift_coef_a1 + mu*limbshift_coef_a2);
00550
00551 if (velocity_correction == kLIBPROJECTION_VCORLevel1) rp=1.0;
00552 u = (float)((u + v_limbshift)/rp + v_rotation*cosB*sinL*cosB0 - (sB0cB - cosL*cB0sB)*v_lat
00553 + obs_vr/rp - S*(obs_vw*sinp_sinrho + obs_vn*cosp_sinrho));
00554
00555 if (velocity_correction == kLIBPROJECTION_VCORLevel2) u = (float)(cosB*cosL*u/(cosrho-S));
00556 }
00557
00558 *(U + rowoffset + col) = u;
00559 }
00560 }
00561 free(VD);
00562 return kLIBPROJECTION_Success;
00563 }