Linuxpops  3.01.04
Spectral Anaysis Package for Single Dish Data
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
atm.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 #include "extern.h"
59 
60 #define SMT_ELEVATION (3.186)
61 #define KP_ELEVATION (1.914)
62 
63 #define D2R (M_PI / 180.0)
64 
65 struct ALMA_BANDS {
66  char *name;
67  char *color;
68  char *frontback;
69  double lower;
70  double upper;
71 };
72 
73 struct ALMA_BANDS alma_bands[] = {
74  { " Band-1", "light-coral", "behind", ALMA_BAND_1_LOWER, ALMA_BAND_1_UPPER },
75  { " Band-2", "orange", "behind", ALMA_BAND_2_LOWER, ALMA_BAND_2_UPPER },
76  { " Band-3", "yellow", "behind", ALMA_BAND_3_LOWER, ALMA_BAND_3_UPPER },
77  { " Band-4", "light-green", "behind", ALMA_BAND_4_LOWER, ALMA_BAND_4_UPPER },
78  { " Band-5", "light-blue", "behind", ALMA_BAND_5_LOWER, ALMA_BAND_5_UPPER },
79  { " Band-6", "aquamarine", "behind", ALMA_BAND_6_LOWER, ALMA_BAND_6_UPPER },
80  { " Band-7", "violet", "behind", ALMA_BAND_7_LOWER, ALMA_BAND_7_UPPER },
81  { " Band-8", "light-cyan", "behind", ALMA_BAND_8_LOWER, ALMA_BAND_8_UPPER },
82  { " Band-9", "light-magenta", "behind", ALMA_BAND_9_LOWER, ALMA_BAND_9_UPPER },
83  { "Band-10", "coral", "behind", ALMA_BAND_10_LOWER, ALMA_BAND_10_UPPER }
84 };
85 
86 #define MAX_ALMA_BANDS (sizeof(alma_bands) / sizeof(struct ALMA_BANDS))
87 
88 #define MAX_ATM_ELEMENTS 10000
89 
95 
96 int nAtm;
98 char siteAtm[256];
99 
100 int atm_atmosp_(float *tamb, float *press, float *h0);
101 int atm_transm_(float *mmwat, float *am, float *freqs, float *tems, float *tatms, float *tauo, float *tauwat, float *tautots, int *ier);
102 
103 
104 /* Use more accurate calculations; for now */
105 int loadAtmFromServer(which, fmin, fmax, fstep, pwv, gtemp, gpress, altitude, ymin)
106 char *which;
107 double fmin, fmax, fstep, pwv, gtemp, gpress, altitude, ymin;
108 {
109  int indx = 0, n;
110  char pbuf[1024], bbuf[256], vbuf[256], ebuf[256];
111  char *string, line[256];
112  FILE *fp;
113  double freq, dry, wet, sky, trans;
114 
115  sprintf(bbuf, "ssh %s \"/usr/local/bin/absorption ", which);
116 
117  sprintf(vbuf, "--fmin %.2f --fmax %.2f --fstep %.2f --pwv %.2f --gtemp %.1f --gpress %.0f --altitude %.0f",
118  fmin, fmax, fstep, pwv, gtemp, gpress, altitude);
119 
120  strcpy(ebuf, " \"");
121 
122  sprintf(pbuf, "%s %s %s", bbuf, vbuf, ebuf);
123 
124  if(isSet(PF_V_FLAG))
125  {
126  printf("%s\n", pbuf);
127  }
128 
129  if( (fp = popen(pbuf, "r") ) <= (FILE *)0 )
130  {
131  st_fail("Unable to open %s", pbuf);
132 
133  return(1);
134  }
135 
136  st_report(" ");
137  st_report("Using Server: %s ", which);
138  st_report("Standby, as this may take a few seconds");
139  st_report(" ");
140 
141  while((string = fgets(line, sizeof(line), fp)) != NULL)
142  {
143  n = sscanf(line, "%le,\t%lf,\t%lf,\t%lf", &freq, &dry, &wet, &sky);
144 
145  if(n == 4)
146  {
147  xdata[indx] = freq / 1e9;
148 
149  tdata[indx] = wet;
150  odata[indx] = dry;
151  bdata[indx] = wet+dry;
152 
153  trans = 1.0 - (wet+dry);
154 
155  if(trans < ymin || gsl_isnan(trans))
156  {
157  trans = ymin;
158  }
159 
160  ydata[indx] = trans;
161 
162  indx++;
163 
164  if(indx >= MAX_ATM_ELEMENTS)
165  {
166  break;
167  }
168  }
169  }
170 
171  pclose(fp);
172 
173  return(indx);
174 }
175 
176 
177 /* airmass calculations */
179 float elv;
180 {
181  float am = 1.0;
182 // only use doubles in the calc of am
183  double airmass, hz, hz1, hz2, hz3, rzero, hzero, eps, Gamma;
184 
185  airmass = 1.0 / sin(elv * D2R);
186 
187  rzero = 6372.0;
188  hzero = 7.8;
189 
191  {
192  st_report("Telescope Elev: %.1f", elv);
193  }
194 
195  eps = asin(rzero / (rzero + hzero) * cos(elv * D2R));
196 
197  if(verboseLevel & VERBOSE_ATM)
198  {
199  st_report("EPS = %f", eps);
200  }
201 
202  Gamma = elv*D2R +eps;
203 
204  if(verboseLevel & VERBOSE_ATM)
205  {
206  st_report("Gamma = %f", Gamma);
207  }
208 
209  hz1 = pow(rzero, 2.0);
210 
211  if(verboseLevel & VERBOSE_ATM)
212  {
213  st_report("hz1 = %f", hz1);
214  }
215 
216  hz2 = pow(rzero+hzero, 2.0);
217 
218  if(verboseLevel & VERBOSE_ATM)
219  {
220  st_report("hz2 = %f", hz2);
221  }
222 
223  hz3 = 2.0 * rzero * (rzero+hzero) * sin(Gamma);
224 
225  if(verboseLevel & VERBOSE_ATM)
226  {
227  st_report("hz3 = %f", hz3);
228  }
229 
230  hz = hz1 + hz2 - hz3;
231 
232  if(verboseLevel & VERBOSE_ATM)
233  {
234  st_report("HZ double sums = %f", hz);
235  }
236 
237  hz = sqrt(hz);
238 
239  if(verboseLevel & VERBOSE_ATM)
240  {
241  st_report("sqrt(HZ) = %f", hz);
242  }
243 
244  am = (float)(hz/hzero);
245 
246  if(verboseLevel & VERBOSE_ATM)
247  {
248  st_report("AM = %.3f; (1.0 / sin(%.1f)) = %.3f", am, elv, airmass);
249  }
250 
251  return(am);
252 }
253 
254 
255 
256 int findMinMax(fmin, fmax)
257 double *fmin, *fmax;
258 {
259  int set=0;
260  double fn=0.0, fx=0.0;
261 
263  {
264  st_report("findMinMax(): Enter %f %f", *fmin, *fmax);
265  }
266 
267  if(isSet(PF_1_FLAG))
268  {
269  fn = ALMA_BAND_1_LOWER;
270  fx = ALMA_BAND_1_UPPER;
271  set = 1;
272  }
273 
274  if(isSet(PF_2_FLAG))
275  {
276  if(fn == 0.0)
277  {
278  fn = ALMA_BAND_2_LOWER;
279  }
280 
281  fx = ALMA_BAND_2_UPPER;
282  set = 1;
283  }
284 
285  if(isSet(PF_3_FLAG))
286  {
287  if(fn == 0.0)
288  {
289  fn = ALMA_BAND_3_LOWER;
290  }
291 
292  fx = ALMA_BAND_3_UPPER;
293  set = 1;
294  }
295 
296  if(isSet(PF_4_FLAG))
297  {
298  if(fn == 0.0)
299  {
300  fn = ALMA_BAND_4_LOWER;
301  }
302 
303  fx = ALMA_BAND_4_UPPER;
304  set = 1;
305  }
306 
307  if(isSet(PF_5_FLAG))
308  {
309  if(fn == 0.0)
310  {
311  fn = ALMA_BAND_5_LOWER;
312  }
313 
314  fx = ALMA_BAND_5_UPPER;
315  set = 1;
316  }
317 
318  if(isSet(PF_6_FLAG))
319  {
320  if(fn == 0.0)
321  {
322  fn = ALMA_BAND_6_LOWER;
323  }
324 
325  fx = ALMA_BAND_6_UPPER;
326  set = 1;
327  }
328 
329  if(isSet(PF_7_FLAG))
330  {
331  if(fn == 0.0)
332  {
333  fn = ALMA_BAND_7_LOWER;
334  }
335 
336  fx = ALMA_BAND_7_UPPER;
337  set = 1;
338  }
339 
340  if(isSet(PF_8_FLAG))
341  {
342  if(fn == 0.0)
343  {
344  fn = ALMA_BAND_8_LOWER;
345  }
346 
347  fx = ALMA_BAND_8_UPPER;
348  set = 1;
349  }
350 
351  if(isSet(PF_9_FLAG))
352  {
353  if(fn == 0.0)
354  {
355  fn = ALMA_BAND_9_LOWER;
356  }
357 
358  fx = ALMA_BAND_9_UPPER;
359  set = 1;
360  }
361 
362  if(isSet(PF_10_FLAG))
363  {
364  if(fn == 0.0)
365  {
366  fn = ALMA_BAND_10_LOWER;
367  }
368 
369  fx = ALMA_BAND_10_UPPER;
370  set = 1;
371  }
372 
373  if(set)
374  {
375  *fmin = fn;
376  *fmax = fx;
377 
378  if(verboseLevel & VERBOSE_ATM)
379  {
380  st_report("findMinMax(): Leaving %f %f", *fmin, *fmax);
381  }
382  }
383 
384  return(0);
385 }
386 
387 
388 int generateAtm(fmin, fmax, mmwat, tamb, press, elev)
389 double fmin, fmax;
390 float mmwat, tamb, press, elev;
391 {
392  int indx=0, ier;
393  double delta;
394  float am=1.0, freqs; /* Inputs */
395  float tems, tatms, tauo, tauwat, tautots; /* Returns */
396  float trans;
397 
398  bzero((char *)&xdata, sizeof(xdata));
399  bzero((char *)&ydata, sizeof(ydata));
400  bzero((char *)&tdata, sizeof(tdata));
401  bzero((char *)&odata, sizeof(odata));
402  bzero((char *)&bdata, sizeof(bdata));
403 
404  if(mmwat < 0.01)
405  {
406  st_fail("mm H2O must be greater than 0.01");
407  return(0);
408  }
409 
410  st_report("Computing atm profile: f = %.1f to %.1f", fmin, fmax);
411 
412  if(!strcmp(site_name, "TUCSON") && notSet(PF_F_FLAG)) /* Use ATM server unless fast flag passed */
413  {
414  indx = 0;
415 
416  delta = (fmax - fmin) / 8192.0;
417  indx = loadAtmFromServer("localhost", fmin, fmax, delta, mmwat, tamb, press, elev*1e3, 0.0);
418 
419  if(indx == 0)
420  {
421  st_fail("No ATM elements found");
422  return(1);
423  }
424 
425  st_report("Loaded %d ATM Elements", indx);
426  }
427  else
428  if(!strcmp(site_name, "KITT_PEAK") && notSet(PF_F_FLAG)) /* Use ATM server unless fast flag passed */
429  {
430  indx = 0;
431 
432  delta = (fmax - fmin) / 8192.0;
433  indx = loadAtmFromServer("modelo", fmin, fmax, delta, mmwat, tamb, press, elev*1e3, 0.0);
434 
435  if(indx == 0)
436  {
437  st_fail("No ATM elements found");
438  return(1);
439  }
440 
441  st_report("Loaded %d ATM Elements", indx);
442  }
443  else
444  if(!strcmp(site_name, "MT_GRAHAM") && notSet(PF_F_FLAG)) /* Use ATM server unless fast flag passed */
445  {
446  indx = 0;
447 
448  delta = (fmax - fmin) / 8192.0;
449  indx = loadAtmFromServer("smtoast", fmin, fmax, delta, mmwat, tamb, press, elev*1e3, 0.0);
450 
451  if(indx == 0)
452  {
453  st_fail("No ATM elements found");
454  return(1);
455  }
456 
457  st_report("Loaded %d ATM Elements", indx);
458  }
459  else /* Use internal calculations */
460  {
461  atm_atmosp_(&tamb, &press, &elev); // One call keeps model in memory
462 
463  indx = 0;
464  freqs = fmin;
465  delta = (fmax - fmin) / 8192.0;
466  while(freqs < fmax)
467  {
468  atm_transm_(&mmwat, &am, &freqs, &tems, &tatms, &tauo, &tauwat, &tautots, &ier);
469 
470  trans = 1.0 - tautots;
471 
472  if(trans < 0.0 || gsl_isnan(trans))
473  {
474  trans = 0.0;
475  }
476 
477  xdata[indx] = freqs;
478  tdata[indx] = tauwat;
479  odata[indx] = tauo;
480  bdata[indx] = tautots;
481  ydata[indx] = trans;
482 
483  indx++;
484 
485  if(indx >= MAX_ATM_ELEMENTS)
486  {
487  break;
488  }
489 
490  freqs += delta;
491  }
492 
493  st_report("Loaded %d ATM Elements", indx);
494  }
495 
496  nAtm = indx;
497  mmh2oAtm = mmwat;
498  amAtm = am;
499  tambAtm = tamb;
500  pressAtm = press;
501  elevAtm = elev;
502  fminAtm = fmin;
503  fmaxAtm = fmax;
504  fdeltaAtm = delta;
505 
506  return(0);
507 }
508 
509 
510 int doATM()
511 {
512  int i, j, ret, abox, yscale = 0;;
513  char sysbuf[1024], demname[256], datname[256];
514  char *cp, *site, plotfname[256], tbuf[256], pdfname[512];
515  double min = 1e9, max = -1e9, freq, fmin, fmax, ymin, ymax,
516  freqDiffMin, freqdiff, freqVal, wl, x1;
517 
518  double ofreq, ofreqDiffMin, ofreqdiff, ofreqVal, bw;
519 
520  float tamb, press, elev;
521  float mmwat=0.0; /* Inputs */
522  float *f;
523  FILE *fp;
524  struct ALMA_BANDS *p;
525 
526  if(isSet(PF_L_FLAG)) /* List what we have used to generate the model */
527  {
528  if(nAtm)
529  {
530  st_report(" ");
531  st_report("Number of Elements in Model: %6d", nAtm);
532  st_report("Starting Freq of Model: %7.1f GHz", fminAtm);
533  st_report("Ending Freq of Model: %7.1f GHz", fmaxAtm);
534  st_report("Delta Freq of Model: %5.3f GHz", fdeltaAtm);
535  st_report("Water Vapor Content: %.3f mm", mmh2oAtm);
536  st_report("Number of Atmophers: %.3f", amAtm);
537  st_report("Surface Temperature: %.3f K", tambAtm);
538  st_report("Surface Barometric Pressure: %.3f mbar", pressAtm);
539  st_report("Site: %16.16s", siteAtm);
540  st_report("Site Elevation: %.3f km", elevAtm);
541  st_report(" ");
542  }
543  else
544  {
545  st_report("ATM Model not generated yet");
546  }
547 
548  return(0);
549  }
550 
551  if(env->issmt)
552  {
553  elev = SMT_ELEVATION;
554  site = "Mt Graham";
555  }
556  else
557  {
558  elev = KP_ELEVATION;
559  site = "Kitt Peak";
560  }
561 
562  if(nAtm == 0 || isSet(PF_G_FLAG)) /* Alway generate the full 10 bands of the model */
563  {
564 
565  if(isSet(PF_A_FLAG)) /* Fetch from scan header ?? */
566  {
567  if(h0->head.scan == 0.0)
568  {
569  st_fail("Must load scan first before using Auto Mode");
570  return(1);
571  }
572 
573  mmwat = h0->head.mmh2o;
574  tamb = h0->head.tamb + 273.4;
575  press = h0->head.pressure * 1.33222; /* Convert to millibars from torr */
576  }
577  else
578  if(isSet(PF_K_FLAG)) /* Test using Mauma Kea values ?? */
579  {
580  if(args->ntokens < 2) /* If you are not fetching from header; Look for passed arg */
581  {
583 
584  return(1);
585  }
586 
587  mmwat = atof(args->secondArg);
588  tamb = 270.0;
589  press = 560.0;
590  elev = 5.000;
591  site = "Mauna Kea";
592  }
593  else
594  if( !nAtm && args->ntokens < 2) /* If you are not fetching from header; Look for passed arg */
595  {
597 
598  return(1);
599  }
600  else /* Use some defaults */
601  {
602  mmwat = atof(args->secondArg);
603 
604  if(env->issmt)
605  {
606  press = 696.0;
607  tamb = 0.0 + 273.4; /* ATP Set to some defaults */
608  }
609  else
610  {
611  press = 810.0; /* millibars not torr */
612  tamb = 15.0 + 273.4;
613  }
614  }
615 
616  if(mmwat && mmwat != mmh2oAtm) /* User passed a different water vapor amount; force regen of model */
617  {
618  nAtm = 0;
619  }
620 
621  if(strcmp(siteAtm, site)) /* User passwd a different site; force regen of model */
622  {
623  nAtm = 0;
624  }
625 
626  fmin = ALMA_BAND_1_LOWER;
627  fmax = ALMA_BAND_10_UPPER;
628 
629  generateAtm(fmin, fmax, mmwat, tamb, press, elev);
630 
631  strcpy(siteAtm, site); /* Remember fro which site this model was generated for */
632 
633  setFlag(PF_L_FLAG, 1); /* Force the 'list' flag and call myself */
634 
635  doATM();
636 
637  return(0);
638  }
639  /* User may only want to display part of the model */
640  if(args->ntokens > 2) /* Possible range of args */
641  { /* 1 2 3 */
642  if(args->ntokens == 3) /* atm [options] fmin fmax */
643  {
644  fmin = atof(args->secondArg);
645  fmax = atof(args->thirdArg);
646  }
647  else /* 1 2 3 4 5 */
648  if(args->ntokens == 5) /* atm [options] fmin fmax ymin ymax */
649  {
650  fmin = atof(args->secondArg);
651  fmax = atof(args->thirdArg);
652 
653  ymin = atof(args->fourthArg);
654  ymax = atof(args->fifthArg);
655 
656  if(ymin > 0.0 || ymax > 0.0)
657  {
658  yscale = 1;
659  }
660  }
661 
662  if(fmin > fmax || fmin < 1.0 || fmin > 1000.0 || fmax < 0.0 || fmax > 1000.0)
663  {
664  st_fail("fmin: %f > fmax: %f or out of range [1.0 - 1000.0]", ymin, ymax);
665 
667 
668  return(1);
669  }
670 
671  if(ymin > ymax)
672  {
673  st_fail("ymin: %f > ymax: %f", ymin, ymax);
674 
676 
677  return(1);
678  }
679  }
680  else /* Look for range limits in flags /1, /2, /3 ... */
681  {
682  fmin = 35.0;
683  fmax = 1000.0;
684 
685  findMinMax(&fmin, &fmax);
686  }
687 
688  /* Now plot it out */
689  if(isSet(PF_W_FLAG)) /* water contribution ?? */
690  {
691  f = &tdata[0];
692  }
693  else
694  if(isSet(PF_O_FLAG)) /* Oxygen contribution ?? */
695  {
696  f = &odata[0];
697  }
698  else
699  if(isSet(PF_B_FLAG)) /* Both ?? */
700  {
701  f = &bdata[0];
702  }
703  else
704  {
705  f = &ydata[0]; /* Else, transmission of atmosphere */
706  }
707  /* Go write the dat file */
708  sprintf(datname, "/tmp/%s/atm.dat", session);
709 
711  {
712  st_report("Opening ATM Dat File: %s", datname);
713  }
714 
715  if((fp = fopen(datname, "w") ) <= (FILE *)0)
716  {
717  st_fail("Unable to open file %s", datname);
718 
719  return(1);
720  }
721 
722  if(h0->head.bw)
723  {
724  bw = h0->head.bw / 1e3;
725  }
726  else
727  {
728  if(env->issmt && env->mode == MODE_SPEC)
729  {
730  bw = 1.0;
731  }
732  else
733  {
734  bw = 4.0;
735  }
736  }
737 
738  freq = h0->head.obsfreq / 1e3;
739  freqDiffMin = 1e9;
740  ofreqDiffMin = 1e9;
741 
742  /* determine other sideband freq */
743  if(h0->head.sideband == 2)
744  {
745  ofreq = (h0->head.obsfreq / 1e3) - ((h0->head.firstif / 1e3) * 2.0);
746  }
747  else
748  {
749  ofreq = (h0->head.obsfreq / 1e3) + ((h0->head.firstif / 1e3) * 2.0);
750  }
751 
752  for(i=0;i<nAtm;i++,f++)
753  {
754  fprintf(fp, "%f %f\n", xdata[i], *f*100.0);
755 
756  if(*f*100.0 < min)
757  {
758  min = *f*100.0;
759  }
760 
761  if(*f*100.0 > max)
762  {
763  max = *f*100.0;
764  }
765 
766  freqdiff = fabs(xdata[i] - freq); /* Find the atm transmission at observed freq */
767  if(freqdiff < freqDiffMin)
768  {
769  freqDiffMin = freqdiff;
770 
771  if(isSet(PF_W_FLAG))
772  {
773  freqVal = tdata[i];
774  }
775  else
776  if(isSet(PF_O_FLAG))
777  {
778  freqVal = odata[i];
779  }
780  else
781  if(isSet(PF_B_FLAG))
782  {
783  freqVal = bdata[i];
784  }
785  else
786  {
787  freqVal = ydata[i];
788  }
789  }
790 
791  ofreqdiff = fabs(xdata[i] - ofreq); /* Find the atm transmission at observed freq */
792  if(ofreqdiff < ofreqDiffMin)
793  {
794  ofreqDiffMin = ofreqdiff;
795 
796  if(isSet(PF_W_FLAG))
797  {
798  ofreqVal = tdata[i];
799  }
800  else
801  if(isSet(PF_O_FLAG))
802  {
803  ofreqVal = odata[i];
804  }
805  else
806  if(isSet(PF_B_FLAG))
807  {
808  ofreqVal = bdata[i];
809  }
810  else
811  {
812  ofreqVal = ydata[i];
813  }
814  }
815  }
816 
817  fclose(fp);
818  /* Go write the dem file */
819  sprintf(demname, "/tmp/%s/atm.dem", session);
820 
821  if(verboseLevel & VERBOSE_ATM)
822  {
823  st_report("Opening ATM Dem File: %s", demname);
824  }
825 
826  if((fp = fopen(demname, "w") ) <= (FILE *)0)
827  {
828  st_fail("Unable to open file %s", demname);
829 
830  return(1);
831  }
832 
833  fprintf(fp, "reset\n");
834 
835  if(isSet(PF_W_FLAG))
836  {
837  fprintf(fp, "set title 'Tau h2o @ %.2f mm H2O' tc rgb \"red\"\n", mmh2oAtm);
838  fprintf(fp, "set ylabel 'Atmospheric Tau (Water)' tc rgb \"red\"\n");
839  }
840  else
841  if(isSet(PF_O_FLAG))
842  {
843  fprintf(fp, "set title 'Tau O2 @ %.2f mm H2O' tc rgb \"red\"\n", mmh2oAtm);
844  fprintf(fp, "set ylabel 'Atmospheric Tau (O2)' tc rgb \"red\"\n");
845  }
846  else
847  if(isSet(PF_B_FLAG))
848  {
849  fprintf(fp, "set title 'Tau O2+Water @ %.2f mm H2O' tc rgb \"red\"\n", mmh2oAtm);
850  fprintf(fp, "set ylabel 'Atmospheric Tau (O2+Water)' tc rgb \"red\"\n");
851  }
852  else
853  {
854  fprintf(fp, "set title 'Atmospheric Transmission: %s PWV: %.2f mm' tc rgb \"red\"\n", siteAtm, mmh2oAtm);
855  fprintf(fp, "set ylabel 'Transmission (%%)' tc rgb \"red\"\n");
856  }
857 
858  fprintf(fp, "set xlabel 'Frequency (GHz)' tc rgb \"red\"\n");
859 
860  fprintf(fp, "set xrange [%.2f:%.2f]\n", fmin, fmax);
861 
862  if(yscale)
863  {
864  fprintf(fp, "set yrange [%.2f:%.2f]\n", ymin*100.0, ymax*100.0);
865  }
866  else
868  {
869  fprintf(fp, "set yrange [-5.0:100.0]\n"); /* Give a little space below 0.0 for visibility */
870  }
871  /* Otherwise, let gnuplot figure it out */
872 
873  fprintf(fp, "set grid\n");
874  fprintf(fp, "set key off\n");
875 
876  if(isSet(PF_U_FLAG) && freq)
877  {
878  st_report("Atm Transparency @ %f: %f", freq, freqVal);
879 
880  fprintf(fp, "set object 8 rect front from %f,%f to %f,%f fill transparent pattern 2 fc rgb 'green'\n",
881  freq - (bw/2.0), (freqVal-0.02)*100.0, freq + (bw/2.0), (freqVal+0.02)*100.0);
882  }
883 
884  if(isSet(PF_U_FLAG) && ofreq)
885  {
886  st_report("Atm Transparency @ %f: %f", ofreq, ofreqVal);
887 
888  fprintf(fp, "set object 9 rect front from %f,%f to %f,%f fill transparent pattern 2 fc rgb 'magenta'\n",
889  ofreq - (bw/2.0), (ofreqVal-0.02)*100.0, ofreq + (bw/2.0), (ofreqVal+0.02)*100.0);
890  }
891 
892  if(isSet(PF_M_FLAG))
893  {
894  p = &alma_bands[0];
895  for(j=0;j<MAX_ALMA_BANDS;j++,p++)
896  {
897  abox = 0;
898 
899  if(p->lower >= fmin && p->upper <= fmax) /* Fully visible */
900  {
901  fprintf(fp, "set object %d rect %s from %f,%f to %f,%f fill transparent solid 0.6 fc rgb '%s'\n",
902  j+10, p->frontback, p->lower, min, p->upper, max, p->color);
903 
904  abox = 1;
905  }
906  else /* partially visiable */
907  if(p->lower >= fmin)
908  {
909  fprintf(fp, "set object %d rect %s from %f,%f to %f,%f fill transparent solid 0.6 fc rgb '%s'\n",
910  j+10, p->frontback, p->lower, min, fmax, max, p->color);
911 
912  abox = 1;
913  }
914  else
915  if(p->upper <= fmax)
916  {
917  fprintf(fp, "set object %d rect %s from %f,%f to %f,%f fill transparent solid 0.6 fc rgb '%s'\n",
918  j+10, p->frontback, fmin, min, p->upper, max, p->color);
919 
920  abox = 1;
921  }
922 
923  if(abox)
924  {
925  x1 = p->lower + (p->upper-p->lower) / 2.0;
926  if(x1 > fmin && x1 < fmax) /* Trap labels outside the plotting area */
927  {
928  wl = 300e3 / (( ((p->upper-p->lower) / 2.0) + p->lower) * 1e3);
929  sprintf(tbuf, "%s %3.1fmm", p->name, wl);
930  fprintf(fp, "set label '%s' at %.6f, %.6f rotate by 90 tc rgb 'black' \n", tbuf, x1, (max-min) / 2.0);
931  }
932  }
933  }
934  }
935 
936  fprintf(fp, "#\n");
937 
938  if(isSet(PF_P_FLAG) || isSet(PF_S_FLAG)) /* print or save ?? */
939  {
940  fprintf(fp, "set terminal postscript color solid enhanced landscape\n");
941 
942  sprintf(plotfname, "/tmp/%s/ccal_plot.ps", session);
943 
944  fprintf(fp, "set out '%s'\n", plotfname);
945  }
946  else
947  {
948  fprintf(fp, "set terminal x11 enhanced %d\n", env->plotwin+1 );
949  }
950 
951  fprintf(fp, "plot '%s' with lines lc rgb \"red\"", datname);
952 
953  fclose(fp);
954 
955  sprintf(sysbuf, "xgraphic load '/tmp/%s/atm.dem'", session);
956 
957  parseCmd(sysbuf);
958 
959  if(isSet(PF_P_FLAG))
960  {
961  usleep(1000000); /* Give Xgraphics time to plot */
962  sprintf(sysbuf, "lpr /tmp/%s/ccal_plot.ps", session);
963  system(sysbuf);
964  }
965  else
966  if(isSet(PF_S_FLAG))
967  {
968  usleep(1000000); /* Give Xgraphics time to plot */
969  sprintf(pdfname, "atm-%s-%.2fmm.pdf", siteAtm, mmh2oAtm);
970 
971  cp = strchr(pdfname, ' ');
972  if(cp)
973  {
974  *cp = '_';
975  }
976  sprintf(sysbuf, "cat /tmp/%s/ccal_plot.ps | /usr/bin/epstopdf -f --outfile=%s", session, pdfname);
977  st_report("%s", sysbuf);
978 
979  ret = system(sysbuf);
980 
981  if(!ret)
982  {
983  st_report("AMT Plot saved to %s", pdfname);
984  }
985  else
986  {
987  st_fail("Error creating PDF file");
988  }
989  }
990 
991  return(0);
992 }
double bw
Definition: header.h:200
struct LP_IMAGE_INFO * h0
Definition: image.c:74
double scan
Definition: header.h:35
#define ALMA_BAND_7_LOWER
Definition: alma.h:22
int hzero(struct LP_IMAGE_INFO *image)
Definition: image.c:616
struct PARSE_STACK * args
Definition: parse.h:196
char site_name[256]
Definition: strings.c:67
Definition: parse.h:8
#define ALMA_BAND_6_LOWER
Definition: alma.h:19
double mmh2o
Definition: header.h:96
FILE * fp
Definition: linuxpops.c:70
#define max(a, b)
Definition: cactus.h:115
double upper
Definition: atm.c:70
char * fifthArg
Definition: parse.h:184
int printH_FlagHelp(char *cmd)
Definition: help.c:430
#define ALMA_BAND_8_LOWER
Definition: alma.h:25
#define min(a, b)
Definition: cactus.h:114
#define ALMA_BAND_10_UPPER
Definition: alma.h:32
int atm_transm_(float *mmwat, float *am, float *freqs, float *tems, float *tatms, float *tauo, float *tauwat, float *tautots, int *ier)
int setFlag(int flag, int state)
Definition: parse.c:685
float tdata[MAX_ATM_ELEMENTS]
Definition: atm.c:92
#define ALMA_BAND_10_LOWER
Definition: alma.h:31
int issmt
Definition: env.h:63
#define ALMA_BAND_8_UPPER
Definition: alma.h:26
#define ALMA_BAND_1_LOWER
Definition: alma.h:4
double sideband
Definition: header.h:143
double lower
Definition: atm.c:69
int doATM()
Definition: atm.c:510
#define ALMA_BAND_1_UPPER
Definition: alma.h:5
Definition: atm.c:65
int notSet(int flag)
Definition: parse.c:669
struct ENVIRONMENT * env
Definition: linuxpops.c:71
double pressure
Definition: header.h:92
double tambAtm
Definition: atm.c:97
char * thirdArg
Definition: parse.h:182
int isSet(int flag)
Definition: parse.c:646
struct HEADER head
Definition: image.h:104
double pressAtm
Definition: atm.c:97
#define ALMA_BAND_5_LOWER
Definition: alma.h:16
double fmaxAtm
Definition: atm.c:97
char * name
Definition: atm.c:66
char siteAtm[256]
Definition: atm.c:98
int nAtm
Definition: atm.c:96
#define ALMA_BAND_6_UPPER
Definition: alma.h:20
double obsfreq
Definition: header.h:197
#define ALMA_BAND_4_UPPER
Definition: alma.h:14
void st_fail()
#define ALMA_BAND_4_LOWER
Definition: alma.h:13
#define ALMA_BAND_3_UPPER
Definition: alma.h:11
int strcmp()
#define MAX_ALMA_BANDS
Definition: atm.c:86
double firstif
Definition: header.h:136
#define ALMA_BAND_2_UPPER
Definition: alma.h:8
#define MAX_ATM_ELEMENTS
Definition: atm.c:88
int loadAtmFromServer(char *which, double fmin, double fmax, double fstep, double pwv, double gtemp, double gpress, double altitude, double ymin)
Definition: atm.c:105
#define ALMA_BAND_5_UPPER
Definition: alma.h:17
float odata[MAX_ATM_ELEMENTS]
Definition: atm.c:93
#define D2R
Definition: atm.c:63
char session[80]
Definition: strings.c:67
int mode
Definition: env.h:75
#define VERBOSE_ATM
Definition: defines.h:79
int plotwin
Definition: env.h:129
#define MODE_SPEC
Definition: defines.h:87
double fdeltaAtm
Definition: atm.c:97
void st_report()
int atm_atmosp_(float *tamb, float *press, float *h0)
#define ALMA_BAND_2_LOWER
Definition: alma.h:7
double mmh2oAtm
Definition: atm.c:97
int site
Definition: linuxpops.c:87
float bdata[MAX_ATM_ELEMENTS]
Definition: atm.c:94
#define KP_ELEVATION
Definition: atm.c:61
Definition: parse.h:9
float xdata[MAX_ATM_ELEMENTS]
Definition: atm.c:90
#define SMT_ELEVATION
Definition: atm.c:60
double amAtm
Definition: atm.c:97
char * fourthArg
Definition: parse.h:183
double fminAtm
Definition: atm.c:97
#define ALMA_BAND_7_UPPER
Definition: alma.h:23
double tamb
Definition: header.h:91
float computeAtmophers(float elv)
Definition: atm.c:178
#define ALMA_BAND_9_LOWER
Definition: alma.h:28
double elevAtm
Definition: atm.c:97
char * secondArg
Definition: parse.h:181
char * frontback
Definition: atm.c:68
int ntokens
Definition: parse.h:173
float ydata[MAX_ATM_ELEMENTS]
Definition: atm.c:91
int findMinMax(double *fmin, double *fmax)
Definition: atm.c:256
char * firstArg
Definition: parse.h:180
int parseCmd(char *buf)
Definition: parse.c:2090
#define ALMA_BAND_3_LOWER
Definition: alma.h:10
int generateAtm(double fmin, double fmax, float mmwat, float tamb, float press, float elev)
Definition: atm.c:388
struct ALMA_BANDS alma_bands[]
Definition: atm.c:73
#define ALMA_BAND_9_UPPER
Definition: alma.h:29
char * color
Definition: atm.c:67
int verboseLevel
Definition: linuxpops.c:80