![]() ![]() |
![]() |
File: [Development] / JSOC / proj / globalhs / apps / mkylms.c
(download)
Revision: 1.8, Wed May 20 18:16:14 2015 UTC (8 years ago) by tplarson Branch: MAIN CVS Tags: globalhs_version_9, globalhs_version_16, globalhs_version_15, globalhs_version_14, globalhs_version_13, globalhs_version_12, globalhs_version_11, globalhs_version_10, Ver_9-0, Ver_8-12, Ver_8-11, Ver_8-10 Changes since 1.7: +7 -1 lines add checking of DTOFF |
#include <stdio.h> #include <math.h> #include <stdlib.h> #include <time.h> #include <sys/time.h> #include <sys/resource.h> #include <fftw3.h> #include "jsoc_main.h" #include "fresize.h" #define kNOTSPECIFIED "not specified" #define ARRLENGTH(ARR) (sizeof(ARR)/sizeof(ARR[0])) #define PI (M_PI) #define RADSINDEG (PI/180) #define RTRUE (6.96000000e8) // meters #define AU (149597870691) // meters/au #define TAU_A (499.004783806) // light travel time in seconds, = 1 AU/c #define C (299792458) // speed of light, m/s char *module_name = "mkylms"; char *cvsinfo_mkylms = "cvsinfo: $Header: /home/cvsuser/cvsroot/JSOC/proj/globalhs/apps/mkylms.c,v 1.8 2015/05/20 19:16:14 tplarson Exp $"; ModuleArgs_t module_args[] = { {ARG_STRING, "out", NULL, "output data series"}, {ARG_STRING, "histlink", "HISTORY", "name of link to ancillary dataseries for processing metadata"}, {ARG_INT, "PERM", "1", "set to 0 for transient records, nonzero for permanent records"}, {ARG_INT, "VERB", "1", "option for level of verbosity: 0=only error and warning messages; >0=print messages outside of loop; >1=print messages inside loop; >2=debugging output", NULL}, {ARG_STRING, "MODELIST", kNOTSPECIFIED, "file specifying modes to generate"}, {ARG_INT, "XPIXELS", "1024", "number of pixels in x direction"}, {ARG_INT, "YPIXELS", "1024", "number of pixels in y direction"}, {ARG_FLOAT, "SOLARP", "0.0", "p-angle in degrees"}, {ARG_FLOAT, "OBSB0", "0.0", "b-angle in degrees"}, {ARG_FLOAT, "OBSDIST", "1.0", "distance from the sun in au"}, {ARG_FLOAT, "XOFFSET", "0.0", "offset in pixels from center in x direction"}, {ARG_FLOAT, "YOFFSET", "0.0", "offset in pixels from center in y direction"}, {ARG_INT, "IINTEN", "0", "flag for making intensity images, make velocity images otherwise"}, {ARG_FLOAT, "PHASE", "0.0", "phase in radians"}, {ARG_FLOAT, "FREQUENCY", "0.0", "frequency in Hz"}, {ARG_INT, "ILIMBDARK", "0", "flag to correct for limb darkening in intensity images"}, {ARG_DOUBLES,"coefs", "0.0", "limb darkening coeficients, 6 needed"}, {ARG_INT, "IHEIGHT", "0", "flag to correct for height of formation"}, // {ARG_INT, "ICUBINT", "0", "flag for convolving psf with cubic interpolation"}, {ARG_INT, "CUB_WID", "-1", "quarter width of kernel for cubic convolution"}, {ARG_FLOAT, "AIRY_CDOWN", "0.0", "ratio of the pixel nyquist frequency to the cutoff frequency of the Airy function"}, {ARG_INT, "AIRY_IAP", "0", "option for type of apodization"}, {ARG_INT, "AIRY_NAP", "1", "distance between sampled points in pixels"}, {ARG_INT, "AIRY_WID", "-1", "half width of kernel"}, {ARG_INT, "AIRY_NSUB", "1", "distance between sampled points in pixels"}, {ARG_INT, "AIRY_XOFF", "0", "offset in pixels to add to x index of input image"}, {ARG_INT, "AIRY_YOFF", "0", "offset in pixels to add to y index of input image"}, {ARG_INT, "NBIN", "-1", "factor for binning"}, {ARG_INT, "BIN_XOFF", "0", "offset in pixels in x direction to apply before binning"}, {ARG_INT, "BIN_YOFF", "0", "offset in pixels in y direction to apply before binning"}, {ARG_FLOAT, "GAUSS_SIG", "-1.0", "width of gaussian"}, {ARG_INT, "GAUSS_WID", "-1", "half width of kernel"}, {ARG_INT, "GAUSS_NSUB", "1", "distance between sampled points in pixels"}, {ARG_INT, "GAUSS_XOFF", "0", "offset in pixels to add to x index of input image"}, {ARG_INT, "GAUSS_YOFF", "0", "offset in pixels to add to y index of input image"}, /* {ARG_INT, "IHORIZ", "0", "flag for outputting horizontal component only, otherwise output radial component only"}, {ARG_INT, "IBOX", "0", "flag for convolving psf with box"}, {ARG_INT, "IGAUSS", "0", "flag for convolving psf with gaussian"}, {ARG_FLOAT, "WPSFX", "1.0", "width of gaussian psf in x direction"}, {ARG_FLOAT, "WPSFY", "1.0", "width of gaussian psf in y direction"}, {ARG_INT, "ILORENTZ", "0", "flag for convolving psf with lorentzian"}, {ARG_FLOAT, "WLORENTZ", "1.0", "width of lorenztian psf"}, {ARG_INT, "ILININT", "0", "flag for convolving psf with linear interpolation"}, {ARG_INT, "IBIN", "0", "flag for binning"}, {ARG_INT, "NBIN", "1", "factor for binning"}, {ARG_INT, "ISKIP", "0", "flag for subsampling"}, {ARG_INT, "NOFF", "2", "offset for subsampling"}, */ {ARG_TIME, "TSTART", "1996.05.26_16:00:00_TAI", "first output time"}, {ARG_INT, "DTOFF", "0", "number of timesteps to offset first image"}, {ARG_INT, "NDT", "0", "number of time points to generate"}, {ARG_END} }; #include "saveparm.c" #include "timing.c" #include "set_history.c" #include "setplm2.c" static void Ccker(double *u, double s); static double Ccintd(double *f, int nx, double x); int DoIt(void) { int newstat=0; int status = DRMS_SUCCESS; DRMS_Record_t *outrec = NULL; DRMS_Segment_t *segout = NULL; DRMS_Array_t *outarr = NULL; DRMS_Type_t usetype = DRMS_TYPE_FLOAT; DRMS_RecLifetime_t lifetime; long long histrecnum=-1; int length[2]; TIME trec, tnow, UNIX_epoch = -220924792.000; /* 1970.01.01_00:00:00_UTC */ int ipsf=0; struct fresize_struct fress, fresscub; static double defaultcoefs[] = {1.0, 0.459224, 0.132395, 0.019601, 0.000802, -4.31934E-05 }; int errbufstat=setvbuf(stderr, NULL, _IONBF, BUFSIZ); int outbufstat=setvbuf(stdout, NULL, _IONBF, BUFSIZ); /* double wt0, wt1, wt2, wt3, wt; double ut0, ut1, ut2, ut3, ut; double st0, st1, st2, st3, st; double ct0, ct1, ct2, ct3, ct; wt0=getwalltime(); ct0=getcputime(&ut0, &st0); */ char *outseries = (char *)cmdparams_save_str(&cmdparams, "out", &newstat); int verbflag = cmdparams_save_int(&cmdparams, "VERB", &newstat); int permflag = cmdparams_save_int(&cmdparams, "PERM", &newstat); if (permflag) lifetime = DRMS_PERMANENT; else lifetime = DRMS_TRANSIENT; char *histlinkname = (char *)cmdparams_save_str(&cmdparams, "histlink", &newstat); char *modefile = (char *)cmdparams_save_str(&cmdparams, "MODELIST", &newstat); int xpixels = cmdparams_save_int(&cmdparams, "XPIXELS", &newstat); int ypixels = cmdparams_save_int(&cmdparams, "YPIXELS", &newstat); double solarp = cmdparams_save_float(&cmdparams, "SOLARP", &newstat); double obsb0 = cmdparams_save_float(&cmdparams, "OBSB0", &newstat); double obsdist = cmdparams_save_float(&cmdparams, "OBSDIST", &newstat); float xoffset = cmdparams_save_float(&cmdparams, "XOFFSET", &newstat); float yoffset = cmdparams_save_float(&cmdparams, "YOFFSET", &newstat); int iinten = cmdparams_save_int(&cmdparams, "IINTEN", &newstat); float phasein = cmdparams_save_float(&cmdparams, "PHASE", &newstat); float freqin = cmdparams_save_float(&cmdparams, "FREQUENCY", &newstat); int ilimbdark = cmdparams_save_int(&cmdparams, "ILIMBDARK", &newstat); double coefs[6]; int n_user_coefs = cmdparams_get_int(&cmdparams, "coefs_nvals", &status); if (ilimbdark) { if (n_user_coefs == 6) { double *cmdcoefs; int i; cmdparams_get_dblarr(&cmdparams, "coefs", &cmdcoefs, &status); for (i=0; i<6; i++) coefs[i] = cmdcoefs[i]; } else { int i; for (i=0; i<6; i++) coefs[i] = defaultcoefs[i]; } } int iheight = cmdparams_save_int(&cmdparams, "IHEIGHT", &newstat); int nbin = cmdparams_save_int(&cmdparams, "NBIN", &newstat); int bxoff = cmdparams_save_int(&cmdparams, "BIN_XOFF", &newstat); int byoff = cmdparams_save_int(&cmdparams, "BIN_YOFF", &newstat); float sigma = cmdparams_save_float(&cmdparams, "GAUSS_SIG", &newstat); int hwidth = cmdparams_save_int(&cmdparams, "GAUSS_WID", &newstat); int nsub = cmdparams_save_int(&cmdparams, "GAUSS_NSUB", &newstat); int gxoff = cmdparams_save_int(&cmdparams, "GAUSS_XOFF", &newstat); int gyoff = cmdparams_save_int(&cmdparams, "GAUSS_YOFF", &newstat); // for now use this patch so i can specify integers for GAUSS_SIG // sigma/=sqrt(2); // now get rid of it for consistency int cubwid = cmdparams_save_int(&cmdparams, "CUB_WID", &newstat); if (cubwid > 0 && nsub > 1) { fprintf(stderr, "ERROR: GAUSS_NSUB must be 1 for CUB_WID > 0\n"); return 1; } double *kcub; double help[] = {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}; if (cubwid > 0) { int i; double total=0.0; kcub = (double *)malloc((4*cubwid+1)*sizeof(double)); for (i=0; i<4*cubwid+1; i++) { kcub[i]=Ccintd(help,4*cubwid+1,1+(double)i/cubwid); total+=kcub[i]; } for (i=0; i<4*cubwid+1; i++) kcub[i]/=total; init_fresize_gaussian(&fresscub, 1.0, 2*cubwid, 1.0); for (i=0; i<4*cubwid+1; i++) { fresscub.kerx[i]=(float)kcub[i]; fresscub.kery[i]=(float)kcub[i]; } } /* int ibox = cmdparams_save_int(&cmdparams, "IBOX", &newstat); int igauss = cmdparams_save_int(&cmdparams, "IGAUSS", &newstat); float wpsfx = cmdparams_save_float(&cmdparams, "WPSFX", &newstat); float wpsfy = cmdparams_save_float(&cmdparams, "WPSFY", &newstat); int ilorentz = cmdparams_save_int(&cmdparams, "ILORENTZ", &newstat); float wlorentz = cmdparams_save_float(&cmdparams, "WLORENTZ", &newstat); int ilinint = cmdparams_save_int(&cmdparams, "ILININT", &newstat); int icubint = cmdparams_save_int(&cmdparams, "ICUBINT", &newstat); int ibin = cmdparams_save_int(&cmdparams, "IBIN", &newstat); int nbin = cmdparams_save_int(&cmdparams, "NBIN", &newstat); int iskip = cmdparams_save_int(&cmdparams, "ISKIP", &newstat); int noff = cmdparams_save_int(&cmdparams, "NOFF", &newstat); */ double tstart = cmdparams_save_time(&cmdparams, "TSTART", &newstat); int dtoff = cmdparams_save_int(&cmdparams, "DTOFF", &newstat); int ndt = cmdparams_save_int(&cmdparams, "NDT", &newstat); if (ndt == 0 && dtoff > 0) { fprintf(stderr, "ERROR: cannot specify DTOFF > 0 when NDT=0\n"); return 1; } double pangle = RADSINDEG*solarp; double b0 = RADSINDEG*obsb0; // if (ibox+igauss+ilorentz+ilinint+icubint > 0) ipsf=1; FILE *fptr = fopen(modefile,"r"); if (fptr == NULL) { fprintf(stderr, "ERROR: can't open mode file %s\n",modefile); return 1; } if (newstat) { fprintf(stderr, "ERROR: problem with input arguments, status = %d, diagnosis follows\n", newstat); cpsave_decode_error(newstat); return 1; } else if (savestrlen != strlen(savestr)) { fprintf(stderr, "ERROR: problem with savestr, savestrlen = %d, strlen(savestr) = %d\n", savestrlen, (int)strlen(savestr)); return 1; } // set up ancillary dataseries for processing metadata DRMS_Record_t *tempoutrec = drms_create_record(drms_env, outseries, DRMS_TRANSIENT, &status); if (status != DRMS_SUCCESS) { fprintf(stderr,"ERROR: couldn't open a record in output dataseries %s, status = %d\n", outseries, status); return 1; } DRMS_Link_t *histlink = hcon_lookup_lower(&tempoutrec->links, histlinkname); if (histlink != NULL) { histrecnum=set_history(histlink); if (histrecnum < 0) { drms_close_record(tempoutrec, DRMS_FREE_RECORD); return 1; } } else { fprintf(stderr,"WARNING: could not find history link in output dataseries\n"); } // these must be present in the output dataseries and variable, not links or constants char *outchecklist[] = {"T_REC", "QUALITY", "T_OBS", "CRLT_OBS", "CRLN_OBS", //"SAT_ROT", "INST_ROT", "IM_SCALE", "CDELT1", "CDELT2"}; int itest; for (itest=0; itest < ARRLENGTH(outchecklist); itest++) { DRMS_Keyword_t *outkeytest = hcon_lookup_lower(&tempoutrec->keywords, outchecklist[itest]); if (!outkeytest || outkeytest->info->islink || outkeytest->info->recscope == 1) { fprintf(stderr, "ERROR: output keyword %s is either missing, constant, or a link\n", outchecklist[itest]); drms_close_record(tempoutrec, DRMS_FREE_RECORD); return 1; } } float cadence = drms_getkey_float(tempoutrec, "T_REC_step", &status); drms_close_record(tempoutrec, DRMS_FREE_RECORD); int i, hold; long nmodes=0; while ((hold = getc(fptr)) != EOF) if (hold == '\n') nmodes++; fclose(fptr); fptr = fopen(modefile,"r"); int *lim, *mim; int lin, min; int mmax=0; int lmax=0; int *marr_lmax, *marr_count, **marr_index; // fscanf(fptr,"%d",&nmodes); lim=(int *)malloc(nmodes*sizeof(int)); mim=(int *)malloc(nmodes*sizeof(int)); for (i=0;i<nmodes;i++) { if (fscanf(fptr,"%d %d\n", &lin, &min) != 2) { fprintf(stderr,"ERROR: something went wrong on line i=%d\n", i); return 1; } // fscanf(fptr,"%d",&lin); // fscanf(fptr,"%d",&min); if (min > lin || lin < 0) { fprintf(stderr,"ERROR: mode file has m > l or l < 0\n"); return 1; } /* if (min > mmax) mmax=min; if (lin > lmax) lmax=lin; */ lim[i]=lin; mim[i]=min; } fclose(fptr); if (verbflag) printf("nmodes=%ld, dtoff=%d, ndt=%d\n", nmodes, dtoff, ndt); int *lim2, *mim2; if (ndt > 0) { if (dtoff + ndt > nmodes) nmodes=nmodes-dtoff; else nmodes=ndt; lim2=(int *)malloc(nmodes*sizeof(int)); mim2=(int *)malloc(nmodes*sizeof(int)); for (i=0;i<nmodes;i++) { lim2[i]=lim[dtoff+i]; mim2[i]=mim[dtoff+i]; } free(lim); free(mim); lim=lim2; mim=mim2; } if (nmodes <= 0) { fprintf(stderr, "ERROR: no modes selected\n"); return 1; } for (i=0;i<nmodes;i++) { if (mim[i] > mmax) mmax=mim[i]; if (lim[i] > lmax) lmax=lim[i]; } marr_lmax=(int *)(malloc((mmax+1)*sizeof(int))); marr_count=(int *)(malloc((mmax+1)*sizeof(int))); marr_index=(int **)(malloc((mmax+1)*sizeof(int *))); for (i=0;i<=mmax;i++) { marr_lmax[i]=-1; marr_count[i]=0; marr_index[i]=(int *)(malloc((lmax+1)*sizeof(int))); } for (i=0;i<nmodes;i++) { if (lim[i] > marr_lmax[mim[i]]) marr_lmax[mim[i]]=lim[i]; marr_index[mim[i]][marr_count[mim[i]]]=i; marr_count[mim[i]]++; } // double obsdist = 1.0; //in au double distobs = obsdist*AU/RTRUE; //in solar radii double dsunobs = obsdist*AU; //in meters double x0=(double)xpixels/2-0.5 + xoffset; double y0=(double)ypixels/2-0.5 + yoffset; long npixels=xpixels*ypixels; double imscale=1.97784*1024/xpixels; double scale=imscale/(180*60*60/PI); length[0]=xpixels; length[1]=ypixels; float obsl0=211.67; int obscr=1784; // double rsunobs=atan(asin(RTRUE/AU/obsdist))*60*60/RADSINDEG; // double rsun=rsunobs/imscale; double rsunobs=asin(RTRUE/AU/obsdist)*60*60/RADSINDEG; double rsun=tan(asin(RTRUE/AU/obsdist))/scale; double cdelt=rsunobs/rsun; // Use mean image scale across solar image /* ; Sun is sitting at the center of the main coordinate system ; and has radius 1. ; Observer is at robs=(xobs,yobs,zobs) moving with a velocity ; vobs. ; Start by setting robs from distobs and b0 */ double robs_x = distobs * cos(b0); double robs_y = 0.0; double robs_z = distobs * sin(b0); // Start with CCD coordinates double *x6 = (double *)(malloc(npixels*sizeof(double))); double *y6 = (double *)(malloc(npixels*sizeof(double))); int j; for (i=0;i<ypixels;i++) for (j=0;j<xpixels;j++) x6[i*ypixels+j]=(double)j; for (i=0;i<ypixels;i++) for (j=0;j<xpixels;j++) y6[i*ypixels+j]=(double)i; double *x4 = (double *)(malloc(npixels*sizeof(double))); double *y4 = (double *)(malloc(npixels*sizeof(double))); for (i=0;i<npixels;i++) { x4[i]=scale*(x6[i] - x0); y4[i]=scale*(y6[i] - y0); } /* ; Rotate by the P-angle. New coordinate system has the y-axis pointing ; towards the solar north pole. */ double *x2 = (double *)(malloc(npixels*sizeof(double))); double *y2 = (double *)(malloc(npixels*sizeof(double))); for (i=0;i<npixels;i++) { x2[i]= x4[i]*cos(pangle) + y4[i]*sin(pangle); y2[i]=-x4[i]*sin(pangle) + y4[i]*cos(pangle); } /* ; Now transform to put the coordinates into the solar coordinate ; system. ; First find the directions (vecx and vecy) the x2 and y2 coordinate ; axis correspond to. vecsun points towards the Sun. Note that the ; (x2,y2,Sun) system is left handed. These vectors are unit vectors. */ double vecx_x=0.0; double vecx_y=1.0; double vecx_z=0.0; double vecy_x=-sin(b0); double vecy_y=0.0; double vecy_z=cos(b0); double vecsun_x=-cos(b0); double vecsun_y=0.0; double vecsun_z=-sin(b0); // Now the proper direction can be found. These are not unit vectors. double *x1 = (double *)(malloc(npixels*sizeof(double))); double *y1 = (double *)(malloc(npixels*sizeof(double))); double *z1 = (double *)(malloc(npixels*sizeof(double))); double *q1 = (double *)(malloc(npixels*sizeof(double))); for (i=0;i<npixels;i++) { x1[i]=vecx_x*x2[i] + vecy_x*y2[i] + vecsun_x; y1[i]=vecx_y*x2[i] + vecy_y*y2[i] + vecsun_y; z1[i]=vecx_z*x2[i] + vecy_z*y2[i] + vecsun_z; q1[i]=1/sqrt(x1[i]*x1[i] + y1[i]*y1[i] + z1[i]*z1[i]); } // Make them unit vectors. for (i=0;i<npixels;i++) { x1[i]*=q1[i]; y1[i]*=q1[i]; z1[i]*=q1[i]; } // Now find intersection with the Sun. // Solve quadratic equation |robs+q*[x1,y1,z1]|=1 for q // a, b and c are terms in a*x^2+bx+c=0. a==1 since [x1,y1,z1] is unit vector. // double *b = (double *)(malloc(npixels*sizeof(double))); // double *d = (double *)(malloc(npixels*sizeof(double))); double b,d; double *q = (double *)(malloc(npixels*sizeof(double))); int *inflag = (int *)(malloc(npixels*sizeof(int))); double c = robs_x*robs_x + robs_y*robs_y + robs_z*robs_z -1; double *xsun = (double *)(malloc(npixels*sizeof(double))); double *ysun = (double *)(malloc(npixels*sizeof(double))); double *zsun = (double *)(malloc(npixels*sizeof(double))); double *cosrho = (double *)(malloc(npixels*sizeof(double))); for (i=0;i<npixels;i++) { // b[i]=2*(x1[i]*robs_x+y1[i]*robs_y+z1[i]*robs_z); // d[i]=b[i]*b[i] - 4*c; b=2*(x1[i]*robs_x+y1[i]*robs_y+z1[i]*robs_z); d=b*b - 4*c; if (d >= 0) { inflag[i]=1; q[i]=(-b - sqrt(d))/2; xsun[i]=robs_x + x1[i]*q[i]; ysun[i]=robs_y + y1[i]*q[i]; zsun[i]=robs_z + z1[i]*q[i]; cosrho[i]=-(x1[i]*xsun[i]+y1[i]*ysun[i]+z1[i]*zsun[i]); } else { inflag[i]=0; xsun[i]=0; ysun[i]=0; zsun[i]=0; cosrho[i]=0; } } if (iheight) { // Now calculate observing height in units of the solar radius double pc3[]={0.24047045,-0.76504325,0.86252178,-0.33859142}; double height; double c0 = robs_x*robs_x + robs_y*robs_y + robs_z*robs_z; for (i=0;i<npixels;i++) { double x=1.0; height=pc3[0]; for (j=1;j<4;j++) { x*=cosrho[i]; height+=pc3[j]*x; } height*=1e6/RTRUE; // Recalculate coordinates. b=2*(x1[i]*robs_x+y1[i]*robs_y+z1[i]*robs_z); c=c0-(1+height)*(1+height); d=b*b - 4*c; if (d >= 0) { inflag[i]=1; q[i]=(-b - sqrt(d))/2; // Remember to divide by new target radius xsun[i]=(robs_x + x1[i]*q[i])/(1+height); ysun[i]=(robs_y + y1[i]*q[i])/(1+height); zsun[i]=(robs_z + z1[i]*q[i])/(1+height); } else { inflag[i]=0; xsun[i]=0; ysun[i]=0; zsun[i]=0; } } } double *phisun = (double *)(malloc(npixels*sizeof(double))); double *cphisun = (double *)(malloc(npixels*sizeof(double))); double *sphisun = (double *)(malloc(npixels*sizeof(double))); double *clatsun = (double *)(malloc(npixels*sizeof(double))); double *slatsun = (double *)(malloc(npixels*sizeof(double))); double *prad = (double *)(malloc(npixels*sizeof(double))); double *pphi = (double *)(malloc(npixels*sizeof(double))); double *plat = (double *)(malloc(npixels*sizeof(double))); for (i=0;i<npixels;i++) { phisun[i] = atan2(ysun[i],xsun[i]); cphisun[i] = cos(phisun[i]); sphisun[i] = sin(phisun[i]); slatsun[i] = zsun[i]; clatsun[i] = sqrt(1 - zsun[i]*zsun[i]); // Set velocity projection factors prad[i]=xsun[i]*x1[i]+ysun[i]*y1[i]+zsun[i]*z1[i]; pphi[i]=-sphisun[i]*x1[i]+cphisun[i]*y1[i]; plat[i]=-cphisun[i]*slatsun[i]*x1[i]-sphisun[i]*slatsun[i]*y1[i]+clatsun[i]*z1[i]; } double *ld; if (ilimbdark) { ld=(double *)malloc(npixels*sizeof(double)); int iy,ix; for (iy=0; iy<ypixels; iy++) for (ix=0; ix<xpixels; ix++) { double costheta2; double xi, mu, z, ldi; double x, y, R2; int ord; int index=iy*xpixels + ix; if (!inflag[index]) continue; /* get coordinates of point */ x = ((double)ix - x0) / rsun; y = ((double)iy - y0) / rsun; R2 = x*x + y*y; if (R2 <= 1.0) costheta2 = 1.0 - R2; else costheta2 = 0.0; mu = sqrt(costheta2); xi = log(mu); z = 1.0; ldi = 1.0; for (ord=1; ord<6; ord++) { z *= xi; ldi += coefs[ord] * z; } // not sure what to do with this... if (ldi <= 0.0 || isnan(ldi)) { //*Op = missval; //ncropped++; ld[index]=0.0; } else ld[index] = ldi; } } free(x6);free(y6);free(x4);free(y4);free(x2);free(y2); free(x1);free(y1);free(z1);free(q1); // free(b);free(d); free(cosrho); free(xsun);free(ysun);free(zsun); if (verbflag) printf("coordinate arrays set up\n"); int lmax1, l, m, il; long nplm=10001; double *plm = (double *)(malloc(nplm*(lmax+1)*sizeof(double))); double *dplm = (double *)(malloc(nplm*(lmax+1)*sizeof(double))); double *plms = (double *)(malloc(nplm*nmodes*sizeof(double))); double *dplms = (double *)(malloc(nplm*nmodes*sizeof(double))); double *dxplm = (double *)(malloc(nplm*sizeof(double))); for (i=0;i<nplm;i++) dxplm[i]= -1 + (double)i * 2 / (nplm - 1); int *indx = (int *)(malloc ((lmax+1)*sizeof(int))); for (l=0; l<=lmax; l++) indx[l]=l; for (m=0;m<=mmax;m++) { if (marr_lmax[m] == -1) continue; lmax1=marr_lmax[m]; setplm2(m, lmax1, m, nplm, indx, dxplm, nplm, plm, dplm); for (i=0;i<marr_count[m];i++) { il=marr_index[m][i]; l=lim[il]; for (j=0;j<nplm;j++) { plms[il*nplm + j]=plm[l*nplm + j]; dplms[il*nplm + j]=dplm[l*nplm + j]; } } } free(plm); free(dplm); free(dxplm); if (verbflag) printf("plms set up\n"); // float cadence=60.0; // double time0=612201600.0 + dtoff*cadence; double time0=tstart + dtoff*cadence; double *vradr=(double *)(malloc(npixels*sizeof(double))); double *vradi=(double *)(malloc(npixels*sizeof(double))); //reuse arrays malloc'ed above to save memory double *vlatr, *vlati; vlatr=vradr; vlati=vradi; // double *vlatr=(double *)(malloc(npixels*sizeof(double))); // double *vlati=(double *)(malloc(npixels*sizeof(double))); double *vphir=(double *)(malloc(npixels*sizeof(double))); double *vphii=(double *)(malloc(npixels*sizeof(double))); /* double *velr=(double *)(malloc(npixels*sizeof(double))); double *veli=(double *)(malloc(npixels*sizeof(double))); double *velsum=(double *)(malloc(npixels*sizeof(double))); */ float *velr=(float *)(malloc(npixels*sizeof(float))); float *veli=(float *)(malloc(npixels*sizeof(float))); float *velsum=(float *)(malloc(npixels*sizeof(float))); float *velrsave=velr; float *velisave=veli; float *velssave=velsum; double *plminterp=(double *)(malloc(npixels*sizeof(double))); double ll, dinterp; float *binptr; int xpix1=xpixels; int ypix1=ypixels; if (nbin > 0) { x0=(x0 - bxoff + 0.5)/nbin - 0.5; y0=(y0 - byoff + 0.5)/nbin - 0.5; // imscale*=nbin; cdelt*=nbin; xpix1=xpixels/nbin; ypix1=ypixels/nbin; length[0]=xpix1; length[1]=ypix1; binptr=(float *)malloc(xpix1*ypix1*sizeof(float)); } float *gaussptr; int xpix2, ypix2; if (hwidth > 0) { x0=(x0 - gxoff)/nsub; y0=(y0 - gyoff)/nsub; // imscale*=nsub; cdelt*=nsub; xpix2=xpix1/nsub; ypix2=ypix1/nsub; length[0]=xpix2; length[1]=ypix2; gaussptr=(float *)malloc(xpix2*ypix2*sizeof(float)); init_fresize_gaussian(&fress, sigma, hwidth, nsub); } double *phase=(double *)malloc(npixels*sizeof(double)); double rsecs = RTRUE/C; for (i=0;i<npixels;i++) { if (inflag[i]) { double deltat; deltat=(q[i]-distobs+1)*rsecs; phase[i]=phasein-2*PI*freqin*deltat; } } DRMS_RecordSet_t *outrecset=drms_create_records(drms_env, nmodes, outseries, lifetime, &status); if (status != DRMS_SUCCESS || outrecset == NULL) { fprintf(stderr,"ERROR: unable to create output recordset, status = %d\n", status); return 0; } for (i=0;i<nmodes;i++) { trec=time0+i*cadence; if (verbflag > 1) printf("i=%d, trec=%f, l=%d, m=%d\n",i,trec,lim[i],mim[i]); /* outrec = drms_create_record(drms_env, outseries, lifetime, &status); if (status != DRMS_SUCCESS || outrec == NULL) { fprintf(stderr,"ERROR: unable to open record in output dataseries, i = %d, status = %d\n", i, status); return 0; } */ outrec=outrecset->records[i]; if (histlink) drms_setlink_static(outrec, histlinkname, histrecnum); for (j=0;j<npixels;j++) plminterp[j]=Ccintd(&plms[i*nplm],nplm,(nplm-1)*(slatsun[j]+1)/2); for (j=0;j<npixels;j++) { if (inflag[j]) { vradr[j]=1000 * (cos(mim[i]*phisun[j]+phase[j])) * plminterp[j]; //Ccintd(&plms[i*nplm],nplm,(nplm-1)*(slatsun[j]+1)/2); vradi[j]=1000 * (sin(mim[i]*phisun[j]+phase[j])) * plminterp[j]; //Ccintd(&plms[i*nplm],nplm,(nplm-1)*(slatsun[j]+1)/2); // needed to make main leaks positive since DATASIGN=-1 if (iinten) { if (ilimbdark) { velr[j]=-1*vradr[j]*ld[j]; veli[j]=-1*vradi[j]*ld[j]; velsum[j]=velr[j]+veli[j]; } else { velr[j]=-1*vradr[j]; veli[j]=-1*vradi[j]; velsum[j]=velr[j]+veli[j]; } } else { velr[j]=prad[j]*vradr[j]; veli[j]=prad[j]*vradi[j]; velsum[j]=velr[j]+veli[j]; } /* if (j == 524800) velsum[j]=1.0; else velsum[j]=0.0; */ } else { velr[j]=0; veli[j]=0; velsum[j]=0; } } if (nbin > 0) { fbin(velr, binptr, xpixels, ypixels, xpixels, xpix1, ypix1, xpix1, nbin, bxoff, byoff, 0.0); velr=binptr; } if (hwidth > 0) { fresize(&fress, velr, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, gxoff, gyoff, 0.0); velr=gaussptr; } if (cubwid > 0) { //in this case xpix1=xpix2 fresize(&fresscub, velr, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, 0.0, 0.0, 0.0); velr=gaussptr; } segout = drms_segment_lookup(outrec, "vradr"); outarr = drms_array_create(DRMS_TYPE_FLOAT, 2, length, velr, &status); if (segout == NULL || outarr == NULL || status != DRMS_SUCCESS) { fprintf(stderr, "ERROR: problem with output segment or array, i = %d, status = %d\n", i, status); return 0; } drms_segment_write(segout, outarr, 0); free(outarr); if (nbin > 0) { fbin(veli, binptr, xpixels, ypixels, xpixels, xpix1, ypix1, xpix1, nbin, bxoff, byoff, 0.0); veli=binptr; } if (hwidth > 0) { fresize(&fress, veli, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, gxoff, gyoff, 0.0); veli=gaussptr; } if (cubwid > 0) { //in this case xpix1=xpix2 fresize(&fresscub, velr, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, 0.0, 0.0, 0.0); veli=gaussptr; } segout = drms_segment_lookup(outrec, "vradi"); outarr = drms_array_create(DRMS_TYPE_FLOAT, 2, length, veli, &status); if (segout == NULL || outarr == NULL || status != DRMS_SUCCESS) { fprintf(stderr, "ERROR: problem with output segment or array, i = %d, status = %d\n", i, status); return 0; } drms_segment_write(segout, outarr, 0); free(outarr); if (nbin > 0) { fbin(velsum, binptr, xpixels, ypixels, xpixels, xpix1, ypix1, xpix1, nbin, bxoff, byoff, 0.0); velsum=binptr; } if (hwidth > 0) { fresize(&fress, velsum, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, gxoff, gyoff, 0.0); velsum=gaussptr; } if (cubwid > 0) { //in this case xpix1=xpix2 fresize(&fresscub, velr, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, 0.0, 0.0, 0.0); velsum=gaussptr; } segout = drms_segment_lookup(outrec, "vradsum"); outarr = drms_array_create(DRMS_TYPE_FLOAT, 2, length, velsum, &status); if (segout == NULL || outarr == NULL || status != DRMS_SUCCESS) { fprintf(stderr, "ERROR: problem with output segment or array, i = %d, status = %d\n", i, status); return 0; } drms_segment_write(segout, outarr, 0); free(outarr); if (!iinten) { velr=velrsave; veli=velisave; velsum=velssave; for (j=0;j<npixels;j++) { if (inflag[j]) { if (lim[i] != 0) { ll=sqrt(lim[i]*(lim[i]+1.0)); dinterp=Ccintd(&dplms[i*nplm],nplm,(nplm-1)*(slatsun[j]+1)/2); vlatr[j]=1000 * (cos(mim[i]*phisun[j]+phase[j]))*dinterp/ll*clatsun[j]; vlati[j]=1000 * (sin(mim[i]*phisun[j]+phase[j]))*dinterp/ll*clatsun[j]; vphir[j]=1000 * mim[i]*(-sin(mim[i]*phisun[j]+phase[j]))*plminterp[j]/ll/clatsun[j]; vphii[j]=1000 * mim[i]*( cos(mim[i]*phisun[j]+phase[j]))*plminterp[j]/ll/clatsun[j]; } else { vlatr[j]=vlati[j]=0; vphir[j]=vphii[j]=0; } velr[j]=pphi[j]*vphir[j]+plat[j]*vlatr[j]; veli[j]=pphi[j]*vphii[j]+plat[j]*vlati[j]; velsum[j]=velr[j]+veli[j]; } else { velr[j]=0; veli[j]=0; velsum[j]=0; } } if (nbin > 0) { fbin(velr, binptr, xpixels, ypixels, xpixels, xpix1, ypix1, xpix1, nbin, bxoff, byoff, 0.0); velr=binptr; } if (hwidth > 0) { fresize(&fress, velr, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, gxoff, gyoff, 0.0); velr=gaussptr; } if (cubwid > 0) { //in this case xpix1=xpix2 fresize(&fresscub, velr, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, 0.0, 0.0, 0.0); velr=gaussptr; } segout = drms_segment_lookup(outrec, "vhorr"); outarr = drms_array_create(DRMS_TYPE_FLOAT, 2, length, velr, &status); if (segout == NULL || outarr == NULL || status != DRMS_SUCCESS) { fprintf(stderr, "ERROR: problem with output segment or array, i = %d, status = %d\n", i, status); return 0; } drms_segment_write(segout, outarr, 0); free(outarr); if (nbin > 0) { fbin(veli, binptr, xpixels, ypixels, xpixels, xpix1, ypix1, xpix1, nbin, bxoff, byoff, 0.0); veli=binptr; } if (hwidth > 0) { fresize(&fress, veli, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, gxoff, gyoff, 0.0); veli=gaussptr; } if (cubwid > 0) { //in this case xpix1=xpix2 fresize(&fresscub, velr, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, 0.0, 0.0, 0.0); veli=gaussptr; } segout = drms_segment_lookup(outrec, "vhori"); outarr = drms_array_create(DRMS_TYPE_FLOAT, 2, length, veli, &status); if (segout == NULL || outarr == NULL || status != DRMS_SUCCESS) { fprintf(stderr, "ERROR: problem with output segment or array, i = %d, status = %d\n", i, status); return 0; } drms_segment_write(segout, outarr, 0); free(outarr); if (nbin > 0) { fbin(velsum, binptr, xpixels, ypixels, xpixels, xpix1, ypix1, xpix1, nbin, bxoff, byoff, 0.0); velsum=binptr; } if (hwidth > 0) { fresize(&fress, velsum, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, gxoff, gyoff, 0.0); velsum=gaussptr; } if (cubwid > 0) { //in this case xpix1=xpix2 fresize(&fresscub, velr, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, 0.0, 0.0, 0.0); velsum=gaussptr; } segout = drms_segment_lookup(outrec, "vhorsum"); outarr = drms_array_create(DRMS_TYPE_FLOAT, 2, length, velsum, &status); if (segout == NULL || outarr == NULL || status != DRMS_SUCCESS) { fprintf(stderr, "ERROR: problem with output segment or array, i = %d, status = %d\n", i, status); return 0; } drms_segment_write(segout, outarr, 0); free(outarr); } velr=velrsave; veli=velisave; velsum=velssave; drms_setkey_time(outrec, "T_REC", trec); drms_setkey_int(outrec, "L", lim[i]); drms_setkey_int(outrec, "M", mim[i]); drms_setkey_float(outrec, "XOFF", xoffset); drms_setkey_float(outrec, "YOFF", yoffset); drms_setkey_float(outrec, "PANGLE", solarp); drms_setkey_float(outrec, "BANGLE", obsb0); //obviously these are redundant, but give series designer freedom to use either drms_setkey_float(outrec, "DISTOBS", distobs); drms_setkey_float(outrec, "OBSDIST", obsdist); drms_setkey_string(outrec, "FILE", modefile); drms_setkey_float(outrec, "CRPIX1", x0+1); drms_setkey_float(outrec, "CRVAL1", 0.0); drms_setkey_float(outrec, "CDELT1", cdelt); drms_setkey_float(outrec, "CRPIX2", y0+1); drms_setkey_float(outrec, "CRVAL2", 0.0); drms_setkey_float(outrec, "CROTA2", -solarp); drms_setkey_float(outrec, "CDELT2", cdelt); drms_setkey_time(outrec, "T_OBS", trec); drms_setkey_int(outrec, "QUALITY", 0); drms_setkey_float(outrec, "CADENCE", cadence); drms_setkey_float(outrec, "CRLT_OBS", obsb0); drms_setkey_float(outrec, "CRLN_OBS", obsl0); drms_setkey_int(outrec, "CAR_ROT", obscr); drms_setkey_double(outrec, "DSUN_OBS", dsunobs); drms_setkey_double(outrec, "RSUN_OBS", rsunobs); drms_setkey_double(outrec, "OBS_VR", 0.0); drms_setkey_double(outrec, "OBS_VW", 0.0); drms_setkey_double(outrec, "OBS_VN", 0.0); drms_setkey_int(outrec, "DATASIGN", -1); tnow = (double)time(NULL); tnow += UNIX_epoch; drms_setkey_time(outrec, "DATE", tnow); // drms_close_record(outrec, DRMS_INSERT_RECORD); } drms_close_records(outrecset, DRMS_INSERT_RECORD); if (hwidth > 0) free_fresize(&fress); if (cubwid > 0) { free(kcub); free_fresize(&fresscub); } // if (verbflag) printf("module %s successful completion\n", cmdparams.argv[0]); return 0; } /* Calculate the interpolation kernel. */ void Ccker(double *u, double s) { double s2, s3; s2= s * s; s3= s2 * s; u[0] = s2 - 0.5 * (s3 + s); u[1] = 1.5*s3 - 2.5*s2 + 1.0; u[2] = -1.5*s3 + 2.0*s2 + 0.5*s; u[3] = 0.5 * (s3 - s2); } /* Cubic convolution interpolation */ double Ccintd(double *f, int nx, double x) { double ux[4]; /* Sum changed to double to speed up things */ double sum; int ix, ix1, i; if (x < 1. || x >= (double)(nx-2)) return 0.0; ix = (int)x; Ccker(ux, x - (double)ix); ix1 = ix - 1; sum = 0.; for (i = 0; i < 4; i++) sum = sum + f[ix1 + i] * ux[i]; return sum; }
Karen Tian |
Powered by ViewCVS 0.9.4 |