1 |
#include <stdio.h> |
2 |
#include <math.h> |
3 |
#include <stdlib.h> |
4 |
#include <time.h> |
5 |
#include <sys/time.h> |
6 |
#include <sys/resource.h> |
7 |
#include <fftw3.h> |
8 |
#include "jsoc_main.h" |
9 |
#include "fresize.h" |
10 |
|
11 |
#define kNOTSPECIFIED "not specified" |
12 |
#define ARRLENGTH(ARR) (sizeof(ARR)/sizeof(ARR[0])) |
13 |
#define PI (M_PI) |
14 |
#define RADSINDEG (PI/180) |
15 |
#define RTRUE (6.96000000e8) // meters |
16 |
#define AU (149597870691) // meters/au |
17 |
#define TAU_A (499.004783806) // light travel time in seconds, = 1 AU/c |
18 |
#define C (299792458) // speed of light, m/s |
19 |
|
20 |
char *module_name = "mkylms"; |
21 |
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 $"; |
22 |
|
23 |
ModuleArgs_t module_args[] = |
24 |
{ |
25 |
{ARG_STRING, "out", NULL, "output data series"}, |
26 |
{ARG_STRING, "histlink", "HISTORY", "name of link to ancillary dataseries for processing metadata"}, |
27 |
{ARG_INT, "PERM", "1", "set to 0 for transient records, nonzero for permanent records"}, |
28 |
{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}, |
29 |
{ARG_STRING, "MODELIST", kNOTSPECIFIED, "file specifying modes to generate"}, |
30 |
{ARG_INT, "XPIXELS", "1024", "number of pixels in x direction"}, |
31 |
{ARG_INT, "YPIXELS", "1024", "number of pixels in y direction"}, |
32 |
{ARG_FLOAT, "SOLARP", "0.0", "p-angle in degrees"}, |
33 |
{ARG_FLOAT, "OBSB0", "0.0", "b-angle in degrees"}, |
34 |
{ARG_FLOAT, "OBSDIST", "1.0", "distance from the sun in au"}, |
35 |
{ARG_FLOAT, "XOFFSET", "0.0", "offset in pixels from center in x direction"}, |
36 |
{ARG_FLOAT, "YOFFSET", "0.0", "offset in pixels from center in y direction"}, |
37 |
{ARG_INT, "IINTEN", "0", "flag for making intensity images, make velocity images otherwise"}, |
38 |
{ARG_FLOAT, "PHASE", "0.0", "phase in radians"}, |
39 |
{ARG_FLOAT, "FREQUENCY", "0.0", "frequency in Hz"}, |
40 |
{ARG_INT, "ILIMBDARK", "0", "flag to correct for limb darkening in intensity images"}, |
41 |
{ARG_DOUBLES,"coefs", "0.0", "limb darkening coeficients, 6 needed"}, |
42 |
{ARG_INT, "IHEIGHT", "0", "flag to correct for height of formation"}, |
43 |
|
44 |
// {ARG_INT, "ICUBINT", "0", "flag for convolving psf with cubic interpolation"}, |
45 |
{ARG_INT, "CUB_WID", "-1", "quarter width of kernel for cubic convolution"}, |
46 |
|
47 |
{ARG_FLOAT, "AIRY_CDOWN", "0.0", "ratio of the pixel nyquist frequency to the cutoff frequency of the Airy function"}, |
48 |
{ARG_INT, "AIRY_IAP", "0", "option for type of apodization"}, |
49 |
{ARG_INT, "AIRY_NAP", "1", "distance between sampled points in pixels"}, |
50 |
{ARG_INT, "AIRY_WID", "-1", "half width of kernel"}, |
51 |
{ARG_INT, "AIRY_NSUB", "1", "distance between sampled points in pixels"}, |
52 |
{ARG_INT, "AIRY_XOFF", "0", "offset in pixels to add to x index of input image"}, |
53 |
{ARG_INT, "AIRY_YOFF", "0", "offset in pixels to add to y index of input image"}, |
54 |
|
55 |
{ARG_INT, "NBIN", "-1", "factor for binning"}, |
56 |
{ARG_INT, "BIN_XOFF", "0", "offset in pixels in x direction to apply before binning"}, |
57 |
{ARG_INT, "BIN_YOFF", "0", "offset in pixels in y direction to apply before binning"}, |
58 |
|
59 |
{ARG_FLOAT, "GAUSS_SIG", "-1.0", "width of gaussian"}, |
60 |
{ARG_INT, "GAUSS_WID", "-1", "half width of kernel"}, |
61 |
{ARG_INT, "GAUSS_NSUB", "1", "distance between sampled points in pixels"}, |
62 |
{ARG_INT, "GAUSS_XOFF", "0", "offset in pixels to add to x index of input image"}, |
63 |
{ARG_INT, "GAUSS_YOFF", "0", "offset in pixels to add to y index of input image"}, |
64 |
|
65 |
/* |
66 |
{ARG_INT, "IHORIZ", "0", "flag for outputting horizontal component only, otherwise output radial component only"}, |
67 |
{ARG_INT, "IBOX", "0", "flag for convolving psf with box"}, |
68 |
{ARG_INT, "IGAUSS", "0", "flag for convolving psf with gaussian"}, |
69 |
{ARG_FLOAT, "WPSFX", "1.0", "width of gaussian psf in x direction"}, |
70 |
{ARG_FLOAT, "WPSFY", "1.0", "width of gaussian psf in y direction"}, |
71 |
{ARG_INT, "ILORENTZ", "0", "flag for convolving psf with lorentzian"}, |
72 |
{ARG_FLOAT, "WLORENTZ", "1.0", "width of lorenztian psf"}, |
73 |
{ARG_INT, "ILININT", "0", "flag for convolving psf with linear interpolation"}, |
74 |
{ARG_INT, "IBIN", "0", "flag for binning"}, |
75 |
{ARG_INT, "NBIN", "1", "factor for binning"}, |
76 |
{ARG_INT, "ISKIP", "0", "flag for subsampling"}, |
77 |
{ARG_INT, "NOFF", "2", "offset for subsampling"}, |
78 |
*/ |
79 |
{ARG_TIME, "TSTART", "1996.05.26_16:00:00_TAI", "first output time"}, |
80 |
{ARG_INT, "DTOFF", "0", "number of timesteps to offset first image"}, |
81 |
{ARG_INT, "NDT", "0", "number of time points to generate"}, |
82 |
|
83 |
{ARG_END} |
84 |
}; |
85 |
|
86 |
#include "saveparm.c" |
87 |
#include "timing.c" |
88 |
#include "set_history.c" |
89 |
#include "setplm2.c" |
90 |
|
91 |
static void Ccker(double *u, double s); |
92 |
static double Ccintd(double *f, int nx, double x); |
93 |
|
94 |
int DoIt(void) |
95 |
{ |
96 |
int newstat=0; |
97 |
int status = DRMS_SUCCESS; |
98 |
DRMS_Record_t *outrec = NULL; |
99 |
DRMS_Segment_t *segout = NULL; |
100 |
DRMS_Array_t *outarr = NULL; |
101 |
DRMS_Type_t usetype = DRMS_TYPE_FLOAT; |
102 |
DRMS_RecLifetime_t lifetime; |
103 |
long long histrecnum=-1; |
104 |
int length[2]; |
105 |
TIME trec, tnow, UNIX_epoch = -220924792.000; /* 1970.01.01_00:00:00_UTC */ |
106 |
int ipsf=0; |
107 |
struct fresize_struct fress, fresscub; |
108 |
static double defaultcoefs[] = {1.0, 0.459224, 0.132395, 0.019601, 0.000802, -4.31934E-05 }; |
109 |
|
110 |
int errbufstat=setvbuf(stderr, NULL, _IONBF, BUFSIZ); |
111 |
int outbufstat=setvbuf(stdout, NULL, _IONBF, BUFSIZ); |
112 |
|
113 |
/* |
114 |
double wt0, wt1, wt2, wt3, wt; |
115 |
double ut0, ut1, ut2, ut3, ut; |
116 |
double st0, st1, st2, st3, st; |
117 |
double ct0, ct1, ct2, ct3, ct; |
118 |
|
119 |
wt0=getwalltime(); |
120 |
ct0=getcputime(&ut0, &st0); |
121 |
*/ |
122 |
|
123 |
char *outseries = (char *)cmdparams_save_str(&cmdparams, "out", &newstat); |
124 |
int verbflag = cmdparams_save_int(&cmdparams, "VERB", &newstat); |
125 |
int permflag = cmdparams_save_int(&cmdparams, "PERM", &newstat); |
126 |
if (permflag) |
127 |
lifetime = DRMS_PERMANENT; |
128 |
else |
129 |
lifetime = DRMS_TRANSIENT; |
130 |
|
131 |
char *histlinkname = (char *)cmdparams_save_str(&cmdparams, "histlink", &newstat); |
132 |
|
133 |
char *modefile = (char *)cmdparams_save_str(&cmdparams, "MODELIST", &newstat); |
134 |
int xpixels = cmdparams_save_int(&cmdparams, "XPIXELS", &newstat); |
135 |
int ypixels = cmdparams_save_int(&cmdparams, "YPIXELS", &newstat); |
136 |
double solarp = cmdparams_save_float(&cmdparams, "SOLARP", &newstat); |
137 |
double obsb0 = cmdparams_save_float(&cmdparams, "OBSB0", &newstat); |
138 |
double obsdist = cmdparams_save_float(&cmdparams, "OBSDIST", &newstat); |
139 |
float xoffset = cmdparams_save_float(&cmdparams, "XOFFSET", &newstat); |
140 |
float yoffset = cmdparams_save_float(&cmdparams, "YOFFSET", &newstat); |
141 |
int iinten = cmdparams_save_int(&cmdparams, "IINTEN", &newstat); |
142 |
float phasein = cmdparams_save_float(&cmdparams, "PHASE", &newstat); |
143 |
float freqin = cmdparams_save_float(&cmdparams, "FREQUENCY", &newstat); |
144 |
int ilimbdark = cmdparams_save_int(&cmdparams, "ILIMBDARK", &newstat); |
145 |
double coefs[6]; |
146 |
int n_user_coefs = cmdparams_get_int(&cmdparams, "coefs_nvals", &status); |
147 |
if (ilimbdark) |
148 |
{ |
149 |
if (n_user_coefs == 6) |
150 |
{ |
151 |
double *cmdcoefs; |
152 |
int i; |
153 |
cmdparams_get_dblarr(&cmdparams, "coefs", &cmdcoefs, &status); |
154 |
for (i=0; i<6; i++) |
155 |
coefs[i] = cmdcoefs[i]; |
156 |
} |
157 |
else |
158 |
{ |
159 |
int i; |
160 |
for (i=0; i<6; i++) |
161 |
coefs[i] = defaultcoefs[i]; |
162 |
} |
163 |
} |
164 |
int iheight = cmdparams_save_int(&cmdparams, "IHEIGHT", &newstat); |
165 |
|
166 |
int nbin = cmdparams_save_int(&cmdparams, "NBIN", &newstat); |
167 |
int bxoff = cmdparams_save_int(&cmdparams, "BIN_XOFF", &newstat); |
168 |
int byoff = cmdparams_save_int(&cmdparams, "BIN_YOFF", &newstat); |
169 |
|
170 |
float sigma = cmdparams_save_float(&cmdparams, "GAUSS_SIG", &newstat); |
171 |
int hwidth = cmdparams_save_int(&cmdparams, "GAUSS_WID", &newstat); |
172 |
int nsub = cmdparams_save_int(&cmdparams, "GAUSS_NSUB", &newstat); |
173 |
int gxoff = cmdparams_save_int(&cmdparams, "GAUSS_XOFF", &newstat); |
174 |
int gyoff = cmdparams_save_int(&cmdparams, "GAUSS_YOFF", &newstat); |
175 |
// for now use this patch so i can specify integers for GAUSS_SIG |
176 |
// sigma/=sqrt(2); |
177 |
// now get rid of it for consistency |
178 |
|
179 |
int cubwid = cmdparams_save_int(&cmdparams, "CUB_WID", &newstat); |
180 |
if (cubwid > 0 && nsub > 1) |
181 |
{ |
182 |
fprintf(stderr, "ERROR: GAUSS_NSUB must be 1 for CUB_WID > 0\n"); |
183 |
return 1; |
184 |
} |
185 |
double *kcub; |
186 |
double help[] = {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}; |
187 |
if (cubwid > 0) |
188 |
{ |
189 |
int i; |
190 |
double total=0.0; |
191 |
kcub = (double *)malloc((4*cubwid+1)*sizeof(double)); |
192 |
for (i=0; i<4*cubwid+1; i++) |
193 |
{ |
194 |
kcub[i]=Ccintd(help,4*cubwid+1,1+(double)i/cubwid); |
195 |
total+=kcub[i]; |
196 |
} |
197 |
for (i=0; i<4*cubwid+1; i++) |
198 |
kcub[i]/=total; |
199 |
init_fresize_gaussian(&fresscub, 1.0, 2*cubwid, 1.0); |
200 |
for (i=0; i<4*cubwid+1; i++) |
201 |
{ |
202 |
fresscub.kerx[i]=(float)kcub[i]; |
203 |
fresscub.kery[i]=(float)kcub[i]; |
204 |
} |
205 |
} |
206 |
|
207 |
/* |
208 |
int ibox = cmdparams_save_int(&cmdparams, "IBOX", &newstat); |
209 |
int igauss = cmdparams_save_int(&cmdparams, "IGAUSS", &newstat); |
210 |
float wpsfx = cmdparams_save_float(&cmdparams, "WPSFX", &newstat); |
211 |
float wpsfy = cmdparams_save_float(&cmdparams, "WPSFY", &newstat); |
212 |
int ilorentz = cmdparams_save_int(&cmdparams, "ILORENTZ", &newstat); |
213 |
float wlorentz = cmdparams_save_float(&cmdparams, "WLORENTZ", &newstat); |
214 |
int ilinint = cmdparams_save_int(&cmdparams, "ILININT", &newstat); |
215 |
int icubint = cmdparams_save_int(&cmdparams, "ICUBINT", &newstat); |
216 |
int ibin = cmdparams_save_int(&cmdparams, "IBIN", &newstat); |
217 |
int nbin = cmdparams_save_int(&cmdparams, "NBIN", &newstat); |
218 |
int iskip = cmdparams_save_int(&cmdparams, "ISKIP", &newstat); |
219 |
int noff = cmdparams_save_int(&cmdparams, "NOFF", &newstat); |
220 |
*/ |
221 |
double tstart = cmdparams_save_time(&cmdparams, "TSTART", &newstat); |
222 |
int dtoff = cmdparams_save_int(&cmdparams, "DTOFF", &newstat); |
223 |
int ndt = cmdparams_save_int(&cmdparams, "NDT", &newstat); |
224 |
if (ndt == 0 && dtoff > 0) |
225 |
{ |
226 |
fprintf(stderr, "ERROR: cannot specify DTOFF > 0 when NDT=0\n"); |
227 |
return 1; |
228 |
} |
229 |
|
230 |
|
231 |
double pangle = RADSINDEG*solarp; |
232 |
double b0 = RADSINDEG*obsb0; |
233 |
|
234 |
// if (ibox+igauss+ilorentz+ilinint+icubint > 0) ipsf=1; |
235 |
|
236 |
FILE *fptr = fopen(modefile,"r"); |
237 |
if (fptr == NULL) |
238 |
{ |
239 |
fprintf(stderr, "ERROR: can't open mode file %s\n",modefile); |
240 |
return 1; |
241 |
} |
242 |
|
243 |
if (newstat) |
244 |
{ |
245 |
fprintf(stderr, "ERROR: problem with input arguments, status = %d, diagnosis follows\n", newstat); |
246 |
cpsave_decode_error(newstat); |
247 |
return 1; |
248 |
} |
249 |
else if (savestrlen != strlen(savestr)) |
250 |
{ |
251 |
fprintf(stderr, "ERROR: problem with savestr, savestrlen = %d, strlen(savestr) = %d\n", savestrlen, (int)strlen(savestr)); |
252 |
return 1; |
253 |
} |
254 |
|
255 |
// set up ancillary dataseries for processing metadata |
256 |
DRMS_Record_t *tempoutrec = drms_create_record(drms_env, |
257 |
outseries, |
258 |
DRMS_TRANSIENT, |
259 |
&status); |
260 |
|
261 |
if (status != DRMS_SUCCESS) |
262 |
{ |
263 |
fprintf(stderr,"ERROR: couldn't open a record in output dataseries %s, status = %d\n", outseries, status); |
264 |
return 1; |
265 |
} |
266 |
|
267 |
DRMS_Link_t *histlink = hcon_lookup_lower(&tempoutrec->links, histlinkname); |
268 |
if (histlink != NULL) |
269 |
{ |
270 |
histrecnum=set_history(histlink); |
271 |
if (histrecnum < 0) |
272 |
{ |
273 |
drms_close_record(tempoutrec, DRMS_FREE_RECORD); |
274 |
return 1; |
275 |
} |
276 |
} |
277 |
else |
278 |
{ |
279 |
fprintf(stderr,"WARNING: could not find history link in output dataseries\n"); |
280 |
} |
281 |
|
282 |
|
283 |
// these must be present in the output dataseries and variable, not links or constants |
284 |
char *outchecklist[] = {"T_REC", "QUALITY", "T_OBS", "CRLT_OBS", "CRLN_OBS", |
285 |
//"SAT_ROT", "INST_ROT", "IM_SCALE", |
286 |
"CDELT1", "CDELT2"}; |
287 |
|
288 |
int itest; |
289 |
for (itest=0; itest < ARRLENGTH(outchecklist); itest++) |
290 |
{ |
291 |
DRMS_Keyword_t *outkeytest = hcon_lookup_lower(&tempoutrec->keywords, outchecklist[itest]); |
292 |
if (!outkeytest || outkeytest->info->islink || outkeytest->info->recscope == 1) |
293 |
{ |
294 |
fprintf(stderr, "ERROR: output keyword %s is either missing, constant, or a link\n", outchecklist[itest]); |
295 |
drms_close_record(tempoutrec, DRMS_FREE_RECORD); |
296 |
return 1; |
297 |
} |
298 |
} |
299 |
float cadence = drms_getkey_float(tempoutrec, "T_REC_step", &status); |
300 |
drms_close_record(tempoutrec, DRMS_FREE_RECORD); |
301 |
|
302 |
int i, hold; |
303 |
long nmodes=0; |
304 |
while ((hold = getc(fptr)) != EOF) |
305 |
if (hold == '\n') |
306 |
nmodes++; |
307 |
fclose(fptr); |
308 |
|
309 |
fptr = fopen(modefile,"r"); |
310 |
int *lim, *mim; |
311 |
int lin, min; |
312 |
int mmax=0; |
313 |
int lmax=0; |
314 |
int *marr_lmax, *marr_count, **marr_index; |
315 |
// fscanf(fptr,"%d",&nmodes); |
316 |
lim=(int *)malloc(nmodes*sizeof(int)); |
317 |
mim=(int *)malloc(nmodes*sizeof(int)); |
318 |
for (i=0;i<nmodes;i++) |
319 |
{ |
320 |
if (fscanf(fptr,"%d %d\n", &lin, &min) != 2) |
321 |
{ |
322 |
fprintf(stderr,"ERROR: something went wrong on line i=%d\n", i); |
323 |
return 1; |
324 |
} |
325 |
// fscanf(fptr,"%d",&lin); |
326 |
// fscanf(fptr,"%d",&min); |
327 |
if (min > lin || lin < 0) |
328 |
{ |
329 |
fprintf(stderr,"ERROR: mode file has m > l or l < 0\n"); |
330 |
return 1; |
331 |
} |
332 |
/* |
333 |
if (min > mmax) |
334 |
mmax=min; |
335 |
if (lin > lmax) |
336 |
lmax=lin; |
337 |
*/ |
338 |
lim[i]=lin; |
339 |
mim[i]=min; |
340 |
} |
341 |
fclose(fptr); |
342 |
|
343 |
if (verbflag) |
344 |
printf("nmodes=%ld, dtoff=%d, ndt=%d\n", nmodes, dtoff, ndt); |
345 |
|
346 |
int *lim2, *mim2; |
347 |
if (ndt > 0) |
348 |
{ |
349 |
if (dtoff + ndt > nmodes) |
350 |
nmodes=nmodes-dtoff; |
351 |
else |
352 |
nmodes=ndt; |
353 |
|
354 |
lim2=(int *)malloc(nmodes*sizeof(int)); |
355 |
mim2=(int *)malloc(nmodes*sizeof(int)); |
356 |
for (i=0;i<nmodes;i++) |
357 |
{ |
358 |
lim2[i]=lim[dtoff+i]; |
359 |
mim2[i]=mim[dtoff+i]; |
360 |
} |
361 |
free(lim); |
362 |
free(mim); |
363 |
lim=lim2; |
364 |
mim=mim2; |
365 |
} |
366 |
|
367 |
if (nmodes <= 0) |
368 |
{ |
369 |
fprintf(stderr, "ERROR: no modes selected\n"); |
370 |
return 1; |
371 |
} |
372 |
|
373 |
for (i=0;i<nmodes;i++) |
374 |
{ |
375 |
if (mim[i] > mmax) |
376 |
mmax=mim[i]; |
377 |
if (lim[i] > lmax) |
378 |
lmax=lim[i]; |
379 |
} |
380 |
|
381 |
marr_lmax=(int *)(malloc((mmax+1)*sizeof(int))); |
382 |
marr_count=(int *)(malloc((mmax+1)*sizeof(int))); |
383 |
marr_index=(int **)(malloc((mmax+1)*sizeof(int *))); |
384 |
for (i=0;i<=mmax;i++) |
385 |
{ |
386 |
marr_lmax[i]=-1; |
387 |
marr_count[i]=0; |
388 |
marr_index[i]=(int *)(malloc((lmax+1)*sizeof(int))); |
389 |
} |
390 |
for (i=0;i<nmodes;i++) |
391 |
{ |
392 |
if (lim[i] > marr_lmax[mim[i]]) |
393 |
marr_lmax[mim[i]]=lim[i]; |
394 |
marr_index[mim[i]][marr_count[mim[i]]]=i; |
395 |
marr_count[mim[i]]++; |
396 |
} |
397 |
|
398 |
// double obsdist = 1.0; //in au |
399 |
double distobs = obsdist*AU/RTRUE; //in solar radii |
400 |
double dsunobs = obsdist*AU; //in meters |
401 |
double x0=(double)xpixels/2-0.5 + xoffset; |
402 |
double y0=(double)ypixels/2-0.5 + yoffset; |
403 |
long npixels=xpixels*ypixels; |
404 |
double imscale=1.97784*1024/xpixels; |
405 |
double scale=imscale/(180*60*60/PI); |
406 |
length[0]=xpixels; |
407 |
length[1]=ypixels; |
408 |
float obsl0=211.67; |
409 |
int obscr=1784; |
410 |
// double rsunobs=atan(asin(RTRUE/AU/obsdist))*60*60/RADSINDEG; |
411 |
// double rsun=rsunobs/imscale; |
412 |
double rsunobs=asin(RTRUE/AU/obsdist)*60*60/RADSINDEG; |
413 |
double rsun=tan(asin(RTRUE/AU/obsdist))/scale; |
414 |
double cdelt=rsunobs/rsun; // Use mean image scale across solar image |
415 |
/* |
416 |
; Sun is sitting at the center of the main coordinate system |
417 |
; and has radius 1. |
418 |
; Observer is at robs=(xobs,yobs,zobs) moving with a velocity |
419 |
; vobs. |
420 |
; Start by setting robs from distobs and b0 |
421 |
*/ |
422 |
|
423 |
double robs_x = distobs * cos(b0); |
424 |
double robs_y = 0.0; |
425 |
double robs_z = distobs * sin(b0); |
426 |
|
427 |
// Start with CCD coordinates |
428 |
double *x6 = (double *)(malloc(npixels*sizeof(double))); |
429 |
double *y6 = (double *)(malloc(npixels*sizeof(double))); |
430 |
int j; |
431 |
for (i=0;i<ypixels;i++) |
432 |
for (j=0;j<xpixels;j++) |
433 |
x6[i*ypixels+j]=(double)j; |
434 |
for (i=0;i<ypixels;i++) |
435 |
for (j=0;j<xpixels;j++) |
436 |
y6[i*ypixels+j]=(double)i; |
437 |
|
438 |
double *x4 = (double *)(malloc(npixels*sizeof(double))); |
439 |
double *y4 = (double *)(malloc(npixels*sizeof(double))); |
440 |
for (i=0;i<npixels;i++) |
441 |
{ |
442 |
x4[i]=scale*(x6[i] - x0); |
443 |
y4[i]=scale*(y6[i] - y0); |
444 |
} |
445 |
|
446 |
|
447 |
/* |
448 |
; Rotate by the P-angle. New coordinate system has the y-axis pointing |
449 |
; towards the solar north pole. |
450 |
*/ |
451 |
|
452 |
double *x2 = (double *)(malloc(npixels*sizeof(double))); |
453 |
double *y2 = (double *)(malloc(npixels*sizeof(double))); |
454 |
for (i=0;i<npixels;i++) |
455 |
{ |
456 |
x2[i]= x4[i]*cos(pangle) + y4[i]*sin(pangle); |
457 |
y2[i]=-x4[i]*sin(pangle) + y4[i]*cos(pangle); |
458 |
} |
459 |
|
460 |
|
461 |
/* |
462 |
; Now transform to put the coordinates into the solar coordinate |
463 |
; system. |
464 |
; First find the directions (vecx and vecy) the x2 and y2 coordinate |
465 |
; axis correspond to. vecsun points towards the Sun. Note that the |
466 |
; (x2,y2,Sun) system is left handed. These vectors are unit vectors. |
467 |
*/ |
468 |
double vecx_x=0.0; |
469 |
double vecx_y=1.0; |
470 |
double vecx_z=0.0; |
471 |
double vecy_x=-sin(b0); |
472 |
double vecy_y=0.0; |
473 |
double vecy_z=cos(b0); |
474 |
double vecsun_x=-cos(b0); |
475 |
double vecsun_y=0.0; |
476 |
double vecsun_z=-sin(b0); |
477 |
// Now the proper direction can be found. These are not unit vectors. |
478 |
double *x1 = (double *)(malloc(npixels*sizeof(double))); |
479 |
double *y1 = (double *)(malloc(npixels*sizeof(double))); |
480 |
double *z1 = (double *)(malloc(npixels*sizeof(double))); |
481 |
double *q1 = (double *)(malloc(npixels*sizeof(double))); |
482 |
for (i=0;i<npixels;i++) |
483 |
{ |
484 |
x1[i]=vecx_x*x2[i] + vecy_x*y2[i] + vecsun_x; |
485 |
y1[i]=vecx_y*x2[i] + vecy_y*y2[i] + vecsun_y; |
486 |
z1[i]=vecx_z*x2[i] + vecy_z*y2[i] + vecsun_z; |
487 |
q1[i]=1/sqrt(x1[i]*x1[i] + y1[i]*y1[i] + z1[i]*z1[i]); |
488 |
} |
489 |
// Make them unit vectors. |
490 |
for (i=0;i<npixels;i++) |
491 |
{ |
492 |
x1[i]*=q1[i]; |
493 |
y1[i]*=q1[i]; |
494 |
z1[i]*=q1[i]; |
495 |
} |
496 |
|
497 |
|
498 |
|
499 |
// Now find intersection with the Sun. |
500 |
// Solve quadratic equation |robs+q*[x1,y1,z1]|=1 for q |
501 |
// a, b and c are terms in a*x^2+bx+c=0. a==1 since [x1,y1,z1] is unit vector. |
502 |
// double *b = (double *)(malloc(npixels*sizeof(double))); |
503 |
// double *d = (double *)(malloc(npixels*sizeof(double))); |
504 |
double b,d; |
505 |
double *q = (double *)(malloc(npixels*sizeof(double))); |
506 |
int *inflag = (int *)(malloc(npixels*sizeof(int))); |
507 |
double c = robs_x*robs_x + robs_y*robs_y + robs_z*robs_z -1; |
508 |
double *xsun = (double *)(malloc(npixels*sizeof(double))); |
509 |
double *ysun = (double *)(malloc(npixels*sizeof(double))); |
510 |
double *zsun = (double *)(malloc(npixels*sizeof(double))); |
511 |
double *cosrho = (double *)(malloc(npixels*sizeof(double))); |
512 |
for (i=0;i<npixels;i++) |
513 |
{ |
514 |
// b[i]=2*(x1[i]*robs_x+y1[i]*robs_y+z1[i]*robs_z); |
515 |
// d[i]=b[i]*b[i] - 4*c; |
516 |
b=2*(x1[i]*robs_x+y1[i]*robs_y+z1[i]*robs_z); |
517 |
d=b*b - 4*c; |
518 |
if (d >= 0) |
519 |
{ |
520 |
inflag[i]=1; |
521 |
q[i]=(-b - sqrt(d))/2; |
522 |
xsun[i]=robs_x + x1[i]*q[i]; |
523 |
ysun[i]=robs_y + y1[i]*q[i]; |
524 |
zsun[i]=robs_z + z1[i]*q[i]; |
525 |
cosrho[i]=-(x1[i]*xsun[i]+y1[i]*ysun[i]+z1[i]*zsun[i]); |
526 |
} |
527 |
else |
528 |
{ |
529 |
inflag[i]=0; |
530 |
xsun[i]=0; |
531 |
ysun[i]=0; |
532 |
zsun[i]=0; |
533 |
cosrho[i]=0; |
534 |
} |
535 |
} |
536 |
|
537 |
if (iheight) |
538 |
{ |
539 |
// Now calculate observing height in units of the solar radius |
540 |
double pc3[]={0.24047045,-0.76504325,0.86252178,-0.33859142}; |
541 |
double height; |
542 |
double c0 = robs_x*robs_x + robs_y*robs_y + robs_z*robs_z; |
543 |
for (i=0;i<npixels;i++) |
544 |
{ |
545 |
double x=1.0; |
546 |
height=pc3[0]; |
547 |
for (j=1;j<4;j++) |
548 |
{ |
549 |
x*=cosrho[i]; |
550 |
height+=pc3[j]*x; |
551 |
} |
552 |
height*=1e6/RTRUE; |
553 |
// Recalculate coordinates. |
554 |
b=2*(x1[i]*robs_x+y1[i]*robs_y+z1[i]*robs_z); |
555 |
c=c0-(1+height)*(1+height); |
556 |
d=b*b - 4*c; |
557 |
if (d >= 0) |
558 |
{ |
559 |
inflag[i]=1; |
560 |
q[i]=(-b - sqrt(d))/2; |
561 |
// Remember to divide by new target radius |
562 |
xsun[i]=(robs_x + x1[i]*q[i])/(1+height); |
563 |
ysun[i]=(robs_y + y1[i]*q[i])/(1+height); |
564 |
zsun[i]=(robs_z + z1[i]*q[i])/(1+height); |
565 |
} |
566 |
else |
567 |
{ |
568 |
inflag[i]=0; |
569 |
xsun[i]=0; |
570 |
ysun[i]=0; |
571 |
zsun[i]=0; |
572 |
} |
573 |
} |
574 |
} |
575 |
|
576 |
double *phisun = (double *)(malloc(npixels*sizeof(double))); |
577 |
double *cphisun = (double *)(malloc(npixels*sizeof(double))); |
578 |
double *sphisun = (double *)(malloc(npixels*sizeof(double))); |
579 |
double *clatsun = (double *)(malloc(npixels*sizeof(double))); |
580 |
double *slatsun = (double *)(malloc(npixels*sizeof(double))); |
581 |
double *prad = (double *)(malloc(npixels*sizeof(double))); |
582 |
double *pphi = (double *)(malloc(npixels*sizeof(double))); |
583 |
double *plat = (double *)(malloc(npixels*sizeof(double))); |
584 |
|
585 |
for (i=0;i<npixels;i++) |
586 |
{ |
587 |
phisun[i] = atan2(ysun[i],xsun[i]); |
588 |
cphisun[i] = cos(phisun[i]); |
589 |
sphisun[i] = sin(phisun[i]); |
590 |
slatsun[i] = zsun[i]; |
591 |
clatsun[i] = sqrt(1 - zsun[i]*zsun[i]); |
592 |
// Set velocity projection factors |
593 |
prad[i]=xsun[i]*x1[i]+ysun[i]*y1[i]+zsun[i]*z1[i]; |
594 |
pphi[i]=-sphisun[i]*x1[i]+cphisun[i]*y1[i]; |
595 |
plat[i]=-cphisun[i]*slatsun[i]*x1[i]-sphisun[i]*slatsun[i]*y1[i]+clatsun[i]*z1[i]; |
596 |
} |
597 |
|
598 |
double *ld; |
599 |
if (ilimbdark) |
600 |
{ |
601 |
ld=(double *)malloc(npixels*sizeof(double)); |
602 |
int iy,ix; |
603 |
for (iy=0; iy<ypixels; iy++) |
604 |
for (ix=0; ix<xpixels; ix++) |
605 |
{ |
606 |
double costheta2; |
607 |
double xi, mu, z, ldi; |
608 |
double x, y, R2; |
609 |
int ord; |
610 |
int index=iy*xpixels + ix; |
611 |
|
612 |
if (!inflag[index]) |
613 |
continue; |
614 |
|
615 |
/* get coordinates of point */ |
616 |
x = ((double)ix - x0) / rsun; |
617 |
y = ((double)iy - y0) / rsun; |
618 |
|
619 |
|
620 |
R2 = x*x + y*y; |
621 |
if (R2 <= 1.0) |
622 |
costheta2 = 1.0 - R2; |
623 |
else |
624 |
costheta2 = 0.0; |
625 |
|
626 |
mu = sqrt(costheta2); |
627 |
xi = log(mu); |
628 |
z = 1.0; |
629 |
ldi = 1.0; |
630 |
for (ord=1; ord<6; ord++) |
631 |
{ |
632 |
z *= xi; |
633 |
ldi += coefs[ord] * z; |
634 |
} |
635 |
// not sure what to do with this... |
636 |
if (ldi <= 0.0 || isnan(ldi)) |
637 |
{ |
638 |
//*Op = missval; |
639 |
//ncropped++; |
640 |
ld[index]=0.0; |
641 |
} |
642 |
else |
643 |
ld[index] = ldi; |
644 |
} |
645 |
} |
646 |
|
647 |
free(x6);free(y6);free(x4);free(y4);free(x2);free(y2); |
648 |
free(x1);free(y1);free(z1);free(q1); |
649 |
// free(b);free(d); |
650 |
free(cosrho); |
651 |
free(xsun);free(ysun);free(zsun); |
652 |
|
653 |
if (verbflag) |
654 |
printf("coordinate arrays set up\n"); |
655 |
|
656 |
int lmax1, l, m, il; |
657 |
long nplm=10001; |
658 |
double *plm = (double *)(malloc(nplm*(lmax+1)*sizeof(double))); |
659 |
double *dplm = (double *)(malloc(nplm*(lmax+1)*sizeof(double))); |
660 |
double *plms = (double *)(malloc(nplm*nmodes*sizeof(double))); |
661 |
double *dplms = (double *)(malloc(nplm*nmodes*sizeof(double))); |
662 |
double *dxplm = (double *)(malloc(nplm*sizeof(double))); |
663 |
for (i=0;i<nplm;i++) |
664 |
dxplm[i]= -1 + (double)i * 2 / (nplm - 1); |
665 |
int *indx = (int *)(malloc ((lmax+1)*sizeof(int))); |
666 |
for (l=0; l<=lmax; l++) |
667 |
indx[l]=l; |
668 |
|
669 |
for (m=0;m<=mmax;m++) |
670 |
{ |
671 |
if (marr_lmax[m] == -1) |
672 |
continue; |
673 |
lmax1=marr_lmax[m]; |
674 |
setplm2(m, lmax1, m, nplm, indx, dxplm, nplm, plm, dplm); |
675 |
for (i=0;i<marr_count[m];i++) |
676 |
{ |
677 |
il=marr_index[m][i]; |
678 |
l=lim[il]; |
679 |
for (j=0;j<nplm;j++) |
680 |
{ |
681 |
plms[il*nplm + j]=plm[l*nplm + j]; |
682 |
dplms[il*nplm + j]=dplm[l*nplm + j]; |
683 |
} |
684 |
} |
685 |
} |
686 |
|
687 |
free(plm); |
688 |
free(dplm); |
689 |
free(dxplm); |
690 |
|
691 |
if (verbflag) |
692 |
printf("plms set up\n"); |
693 |
|
694 |
// float cadence=60.0; |
695 |
// double time0=612201600.0 + dtoff*cadence; |
696 |
double time0=tstart + dtoff*cadence; |
697 |
double *vradr=(double *)(malloc(npixels*sizeof(double))); |
698 |
double *vradi=(double *)(malloc(npixels*sizeof(double))); |
699 |
|
700 |
//reuse arrays malloc'ed above to save memory |
701 |
double *vlatr, *vlati; |
702 |
vlatr=vradr; |
703 |
vlati=vradi; |
704 |
// double *vlatr=(double *)(malloc(npixels*sizeof(double))); |
705 |
// double *vlati=(double *)(malloc(npixels*sizeof(double))); |
706 |
double *vphir=(double *)(malloc(npixels*sizeof(double))); |
707 |
double *vphii=(double *)(malloc(npixels*sizeof(double))); |
708 |
|
709 |
/* |
710 |
double *velr=(double *)(malloc(npixels*sizeof(double))); |
711 |
double *veli=(double *)(malloc(npixels*sizeof(double))); |
712 |
double *velsum=(double *)(malloc(npixels*sizeof(double))); |
713 |
*/ |
714 |
float *velr=(float *)(malloc(npixels*sizeof(float))); |
715 |
float *veli=(float *)(malloc(npixels*sizeof(float))); |
716 |
float *velsum=(float *)(malloc(npixels*sizeof(float))); |
717 |
float *velrsave=velr; |
718 |
float *velisave=veli; |
719 |
float *velssave=velsum; |
720 |
|
721 |
double *plminterp=(double *)(malloc(npixels*sizeof(double))); |
722 |
double ll, dinterp; |
723 |
|
724 |
float *binptr; |
725 |
int xpix1=xpixels; |
726 |
int ypix1=ypixels; |
727 |
if (nbin > 0) |
728 |
{ |
729 |
x0=(x0 - bxoff + 0.5)/nbin - 0.5; |
730 |
y0=(y0 - byoff + 0.5)/nbin - 0.5; |
731 |
// imscale*=nbin; |
732 |
cdelt*=nbin; |
733 |
xpix1=xpixels/nbin; |
734 |
ypix1=ypixels/nbin; |
735 |
length[0]=xpix1; |
736 |
length[1]=ypix1; |
737 |
binptr=(float *)malloc(xpix1*ypix1*sizeof(float)); |
738 |
} |
739 |
|
740 |
float *gaussptr; |
741 |
int xpix2, ypix2; |
742 |
if (hwidth > 0) |
743 |
{ |
744 |
x0=(x0 - gxoff)/nsub; |
745 |
y0=(y0 - gyoff)/nsub; |
746 |
// imscale*=nsub; |
747 |
cdelt*=nsub; |
748 |
xpix2=xpix1/nsub; |
749 |
ypix2=ypix1/nsub; |
750 |
length[0]=xpix2; |
751 |
length[1]=ypix2; |
752 |
gaussptr=(float *)malloc(xpix2*ypix2*sizeof(float)); |
753 |
init_fresize_gaussian(&fress, sigma, hwidth, nsub); |
754 |
} |
755 |
|
756 |
double *phase=(double *)malloc(npixels*sizeof(double)); |
757 |
double rsecs = RTRUE/C; |
758 |
for (i=0;i<npixels;i++) |
759 |
{ |
760 |
if (inflag[i]) |
761 |
{ |
762 |
double deltat; |
763 |
deltat=(q[i]-distobs+1)*rsecs; |
764 |
phase[i]=phasein-2*PI*freqin*deltat; |
765 |
} |
766 |
} |
767 |
|
768 |
DRMS_RecordSet_t *outrecset=drms_create_records(drms_env, nmodes, outseries, lifetime, &status); |
769 |
if (status != DRMS_SUCCESS || outrecset == NULL) |
770 |
{ |
771 |
fprintf(stderr,"ERROR: unable to create output recordset, status = %d\n", status); |
772 |
return 0; |
773 |
} |
774 |
|
775 |
for (i=0;i<nmodes;i++) |
776 |
{ |
777 |
trec=time0+i*cadence; |
778 |
if (verbflag > 1) |
779 |
printf("i=%d, trec=%f, l=%d, m=%d\n",i,trec,lim[i],mim[i]); |
780 |
|
781 |
/* |
782 |
outrec = drms_create_record(drms_env, outseries, lifetime, &status); |
783 |
if (status != DRMS_SUCCESS || outrec == NULL) |
784 |
{ |
785 |
fprintf(stderr,"ERROR: unable to open record in output dataseries, i = %d, status = %d\n", i, status); |
786 |
return 0; |
787 |
} |
788 |
*/ |
789 |
outrec=outrecset->records[i]; |
790 |
if (histlink) |
791 |
drms_setlink_static(outrec, histlinkname, histrecnum); |
792 |
|
793 |
for (j=0;j<npixels;j++) |
794 |
plminterp[j]=Ccintd(&plms[i*nplm],nplm,(nplm-1)*(slatsun[j]+1)/2); |
795 |
|
796 |
for (j=0;j<npixels;j++) |
797 |
{ |
798 |
if (inflag[j]) |
799 |
{ |
800 |
vradr[j]=1000 * (cos(mim[i]*phisun[j]+phase[j])) * plminterp[j]; //Ccintd(&plms[i*nplm],nplm,(nplm-1)*(slatsun[j]+1)/2); |
801 |
vradi[j]=1000 * (sin(mim[i]*phisun[j]+phase[j])) * plminterp[j]; //Ccintd(&plms[i*nplm],nplm,(nplm-1)*(slatsun[j]+1)/2); |
802 |
// needed to make main leaks positive since DATASIGN=-1 |
803 |
if (iinten) |
804 |
{ |
805 |
if (ilimbdark) |
806 |
{ |
807 |
velr[j]=-1*vradr[j]*ld[j]; |
808 |
veli[j]=-1*vradi[j]*ld[j]; |
809 |
velsum[j]=velr[j]+veli[j]; |
810 |
} |
811 |
else |
812 |
{ |
813 |
velr[j]=-1*vradr[j]; |
814 |
veli[j]=-1*vradi[j]; |
815 |
velsum[j]=velr[j]+veli[j]; |
816 |
} |
817 |
} |
818 |
else |
819 |
{ |
820 |
velr[j]=prad[j]*vradr[j]; |
821 |
veli[j]=prad[j]*vradi[j]; |
822 |
velsum[j]=velr[j]+veli[j]; |
823 |
} |
824 |
/* |
825 |
if (j == 524800) |
826 |
velsum[j]=1.0; |
827 |
else |
828 |
velsum[j]=0.0; |
829 |
*/ |
830 |
} |
831 |
else |
832 |
{ |
833 |
velr[j]=0; |
834 |
veli[j]=0; |
835 |
velsum[j]=0; |
836 |
} |
837 |
} |
838 |
|
839 |
segout = drms_segment_lookup(outrec, "vradr"); |
840 |
if (segout != NULL) |
841 |
{ |
842 |
if (nbin > 0) |
843 |
{ |
844 |
fbin(velr, binptr, xpixels, ypixels, xpixels, xpix1, ypix1, xpix1, nbin, bxoff, byoff, 0.0); |
845 |
velr=binptr; |
846 |
} |
847 |
|
848 |
if (hwidth > 0) |
849 |
{ |
850 |
fresize(&fress, velr, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, gxoff, gyoff, 0.0); |
851 |
velr=gaussptr; |
852 |
} |
853 |
|
854 |
if (cubwid > 0) |
855 |
{ |
856 |
//in this case xpix1=xpix2 |
857 |
fresize(&fresscub, velr, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, 0.0, 0.0, 0.0); |
858 |
velr=gaussptr; |
859 |
} |
860 |
|
861 |
outarr = drms_array_create(DRMS_TYPE_FLOAT, 2, length, velr, &status); |
862 |
if (outarr == NULL || status != DRMS_SUCCESS) |
863 |
{ |
864 |
fprintf(stderr, "ERROR: problem with output segment or array, i = %d, status = %d\n", i, status); |
865 |
return 0; |
866 |
} |
867 |
outarr->bzero=segout->bzero; |
868 |
outarr->bscale=segout->bscale; |
869 |
drms_segment_write(segout, outarr, 0); |
870 |
free(outarr); |
871 |
} |
872 |
|
873 |
|
874 |
segout = drms_segment_lookup(outrec, "vradi"); |
875 |
if (segout != NULL) |
876 |
{ |
877 |
if (nbin > 0) |
878 |
{ |
879 |
fbin(veli, binptr, xpixels, ypixels, xpixels, xpix1, ypix1, xpix1, nbin, bxoff, byoff, 0.0); |
880 |
veli=binptr; |
881 |
} |
882 |
|
883 |
if (hwidth > 0) |
884 |
{ |
885 |
fresize(&fress, veli, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, gxoff, gyoff, 0.0); |
886 |
veli=gaussptr; |
887 |
} |
888 |
|
889 |
if (cubwid > 0) |
890 |
{ |
891 |
//in this case xpix1=xpix2 |
892 |
fresize(&fresscub, velr, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, 0.0, 0.0, 0.0); |
893 |
veli=gaussptr; |
894 |
} |
895 |
|
896 |
outarr = drms_array_create(DRMS_TYPE_FLOAT, 2, length, veli, &status); |
897 |
if (outarr == NULL || status != DRMS_SUCCESS) |
898 |
{ |
899 |
fprintf(stderr, "ERROR: problem with output segment or array, i = %d, status = %d\n", i, status); |
900 |
return 0; |
901 |
} |
902 |
outarr->bzero=segout->bzero; |
903 |
outarr->bscale=segout->bscale; |
904 |
drms_segment_write(segout, outarr, 0); |
905 |
free(outarr); |
906 |
} |
907 |
|
908 |
|
909 |
segout = drms_segment_lookup(outrec, "vradsum"); |
910 |
if (segout != NULL) |
911 |
{ |
912 |
if (nbin > 0) |
913 |
{ |
914 |
fbin(velsum, binptr, xpixels, ypixels, xpixels, xpix1, ypix1, xpix1, nbin, bxoff, byoff, 0.0); |
915 |
velsum=binptr; |
916 |
} |
917 |
|
918 |
if (hwidth > 0) |
919 |
{ |
920 |
fresize(&fress, velsum, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, gxoff, gyoff, 0.0); |
921 |
velsum=gaussptr; |
922 |
} |
923 |
|
924 |
if (cubwid > 0) |
925 |
{ |
926 |
//in this case xpix1=xpix2 |
927 |
fresize(&fresscub, velr, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, 0.0, 0.0, 0.0); |
928 |
velsum=gaussptr; |
929 |
} |
930 |
|
931 |
outarr = drms_array_create(DRMS_TYPE_FLOAT, 2, length, velsum, &status); |
932 |
if (outarr == NULL || status != DRMS_SUCCESS) |
933 |
{ |
934 |
fprintf(stderr, "ERROR: problem with output segment or array, i = %d, status = %d\n", i, status); |
935 |
return 0; |
936 |
} |
937 |
outarr->bzero=segout->bzero; |
938 |
outarr->bscale=segout->bscale; |
939 |
drms_segment_write(segout, outarr, 0); |
940 |
free(outarr); |
941 |
} |
942 |
|
943 |
|
944 |
if (!iinten) |
945 |
{ |
946 |
velr=velrsave; |
947 |
veli=velisave; |
948 |
velsum=velssave; |
949 |
for (j=0;j<npixels;j++) |
950 |
{ |
951 |
if (inflag[j]) |
952 |
{ |
953 |
if (lim[i] != 0) |
954 |
{ |
955 |
ll=sqrt(lim[i]*(lim[i]+1.0)); |
956 |
dinterp=Ccintd(&dplms[i*nplm],nplm,(nplm-1)*(slatsun[j]+1)/2); |
957 |
vlatr[j]=1000 * (cos(mim[i]*phisun[j]+phase[j]))*dinterp/ll*clatsun[j]; |
958 |
vlati[j]=1000 * (sin(mim[i]*phisun[j]+phase[j]))*dinterp/ll*clatsun[j]; |
959 |
vphir[j]=1000 * mim[i]*(-sin(mim[i]*phisun[j]+phase[j]))*plminterp[j]/ll/clatsun[j]; |
960 |
vphii[j]=1000 * mim[i]*( cos(mim[i]*phisun[j]+phase[j]))*plminterp[j]/ll/clatsun[j]; |
961 |
} |
962 |
else |
963 |
{ |
964 |
vlatr[j]=vlati[j]=0; |
965 |
vphir[j]=vphii[j]=0; |
966 |
} |
967 |
velr[j]=pphi[j]*vphir[j]+plat[j]*vlatr[j]; |
968 |
veli[j]=pphi[j]*vphii[j]+plat[j]*vlati[j]; |
969 |
velsum[j]=velr[j]+veli[j]; |
970 |
} |
971 |
else |
972 |
{ |
973 |
velr[j]=0; |
974 |
veli[j]=0; |
975 |
velsum[j]=0; |
976 |
} |
977 |
} |
978 |
|
979 |
segout = drms_segment_lookup(outrec, "vhorr"); |
980 |
if (segout != NULL) |
981 |
{ |
982 |
if (nbin > 0) |
983 |
{ |
984 |
fbin(velr, binptr, xpixels, ypixels, xpixels, xpix1, ypix1, xpix1, nbin, bxoff, byoff, 0.0); |
985 |
velr=binptr; |
986 |
} |
987 |
|
988 |
if (hwidth > 0) |
989 |
{ |
990 |
fresize(&fress, velr, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, gxoff, gyoff, 0.0); |
991 |
velr=gaussptr; |
992 |
} |
993 |
|
994 |
if (cubwid > 0) |
995 |
{ |
996 |
//in this case xpix1=xpix2 |
997 |
fresize(&fresscub, velr, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, 0.0, 0.0, 0.0); |
998 |
velr=gaussptr; |
999 |
} |
1000 |
|
1001 |
outarr = drms_array_create(DRMS_TYPE_FLOAT, 2, length, velr, &status); |
1002 |
if (outarr == NULL || status != DRMS_SUCCESS) |
1003 |
{ |
1004 |
fprintf(stderr, "ERROR: problem with output segment or array, i = %d, status = %d\n", i, status); |
1005 |
return 0; |
1006 |
} |
1007 |
outarr->bzero=segout->bzero; |
1008 |
outarr->bscale=segout->bscale; |
1009 |
drms_segment_write(segout, outarr, 0); |
1010 |
free(outarr); |
1011 |
} |
1012 |
|
1013 |
|
1014 |
segout = drms_segment_lookup(outrec, "vhori"); |
1015 |
if (segout != NULL) |
1016 |
{ |
1017 |
if (nbin > 0) |
1018 |
{ |
1019 |
fbin(veli, binptr, xpixels, ypixels, xpixels, xpix1, ypix1, xpix1, nbin, bxoff, byoff, 0.0); |
1020 |
veli=binptr; |
1021 |
} |
1022 |
|
1023 |
if (hwidth > 0) |
1024 |
{ |
1025 |
fresize(&fress, veli, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, gxoff, gyoff, 0.0); |
1026 |
veli=gaussptr; |
1027 |
} |
1028 |
|
1029 |
if (cubwid > 0) |
1030 |
{ |
1031 |
//in this case xpix1=xpix2 |
1032 |
fresize(&fresscub, velr, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, 0.0, 0.0, 0.0); |
1033 |
veli=gaussptr; |
1034 |
} |
1035 |
|
1036 |
outarr = drms_array_create(DRMS_TYPE_FLOAT, 2, length, veli, &status); |
1037 |
if (outarr == NULL || status != DRMS_SUCCESS) |
1038 |
{ |
1039 |
fprintf(stderr, "ERROR: problem with output segment or array, i = %d, status = %d\n", i, status); |
1040 |
return 0; |
1041 |
} |
1042 |
outarr->bzero=segout->bzero; |
1043 |
outarr->bscale=segout->bscale; |
1044 |
drms_segment_write(segout, outarr, 0); |
1045 |
free(outarr); |
1046 |
} |
1047 |
|
1048 |
|
1049 |
segout = drms_segment_lookup(outrec, "vhorsum"); |
1050 |
if (segout != NULL) |
1051 |
{ |
1052 |
if (nbin > 0) |
1053 |
{ |
1054 |
fbin(velsum, binptr, xpixels, ypixels, xpixels, xpix1, ypix1, xpix1, nbin, bxoff, byoff, 0.0); |
1055 |
velsum=binptr; |
1056 |
} |
1057 |
|
1058 |
if (hwidth > 0) |
1059 |
{ |
1060 |
fresize(&fress, velsum, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, gxoff, gyoff, 0.0); |
1061 |
velsum=gaussptr; |
1062 |
} |
1063 |
|
1064 |
if (cubwid > 0) |
1065 |
{ |
1066 |
//in this case xpix1=xpix2 |
1067 |
fresize(&fresscub, velr, gaussptr, xpix1, ypix1, xpix1, xpix2, ypix2, xpix2, 0.0, 0.0, 0.0); |
1068 |
velsum=gaussptr; |
1069 |
} |
1070 |
|
1071 |
outarr = drms_array_create(DRMS_TYPE_FLOAT, 2, length, velsum, &status); |
1072 |
if (outarr == NULL || status != DRMS_SUCCESS) |
1073 |
{ |
1074 |
fprintf(stderr, "ERROR: problem with output segment or array, i = %d, status = %d\n", i, status); |
1075 |
return 0; |
1076 |
} |
1077 |
outarr->bzero=segout->bzero; |
1078 |
outarr->bscale=segout->bscale; |
1079 |
drms_segment_write(segout, outarr, 0); |
1080 |
free(outarr); |
1081 |
} |
1082 |
|
1083 |
} |
1084 |
|
1085 |
velr=velrsave; |
1086 |
veli=velisave; |
1087 |
velsum=velssave; |
1088 |
|
1089 |
drms_setkey_time(outrec, "T_REC", trec); |
1090 |
drms_setkey_int(outrec, "L", lim[i]); |
1091 |
drms_setkey_int(outrec, "M", mim[i]); |
1092 |
drms_setkey_float(outrec, "XOFF", xoffset); |
1093 |
drms_setkey_float(outrec, "YOFF", yoffset); |
1094 |
drms_setkey_float(outrec, "PANGLE", solarp); |
1095 |
drms_setkey_float(outrec, "BANGLE", obsb0); |
1096 |
//obviously these are redundant, but give series designer freedom to use either |
1097 |
drms_setkey_float(outrec, "DISTOBS", distobs); |
1098 |
drms_setkey_float(outrec, "OBSDIST", obsdist); |
1099 |
|
1100 |
drms_setkey_string(outrec, "FILE", modefile); |
1101 |
|
1102 |
drms_setkey_float(outrec, "CRPIX1", x0+1); |
1103 |
drms_setkey_float(outrec, "CRVAL1", 0.0); |
1104 |
drms_setkey_float(outrec, "CDELT1", cdelt); |
1105 |
|
1106 |
drms_setkey_float(outrec, "CRPIX2", y0+1); |
1107 |
drms_setkey_float(outrec, "CRVAL2", 0.0); |
1108 |
drms_setkey_float(outrec, "CROTA2", -solarp); |
1109 |
drms_setkey_float(outrec, "CDELT2", cdelt); |
1110 |
|
1111 |
drms_setkey_time(outrec, "T_OBS", trec); |
1112 |
drms_setkey_int(outrec, "QUALITY", 0); |
1113 |
drms_setkey_float(outrec, "CADENCE", cadence); |
1114 |
drms_setkey_float(outrec, "CRLT_OBS", obsb0); |
1115 |
drms_setkey_float(outrec, "CRLN_OBS", obsl0); |
1116 |
drms_setkey_int(outrec, "CAR_ROT", obscr); |
1117 |
|
1118 |
drms_setkey_double(outrec, "DSUN_OBS", dsunobs); |
1119 |
drms_setkey_double(outrec, "RSUN_OBS", rsunobs); |
1120 |
|
1121 |
drms_setkey_double(outrec, "OBS_VR", 0.0); |
1122 |
drms_setkey_double(outrec, "OBS_VW", 0.0); |
1123 |
drms_setkey_double(outrec, "OBS_VN", 0.0); |
1124 |
|
1125 |
drms_setkey_int(outrec, "DATASIGN", -1); |
1126 |
|
1127 |
tnow = (double)time(NULL); |
1128 |
tnow += UNIX_epoch; |
1129 |
drms_setkey_time(outrec, "DATE", tnow); |
1130 |
// drms_close_record(outrec, DRMS_INSERT_RECORD); |
1131 |
|
1132 |
} |
1133 |
|
1134 |
drms_close_records(outrecset, DRMS_INSERT_RECORD); |
1135 |
|
1136 |
if (hwidth > 0) |
1137 |
free_fresize(&fress); |
1138 |
|
1139 |
if (cubwid > 0) |
1140 |
{ |
1141 |
free(kcub); |
1142 |
free_fresize(&fresscub); |
1143 |
} |
1144 |
|
1145 |
// if (verbflag) |
1146 |
printf("module %s successful completion\n", cmdparams.argv[0]); |
1147 |
|
1148 |
return 0; |
1149 |
} |
1150 |
|
1151 |
|
1152 |
|
1153 |
/* Calculate the interpolation kernel. */ |
1154 |
void Ccker(double *u, double s) |
1155 |
{ |
1156 |
double s2, s3; |
1157 |
|
1158 |
s2= s * s; |
1159 |
s3= s2 * s; |
1160 |
u[0] = s2 - 0.5 * (s3 + s); |
1161 |
u[1] = 1.5*s3 - 2.5*s2 + 1.0; |
1162 |
u[2] = -1.5*s3 + 2.0*s2 + 0.5*s; |
1163 |
u[3] = 0.5 * (s3 - s2); |
1164 |
} |
1165 |
|
1166 |
/* Cubic convolution interpolation */ |
1167 |
double Ccintd(double *f, int nx, double x) |
1168 |
{ |
1169 |
double ux[4]; |
1170 |
/* Sum changed to double to speed up things */ |
1171 |
double sum; |
1172 |
|
1173 |
int ix, ix1, i; |
1174 |
|
1175 |
if (x < 1. || x >= (double)(nx-2)) |
1176 |
return 0.0; |
1177 |
|
1178 |
ix = (int)x; |
1179 |
Ccker(ux, x - (double)ix); |
1180 |
|
1181 |
ix1 = ix - 1; |
1182 |
sum = 0.; |
1183 |
for (i = 0; i < 4; i++) |
1184 |
sum = sum + f[ix1 + i] * ux[i]; |
1185 |
return sum; |
1186 |
} |
1187 |
|
1188 |
|