Linuxpops  3.01.04
Spectral Anaysis Package for Single Dish Data
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
convol.c
Go to the documentation of this file.
1 /*
2 Copyright 2021 Arizona Board of Regents on behalf of the University of Arizona.
3 
4 For commercial uses, to obtain a license to sell and or sublicense copies of
5 the Software please contact the University of Arizona at Tech Launch Arizona:
6 lewish@tla.arizona.edu.
7 
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction for non-commercial use educational and
11 research purposes, including without limitation the rights to use, copy,
12 modify, merge, publish, distribute, and to permit persons to whom the Software
13 is furnished to do so, subject to the following conditions:
14 
15 The entire above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 SOFTWARE.
25 
26 1. Additional Required Provisions
27 
28 1.1. Arbitration. The parties agree that if a dispute arises between them
29 concerning this Agreement, the parties may be required to submit the matter to
30 arbitration pursuant to Arizona law.
31 
32 1.2. Applicable Law and Venue. This Agreement shall be interpreted pursuant
33 to the laws of the State of Arizona. Any arbitration or litigation between the
34 Parties shall be conducted in Pima County, ARIZONA, and LICENSEE hereby
35 submits to venue and jurisdiction in Pima County, ARIZONA.
36 
37 1.3. Non-Discrimination. The Parties agree to be bound by state and federal
38 laws and regulations governing equal opportunity and non-discrimination and
39 immigration.
40 
41 1.4. Appropriation of Funds. The Parties recognize that performance by
42 ARIZONA may depend upon appropriation of funds by the State Legislature of
43 ARIZONA. If the Legislature fails to appropriate the necessary funds, or if
44 ARIZONA’S appropriation is reduced during the fiscal year, ARIZONA may cancel
45 this Agreement without further duty or obligation. ARIZONA will notify
46 LICENSEE as soon as reasonably possible after it knows of the loss of funds.
47 
48 1.5. Conflict of Interest. This Agreement is subject to the provisions of
49 A.R.S. 38-511 and other conflict of interest regulations. Within three years
50 of the EFFECTIVE DATE, ARIZONA may cancel this Agreement if any person
51 significantly involved in initiating, negotiating, drafting, securing, or
52 creating this Agreement for or on behalf of ARIZONA becomes an employee or
53 consultant in any capacity of LICENSEE with respect to the subject matter of
54 this Agreement.
55 
56  */
57 
58 
59 #include "extern.h"
60 
61 #define TESTING 1
62 
63 #define MAX_RESULTS 200
64 #define SPL 0.299792458
65 #define MAX_DECON_SIZE 1024
66 
67 #define MAX_GOOD_SOURCES 5
68 char *good_sources[] = { "Mercury", "Venus", "Mars", "Saturn", "Jupiter"};
69 
75 
77 
78 struct RESULTS {
79  int i;
80  double beam;
81  double source;
82  double fit;
83 };
84 
85 
87 
88 
90  char planet[32];
92  int telescope;
93  int count;
94  double source_size;
98 };
99 
101 
102 int mon;
103 
105 
106 int convol_get_tok(edit)
107 char *edit;
108 {
109  int c = 0;
110  char *token;
111 
112  token = strtok(edit, " \n\t");
113  while(token != NULL)
114  {
115  sprintf(convol_tok[c++], "%s", token);
116  token = strtok(NULL, " \n\t");
117  }
118 
119  return(c);
120 }
121 
122 double fwhm(freq)
123 double freq;
124 {
125  double lambda, theta, hm, dish_size, taper;
126 
127  if(env->issmt)
128  {
129  dish_size = 10.0;
130  taper = 1.28;
131  }
132  else
133  {
134  dish_size = 12.0;
135  taper = 1.12; /* 10 dB edge taper; derived Jan-05-2016; glauria/tfolkers */
136  /* Was 1.22 then changed to 1.28; now 1.15 */
137 // taper = 1.28;
138  }
139 
140  if(env->dish_size)
141  {
142  dish_size = env->dish_size;
143  st_report("fwhm(): Using Non Standard Dish Size: %.2f M", dish_size);
144  }
145 
146  if(env->taper)
147  {
148  taper = env->taper;
149  st_report("fwhm(): Using Non Standard Taper: %.2f", taper);
150  }
151 
152  st_report("fwhm(): Dish Size = %5.2f M", dish_size);
153  st_report("fwhm(): Taper Factor = %5.2f", taper);
154 
155  lambda = SPL / freq;
156  theta = taper * (lambda / dish_size);
157  hm = theta * (180.0 / M_PI) * 1800.0;
158 
159  st_report("fwhm(): lambda = %5.2f mm", lambda * 1000.0);
160 
161  return(hm);
162 }
163 
164 
165 double findObj(name)
166 char *name;
167 {
168  FILE *fp;
169  int day, mon, n;
170  int yr, curyea, curmon, curday;
171  double ven_d, mar_d, jup_d, sat_d;
172  double ow;
173  char tbuf[256], ename[256];
174 
175  curyea = getYear(0);
176  curmon = getMonth(0);
177  curday = getDom(0);
178 
179  sprintf(ename, "%s/share/%s", pkg_home, EPHEM);
180 
181  if((fp = fopen(ename, "r")) == NULL)
182  {
183  st_fail("Can't Open Ephemeris File: %s", ename);
184 
185  return(-1.0);
186  }
187 
188  /* read line matching input date and time plus the one after that */
189  /* (skip the sun-angle data fields in the ephemeris) */
190 /*
191  YR M D Vd ? Mdia Mdist ? Jdia ? Sdia Sinc ?
192 2015 1 21 10.76 21.2 4.53 1.392 36.1 43.45 160.8 15.11 24.8 57.9
193  0 1 2 3 4 5 6 7 8 9 10 11 12
194  */
195 
196  while(fgets(tbuf, sizeof(tbuf), fp) != NULL)
197  {
198  n = convol_get_tok(tbuf);
199 
200  if(n == 13)
201  {
202  yr = atoi(convol_tok[0]);
203  mon = atoi(convol_tok[1]);
204  day = atoi(convol_tok[2]);
205 
206  if(yr == curyea && mon == curmon && day == curday)
207  {
208  ven_d = atof(convol_tok[ 3]);
209  mar_d = atof(convol_tok[ 5]);
210  jup_d = atof(convol_tok[ 8]);
211  sat_d = atof(convol_tok[10]);
212 
213  break;
214  }
215  }
216  }
217 
218  fclose(fp);
219 
220  st_report("Venus = %.2f, Mars = %.2f, Jup = %.2f, Sat = %.2f",
221  ven_d, mar_d, jup_d, sat_d);
222 
223  if(!strcmp(name, "Mars"))
224  {
225  ow = mar_d;
226  }
227  else
228  if(!strcmp(name, "Jupiter"))
229  {
230  ow = jup_d;
231  }
232  else
233  if(!strcmp(name, "Venus"))
234  {
235  ow = ven_d;
236  }
237  else
238  if(!strcmp(name, "Saturn"))
239  {
240  ow = sat_d;
241  }
242  else
243  {
244  ow = 0.0;
245  }
246 
247  return(ow);
248 }
249 
250 
251 void convolve(const double Signal[/* SignalLen */], size_t SignalLen,
252  const double Kernel[/* KernelLen */], size_t KernelLen,
253  double Result[/* SignalLen + KernelLen - 1 */])
254 {
255  size_t n;
256 
257  for (n = 0; n < SignalLen + KernelLen - 1; n++)
258  {
259  size_t kmin, kmax, k;
260 
261  Result[n] = 0.0;
262 
263  kmin = (n >= KernelLen - 1) ? n - (KernelLen - 1) : 0;
264  kmax = (n < SignalLen - 1) ? n : SignalLen - 1;
265 
266  for (k = kmin; k <= kmax; k++)
267  {
268  Result[n] += Signal[k] * Kernel[n - k];
269  }
270  }
271 }
272 
274 char *s;
275 {
276  int i;
277 
278  for(i=0;i<MAX_GOOD_SOURCES;i++)
279  {
280  if(!strcasecmp(s, good_sources[i]) )
281  {
282  return(1);
283  }
284  }
285 
286  return(0);
287 }
288 
289 
290 int convol(source, first, freq, fw, source_size, beam_size)
291 int first;
292 char *source;
293 double freq, *fw, *source_size, *beam_size;
294 {
295  int i;
296  double beam_width, half_obj;
297  double a[4], dyda[4], y, maxg=0.0;
298  struct RESULTS *p;
299  static double obj_width;
300 
301  st_report("convol(): Object = %s", source);
302  st_report("convol(): Freq = %10.6f GHz", freq);
303 
304  beam_width = fwhm(freq) * 2.0;
305  *fw = beam_width;
306 
307  st_report("convol(): FWHM = %5.2f arcsecs", beam_width);
308 
309  if(!goodSource(source))
310  {
311  st_report("convol(): Skipping %s", source);
312  st_report("convol(): Setting planet_hp to %.2f", 3600.0 * beam_width / 2.0);
313 
314  return(1);
315  }
316 
317  if(first)
318  {
319  obj_width = findObj(source);
320  }
321 
322  *source_size = obj_width;
323 
324  if(obj_width < 0.0) /* Something failed */
325  {
326  return(1);
327  }
328 
329  st_report("convol(): Object Width = %5.2f arcsecs", obj_width);
330 
331  half_obj = obj_width / 2.0;
332 
333  a[1] = 1.0;
334  a[2] = 0.0;
335  a[3] = beam_width;
336 
337 // Compute a perfect gauss and object width
338  p = &results[0];
339  for(i=-100;i<100;i++, p++)
340  {
341  fgauss((double)i, a, &y, dyda);
342 
343  p->i = i;
344  p->beam = y;
345 
346  if(i < (int)-half_obj || i > (int)half_obj)
347  {
348  p->source = 0.0;
349  }
350  else
351  {
352  p->source = 1.0;
353  }
354  }
355 
356 // load the convol arrays
357  p = &results[0];
358  for(i=0;i<MAX_RESULTS;i++, p++)
359  {
360  b_array[i] = p->beam;
361  s_array[i] = p->source;
362  r_array[i] = 0.0;
363  }
364 
365  convolve(b_array, MAX_RESULTS, s_array, MAX_RESULTS, r_array);
366 
367 // Find the peak value for scaling later
368  for(i=0;i<MAX_RESULTS;i++, p++)
369  {
370  if(r_array[i] > maxg)
371  {
372  maxg = r_array[i];
373  }
374  }
375 
376 // Fill the fit array with the results of convolve()
377  p = &results[0];
378  for(i=0;i<MAX_RESULTS;i++, p++)
379  {
380  if(i <= 100)
381  {
382  p->fit = r_array[i+100];
383  }
384  else
385  {
386  p->fit = r_array[MAX_RESULTS-(i-100)];
387  }
388 
389 // Scale to ~1.0
390  p->fit = p->fit / maxg;
391  }
392 
393 // Find the peak value again as there may be points slightly
394 // greater then 1.0; for scaling later
395  maxg = 0.0;
396  p = &results[0];
397  for(i=0;i<MAX_RESULTS;i++, p++)
398  {
399  if(p->fit > maxg)
400  {
401  maxg = p->fit;
402  }
403  }
404 
405 // Fit a gauss to the resulting beam to find useful FWHM for pointing
406  a[1] = 1.0;
407  a[2] = 100.0;
408  a[3] = 10.0;
409 
410  p = &results[0];
411  for(i=0;i<MAX_RESULTS;i++, p++)
412  {
413  x_array[i] = (double)i;
414  y_array[i] = p->fit;
415  s_array[i] = 1.0;
416  }
417 
418  if(!gauss_fit(x_array, y_array, s_array, MAX_RESULTS-1, a, 0)) /* last flag is verbose */
419  {
420  st_fail("gauss_fit() returned failure");
421  return(1);
422  }
423 
424  st_report("convol(): GaussFit = %.2f %.2f %.2f", a[1], a[2], a[3]);
425 
426  *beam_size = a[3];
427 
428  return(0);
429 }
430 
431 
433 {
434  int i;
435  double freq, fw, source_size, beam_size;
436  struct DECONVOL_STRUCT *p;
437  FILE *fp;
438 
439  bzero((char *)&dcs, sizeof(dcs));
440 
441  st_report("initDeConStruct(): Initializing Convole Table for %s on planet: %s",
442  env->issmt == 1 ? "SMT" : "12M", env->source);
443 
444  dcs.telescope = env->issmt;
445  strcpy(dcs.planet, env->source);
446 
447  freq = 850.0;
448 
449  i = 0;
450  stquiet = 1; /* Quiet from now on */
451 
452  while(freq >= 30.0)
453  {
454  if(fabs(freq-(restFreq(&h0->head)/1000.0)) < 0.5)
455  {
456  stquiet = 0;
457  }
458 
459  if(convol(dcs.planet, i == 0, freq, &fw, &source_size, &beam_size))
460  {
461  stquiet = 0;
462  return(1);
463  }
464 
465  stquiet = 1; /* Quiet back on */
466 
467  dcs.freq_array[i] = freq;
468  dcs.fw_array[i] = fw;
469  dcs.bs_array[i] = beam_size;
470 
471  freq -= 1.0;
472  i++;
473  p++;
474  }
475 
476  stquiet = 0;
477 
478  dcs.count = i;
480 
481  st_report("initDeConStruct(): Table Size = %4d", dcs.count);
482 
483  if((fp = fopen("convol.table", "w")) == NULL)
484  {
485  st_fail("initDeConStruct(): Can't Open Convol Table File: %s", "convol.table");
486 
487  return(1);
488  }
489 
490  for(i=0;i<dcs.count;i++)
491  {
492  fprintf(fp, "%10.5f %10.6f %10.6f %10.6f\n",
494  }
495 
496  fclose(fp);
497 
498  dcs.initialized = 1;
499 
500  return(0);
501 }
502 
503 
505 {
506  int next, fail = 0;
507  double formula_bs, source_size2, con2;
508 
510  {
511  initDeConStruct();
512  }
513 
514  st_report("doDeConvol(): Searching table BS = %.2f", beam_map.gmap_bw1);
515 
517 
518  if(next < dcs.count)
519  {
520  st_report("doDeConvol(): Found @ Table Index: = %d", next);
521  st_report("doDeConvol(): Decon Table Result = %.2f", decon_beam_size);
522  }
523  else
524  {
525  st_fail("doDeConvol(): Decon Function ran off end of table");
526  fail = 1;
527  }
528 
529  /* Now compute deconvolved beam using a formula */
531  source_size2 = dcs.source_size*dcs.source_size;
532 
533  formula_bs = sqrt(con2 - (log(2.0) / 2.0) * source_size2);
534  st_report("doDeConvol(): Decon Formula Result = %.2f", formula_bs);
535 
536  if(fail)
537  {
538  decon_beam_size = formula_bs;
539  }
540 
541  return(0);
542 }
543 
544 
545 /* Return the interpolated value in the table of "no" points, (xtab, ytab),
546  * that corresponds to the xtab value, "x". "xtab" must be stored in increasing
547  * order. "next" is returned such that xtab[next] < x < xtab[next+1].
548  */
549 
550 double interpl8( xtab, ytab, no, x, next )
551 double *xtab;
552 double *ytab;
553 int no;
554 double x;
555 int *next;
556 {
557  int i;
558 
559  if(x >= xtab[0])
560  {
561  for(i=0;i<no-1 && xtab[i+1]<x;i++)
562  {
563  continue;
564  }
565 
566  if(i >= no-1)
567  {
568  i = no - 2;
569  }
570  }
571  else
572  {
573  for(i=0;i>0 && xtab[i]>x;i--)
574  {
575  continue;
576  }
577 
578  if(i < 0)
579  {
580  i = 0;
581  }
582  }
583 
584  *next = i;
585 
586  return(ytab[i] + (ytab[i+1] - ytab[i]) * (x - xtab[i]) /
587  (xtab[i+1] - xtab[i]));
588 }
struct LP_IMAGE_INFO * h0
Definition: image.c:74
char pkg_home[256]
Definition: makemem.c:97
int first
Definition: dbase.c:106
struct RESULTS results[MAX_BKNDS][MAX_BKNDS]
Definition: beam.c:81
double y_array[MAX_RESULTS]
Definition: convol.c:74
double bs_array[MAX_DECON_SIZE]
Definition: convol.c:97
double r_array[MAX_RESULTS]
Definition: convol.c:72
char source[SRCLEN+1]
Definition: dataserv.c:52
#define MAX_TOKENS
Definition: defines.h:40
FILE * fp
Definition: linuxpops.c:70
char convol_tok[MAX_TOKENS][MAX_TOKENS]
Definition: convol.c:104
void fgauss()
int gauss_fit()
double dish_size
Definition: env.h:299
int stquiet
Definition: env.c:90
int issmt
Definition: env.h:63
int getMonth(int offset)
#define MAX_RESULTS
Definition: convol.c:63
double restFreq(struct HEADER *h)
Definition: linuxpops.c:2837
int initDeConStruct()
Definition: convol.c:432
int getYear(int offset)
struct BEAM_MAP beam_map
Definition: gridmap.c:61
int convol_get_tok(char *edit)
Definition: convol.c:106
double interpl8(double *xtab, double *ytab, int no, double x, int *next)
Definition: convol.c:550
int mon
Definition: convol.c:102
struct ENVIRONMENT * env
Definition: linuxpops.c:71
double decon_beam_size
Definition: convol.c:76
#define MAX_GOOD_SOURCES
Definition: convol.c:67
char source[64]
Definition: env.h:11
struct HEADER head
Definition: image.h:104
double source
Definition: convol.c:81
double fit
Definition: convol.c:82
void st_fail()
float gmap_bw1
Definition: gridmap.h:56
int strcmp()
int i
Definition: convol.c:79
double s_array[MAX_RESULTS]
Definition: convol.c:71
int goodSource(char *s)
Definition: convol.c:273
int telescope
Definition: convol.c:92
int getDom(int offset)
double fw_array[MAX_DECON_SIZE]
Definition: convol.c:96
char planet[32]
Definition: convol.c:90
struct DECONVOL_STRUCT dcs
Definition: convol.c:100
char * good_sources[]
Definition: convol.c:68
double fwhm(double freq)
Definition: convol.c:122
void convolve(const double Signal[], size_t SignalLen, const double Kernel[], size_t KernelLen, double Result[])
Definition: convol.c:251
#define MAX_DECON_SIZE
Definition: convol.c:65
void st_report()
#define EPHEM
Definition: ephem.h:2
double x_array[MAX_RESULTS]
Definition: convol.c:73
#define SPL
Definition: convol.c:64
double findObj(char *name)
Definition: convol.c:165
double taper
Definition: env.h:300
double source_size
Definition: convol.c:94
int doDeConvol()
Definition: convol.c:504
double freq_array[MAX_DECON_SIZE]
Definition: convol.c:95
double b_array[MAX_RESULTS]
Definition: convol.c:70
Definition: beam.c:72
double beam
Definition: convol.c:80
int convol(char *source, int first, double freq, double *fw, double *source_size, double *beam_size)
Definition: convol.c:290
int initialized
Definition: convol.c:91