LCOV - code coverage report
Current view: top level - asdmstman - AsdmStMan.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 234 352 66.5 %
Date: 2024-12-11 20:54:31 Functions: 33 46 71.7 %

          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

Generated by: LCOV version 1.16