ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/JSOC/proj/globalhs/apps/mkylms.c
Revision: 1.9
Committed: Fri Mar 31 19:43:58 2017 UTC (6 years, 5 months ago) by tplarson
Content type: text/plain
Branch: MAIN
CVS Tags: globalhs_version_23, globalhs_version_22, globalhs_version_21, globalhs_version_20, Ver_LATEST, globalhs_version_24, Ver_9-41, Ver_9-5, globalhs_version_19, Ver_9-1, Ver_9-2, globalhs_version_17, globalhs_version_18, Ver_9-4, Ver_9-3, HEAD
Changes since 1.8: +165 -130 lines
Log Message:
update

File Contents

# Content
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