Line data Source code
1 : //# AsdmStMan.cc: Storage Manager for the main table of a raw ASDM MS
2 : //# Copyright (C) 2012
3 : //# Associated Universities, Inc. Washington DC, USA.
4 : //# (c) European Southern Observatory, 2012
5 : //# Copyright by ESO (in the framework of the ALMA collaboration)
6 : //#
7 : //# This library is free software; you can redistribute it and/or modify it
8 : //# under the terms of the GNU Library General Public License as published by
9 : //# the Free Software Foundation; either version 2 of the License, or (at your
10 : //# option) any later version.
11 : //#
12 : //# This library is distributed in the hope that it will be useful, but WITHOUT
13 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
15 : //# License for more details.
16 : //#
17 : //# You should have receied a copy of the GNU Library General Public License
18 : //# along with this library; if not, write to the Free Software Foundation,
19 : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
20 : //#
21 : //# Correspondence concerning AIPS++ should be addressed as follows:
22 : //# Internet email: casa-feedback@nrao.edu.
23 : //# Postal address: AIPS++ Project Office
24 : //# National Radio Astronomy Observatory
25 : //# 520 Edgemont Road
26 : //# Charlottesville, VA 22903-2475 USA
27 : //#
28 : //# $Id: AsdmStMan.cc 21600 2012-07-16 09:59:20Z diepen $
29 :
30 : #include <asdmstman/AsdmStMan.h>
31 : #include <asdmstman/AsdmColumn.h>
32 : #include <casacore/tables/Tables/Table.h>
33 : #include <casacore/tables/DataMan/DataManError.h>
34 : #include <casacore/casa/Containers/Record.h>
35 : #include <casacore/casa/Containers/BlockIO.h>
36 : #include <casacore/casa/IO/AipsIO.h>
37 : #include <casacore/casa/OS/CanonicalConversion.h>
38 : #include <casacore/casa/OS/HostInfo.h>
39 : #include <casacore/casa/OS/DOos.h>
40 : #include <casacore/casa/Utilities/BinarySearch.h>
41 : #include <casacore/casa/Utilities/Assert.h>
42 : #include <casacore/casa/Logging/LogIO.h>
43 :
44 : #include <map>
45 :
46 : #if !defined(__clang__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
47 : #define CASA_ATTR_VECTORIZE __attribute__((optimize("tree-vectorize")))
48 : #else
49 : #define CASA_ATTR_VECTORIZE
50 : #endif
51 :
52 : using namespace std;
53 :
54 : using namespace casacore;
55 : namespace casa {
56 :
57 1986 : AsdmStMan::AsdmStMan (const String& dataManName)
58 : : DataManager (),
59 1986 : itsDataManName (dataManName),
60 1986 : itsBDF (0),
61 1986 : itsOpenBDF (-1),
62 1986 : itsNBl(0)
63 1986 : {}
64 :
65 248 : AsdmStMan::AsdmStMan (const String& dataManName,
66 248 : const Record&)
67 : : DataManager (),
68 248 : itsDataManName (dataManName),
69 248 : itsBDF (0),
70 248 : itsOpenBDF (-1),
71 248 : itsNBl(0)
72 248 : {}
73 :
74 33 : AsdmStMan::AsdmStMan (const AsdmStMan& that)
75 : : DataManager (),
76 33 : itsDataManName (that.itsDataManName),
77 33 : itsBDF (0),
78 33 : itsOpenBDF (-1),
79 33 : itsNBl(0)
80 33 : {}
81 :
82 2544 : AsdmStMan::~AsdmStMan()
83 : {
84 2542 : for (uInt i=0; i<ncolumn(); i++) {
85 277 : delete itsColumns[i];
86 : }
87 2265 : closeBDF();
88 2544 : }
89 :
90 33 : DataManager* AsdmStMan::clone() const
91 : {
92 33 : return new AsdmStMan (*this);
93 : }
94 :
95 222 : String AsdmStMan::dataManagerType() const
96 : {
97 222 : return "AsdmStMan";
98 : }
99 :
100 586 : String AsdmStMan::dataManagerName() const
101 : {
102 586 : return itsDataManName;
103 : }
104 :
105 5 : Record AsdmStMan::dataManagerSpec() const
106 : {
107 5 : return itsSpec;
108 : }
109 :
110 :
111 0 : DataManagerColumn* AsdmStMan::makeScalarColumn (const String& name,
112 : int,
113 : const String&)
114 : {
115 0 : throw DataManError(name + " is unknown scalar column for AsdmStMan");
116 : }
117 :
118 0 : DataManagerColumn* AsdmStMan::makeDirArrColumn (const String& name,
119 : int dataType,
120 : const String& dataTypeId)
121 : {
122 0 : return makeIndArrColumn (name, dataType, dataTypeId);
123 : }
124 :
125 279 : DataManagerColumn* AsdmStMan::makeIndArrColumn (const String& name,
126 : int dtype,
127 : const String&)
128 : {
129 : AsdmColumn* col;
130 279 : if (name == "DATA") {
131 239 : col = new AsdmDataColumn(this, dtype);
132 40 : } else if (name == "FLOAT_DATA") {
133 38 : col = new AsdmFloatDataColumn(this, dtype);
134 2 : } else if (name == "FLAG") {
135 0 : col = new AsdmFlagColumn(this, dtype);
136 2 : } else if (name == "WEIGHT") {
137 0 : col = new AsdmWeightColumn(this, dtype);
138 2 : } else if (name == "SIGMA") {
139 0 : col = new AsdmSigmaColumn(this, dtype);
140 : } else {
141 2 : throw DataManError (name + " is unknown array column for AsdmStMan");
142 : }
143 277 : itsColumns.push_back (col);
144 277 : return col;
145 : }
146 :
147 248 : DataManager* AsdmStMan::makeObject (const String& group, const Record& spec)
148 : {
149 : // This function is called when reading a table back.
150 248 : return new AsdmStMan (group, spec);
151 : }
152 :
153 60 : void AsdmStMan::registerClass()
154 : {
155 60 : DataManager::registerCtor ("AsdmStMan", makeObject);
156 60 : }
157 :
158 0 : Bool AsdmStMan::isRegular() const
159 : {
160 0 : return false;
161 : }
162 0 : Bool AsdmStMan::canAddRow() const
163 : {
164 0 : return true;
165 : }
166 0 : Bool AsdmStMan::canRemoveRow() const
167 : {
168 0 : return false;
169 : }
170 0 : Bool AsdmStMan::canAddColumn() const
171 : {
172 0 : return true;
173 : }
174 0 : Bool AsdmStMan::canRemoveColumn() const
175 : {
176 0 : return true;
177 : }
178 :
179 4231 : void AsdmStMan::addRow (uInt)
180 4231 : {}
181 0 : void AsdmStMan::removeRow (uInt)
182 : {
183 0 : throw DataManError ("AsdmStMan cannot remove rows");
184 : }
185 0 : void AsdmStMan::addColumn (DataManagerColumn*)
186 0 : {}
187 0 : void AsdmStMan::removeColumn (DataManagerColumn*)
188 0 : {}
189 :
190 121 : Bool AsdmStMan::flush (AipsIO&, Bool)
191 : {
192 121 : return false;
193 : }
194 :
195 31 : void AsdmStMan::create (uInt)
196 31 : {}
197 :
198 246 : void AsdmStMan::open (uInt, AipsIO&)
199 : {
200 : // Read the index file.
201 246 : init();
202 246 : }
203 :
204 277 : void AsdmStMan::prepare()
205 : {
206 554 : for (uInt i=0; i<ncolumn(); i++) {
207 277 : itsColumns[i]->prepareCol();
208 : }
209 277 : }
210 :
211 0 : void AsdmStMan::resync (uInt)
212 0 : {}
213 :
214 24 : void AsdmStMan::reopenRW()
215 24 : {}
216 :
217 0 : void AsdmStMan::deleteManager()
218 : {
219 0 : closeBDF();
220 : // Remove index file.
221 0 : DOos::remove (fileName()+"asdmindex", false, false);
222 0 : }
223 :
224 18819 : void AsdmStMan::closeBDF()
225 : {
226 18819 : if (itsOpenBDF >= 0) {
227 16554 : delete itsBDF;
228 16554 : itsBDF = 0;
229 16554 : FiledesIO::close (itsFD);
230 16554 : itsOpenBDF = -1;
231 : }
232 18819 : }
233 :
234 246 : void AsdmStMan::init()
235 : {
236 : // Open index file and check version.
237 492 : AipsIO aio(fileName() + "asdmindex");
238 246 : itsVersion = aio.getstart ("AsdmStMan");
239 246 : if (itsVersion > 1) {
240 0 : throw DataManError ("AsdmStMan can only handle up to version 1");
241 : }
242 : // Read the index info.
243 : Bool asBigEndian;
244 246 : aio >> asBigEndian >> itsBDFNames;
245 246 : aio.get (itsIndex);
246 246 : aio.getend();
247 246 : itsDoSwap = (asBigEndian != HostInfo::bigEndian());
248 : // Fill the vector with rows from the index.
249 246 : itsIndexRows.resize (itsIndex.size());
250 724934 : for (uInt i=0; i<itsIndex.size(); ++i) {
251 724688 : itsIndexRows[i] = itsIndex[i].row;
252 : }
253 : // Fill the specification record (only used for reporting purposes).
254 246 : itsSpec.define ("version", itsVersion);
255 246 : itsSpec.define ("bigEndian", asBigEndian);
256 246 : itsSpec.define ("BDFs", Vector<String>(itsBDFNames.begin(),itsBDFNames.end()));
257 : // Set to nothing read yet.
258 246 : itsStartRow = -1;
259 246 : itsEndRow = -1;
260 246 : itsIndexEntry = 0;
261 :
262 246 : if(itsIndex.size()>0){
263 : // test if the referenced ASDM seems to be present
264 : try{
265 246 : itsFD = FiledesIO::open (itsBDFNames[0].c_str(), false);
266 246 : itsBDF = new FiledesIO (itsFD, itsBDFNames[0]);
267 246 : itsOpenBDF = 0;
268 246 : closeBDF();
269 : }
270 0 : catch (AipsError x){
271 0 : LogIO os(LogOrigin("AsdmStMan", "init()"));
272 : os << LogIO::WARN
273 : << "An error occured when accessing the ASDM referenced by this table:" << endl
274 : << x.what() << endl
275 0 : << "This means you will not be able to access the columns" << endl;
276 0 : for(uInt i=0; i<itsColumns.size(); i++){
277 0 : os << itsColumns[i]->columnName() << endl;
278 : }
279 : os << "You may have (re)moved the ASDM from its import location." << endl
280 : << "If you want to access the above columns, please restore the ASDM\nor correct the reference to it."
281 0 : << LogIO::POST;
282 0 : }
283 : }
284 :
285 246 : }
286 :
287 6442727 : uInt AsdmStMan::searchIndex (Int64 rownr)
288 : {
289 : // Search index entry matching this rownr.
290 : // If not exactly found, it is previous one.
291 : /// vector<uInt>::const_iterator low = std::lower_bound (itsIndexRows.begin(),
292 : /// itsIndexRows.end(),
293 : /// rownr);
294 : ///return low - itsIndexRows.begin();
295 : Bool found;
296 6442727 : uInt v = binarySearchBrackets (found, itsIndexRows, rownr,
297 6442727 : itsIndexRows.size());
298 6442727 : if (!found){
299 6337892 : if(v>0){
300 6337892 : v--;
301 : }
302 : else{
303 0 : throw DataManError ("AsdmStMan: index empty.");
304 : }
305 : }
306 :
307 6442727 : return v;
308 : }
309 :
310 6245575 : const AsdmIndex& AsdmStMan::findIndex (Int64 rownr)
311 : {
312 : // Only get if not current.
313 6245575 : if (rownr < itsStartRow || rownr >= itsEndRow) {
314 345095 : itsIndexEntry = searchIndex (rownr);
315 345095 : const AsdmIndex& ix = itsIndex[itsIndexEntry];
316 : // Resize to indicate not read yet.
317 : // Note that reserved size stays the same, so no extra mallocs needed.
318 : // itsData.resize (0); commented out by Michel Caillat 03 Dec 2012
319 345095 : itsStartRow = ix.row;
320 345095 : itsEndRow = ix.row + ix.nrow();
321 : }
322 6245575 : return itsIndex[itsIndexEntry];
323 : }
324 :
325 3704829 : void CASA_ATTR_VECTORIZE AsdmStMan::getShort (const AsdmIndex& ix, Complex* buf, uInt bl, uInt spw)
326 : {
327 : // Get pointer to the data in the block.
328 3704829 : Short* data = (reinterpret_cast<Short*>(&itsData[0]));
329 3704829 : data = data + 2 * ix.blockOffset + 2 * bl * ix.stepBl ; // Michel Caillat - 21 Nov 2012
330 :
331 : //cout << "getShort works at this adress : " << (unsigned long long int) data << endl;
332 :
333 3704829 : if (itsDoSwap) {
334 : Short real,imag;
335 0 : for (uInt j=0; j<ix.nChan; ++j) {
336 0 : for (uInt i=0; i<ix.nPol; ++i) {
337 0 : CanonicalConversion::reverse2 (&real, data);
338 0 : CanonicalConversion::reverse2 (&imag, data+1);
339 0 : *buf++ = Complex(real/ix.scaleFactors[spw],
340 0 : imag/ix.scaleFactors[spw]);
341 0 : data += 2;
342 : }
343 : }
344 : } else {
345 : // GCC < 5 fails vectorizing Complex so use floats (same layout c++11 26.4)
346 3704829 : Float * fbuf = reinterpret_cast<Float*>(buf);
347 172492677 : for (uInt j=0; j<ix.nChan * ix.nPol; ++j) {
348 168787848 : *fbuf++ = data[0]/ix.scaleFactors[spw];
349 168787848 : *fbuf++ = data[1]/ix.scaleFactors[spw];
350 168787848 : data += 2;
351 : }
352 : }
353 3704829 : }
354 :
355 2004480 : void AsdmStMan::getInt (const AsdmIndex& ix, Complex* buf, uInt bl, uInt spw)
356 : {
357 : // Get pointer to the data in the block.
358 2004480 : Int* data = (reinterpret_cast<Int*>(&(itsData[0])));
359 2004480 : data = data + 2 * ix.blockOffset + 2 * bl * ix.stepBl; // 21 Nov 2012 - Michel Caillat
360 2004480 : if (itsDoSwap) {
361 : Int real,imag;
362 0 : for (uInt j=0; j<ix.nChan; ++j) {
363 0 : for (uInt i=0; i<ix.nPol; ++i) {
364 0 : CanonicalConversion::reverse4 (&real, data);
365 0 : CanonicalConversion::reverse4 (&imag, data+1);
366 0 : *buf++ = Complex(real/ix.scaleFactors[spw],
367 0 : imag/ix.scaleFactors[spw]);
368 0 : data += 2;
369 : }
370 : }
371 : } else {
372 258577920 : for (uInt j=0; j<ix.nChan; ++j) {
373 769720320 : for (uInt i=0; i<ix.nPol; ++i) {
374 513146880 : *buf++ = Complex(data[0]/ix.scaleFactors[spw],
375 513146880 : data[1]/ix.scaleFactors[spw]);
376 513146880 : data += 2;
377 : }
378 : }
379 : }
380 2004480 : }
381 :
382 0 : void AsdmStMan::getFloat (const AsdmIndex& ix, Complex* buf, uInt bl, uInt spw)
383 : {
384 : // Get pointer to the data in the block.
385 0 : Float* data = (reinterpret_cast<Float*>(&(itsData[0])));
386 0 : data = data + 2 * ix.blockOffset + 2 * bl * ix.stepBl; // 21 Nov 2012 Michel Caillat
387 0 : if (itsDoSwap) {
388 : Float real,imag;
389 0 : for (uInt j=0; j<ix.nChan; ++j) {
390 0 : for (uInt i=0; i<ix.nPol; ++i) {
391 0 : CanonicalConversion::reverse4 (&real, data);
392 0 : CanonicalConversion::reverse4 (&imag, data+1);
393 0 : *buf++ = Complex(real/ix.scaleFactors[spw],
394 0 : imag/ix.scaleFactors[spw]);
395 0 : data += 2;
396 : }
397 : }
398 : } else {
399 0 : for (uInt j=0; j<ix.nChan; ++j) {
400 0 : for (uInt i=0; i<ix.nPol; ++i) {
401 0 : *buf++ = Complex(data[0]/ix.scaleFactors[spw],
402 0 : data[1]/ix.scaleFactors[spw]);
403 0 : data += 2;
404 : }
405 : }
406 : }
407 0 : }
408 :
409 456054 : void AsdmStMan::getAuto (const AsdmIndex& ix, Complex* buf, uInt bl)
410 : {
411 : // Get pointer to the data in the block.
412 456054 : Float* data = (reinterpret_cast<Float*>(&(itsData[0])));
413 456054 : data = data + ix.blockOffset + bl * ix.stepBl; // 21 Nov 2012 . Michel Caillat
414 :
415 : // The autocorr can have 1, 2, 3 or 4 npol.
416 : // 1 and 2 are XX and/or YY which are real numbers.
417 : // 3 are all 4 pols with XY a complex number and YX=conj(XY).
418 : // 4 are all 4 pols with XX,YY real and XY,YX complex.
419 456054 : if (itsDoSwap) {
420 : Float valr, vali;
421 0 : if (ix.nPol == 3) {
422 0 : for (uInt i=0; i<ix.nChan; ++i) {
423 0 : CanonicalConversion::reverse4 (&valr, data++);
424 0 : *buf++ = Complex(valr); // XX
425 0 : CanonicalConversion::reverse4 (&valr, data++);
426 0 : CanonicalConversion::reverse4 (&vali, data++);
427 0 : *buf++ = Complex(valr, vali); // XY
428 0 : *buf++ = Complex(valr, -vali); // YX
429 0 : CanonicalConversion::reverse4 (&valr, data++);
430 0 : *buf++ = Complex(valr); // YY
431 : }
432 0 : } else if (ix.nPol == 4) {
433 0 : for (uInt i=0; i<ix.nChan; ++i) {
434 0 : CanonicalConversion::reverse4 (&valr, data++);
435 0 : *buf++ = Complex(valr); // XX
436 0 : CanonicalConversion::reverse4 (&valr, data++);
437 0 : CanonicalConversion::reverse4 (&vali, data++);
438 0 : *buf++ = Complex(valr, vali); // XY
439 0 : CanonicalConversion::reverse4 (&valr, data++);
440 0 : CanonicalConversion::reverse4 (&vali, data++);
441 0 : *buf++ = Complex(valr, vali); // YX
442 0 : CanonicalConversion::reverse4 (&valr, data++);
443 0 : *buf++ = Complex(valr); // YY
444 : }
445 : } else {
446 0 : for (uInt i=0; i<ix.nChan * ix.nPol; ++i) {
447 0 : CanonicalConversion::reverse4 (&valr, data++);
448 0 : *buf++ = Complex(valr);
449 : }
450 : }
451 : } else {
452 : // No byte swap needed.
453 456054 : if (ix.nPol == 3) {
454 0 : for (uInt i=0; i<ix.nChan; ++i) {
455 0 : *buf++ = Complex(data[0]);
456 0 : *buf++ = Complex(data[1], data[2]);
457 0 : *buf++ = Complex(data[1], -data[2]);
458 0 : *buf++ = Complex(data[3]);
459 0 : data += 4;
460 : }
461 456054 : } else if (ix.nPol == 4) {
462 0 : for (uInt i=0; i<ix.nChan; ++i) {
463 0 : *buf++ = Complex(data[0]);
464 0 : *buf++ = Complex(data[1], data[2]);
465 0 : *buf++ = Complex(data[3], data[4]);
466 0 : *buf++ = Complex(data[5]);
467 0 : data += 6;
468 : }
469 : } else {
470 52879014 : for (uInt i=0; i<ix.nChan * ix.nPol; ++i) {
471 52422960 : *buf++ = Complex(data[i]);
472 : }
473 : }
474 : }
475 456054 : }
476 :
477 80212 : void AsdmStMan::getAuto (const AsdmIndex& ix, Float* buf, uInt bl)
478 : {
479 : // Get pointer to the data in the block.
480 80212 : Float* data = (reinterpret_cast<Float*>(&(itsData[0])));
481 80212 : data = data + ix.blockOffset + bl * ix.stepBl;
482 :
483 : // This can only apply to the FLOAT_DATA column, and in that
484 : // case nPol can only be 1 or 2, anything else is an error.
485 : // No complex values should be possible here.
486 :
487 80212 : if (ix.nPol > 2) {
488 0 : throw DataManError ("AsdmStMan: more than 2 polarizations found for FLOAT_DATA, can not accomodate.");
489 : }
490 :
491 80212 : if (itsDoSwap) {
492 : Float valr;
493 0 : for (uInt i=0; i<ix.nChan * ix.nPol; ++i) {
494 0 : CanonicalConversion::reverse4 (&valr, data++);
495 0 : *buf++ = valr;
496 : }
497 : } else {
498 : // No byte swap needed.
499 113565860 : for (uInt i=0; i<ix.nChan * ix.nPol; ++i) {
500 113485648 : *buf++ = data[i];
501 : }
502 : }
503 80212 : }
504 :
505 6097632 : IPosition AsdmStMan::getShape (uInt rownr)
506 : {
507 : // Here determine the shape from the rownr.
508 : /// For now fill in some shape.
509 6097632 : uInt inx = searchIndex (rownr);
510 6097632 : const AsdmIndex& ix = itsIndex[inx];
511 6097632 : if (ix.dataType == 10 && ix.nPol == 3) {
512 : // 3 autocorrs means 4 (YX = conj(XY));
513 0 : return IPosition(2, 4, ix.nChan);
514 : }
515 6097632 : return IPosition(2, ix.nPol, ix.nChan);
516 : }
517 :
518 6165363 : void AsdmStMan::getData (uInt rownr, Complex* buf)
519 : {
520 6165363 : const AsdmIndex& ix = findIndex (rownr);
521 :
522 : // If we are in front of Correlator data, do we have to update the baseline numbers tranposition ?
523 6165363 : if (ix.dataType != 10)
524 5709309 : if (ix.nBl != itsNBl)
525 50 : setTransposeBLNum(ix.nBl);
526 :
527 : // Open the BDF if needed.
528 6165363 : if (Int(ix.fileNr) != itsOpenBDF) {
529 6935 : closeBDF();
530 6935 : itsFD = FiledesIO::open (itsBDFNames[ix.fileNr].c_str(), false);
531 6935 : itsBDF = new FiledesIO (itsFD, itsBDFNames[ix.fileNr]);
532 6935 : itsOpenBDF = ix.fileNr;
533 6935 : itsFileOffset = ix.fileOffset;
534 6935 : itsData.resize(0);
535 : }
536 :
537 : // Or we did not have open a new BDF but are aiming at a new position in the same BDF
538 6158428 : else if ( itsFileOffset != ix.fileOffset ) {
539 327884 : itsFileOffset = ix.fileOffset;
540 327884 : itsData.resize(0);
541 : }
542 :
543 : // Read data block if not done yet, i.e. if and only if we are in a new BDF or in the same
544 : // one but at a new position (fileOffset).
545 : //
546 6165363 : if (itsData.empty()) {
547 334819 : itsData.resize (ix.dataSize());
548 334819 : itsBDF->seek (ix.fileOffset);
549 334819 : itsBDF->read (itsData.size(), &(itsData[0]));
550 : }
551 : // Determine the spw and baseline from the row.
552 : // The rows are stored in order of spw,baseline.
553 6165363 : uInt spw = ix.iSpw ; // 19 Feb 2014 : Michel Caillat changed this assignement;
554 :
555 : //
556 : // Attention !!! If we are in front of Correlator data we must apply the transposition function
557 : uInt bl;
558 : //cerr << "shape0 "<< itsTransposeBLNum_v.size() << endl;
559 6165363 : if (ix.dataType != 10 )
560 5709309 : bl = itsTransposeBLNum_v[rownr - ix.row];
561 : else
562 456054 : bl = (rownr - ix.row);
563 :
564 6165363 : switch (ix.dataType) {
565 3704829 : case 0:
566 3704829 : getShort (ix, buf, bl, spw);
567 3704829 : break;
568 2004480 : case 1:
569 2004480 : getInt (ix, buf, bl, spw);
570 2004480 : break;
571 0 : case 3:
572 0 : getFloat (ix, buf, bl, spw);
573 0 : break;
574 456054 : case 10:
575 456054 : getAuto (ix, buf, bl);
576 456054 : break;
577 0 : default:
578 0 : throw DataManError ("AsdmStMan: Unknown data type");
579 : }
580 6165363 : }
581 :
582 80212 : void AsdmStMan::getData (uInt rownr, Float* buf)
583 : {
584 80212 : const AsdmIndex& ix = findIndex (rownr);
585 :
586 : // float data can only be fetched for type 10
587 80212 : if (ix.dataType != 10) {
588 0 : throw DataManError ("AsdmStMan: illegal data type for FLOAT_DATA column");
589 : }
590 :
591 : // Open the BDF if needed.
592 80212 : if (Int(ix.fileNr) != itsOpenBDF) {
593 9373 : closeBDF();
594 9373 : itsFD = FiledesIO::open (itsBDFNames[ix.fileNr].c_str(), false);
595 9373 : itsBDF = new FiledesIO (itsFD, itsBDFNames[ix.fileNr]);
596 9373 : itsOpenBDF = ix.fileNr;
597 9373 : itsFileOffset = ix.fileOffset;
598 9373 : itsData.resize(0);
599 : }
600 :
601 : // Or we did not have open a new BDF but are aiming at a new position in the same BDF
602 70839 : else if ( itsFileOffset != ix.fileOffset ) {
603 3 : itsFileOffset = ix.fileOffset;
604 3 : itsData.resize(0);
605 : }
606 :
607 : // Read data block if not done yet, i.e. if and only if we are in a new BDF or in the same
608 : // one but at a new position (fileOffset).
609 : //
610 80212 : if (itsData.empty()) {
611 9376 : itsData.resize (ix.dataSize());
612 9376 : itsBDF->seek (ix.fileOffset);
613 9376 : itsBDF->read (itsData.size(), &(itsData[0]));
614 : }
615 : // Determine the spw and baseline from the row.
616 : // The rows are stored in order of spw,baseline.
617 : // getAuto appears to not depend on spw. R.Garwood.
618 :
619 80212 : uInt bl = (rownr - ix.row);
620 80212 : getAuto (ix, buf, bl);
621 80212 : }
622 :
623 3 : void AsdmStMan::getBDFNames(Block<String>& bDFNames)
624 : {
625 3 : bDFNames = itsBDFNames;
626 3 : return;
627 : }
628 :
629 3 : Bool AsdmStMan::setBDFNames(Block<String>& bDFNames)
630 : {
631 3 : if(bDFNames.size() == itsBDFNames.size()){
632 3 : itsBDFNames = bDFNames;
633 3 : return true;
634 : }
635 : else{
636 0 : return false;
637 : }
638 : }
639 :
640 3 : void AsdmStMan::writeIndex(){
641 :
642 6 : AipsIO aio(fileName() + "asdmindex", ByteIO::New);
643 3 : aio.putstart("AsdmStMan", itsVersion);
644 3 : aio << HostInfo::bigEndian() << itsBDFNames;
645 3 : aio.put(itsIndex);
646 3 : aio.putend();
647 :
648 3 : }
649 :
650 50 : void AsdmStMan::setTransposeBLNum(uInt nBl) {
651 :
652 50 : itsTransposeBLNum_v.clear();
653 :
654 : // Deduce the number of antennas from the number of baselines
655 50 : uInt numAnt = (uInt) (floor((1 + sqrt(1 + 8*nBl)) / 2 + 0.5));
656 :
657 : //cerr << "AsdmStMan::setTransposeBLNum, numAnt=" << numAnt << endl;
658 :
659 50 : uInt blNum = 0;
660 50 : map<uInt, map<uInt, uInt> > _mm;
661 1589 : for (uInt i2 = 1; i2 < numAnt; i2++) {
662 1539 : map<uInt, uInt> _m;
663 28768 : for (uInt i1 = 0; i1 < i2; i1++) {
664 27229 : _m[i1] = blNum;
665 27229 : blNum++;
666 : }
667 1539 : _mm[i2] = _m;
668 1539 : }
669 :
670 1639 : for (uInt i1 = 0; i1 < numAnt; i1++)
671 28818 : for (uInt i2 = i1+1; i2 < numAnt; i2++)
672 27229 : itsTransposeBLNum_v.push_back(_mm[i2][i1]);
673 :
674 50 : itsNBl = nBl;
675 50 : }
676 :
677 : } //# end namespace
|