Line data Source code
1 : //# VLASDA.cc:
2 : //# Copyright (C) 1999,2000,2001,2003
3 : //# Associated Universities, Inc. Washington DC, USA.
4 : //#
5 : //# This library is free software; you can redistribute it and/or modify it
6 : //# under the terms of the GNU Library General Public License as published by
7 : //# the Free Software Foundation; either version 2 of the License, or (at your
8 : //# option) any later version.
9 : //#
10 : //# This library is distributed in the hope that it will be useful, but WITHOUT
11 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 : //# License for more details.
14 : //#
15 : //# You should have received a copy of the GNU Library General Public License
16 : //# along with this library; if not, write to the Free Software Foundation,
17 : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 : //#
19 : //# Correspondence concerning AIPS++ should be addressed as follows:
20 : //# Internet email: aips2-request@nrao.edu.
21 : //# Postal address: AIPS++ Project Office
22 : //# National Radio Astronomy Observatory
23 : //# 520 Edgemont Road
24 : //# Charlottesville, VA 22903-2475 USA
25 : //#
26 : //# $Id$
27 :
28 : #include <nrao/VLA/VLASDA.h>
29 : #include <casacore/casa/Utilities/Assert.h>
30 : #include <casacore/casa/BasicSL/String.h>
31 : #include <casacore/casa/Exceptions/Error.h>
32 : #include <casacore/casa/Logging/LogOrigin.h>
33 : #include <casacore/casa/Logging/LogIO.h>
34 : #include <casacore/casa/BasicMath/Math.h>
35 : #include <casacore/casa/Arrays/Vector.h>
36 : #include <casacore/casa/Arrays/Matrix.h>
37 :
38 16 : VLASDA::VLASDA()
39 : :itsRecord(),
40 16 : itsOffset(0)
41 : {
42 16 : }
43 :
44 0 : VLASDA::VLASDA(ByteSource& record, uInt offset)
45 : :itsRecord(record),
46 0 : itsOffset(offset)
47 : {
48 0 : DebugAssert(record.isReadable(), AipsError);
49 0 : DebugAssert(record.isSeekable(), AipsError);
50 0 : }
51 :
52 16 : VLASDA::VLASDA(const VLASDA& other)
53 16 : :itsRecord(other.itsRecord),
54 16 : itsOffset(other.itsOffset)
55 : {
56 16 : }
57 :
58 32 : VLASDA::~VLASDA() {
59 32 : }
60 :
61 0 : VLASDA& VLASDA::operator=(const VLASDA& other) {
62 0 : if (this != &other) {
63 0 : itsRecord = other.itsRecord;
64 0 : itsOffset = other.itsOffset;
65 : }
66 0 : return *this;
67 : }
68 :
69 20569 : void VLASDA::attach(ByteSource& record, uInt offset) {
70 20569 : itsRecord = record;
71 20569 : itsOffset = offset;
72 20569 : DebugAssert(record.isReadable(), AipsError);
73 20569 : DebugAssert(record.isSeekable(), AipsError);
74 20569 : }
75 :
76 321468 : uInt VLASDA::trueChannels(VLAEnum::CDA cda) const {
77 321468 : Int64 where = itsOffset + 2*(18);
78 321468 : if (cda > VLAEnum::CDA1) where++;
79 321468 : itsRecord.seek(where);
80 : uChar byte;
81 321468 : itsRecord >> byte;
82 : uInt exponent;
83 321468 : if ((cda == VLAEnum::CDA0) || (cda == VLAEnum::CDA2)) {
84 210743 : exponent = (byte & 0xf0) >> 4;
85 : } else {
86 110725 : exponent = (byte & 0x0f);
87 : }
88 321468 : uInt nChan = 1;
89 321468 : return nChan << exponent;
90 : }
91 :
92 116930 : uInt VLASDA::nChannels(VLAEnum::CDA cda) const {
93 116930 : uInt nChan = trueChannels(cda);
94 116930 : if (nChan > 1) nChan--;
95 : // A special kludge because the first channel is the vector average of the
96 : // inner 3/4 of the remaining channels. I discard the first channel and
97 : // hence have to correct for this here.
98 116930 : return nChan;
99 : }
100 :
101 6150 : Double VLASDA::obsFrequency(VLAEnum::CDA cda) const {
102 : // Calculate the centre frequency using the edge frequency to allow for
103 : // channel offsets.
104 6150 : Double freq = edgeFrequency(cda);
105 6150 : freq += nChannels(cda)/2.0 * channelWidth(cda);
106 6150 : return freq;
107 : }
108 :
109 38987 : Double VLASDA::edgeFrequency(VLAEnum::CDA cda) const {
110 :
111 38987 : uInt which=cda;
112 : // Trap full-pol sp-line modes correctly
113 38987 : if (correlatorMode()==VLAEnum::PA) which=0; // only the A (& C) freq
114 38987 : if (correlatorMode()==VLAEnum::PB) which=1; // only the B (& D) freq
115 38987 : Int64 where = itsOffset + 2*(40+which*4) ;
116 38987 : itsRecord.seek(where);
117 : Double edgeFreq;
118 38987 : itsRecord >> edgeFreq;
119 38987 : edgeFreq *= 1E9;
120 :
121 38987 : where = itsOffset + 2*(56+which*4) ;
122 38987 : itsRecord.seek(where);
123 : Double centreFreq;
124 38987 : itsRecord >> centreFreq;
125 38987 : centreFreq *= 1E9;
126 38987 : if (edgeFreq > centreFreq) {//Looks like we are pointing to the upper edge
127 30742 : edgeFreq -= correlatedBandwidth(cda);
128 : }
129 :
130 : // Now check if there is a channel offset.
131 38987 : if (nChannels(cda) > 1) {
132 3327 : where = itsOffset + 2*(162+which);
133 3327 : itsRecord.seek(where);
134 : uShort offset;
135 3327 : itsRecord >> offset;
136 3327 : if (offset > 0) {
137 0 : edgeFreq += static_cast<Double>(offset)*channelWidth(cda);
138 : }
139 : }
140 38987 : if (nChannels(cda) > 1) {
141 : // A special kludge because the first channel is the vector average of the
142 : // inner 3/4 of the remaining channels. I discard the first channel and
143 : // hence have to correct for this here. The 0.5 is to get the edge of the
144 : // channel and not the centre of it.
145 3327 : edgeFreq += 0.5 * channelWidth(cda);;
146 : }
147 38987 : return edgeFreq;
148 : }
149 :
150 7593 : Bool VLASDA::dopplerTracking(VLAEnum::CDA cda) const {
151 7593 : Int64 where = itsOffset + 2*(153+uInt(cda))+1 ;
152 7593 : itsRecord.seek(where);
153 : Char code;
154 7593 : itsRecord >> code;
155 7593 : if (code == 'F' || code == ' ') return false;
156 1415 : return true;
157 : }
158 :
159 1458 : Double VLASDA::restFrequency(VLAEnum::CDA cda) const {
160 : Double freq;
161 1458 : Int64 where = itsOffset + 2*(137+uInt(cda)*4) ;
162 1458 : itsRecord.seek(where);
163 1458 : itsRecord >> freq;
164 1458 : return freq*1E6;
165 : }
166 :
167 1461 : Double VLASDA::radialVelocity(VLAEnum::CDA cda) const {
168 1461 : Int64 where = itsOffset + 2*(121+uInt(cda)*4) ;
169 1461 : itsRecord.seek(where);
170 : Double rv;
171 1461 : itsRecord >> rv;
172 1461 : return rv*1E3;
173 : }
174 :
175 1467 : MFrequency::Types VLASDA::restFrame(VLAEnum::CDA cda) const {
176 1467 : Int64 where = itsOffset + 2*(153+uInt(cda)) ;
177 1467 : itsRecord.seek(where);
178 : Char code;
179 1467 : itsRecord >> code;
180 1467 : switch (code) {
181 0 : case 'G':
182 0 : return MFrequency::GEO;
183 0 : case 'B':
184 0 : return MFrequency::BARY;
185 1426 : case 'L':
186 1426 : return MFrequency::LSRK;
187 41 : case 'T':
188 : default:
189 : // Assume TOPO when not specified
190 41 : return MFrequency::TOPO;
191 : }
192 : // I have to return something! This should be suitably meaningless.
193 : return MFrequency::N_Types;
194 : }
195 :
196 1415 : MDoppler::Types VLASDA::dopplerDefn(VLAEnum::CDA cda) const {
197 1415 : Int64 where = itsOffset + 2*(153+uInt(cda))+1 ;
198 1415 : itsRecord.seek(where);
199 : Char code;
200 1415 : itsRecord >> code;
201 1415 : switch (code) {
202 0 : case 'Z':
203 0 : return MDoppler::OPTICAL;
204 1415 : case 'V':
205 1415 : return MDoppler::RADIO;
206 : }
207 : // I have to return something! This should be suitably meaningless.
208 0 : return MDoppler::N_Types;
209 : }
210 :
211 49876 : Double VLASDA::channelWidth(VLAEnum::CDA cda) const {
212 49876 : if (trueChannels(cda) == 1) {
213 41644 : return correlatedBandwidth(cda);
214 : } // As word 166 is only valid is spectral line mode!
215 8232 : const Int64 where = itsOffset + 2*(166+uInt(cda));
216 8232 : itsRecord.seek(where);
217 : Short exponent;
218 8232 : itsRecord >> exponent;
219 8232 : const Int factor = 1 << exponent;
220 8232 : return 50.0/Double(factor)*1E6;
221 : }
222 :
223 72386 : Double VLASDA::correlatedBandwidth(VLAEnum::CDA cda) const {
224 72386 : Int64 where = itsOffset + 2*(100) ;
225 72386 : if (cda > VLAEnum::CDA1) where++;
226 72386 : itsRecord.seek(where);
227 : uChar byte;
228 72386 : itsRecord >> byte;
229 : Int code;
230 : if ((cda == VLAEnum::CDA0) || (VLAEnum::CDA2)) {
231 72386 : code = (byte & 0xf0) >> 4;
232 : } else {
233 : code = (byte & 0x0f);
234 : }
235 72386 : if (trueChannels(cda) > 1) {
236 0 : if (code == 7) return 25.0/32.0 * 1E6;
237 0 : if (code == 9) return 25.0/128.0 * 1E6;
238 0 : Int factor = 1 << code;
239 0 : return 50.0/static_cast<Double>(factor) * 1E6;
240 : } else {// continuum
241 72386 : if (code == 7) return 25.0/128.0 * 1E6;
242 72386 : if (code == 8) return 70.0 * 1E6;
243 72386 : if (code == 9) return doubleInf();
244 72386 : Int factor = 1 << code;
245 72386 : return 50.0/static_cast<Double>(factor) * 1E6;
246 : }
247 : }
248 :
249 0 : Double VLASDA::filterBandwidth(VLAEnum::CDA cda) const {
250 0 : Int64 where = itsOffset + 2*(101) ;
251 0 : if (cda > VLAEnum::CDA1) where++;
252 0 : itsRecord.seek(where);
253 : uChar byte;
254 0 : itsRecord >> byte;
255 : Int code;
256 : if ((cda == VLAEnum::CDA0) || (VLAEnum::CDA2)) {
257 0 : code = (byte & 0xf0) >> 4;
258 : } else {
259 : code = (byte & 0x0f);
260 : }
261 0 : if (code == 4) {
262 : Float retVal;
263 0 : setNaN(retVal);
264 0 : return retVal;
265 : }
266 0 : if (code == 3) return 1E200; // Should translate into Inf
267 0 : Int factor = 1 << code;
268 0 : return 50.0/Double(factor)*1E6;
269 : }
270 :
271 127916 : VLAEnum::CorrMode VLASDA::correlatorMode() const {
272 127916 : const Int64 where = itsOffset + 2*(157) ;
273 127916 : itsRecord.seek(where);
274 : Char modeChars[4];
275 127916 : itsRecord.read(4, modeChars);
276 127916 : uInt strLen = 4;
277 127916 : if (modeChars[3] == ' ') strLen--;
278 127916 : if (strLen == 3 && modeChars[2] == ' ') strLen--;
279 127916 : if (strLen == 2 && modeChars[1] == ' ') strLen--;
280 127916 : return VLAEnum::corrMode(String(modeChars, strLen));
281 : }
282 :
283 15124 : uInt VLASDA::npol(VLAEnum::CDA cda) const {
284 15124 : const VLAEnum::CorrMode mode = correlatorMode();
285 15124 : switch (mode) {
286 11968 : case VLAEnum::CONTINUUM:
287 11968 : if ((cda == VLAEnum::CDA0) || (cda == VLAEnum::CDA1)) return 4;
288 0 : break;
289 3156 : case VLAEnum::A:
290 3156 : if (cda == VLAEnum::CDA0) return 1;
291 0 : break;
292 0 : case VLAEnum::B:
293 0 : if (cda == VLAEnum::CDA1) return 1;
294 0 : break;
295 0 : case VLAEnum::C:
296 0 : if (cda == VLAEnum::CDA2) return 1;
297 0 : break;
298 0 : case VLAEnum::D:
299 0 : if (cda == VLAEnum::CDA3) return 1;
300 0 : break;
301 0 : case VLAEnum::AB:
302 0 : if ((cda == VLAEnum::CDA0) || (cda == VLAEnum::CDA1)) return 1;
303 0 : break;
304 0 : case VLAEnum::AC:
305 0 : if ((cda == VLAEnum::CDA0) || (cda == VLAEnum::CDA2)) return 1;
306 0 : break;
307 0 : case VLAEnum::AD:
308 0 : if ((cda == VLAEnum::CDA0) || (cda == VLAEnum::CDA3)) return 1;
309 0 : break;
310 0 : case VLAEnum::BC:
311 0 : if ((cda == VLAEnum::CDA1) || (cda == VLAEnum::CDA2)) return 1;
312 0 : break;
313 0 : case VLAEnum::BD:
314 0 : if ((cda == VLAEnum::CDA1) || (cda == VLAEnum::CDA3)) return 1;
315 0 : break;
316 0 : case VLAEnum::CD:
317 0 : if ((cda == VLAEnum::CDA2) || (cda == VLAEnum::CDA3)) return 1;
318 0 : break;
319 0 : case VLAEnum::ABCD:
320 : case VLAEnum::PA:
321 : case VLAEnum::PB:
322 0 : return 1;
323 0 : default:
324 0 : return 0;
325 : }
326 0 : return 0;
327 : }
328 :
329 22686 : Matrix<VLAEnum::IF> VLASDA::ifUsage(VLAEnum::CDA cda) const {
330 22686 : const VLAEnum::CorrMode mode = correlatorMode();
331 22686 : switch (mode) {
332 17952 : case VLAEnum::CONTINUUM:
333 17952 : if (cda == VLAEnum::CDA0) {
334 17952 : Matrix<VLAEnum::IF> retVal(2, 4);
335 8976 : retVal(0,0) = VLAEnum::IFA; retVal(1,0) = VLAEnum::IFA;
336 8976 : retVal(0,1) = VLAEnum::IFC; retVal(1,1) = VLAEnum::IFC;
337 8976 : retVal(0,2) = VLAEnum::IFA; retVal(1,2) = VLAEnum::IFC;
338 8976 : retVal(0,3) = VLAEnum::IFC; retVal(1,3) = VLAEnum::IFA;
339 8976 : return retVal;
340 8976 : } else if (cda == VLAEnum::CDA1) {
341 17952 : Matrix<VLAEnum::IF> retVal(2, 4);
342 8976 : retVal(0,0) = VLAEnum::IFB; retVal(1,0) = VLAEnum::IFB;
343 8976 : retVal(0,1) = VLAEnum::IFD; retVal(1,1) = VLAEnum::IFD;
344 8976 : retVal(0,2) = VLAEnum::IFB; retVal(1,2) = VLAEnum::IFD;
345 8976 : retVal(0,3) = VLAEnum::IFD; retVal(1,3) = VLAEnum::IFB;
346 8976 : return retVal;
347 : }
348 0 : break;
349 4734 : case VLAEnum::A:
350 4734 : if (cda == VLAEnum::CDA0) {
351 9468 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFA);
352 4734 : return retVal;
353 : }
354 0 : break;
355 0 : case VLAEnum::B:
356 0 : if (cda == VLAEnum::CDA1) {
357 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFB);
358 0 : return retVal;
359 : }
360 0 : break;
361 0 : case VLAEnum::C:
362 0 : if (cda == VLAEnum::CDA2) {
363 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFC);
364 0 : return retVal;
365 : }
366 0 : break;
367 0 : case VLAEnum::D:
368 0 : if (cda == VLAEnum::CDA3) {
369 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFD);
370 0 : return retVal;
371 : }
372 0 : break;
373 0 : case VLAEnum::AB:
374 0 : if (cda == VLAEnum::CDA0) {
375 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFA);
376 0 : return retVal;
377 0 : } else if (cda == VLAEnum::CDA1) {
378 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFB);
379 0 : return retVal;
380 : }
381 0 : break;
382 0 : case VLAEnum::AC:
383 0 : if (cda == VLAEnum::CDA0) {
384 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFA);
385 0 : return retVal;
386 0 : } else if (cda == VLAEnum::CDA2) {
387 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFC);
388 0 : return retVal;
389 : }
390 0 : break;
391 0 : case VLAEnum::AD:
392 0 : if (cda == VLAEnum::CDA0) {
393 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFA);
394 0 : return retVal;
395 0 : } else if (cda == VLAEnum::CDA3) {
396 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFD);
397 0 : return retVal;
398 : }
399 0 : break;
400 0 : case VLAEnum::BC:
401 0 : if (cda == VLAEnum::CDA1) {
402 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFB);
403 0 : return retVal;
404 0 : } else if (cda == VLAEnum::CDA2) {
405 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFC);
406 0 : return retVal;
407 : }
408 0 : break;
409 0 : case VLAEnum::BD:
410 0 : if (cda == VLAEnum::CDA1) {
411 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFB);
412 0 : return retVal;
413 0 : } else if (cda == VLAEnum::CDA3) {
414 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFD);
415 0 : return retVal;
416 : }
417 0 : break;
418 0 : case VLAEnum::CD:
419 0 : if (cda == VLAEnum::CDA2) {
420 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFC);
421 0 : return retVal;
422 0 : } else if (cda == VLAEnum::CDA3) {
423 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFD);
424 0 : return retVal;
425 : }
426 0 : break;
427 0 : case VLAEnum::ABCD:
428 0 : if (cda == VLAEnum::CDA0) {
429 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFA);
430 0 : return retVal;
431 0 : } else if (cda == VLAEnum::CDA1) {
432 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFB);
433 0 : return retVal;
434 0 : } else if (cda == VLAEnum::CDA2) {
435 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFC);
436 0 : return retVal;
437 0 : } else if (cda == VLAEnum::CDA3) {
438 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFD);
439 0 : return retVal;
440 : }
441 0 : break;
442 0 : case VLAEnum::PA:
443 0 : if (cda == VLAEnum::CDA0) {
444 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFA);
445 0 : return retVal;
446 0 : } else if (cda == VLAEnum::CDA1) {
447 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFC);
448 0 : return retVal;
449 0 : } else if (cda == VLAEnum::CDA2) {
450 0 : Matrix<VLAEnum::IF> retVal(2, 1);
451 0 : retVal(0,0) = VLAEnum::IFA;
452 0 : retVal(1,0) = VLAEnum::IFC;
453 0 : return retVal;
454 0 : } else if (cda == VLAEnum::CDA3) {
455 0 : Matrix<VLAEnum::IF> retVal(2, 1);
456 0 : retVal(0,0) = VLAEnum::IFC;
457 0 : retVal(1,0) = VLAEnum::IFA;
458 0 : return retVal;
459 : }
460 0 : break;
461 0 : case VLAEnum::PB:
462 0 : if (cda == VLAEnum::CDA0) {
463 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFB);
464 0 : return retVal;
465 0 : } else if (cda == VLAEnum::CDA1) {
466 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFD);
467 0 : return retVal;
468 0 : } else if (cda == VLAEnum::CDA2) {
469 0 : Matrix<VLAEnum::IF> retVal(2, 1);
470 0 : retVal(0,0) = VLAEnum::IFB;
471 0 : retVal(1,0) = VLAEnum::IFD;
472 0 : return retVal;
473 0 : } else if (cda == VLAEnum::CDA3) {
474 0 : Matrix<VLAEnum::IF> retVal(2, 1);
475 0 : retVal(0,0) = VLAEnum::IFD;
476 0 : retVal(1,0) = VLAEnum::IFB;
477 0 : return retVal;
478 : }
479 0 : break;
480 0 : default:
481 0 : return Matrix<VLAEnum::IF>(2,1);
482 : }
483 0 : return Matrix<VLAEnum::IF>(2,1);
484 : }
485 :
486 7562 : uInt VLASDA::electronicPath(VLAEnum::CDA cda) const {
487 7562 : const VLAEnum::CorrMode mode = correlatorMode();
488 7562 : if (mode == VLAEnum::PA) return 0;
489 7562 : if (mode == VLAEnum::PB) return 1;
490 7562 : if ((cda == VLAEnum::CDA0) || (cda == VLAEnum::CDA2)) return 0;
491 2992 : return 1;
492 : }
493 :
494 4570 : uInt VLASDA::subArray() const {
495 4570 : const Int64 where = itsOffset;
496 4570 : itsRecord.seek(where);
497 : Short id;
498 4570 : itsRecord >> id;
499 4570 : DebugAssert(id >= 0, AipsError);
500 4570 : return id;
501 : }
502 :
503 0 : String VLASDA::arrayConfig() const {
504 0 : const Int64 where = itsOffset + 2*(10);
505 0 : itsRecord.seek(where);
506 : Char c[2];
507 0 : itsRecord.read(2,c);
508 0 : uInt len = 2;
509 0 : if (c[1] == ' ') len = 1;
510 0 : return String(c, len);
511 : }
512 :
513 4570 : Vector<Double> VLASDA::sourceDir() const {
514 4570 : Vector<Double> pos(2);
515 4570 : const Int64 where = itsOffset + 2*(24);
516 4570 : itsRecord.seek(where);
517 : Bool isACopy;
518 4570 : Double* dPtr = pos.getStorage(isACopy);
519 4570 : itsRecord.read(2,dPtr);
520 4570 : pos.putStorage(dPtr, isACopy);
521 9140 : return pos;
522 : }
523 :
524 25037 : String VLASDA::sourceName() const {
525 25037 : Int64 where = itsOffset + 2*(1) ;
526 25037 : itsRecord.seek(where);
527 25037 : Int len = 16;
528 25037 : Char *c = new Char[len];
529 25037 : itsRecord.read(len, c);
530 250161 : while (len > 0 && c[--len] == ' ');
531 25037 : String name(c, len+1);
532 25037 : delete [] c;
533 25037 : return name;
534 : }
535 :
536 0 : Int VLASDA::sourceQual() const {
537 0 : Int64 where = itsOffset + 2*(9) ;
538 0 : itsRecord.seek(where);
539 : Short qual;
540 0 : itsRecord >> qual;
541 0 : return qual;
542 : }
543 :
544 24710 : Double VLASDA::intTime() const {
545 24710 : Int64 where = itsOffset + 2*(19) ;
546 24710 : itsRecord.seek(where);
547 : Short interrupts;
548 24710 : itsRecord >> interrupts;
549 24710 : return Double(interrupts)/19.2;
550 : }
551 :
552 20140 : Double VLASDA::obsTime() const {
553 20140 : Int64 where = itsOffset + 2*(72) ;
554 20140 : itsRecord.seek(where);
555 : Double radians;
556 20140 : itsRecord >> radians;
557 20140 : return radians/C::_2pi * 60.0 * 60.0 * 24.0 - intTime()/2.0;
558 : }
559 :
560 9140 : String VLASDA::obsId() const {
561 9140 : Int64 where = itsOffset + 2*(11) ;
562 9140 : itsRecord.seek(where);
563 9140 : Int len = 6;
564 9140 : Char *c = new Char[len];
565 9140 : itsRecord.read(len, c);
566 18280 : while (len > 0 && c[--len] == ' ');
567 9140 : String name(c, len+1);
568 9140 : delete [] c;
569 9140 : return name;
570 : }
571 :
572 30062 : String VLASDA::obsMode() const {
573 30062 : const Int64 where = itsOffset + 2*(15);
574 30062 : itsRecord.seek(where);
575 : Char c[2];
576 30062 : itsRecord.read(2,c);
577 30062 : uInt len = 2;
578 60124 : return String(c, len);
579 : }
580 :
581 11 : String VLASDA::obsModeFull() const {
582 22 : String om=obsMode();
583 11 : if(om==" ") {
584 11 : return String("Standard Observing");
585 : }
586 0 : else if(om=="D ") {
587 0 : return String("Delay center determination mode");
588 : }
589 0 : else if(om=="H ") {
590 0 : return String("Holography raster mode");
591 : }
592 0 : else if(om=="IR") {
593 0 : return String("Interferometer reference pointing mode");
594 : }
595 0 : else if(om=="IA") {
596 0 : return String("Interferometer pointing mode (IF A)");
597 : }
598 0 : else if(om=="IB") {
599 0 : return String("Interferometer pointing mode (IF B)");
600 : }
601 0 : else if(om=="IC") {
602 0 : return String("Interferometer pointing mode (IF C)");
603 : }
604 0 : else if(om=="ID") {
605 0 : return String("Interferometer pointing mode (IF D)");
606 : }
607 0 : else if(om=="JA") {
608 0 : return String("JPL mode (IF A)");
609 : }
610 0 : else if(om=="JB") {
611 0 : return String("JPL mode (IF B)");
612 : }
613 0 : else if(om=="JC") {
614 0 : return String("JPL mode (IF C)");
615 : }
616 0 : else if(om=="JD") {
617 0 : return String("JPL mode (IF D)");
618 : }
619 0 : else if(om=="PA") {
620 0 : return String("Single dish pointing mode (IF A)");
621 : }
622 0 : else if(om=="PB") {
623 0 : return String("Single dish pointing mode (IF B)");
624 : }
625 0 : else if(om=="PC") {
626 0 : return String("Single dish pointing mode (IF C)");
627 : }
628 0 : else if(om=="PD") {
629 0 : return String("Single dish pointing mode (IF D)");
630 : }
631 0 : else if(om=="S ") {
632 0 : return String("Solar observing configuration");
633 : }
634 0 : else if(om=="SP") {
635 0 : return String("Solar observing configuration (low accuracy empheris)");
636 : }
637 0 : else if(om=="TB") {
638 0 : return String("Test back-end and front-end");
639 : }
640 0 : else if(om=="TE") {
641 0 : return String("Tipping curve");
642 : }
643 0 : else if(om=="TF") {
644 0 : return String("Test front-end");
645 : }
646 0 : else if(om=="VA") {
647 0 : return String("Self-phasing mode for VLBI phased-array (IFs A and D)");
648 : }
649 0 : else if(om=="VB") {
650 0 : return String("Self-phasing mode for VLBI phased-array (IFs B and C)");
651 : }
652 0 : else if(om=="VL") {
653 0 : return String("Self-phasing mode for VLBI phased-array (IFs C and D)");
654 : }
655 0 : else if(om=="VR") {
656 0 : return String("Self-phasing mode for VLBI phased-array (IFs A and B)");
657 : }
658 0 : else if(om=="VS") {
659 0 : return String("Single dish VLBI");
660 : }
661 0 : else if(om=="VX") {
662 0 : return String("Applies last phase update from source line using VA mode");
663 : }
664 0 : return String("Unknown mode: ") + om;
665 : }
666 :
667 15630 : String VLASDA::calCode() const {
668 15630 : Int64 where = itsOffset + 2*(16) ;
669 15630 : itsRecord.seek(where);
670 : Char c;
671 15630 : itsRecord >> c;
672 31260 : return String(c);
673 : }
674 :
675 9149 : MDirection::Types VLASDA::epoch() const {
676 9149 : const Int64 where = itsOffset + 2*(161) ;
677 9149 : itsRecord.seek(where);
678 : Short year;
679 9149 : itsRecord >> year;
680 9149 : if (year == 2000) {
681 3160 : return MDirection::J2000;
682 5989 : } else if (year == 1950) {
683 : // the 1979.9 epoch B1950 direction
684 5989 : return MDirection::B1950_VLA;
685 0 : } else if (year == -1) {
686 0 : return MDirection::APP;
687 : }
688 : // year is likely 0, N_Types can't be used as is but this signals the problem
689 0 : return MDirection::N_Types;
690 : }
691 :
692 31 : Bool VLASDA::smoothed() const {
693 31 : Int64 where = itsOffset + 2*(159) ;
694 31 : itsRecord.seek(where);
695 : Char c;
696 31 : itsRecord >> c;
697 31 : if (c == 'H') return true;
698 26 : itsRecord >> c;
699 26 : if (c == 'H') return true;
700 26 : return false;
701 : }
702 :
703 : // Local Variables:
704 : // compile-command: "gmake VLASDA; cd test; gmake OPTLIB=1 tVLASDA"
705 : // End:
|