Linuxpops  3.01.04
Spectral Anaysis Package for Single Dish Data
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
chngres.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 #include <gsl/gsl_math.h>
62 
63 /*
64  *-------------------------------------------------------------------------------
65  * @(#)chgres.f 5.2 09/10/98
66  *-------------------------------------------------------------------------------
67  *
68  * THIS SUBROUTINE SMOOTHS SPECTRAL LINE DATA FROM ITS INITIAL
69  * RESOLUTION TO A LOWER RESOLUTION SPECIFIED BY THE ADVERB
70  * 'NEWRES'. THE ROUTINE WORKS BY STEPPING A GAUSSIAN OF
71  * APPROPRIATE FWHM THROUGH THE EXISTING SPECTRUM AND PERFORMING
72  * A CONVOLUTION AT EACH POSITION. THE ROUTINE ASSUMES THAT
73  * THERE ARE AN EVEN NUMBER OF CHANNELS IN THE INITIAL SPECTRUM
74  * AND THAT THE CENTER FREQENCY IN THE SCAN HEADER CORRESPONDS
75  * TO CHANNEL N/2 + 0.5, E.G., 64.5, 128.5, ETC. EACH INDIVIDUAL
76  * CONVOLUTION IS PERFORMED OUT TO A SPECIFIED NUMBER OF STANDARD
77  * DEVIATIONS OF THE CONVOLVING GAUSSIAN, SAY 5 OR 6 SIGMA. THE
78  * SMOOTHING IS TERMINATED WHEN THE CONVOLVING GAUSSIAN IS WITHIN
79  * A SPECIFIED NUMBER OF SIGMAS OF THE ENDS OF THE INITIAL SPECTRUM
80  * SO THAT THE END POINTS OF THE NEW SPECTRUM REPRESENT VALID
81  * INFORMATION (2 OR 3 SIGMA IS A REASONABLE LIMIT). THE REMAINING
82  * POINTS IN THE NEW SPECTRUM ARE SET EQUAL TO ZERO; THE USER CAN
83  * DROP THESE POINTS FROM THE DISPLAYED SPECTRUM.
84  *
85  * The center freq./reference channel need not be N/2 + 0.5, the
86  * reference channel is corrected in au2 after chgres returns
87  *
88  * ** WRITTEN BY P. R. JEWELL AND E. B. STOBIE 7 NOV 1985 **
89  * ** LAST MODIFIED BY P.R.J. AND E.B.S. 9 NOV 1985 **
90  * Modified 8903 [RJM] See CHANGES.DOC
91  *
92  * ** Converted to 'C', April 12, 2016; t.w.folkers **
93  *
94  * KEY TO VARIABLE NAMES:
95  * OLDRES = ORIGINAL FREQ. RESOLUTION OF THE SPECTRUM
96  * NCHAN = TOTAL NUMBER OF CHANNELS IN THE SPECTRUM
97  * NEWRES = DESIRED NEW FREQ. RESOLUTION OF THE SPECTRUM
98  * = FWHM of convolving gaussian
99  * CONRES = RESOLUTION OF THE CONVOLVING GAUSSIAN
100  * CONLIM = NUMBER OF SIGMAS OF THE CONVOLVING GAUSSIAN TO
101  * CARRY AN INDIVIDUAL CONVOLUTION OUT TO.
102  * CONEND = NUMBER OF SIGMAS OF THE CONVOLVING GAUSSIAN TO
103  * ALLOW AS A BORDER AT THE 2 ENDPOINTS OF THE SPEC.
104  *
105  */
106 int chgres(told, nchan, oldres, newres)
107 float *told, oldres, newres;
108 int nchan;
109 {
110  int ncon, i, j, ichan, istart, istop;
111  float tnew[8192];
112  float conres, a2, rta2, conlim, conend,
113  freqend, bord, conbord, cchan, chstep, chpos, xarg, xnorm,
114  freqlc, chlim, xdist, arg, rinfinity = GSL_POSINF;
115 
116 // newres must be > oldres
117  if(newres < oldres || min(newres, oldres) < 0.0)
118  {
119  st_fail("CHNGRES: newres %f must be > oldres %f", newres, oldres);
120  return(1);
121  }
122 
123 // NCHAN must be even
124  if((nchan%2) != 0)
125  {
126  st_fail("CHNGRES: nchan %d must be even", nchan);
127  return(1);
128  }
129 
130  if(nchan < 1 || nchan > 8196)
131  {
132  st_fail("CHNGRES: nchan %d out of range", nchan);
133  return(1);
134  }
135 
136  cchan = (float)nchan / 2.0 + 0.5;
137 
138 /*
139  *
140  * THE FWHM'S OF CONVOLVING GAUSSIANS ADD QUADRATICALLY:
141  * CONRES = SQRT( NEWRES*NEWRES - OLDRES*OLDRES )
142  * I don't understand why the below is preferred over the above - rwg.
143  */
144  conres = newres;
145  a2 = 4.0 * log(2.0);
146  rta2 = sqrt(a2);
147  xarg = rta2 * oldres / conres;
148  conlim = 4.0;
149  conend = 1.0;
150 
151 /*
152  * A STANDARD DEVIATION SIGMA = 0.4248 * FWHM
153  * 0.4248 = 1 / sqrt(8 ln(2))
154  * CALCULATE THE NUMBER OF CONVOLUTIONS PERFORMED ON EITHER SIDE OF THE
155  * CENTER POINT
156  */
157  freqend = (nchan - cchan) * oldres;
158  conbord = conend * 0.4248 * conres;
159  ncon = freqend / newres;
160  freqlc = ncon * newres;
161  bord = freqend - freqlc;
162 
163  if(bord < conbord)
164  {
165  ncon = ncon - 1;
166  }
167 /*
168  *
169  * IN THE LOOPS BELOW, THE OUTER LOOP STEPS THE CONVOLVING GAUSSIAN
170  * THROUGH THE SPECTRUM WITH STEPSIZES = NEWRES; THE INNER LOOP
171  * PERFORMS THE INDIVIDUAL CONVOLUTIONS. TWO SETS OF LOOPS ARE USED,
172  * THE FIRST WORKING FROM THE CENTER TO HIGHER CHANNELS AND THE
173  * SECOND FROM THE CENTER TO LOWER CHANNELS.
174  *
175  * COMPUTE THE STEPSIZE, THE LIMIT OF THE CONVOLUTION, AND THE POSITION
176  * OF THE CENTER OF THE CONV. GAUSSIAN IN FRACTIONAL CHANNEL NUMBERS.
177  *
178  */
179  chstep = newres / oldres;
180  chlim = conlim * 0.4248 * chstep;
181  chpos = cchan + 0.5 * chstep;
182 
183 // Initialize the new spectrum to zero
184  bzero((char *)&tnew, sizeof(tnew));
185 
186 /*
187  *
188  * DO THE CONVOLUTION FOR THE UPPER HALF OF THE SPECTRUM:
189  *
190  */
191  ichan = cchan;
192 
193  for(i=0;i<ncon;i++)
194  {
195  ichan = ichan + 1;
196  istart = chpos - chlim + 0.5;
197  istop = chpos + chlim + 0.5;
198 
199  if(istart < 1)
200  {
201  istart = 1;
202  }
203 
204  if(istop > nchan)
205  {
206  istop = nchan;
207  }
208 
209  xnorm = 0.0;
210 
211  for(j=istart;j<istop;j++)
212  {
213  xdist = chpos - j;
214  arg = -xarg * xdist * xarg * xdist;
215 
216  if(gsl_finite(told[j]))
217  {
218  tnew[ichan] = told[j] * exp(arg) + tnew[ichan];
219  xnorm += exp(arg);
220  }
221  }
222 
223  if(xnorm > 0.0)
224  {
225  tnew[ichan] /= xnorm;
226  }
227  else
228  {
229  tnew[ichan] = rinfinity;
230  }
231 
232  chpos += chstep;
233  }
234 
235 /*
236  *
237  * DO THE CONVOLUTION FOR THE LOWER HALF OF THE SPECTRUM:
238  *
239  */
240  chpos = cchan - 0.5 * chstep;
241  ichan = cchan + 1.0;
242 
243  for(i=0;i<ncon;i++)
244  {
245  ichan = ichan - 1;
246  istart = chpos - chlim + 0.5;
247  istop = chpos + chlim + 0.5;
248 
249  if(istart < 1)
250  {
251  istart = 1;
252  }
253 
254  if(istop > nchan)
255  {
256  istop = nchan;
257  }
258 
259  xnorm = 0.0;
260 
261  for(j=istart;j<istop;j++)
262  {
263  xdist = chpos - j;
264  arg = -xarg * xdist * xarg * xdist;
265 
266  if(gsl_finite(told[j]))
267  {
268  tnew[ichan] = told[j] * exp(arg) + tnew[ichan];
269  xnorm = xnorm + exp(arg);
270  }
271  }
272 
273  if(xnorm > 0.0)
274  {
275  tnew[ichan] /= xnorm;
276  }
277  else
278  {
279  tnew[ichan] = rinfinity;
280  }
281 
282  chpos = chpos - chstep;
283  }
284 /*
285  *
286  * REPLACE THE OLD SPECTRUM AND HEADER VALUES WITH THE NEW VALUES:
287  *
288  */
289  for(i=0;i<nchan;i++)
290  {
291  if(i < cchan-ncon || i > cchan+ncon)
292  {
293  told[i] = rinfinity;
294  }
295  else
296  {
297  told[i] = tnew[i];
298  }
299  }
300 
301  return(0);
302 }
int chgres(float *told, int nchan, float oldres, float newres)
Definition: chngres.c:106
#define min(a, b)
Definition: cactus.h:114
void st_fail()