LCOV - code coverage report
Current view: top level - asdmstman - AsdmStMan.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 16 352 4.5 %
Date: 2024-10-12 00:35:29 Functions: 4 46 8.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          32 :   AsdmStMan::AsdmStMan (const String& dataManName)
      58             :   : DataManager    (),
      59          32 :     itsDataManName (dataManName),
      60          32 :     itsBDF         (0),
      61          32 :     itsOpenBDF     (-1),
      62          32 :     itsNBl(0)
      63          32 :   {}
      64             : 
      65           0 :   AsdmStMan::AsdmStMan (const String& dataManName,
      66           0 :                         const Record&)
      67             :   : DataManager    (),
      68           0 :     itsDataManName (dataManName),
      69           0 :     itsBDF         (0),
      70           0 :     itsOpenBDF     (-1),
      71           0 :     itsNBl(0)
      72           0 :   {}
      73             : 
      74           0 :   AsdmStMan::AsdmStMan (const AsdmStMan& that)
      75             :   : DataManager    (),
      76           0 :     itsDataManName (that.itsDataManName),
      77           0 :     itsBDF         (0),
      78           0 :     itsOpenBDF     (-1),
      79           0 :     itsNBl(0)
      80           0 :   {}
      81             : 
      82          32 :   AsdmStMan::~AsdmStMan()
      83             :   {
      84          32 :     for (uInt i=0; i<ncolumn(); i++) {
      85           0 :       delete itsColumns[i];
      86             :     }
      87          32 :     closeBDF();
      88          32 :   }
      89             : 
      90           0 :   DataManager* AsdmStMan::clone() const
      91             :   {
      92           0 :     return new AsdmStMan (*this);
      93             :   }
      94             : 
      95           0 :   String AsdmStMan::dataManagerType() const
      96             :   {
      97           0 :     return "AsdmStMan";
      98             :   }
      99             : 
     100           0 :   String AsdmStMan::dataManagerName() const
     101             :   {
     102           0 :     return itsDataManName;
     103             :   }
     104             : 
     105           0 :   Record AsdmStMan::dataManagerSpec() const
     106             :   {
     107           0 :     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           0 :   DataManagerColumn* AsdmStMan::makeIndArrColumn (const String& name,
     126             :                                                   int dtype,
     127             :                                                   const String&)
     128             :   {
     129             :     AsdmColumn* col;
     130           0 :     if (name == "DATA") {
     131           0 :       col = new AsdmDataColumn(this, dtype);
     132           0 :     } else if (name ==  "FLOAT_DATA") {
     133           0 :       col = new AsdmFloatDataColumn(this, dtype);
     134           0 :     } else if (name == "FLAG") {
     135           0 :       col = new AsdmFlagColumn(this, dtype);
     136           0 :     } else if (name == "WEIGHT") {
     137           0 :       col = new AsdmWeightColumn(this, dtype);
     138           0 :     } else if (name == "SIGMA") {
     139           0 :       col = new AsdmSigmaColumn(this, dtype);
     140             :     } else {
     141           0 :       throw DataManError (name + " is unknown array column for AsdmStMan");
     142             :     }
     143           0 :     itsColumns.push_back (col);
     144           0 :     return col;
     145             :   }
     146             : 
     147           0 :   DataManager* AsdmStMan::makeObject (const String& group, const Record& spec)
     148             :   {
     149             :     // This function is called when reading a table back.
     150           0 :     return new AsdmStMan (group, spec);
     151             :   }
     152             : 
     153           3 :   void AsdmStMan::registerClass()
     154             :   {
     155           3 :     DataManager::registerCtor ("AsdmStMan", makeObject);
     156           3 :   }
     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           0 :   void AsdmStMan::addRow (uInt)
     180           0 :   {}
     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           0 :   Bool AsdmStMan::flush (AipsIO&, Bool)
     191             :   {
     192           0 :     return false;
     193             :   }
     194             : 
     195           0 :   void AsdmStMan::create (uInt)
     196           0 :   {}
     197             : 
     198           0 :   void AsdmStMan::open (uInt, AipsIO&)
     199             :   {
     200             :     // Read the index file.
     201           0 :     init();
     202           0 :   }
     203             : 
     204           0 :   void AsdmStMan::prepare()
     205             :   {
     206           0 :     for (uInt i=0; i<ncolumn(); i++) {
     207           0 :       itsColumns[i]->prepareCol();
     208             :     }
     209           0 :   }
     210             : 
     211           0 :   void AsdmStMan::resync (uInt)
     212           0 :   {}
     213             : 
     214           0 :   void AsdmStMan::reopenRW()
     215           0 :   {}
     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          32 :   void AsdmStMan::closeBDF()
     225             :   {
     226          32 :     if (itsOpenBDF >= 0) {
     227           0 :       delete itsBDF;
     228           0 :       itsBDF = 0;
     229           0 :       FiledesIO::close (itsFD);
     230           0 :       itsOpenBDF = -1;
     231             :     }
     232          32 :   }
     233             : 
     234           0 :   void AsdmStMan::init()
     235             :   {
     236             :     // Open index file and check version.
     237           0 :     AipsIO aio(fileName() + "asdmindex");
     238           0 :     itsVersion = aio.getstart ("AsdmStMan");
     239           0 :     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           0 :     aio >> asBigEndian >> itsBDFNames;
     245           0 :     aio.get (itsIndex);
     246           0 :     aio.getend();
     247           0 :     itsDoSwap = (asBigEndian != HostInfo::bigEndian());
     248             :     // Fill the vector with rows from the index.
     249           0 :     itsIndexRows.resize (itsIndex.size());
     250           0 :     for (uInt i=0; i<itsIndex.size(); ++i) {
     251           0 :       itsIndexRows[i] = itsIndex[i].row;
     252             :     }
     253             :     // Fill the specification record (only used for reporting purposes).
     254           0 :     itsSpec.define ("version", itsVersion);
     255           0 :     itsSpec.define ("bigEndian", asBigEndian);
     256           0 :     itsSpec.define ("BDFs", Vector<String>(itsBDFNames.begin(),itsBDFNames.end()));
     257             :     // Set to nothing read yet.
     258           0 :     itsStartRow   = -1;
     259           0 :     itsEndRow     = -1;
     260           0 :     itsIndexEntry = 0;
     261             : 
     262           0 :     if(itsIndex.size()>0){
     263             :       // test if the referenced ASDM seems to be present
     264             :       try{
     265           0 :         itsFD  = FiledesIO::open (itsBDFNames[0].c_str(), false);
     266           0 :         itsBDF = new FiledesIO (itsFD, itsBDFNames[0]);
     267           0 :         itsOpenBDF = 0;
     268           0 :         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           0 :   }
     286             : 
     287           0 :   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           0 :     uInt v = binarySearchBrackets (found, itsIndexRows, rownr,
     297           0 :                                    itsIndexRows.size());
     298           0 :     if (!found){
     299           0 :       if(v>0){
     300           0 :         v--;
     301             :       }
     302             :       else{
     303           0 :         throw DataManError ("AsdmStMan: index empty.");
     304             :       }
     305             :     }
     306             : 
     307           0 :     return v;
     308             :   }
     309             : 
     310           0 :   const AsdmIndex& AsdmStMan::findIndex (Int64 rownr)
     311             :   {
     312             :     // Only get if not current.
     313           0 :     if (rownr < itsStartRow  ||  rownr >= itsEndRow) {
     314           0 :       itsIndexEntry = searchIndex (rownr);
     315           0 :       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           0 :       itsStartRow = ix.row;
     320           0 :       itsEndRow   = ix.row + ix.nrow();
     321             :     }
     322           0 :     return itsIndex[itsIndexEntry];
     323             :   }
     324             : 
     325           0 :   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           0 :     Short* data = (reinterpret_cast<Short*>(&itsData[0]));
     329           0 :     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           0 :     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           0 :       Float * fbuf = reinterpret_cast<Float*>(buf);
     347           0 :       for (uInt j=0; j<ix.nChan * ix.nPol; ++j) {
     348           0 :           *fbuf++ = data[0]/ix.scaleFactors[spw];
     349           0 :           *fbuf++ = data[1]/ix.scaleFactors[spw];
     350           0 :           data += 2;
     351             :       }
     352             :     }
     353           0 :   }
     354             : 
     355           0 :   void AsdmStMan::getInt (const AsdmIndex& ix, Complex* buf, uInt bl, uInt spw)
     356             :   {
     357             :     // Get pointer to the data in the block.
     358           0 :     Int* data = (reinterpret_cast<Int*>(&(itsData[0])));
     359           0 :     data = data + 2 * ix.blockOffset + 2 * bl * ix.stepBl;   // 21 Nov 2012 - Michel Caillat
     360           0 :     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           0 :       for (uInt j=0; j<ix.nChan; ++j) {
     373           0 :         for (uInt i=0; i<ix.nPol; ++i) {
     374           0 :           *buf++ = Complex(data[0]/ix.scaleFactors[spw],
     375           0 :                            data[1]/ix.scaleFactors[spw]);
     376           0 :           data += 2;
     377             :         }
     378             :       }
     379             :     }
     380           0 :   }
     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           0 :   void AsdmStMan::getAuto (const AsdmIndex& ix, Complex* buf, uInt bl)
     410             :   {
     411             :     // Get pointer to the data in the block.
     412           0 :     Float* data = (reinterpret_cast<Float*>(&(itsData[0])));
     413           0 :     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           0 :     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           0 :       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           0 :       } 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           0 :         for (uInt i=0; i<ix.nChan * ix.nPol; ++i) {
     471           0 :           *buf++ = Complex(data[i]);
     472             :         }
     473             :       }
     474             :     }
     475           0 :   }
     476             : 
     477           0 :   void AsdmStMan::getAuto (const AsdmIndex& ix, Float* buf, uInt bl)
     478             :   {
     479             :     // Get pointer to the data in the block.
     480           0 :     Float* data = (reinterpret_cast<Float*>(&(itsData[0])));
     481           0 :     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           0 :     if (ix.nPol > 2) {
     488           0 :       throw DataManError ("AsdmStMan: more than 2 polarizations found for FLOAT_DATA, can not accomodate.");
     489             :     }
     490             : 
     491           0 :     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           0 :       for (uInt i=0; i<ix.nChan * ix.nPol; ++i) {
     500           0 :         *buf++ = data[i];
     501             :       }
     502             :     }
     503           0 :   }
     504             : 
     505           0 :   IPosition AsdmStMan::getShape (uInt rownr)
     506             :   {
     507             :     // Here determine the shape from the rownr.
     508             :     /// For now fill in some shape.
     509           0 :     uInt inx = searchIndex (rownr);
     510           0 :     const AsdmIndex& ix = itsIndex[inx];
     511           0 :     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           0 :     return IPosition(2, ix.nPol, ix.nChan);
     516             :   }
     517             : 
     518           0 :   void AsdmStMan::getData (uInt rownr, Complex* buf)
     519             :   {
     520           0 :     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           0 :     if (ix.dataType != 10)
     524           0 :       if (ix.nBl != itsNBl)
     525           0 :         setTransposeBLNum(ix.nBl);
     526             :   
     527             :     // Open the BDF if needed.
     528           0 :     if (Int(ix.fileNr) != itsOpenBDF) {
     529           0 :       closeBDF();
     530           0 :       itsFD  = FiledesIO::open (itsBDFNames[ix.fileNr].c_str(), false);
     531           0 :       itsBDF = new FiledesIO (itsFD, itsBDFNames[ix.fileNr]);
     532           0 :       itsOpenBDF = ix.fileNr;
     533           0 :       itsFileOffset = ix.fileOffset;
     534           0 :       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           0 :     else if ( itsFileOffset != ix.fileOffset ) {
     539           0 :       itsFileOffset = ix.fileOffset;
     540           0 :       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           0 :     if (itsData.empty()) {
     547           0 :       itsData.resize (ix.dataSize());
     548           0 :       itsBDF->seek (ix.fileOffset);
     549           0 :       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           0 :     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           0 :     if (ix.dataType != 10 ) 
     560           0 :       bl = itsTransposeBLNum_v[rownr - ix.row];
     561             :     else
     562           0 :       bl = (rownr - ix.row);
     563             : 
     564           0 :     switch (ix.dataType) {
     565           0 :     case 0:
     566           0 :       getShort (ix, buf, bl, spw);
     567           0 :       break;
     568           0 :     case 1:
     569           0 :       getInt (ix, buf, bl, spw);
     570           0 :       break;
     571           0 :     case 3:
     572           0 :       getFloat (ix, buf, bl, spw);
     573           0 :       break;
     574           0 :     case 10:
     575           0 :       getAuto (ix, buf, bl);
     576           0 :       break;
     577           0 :     default:
     578           0 :       throw DataManError ("AsdmStMan: Unknown data type");
     579             :     }
     580           0 :   }
     581             : 
     582           0 :   void AsdmStMan::getData (uInt rownr, Float* buf)
     583             :   {
     584           0 :     const AsdmIndex& ix = findIndex (rownr);
     585             : 
     586             :     // float data can only be fetched for type 10
     587           0 :     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           0 :     if (Int(ix.fileNr) != itsOpenBDF) {
     593           0 :       closeBDF();
     594           0 :       itsFD  = FiledesIO::open (itsBDFNames[ix.fileNr].c_str(), false);
     595           0 :       itsBDF = new FiledesIO (itsFD, itsBDFNames[ix.fileNr]);
     596           0 :       itsOpenBDF = ix.fileNr;
     597           0 :       itsFileOffset = ix.fileOffset;
     598           0 :       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           0 :     else if ( itsFileOffset != ix.fileOffset ) {
     603           0 :       itsFileOffset = ix.fileOffset;
     604           0 :       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           0 :     if (itsData.empty()) {
     611           0 :       itsData.resize (ix.dataSize());
     612           0 :       itsBDF->seek (ix.fileOffset);
     613           0 :       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           0 :     uInt bl = (rownr - ix.row);
     620           0 :     getAuto (ix, buf, bl);
     621           0 :   }
     622             : 
     623           0 :   void AsdmStMan::getBDFNames(Block<String>& bDFNames)
     624             :   {
     625           0 :     bDFNames = itsBDFNames;
     626           0 :     return;
     627             :   }
     628             : 
     629           0 :   Bool AsdmStMan::setBDFNames(Block<String>& bDFNames)
     630             :   {
     631           0 :     if(bDFNames.size() == itsBDFNames.size()){
     632           0 :       itsBDFNames = bDFNames;
     633           0 :       return true;
     634             :     }
     635             :     else{
     636           0 :       return false;
     637             :     }
     638             :   }
     639             :   
     640           0 :   void AsdmStMan::writeIndex(){
     641             :   
     642           0 :     AipsIO aio(fileName() + "asdmindex", ByteIO::New);
     643           0 :     aio.putstart("AsdmStMan", itsVersion);
     644           0 :     aio << HostInfo::bigEndian() << itsBDFNames;
     645           0 :     aio.put(itsIndex);
     646           0 :     aio.putend();
     647             :   
     648           0 :   }
     649             : 
     650           0 :   void AsdmStMan::setTransposeBLNum(uInt nBl) {
     651             :     
     652           0 :     itsTransposeBLNum_v.clear();
     653             : 
     654             :     // Deduce the number of antennas from the number of baselines
     655           0 :     uInt numAnt = (uInt) (floor((1 + sqrt(1 + 8*nBl)) / 2 + 0.5));
     656             : 
     657             :     //cerr << "AsdmStMan::setTransposeBLNum, numAnt=" << numAnt << endl;
     658             :     
     659           0 :     uInt blNum = 0;
     660           0 :     map<uInt, map<uInt, uInt> > _mm;
     661           0 :     for (uInt i2 = 1; i2 < numAnt; i2++) {
     662           0 :       map<uInt, uInt> _m;
     663           0 :       for (uInt i1 = 0; i1 < i2; i1++) {
     664           0 :         _m[i1] = blNum;
     665           0 :         blNum++;
     666             :       }
     667           0 :       _mm[i2] = _m;
     668           0 :     }
     669             : 
     670           0 :     for (uInt i1 = 0; i1 < numAnt; i1++)
     671           0 :       for (uInt i2 = i1+1; i2 < numAnt; i2++)
     672           0 :         itsTransposeBLNum_v.push_back(_mm[i2][i1]);
     673             : 
     674           0 :     itsNBl = nBl;
     675           0 :   }
     676             :   
     677             : } //# end namespace

Generated by: LCOV version 1.16