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 0 : VLASDA::VLASDA()
39 : :itsRecord(),
40 0 : itsOffset(0)
41 : {
42 0 : }
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 0 : VLASDA::VLASDA(const VLASDA& other)
53 0 : :itsRecord(other.itsRecord),
54 0 : itsOffset(other.itsOffset)
55 : {
56 0 : }
57 :
58 0 : VLASDA::~VLASDA() {
59 0 : }
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 0 : void VLASDA::attach(ByteSource& record, uInt offset) {
70 0 : itsRecord = record;
71 0 : itsOffset = offset;
72 0 : DebugAssert(record.isReadable(), AipsError);
73 0 : DebugAssert(record.isSeekable(), AipsError);
74 0 : }
75 :
76 0 : uInt VLASDA::trueChannels(VLAEnum::CDA cda) const {
77 0 : Int64 where = itsOffset + 2*(18);
78 0 : if (cda > VLAEnum::CDA1) where++;
79 0 : itsRecord.seek(where);
80 : uChar byte;
81 0 : itsRecord >> byte;
82 : uInt exponent;
83 0 : if ((cda == VLAEnum::CDA0) || (cda == VLAEnum::CDA2)) {
84 0 : exponent = (byte & 0xf0) >> 4;
85 : } else {
86 0 : exponent = (byte & 0x0f);
87 : }
88 0 : uInt nChan = 1;
89 0 : return nChan << exponent;
90 : }
91 :
92 0 : uInt VLASDA::nChannels(VLAEnum::CDA cda) const {
93 0 : uInt nChan = trueChannels(cda);
94 0 : 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 0 : return nChan;
99 : }
100 :
101 0 : Double VLASDA::obsFrequency(VLAEnum::CDA cda) const {
102 : // Calculate the centre frequency using the edge frequency to allow for
103 : // channel offsets.
104 0 : Double freq = edgeFrequency(cda);
105 0 : freq += nChannels(cda)/2.0 * channelWidth(cda);
106 0 : return freq;
107 : }
108 :
109 0 : Double VLASDA::edgeFrequency(VLAEnum::CDA cda) const {
110 :
111 0 : uInt which=cda;
112 : // Trap full-pol sp-line modes correctly
113 0 : if (correlatorMode()==VLAEnum::PA) which=0; // only the A (& C) freq
114 0 : if (correlatorMode()==VLAEnum::PB) which=1; // only the B (& D) freq
115 0 : Int64 where = itsOffset + 2*(40+which*4) ;
116 0 : itsRecord.seek(where);
117 : Double edgeFreq;
118 0 : itsRecord >> edgeFreq;
119 0 : edgeFreq *= 1E9;
120 :
121 0 : where = itsOffset + 2*(56+which*4) ;
122 0 : itsRecord.seek(where);
123 : Double centreFreq;
124 0 : itsRecord >> centreFreq;
125 0 : centreFreq *= 1E9;
126 0 : if (edgeFreq > centreFreq) {//Looks like we are pointing to the upper edge
127 0 : edgeFreq -= correlatedBandwidth(cda);
128 : }
129 :
130 : // Now check if there is a channel offset.
131 0 : if (nChannels(cda) > 1) {
132 0 : where = itsOffset + 2*(162+which);
133 0 : itsRecord.seek(where);
134 : uShort offset;
135 0 : itsRecord >> offset;
136 0 : if (offset > 0) {
137 0 : edgeFreq += static_cast<Double>(offset)*channelWidth(cda);
138 : }
139 : }
140 0 : 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 0 : edgeFreq += 0.5 * channelWidth(cda);;
146 : }
147 0 : return edgeFreq;
148 : }
149 :
150 0 : Bool VLASDA::dopplerTracking(VLAEnum::CDA cda) const {
151 0 : Int64 where = itsOffset + 2*(153+uInt(cda))+1 ;
152 0 : itsRecord.seek(where);
153 : Char code;
154 0 : itsRecord >> code;
155 0 : if (code == 'F' || code == ' ') return false;
156 0 : return true;
157 : }
158 :
159 0 : Double VLASDA::restFrequency(VLAEnum::CDA cda) const {
160 : Double freq;
161 0 : Int64 where = itsOffset + 2*(137+uInt(cda)*4) ;
162 0 : itsRecord.seek(where);
163 0 : itsRecord >> freq;
164 0 : return freq*1E6;
165 : }
166 :
167 0 : Double VLASDA::radialVelocity(VLAEnum::CDA cda) const {
168 0 : Int64 where = itsOffset + 2*(121+uInt(cda)*4) ;
169 0 : itsRecord.seek(where);
170 : Double rv;
171 0 : itsRecord >> rv;
172 0 : return rv*1E3;
173 : }
174 :
175 0 : MFrequency::Types VLASDA::restFrame(VLAEnum::CDA cda) const {
176 0 : Int64 where = itsOffset + 2*(153+uInt(cda)) ;
177 0 : itsRecord.seek(where);
178 : Char code;
179 0 : itsRecord >> code;
180 0 : switch (code) {
181 0 : case 'G':
182 0 : return MFrequency::GEO;
183 0 : case 'B':
184 0 : return MFrequency::BARY;
185 0 : case 'L':
186 0 : return MFrequency::LSRK;
187 0 : case 'T':
188 : default:
189 : // Assume TOPO when not specified
190 0 : return MFrequency::TOPO;
191 : }
192 : // I have to return something! This should be suitably meaningless.
193 : return MFrequency::N_Types;
194 : }
195 :
196 0 : MDoppler::Types VLASDA::dopplerDefn(VLAEnum::CDA cda) const {
197 0 : Int64 where = itsOffset + 2*(153+uInt(cda))+1 ;
198 0 : itsRecord.seek(where);
199 : Char code;
200 0 : itsRecord >> code;
201 0 : switch (code) {
202 0 : case 'Z':
203 0 : return MDoppler::OPTICAL;
204 0 : case 'V':
205 0 : return MDoppler::RADIO;
206 : }
207 : // I have to return something! This should be suitably meaningless.
208 0 : return MDoppler::N_Types;
209 : }
210 :
211 0 : Double VLASDA::channelWidth(VLAEnum::CDA cda) const {
212 0 : if (trueChannels(cda) == 1) {
213 0 : return correlatedBandwidth(cda);
214 : } // As word 166 is only valid is spectral line mode!
215 0 : const Int64 where = itsOffset + 2*(166+uInt(cda));
216 0 : itsRecord.seek(where);
217 : Short exponent;
218 0 : itsRecord >> exponent;
219 0 : const Int factor = 1 << exponent;
220 0 : return 50.0/Double(factor)*1E6;
221 : }
222 :
223 0 : Double VLASDA::correlatedBandwidth(VLAEnum::CDA cda) const {
224 0 : Int64 where = itsOffset + 2*(100) ;
225 0 : if (cda > VLAEnum::CDA1) where++;
226 0 : itsRecord.seek(where);
227 : uChar byte;
228 0 : itsRecord >> byte;
229 : Int code;
230 : if ((cda == VLAEnum::CDA0) || (VLAEnum::CDA2)) {
231 0 : code = (byte & 0xf0) >> 4;
232 : } else {
233 : code = (byte & 0x0f);
234 : }
235 0 : 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 0 : if (code == 7) return 25.0/128.0 * 1E6;
242 0 : if (code == 8) return 70.0 * 1E6;
243 0 : if (code == 9) return doubleInf();
244 0 : Int factor = 1 << code;
245 0 : 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 0 : VLAEnum::CorrMode VLASDA::correlatorMode() const {
272 0 : const Int64 where = itsOffset + 2*(157) ;
273 0 : itsRecord.seek(where);
274 : Char modeChars[4];
275 0 : itsRecord.read(4, modeChars);
276 0 : uInt strLen = 4;
277 0 : if (modeChars[3] == ' ') strLen--;
278 0 : if (strLen == 3 && modeChars[2] == ' ') strLen--;
279 0 : if (strLen == 2 && modeChars[1] == ' ') strLen--;
280 0 : return VLAEnum::corrMode(String(modeChars, strLen));
281 : }
282 :
283 0 : uInt VLASDA::npol(VLAEnum::CDA cda) const {
284 0 : const VLAEnum::CorrMode mode = correlatorMode();
285 0 : switch (mode) {
286 0 : case VLAEnum::CONTINUUM:
287 0 : if ((cda == VLAEnum::CDA0) || (cda == VLAEnum::CDA1)) return 4;
288 0 : break;
289 0 : case VLAEnum::A:
290 0 : 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 0 : Matrix<VLAEnum::IF> VLASDA::ifUsage(VLAEnum::CDA cda) const {
330 0 : const VLAEnum::CorrMode mode = correlatorMode();
331 0 : switch (mode) {
332 0 : case VLAEnum::CONTINUUM:
333 0 : if (cda == VLAEnum::CDA0) {
334 0 : Matrix<VLAEnum::IF> retVal(2, 4);
335 0 : retVal(0,0) = VLAEnum::IFA; retVal(1,0) = VLAEnum::IFA;
336 0 : retVal(0,1) = VLAEnum::IFC; retVal(1,1) = VLAEnum::IFC;
337 0 : retVal(0,2) = VLAEnum::IFA; retVal(1,2) = VLAEnum::IFC;
338 0 : retVal(0,3) = VLAEnum::IFC; retVal(1,3) = VLAEnum::IFA;
339 0 : return retVal;
340 0 : } else if (cda == VLAEnum::CDA1) {
341 0 : Matrix<VLAEnum::IF> retVal(2, 4);
342 0 : retVal(0,0) = VLAEnum::IFB; retVal(1,0) = VLAEnum::IFB;
343 0 : retVal(0,1) = VLAEnum::IFD; retVal(1,1) = VLAEnum::IFD;
344 0 : retVal(0,2) = VLAEnum::IFB; retVal(1,2) = VLAEnum::IFD;
345 0 : retVal(0,3) = VLAEnum::IFD; retVal(1,3) = VLAEnum::IFB;
346 0 : return retVal;
347 : }
348 0 : break;
349 0 : case VLAEnum::A:
350 0 : if (cda == VLAEnum::CDA0) {
351 0 : Matrix<VLAEnum::IF> retVal(2, 1, VLAEnum::IFA);
352 0 : 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 0 : uInt VLASDA::electronicPath(VLAEnum::CDA cda) const {
487 0 : const VLAEnum::CorrMode mode = correlatorMode();
488 0 : if (mode == VLAEnum::PA) return 0;
489 0 : if (mode == VLAEnum::PB) return 1;
490 0 : if ((cda == VLAEnum::CDA0) || (cda == VLAEnum::CDA2)) return 0;
491 0 : return 1;
492 : }
493 :
494 0 : uInt VLASDA::subArray() const {
495 0 : const Int64 where = itsOffset;
496 0 : itsRecord.seek(where);
497 : Short id;
498 0 : itsRecord >> id;
499 0 : DebugAssert(id >= 0, AipsError);
500 0 : 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 0 : Vector<Double> VLASDA::sourceDir() const {
514 0 : Vector<Double> pos(2);
515 0 : const Int64 where = itsOffset + 2*(24);
516 0 : itsRecord.seek(where);
517 : Bool isACopy;
518 0 : Double* dPtr = pos.getStorage(isACopy);
519 0 : itsRecord.read(2,dPtr);
520 0 : pos.putStorage(dPtr, isACopy);
521 0 : return pos;
522 : }
523 :
524 0 : String VLASDA::sourceName() const {
525 0 : Int64 where = itsOffset + 2*(1) ;
526 0 : itsRecord.seek(where);
527 0 : Int len = 16;
528 0 : Char *c = new Char[len];
529 0 : itsRecord.read(len, c);
530 0 : while (len > 0 && c[--len] == ' ');
531 0 : String name(c, len+1);
532 0 : delete [] c;
533 0 : 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 0 : Double VLASDA::intTime() const {
545 0 : Int64 where = itsOffset + 2*(19) ;
546 0 : itsRecord.seek(where);
547 : Short interrupts;
548 0 : itsRecord >> interrupts;
549 0 : return Double(interrupts)/19.2;
550 : }
551 :
552 0 : Double VLASDA::obsTime() const {
553 0 : Int64 where = itsOffset + 2*(72) ;
554 0 : itsRecord.seek(where);
555 : Double radians;
556 0 : itsRecord >> radians;
557 0 : return radians/C::_2pi * 60.0 * 60.0 * 24.0 - intTime()/2.0;
558 : }
559 :
560 0 : String VLASDA::obsId() const {
561 0 : Int64 where = itsOffset + 2*(11) ;
562 0 : itsRecord.seek(where);
563 0 : Int len = 6;
564 0 : Char *c = new Char[len];
565 0 : itsRecord.read(len, c);
566 0 : while (len > 0 && c[--len] == ' ');
567 0 : String name(c, len+1);
568 0 : delete [] c;
569 0 : return name;
570 : }
571 :
572 0 : String VLASDA::obsMode() const {
573 0 : const Int64 where = itsOffset + 2*(15);
574 0 : itsRecord.seek(where);
575 : Char c[2];
576 0 : itsRecord.read(2,c);
577 0 : uInt len = 2;
578 0 : return String(c, len);
579 : }
580 :
581 0 : String VLASDA::obsModeFull() const {
582 0 : String om=obsMode();
583 0 : if(om==" ") {
584 0 : 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 0 : String VLASDA::calCode() const {
668 0 : Int64 where = itsOffset + 2*(16) ;
669 0 : itsRecord.seek(where);
670 : Char c;
671 0 : itsRecord >> c;
672 0 : return String(c);
673 : }
674 :
675 0 : MDirection::Types VLASDA::epoch() const {
676 0 : const Int64 where = itsOffset + 2*(161) ;
677 0 : itsRecord.seek(where);
678 : Short year;
679 0 : itsRecord >> year;
680 0 : if (year == 2000) {
681 0 : return MDirection::J2000;
682 0 : } else if (year == 1950) {
683 : // the 1979.9 epoch B1950 direction
684 0 : 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 0 : Bool VLASDA::smoothed() const {
693 0 : Int64 where = itsOffset + 2*(159) ;
694 0 : itsRecord.seek(where);
695 : Char c;
696 0 : itsRecord >> c;
697 0 : if (c == 'H') return true;
698 0 : itsRecord >> c;
699 0 : if (c == 'H') return true;
700 0 : return false;
701 : }
702 :
703 : // Local Variables:
704 : // compile-command: "gmake VLASDA; cd test; gmake OPTLIB=1 tVLASDA"
705 : // End:
|