LCOV - code coverage report
Current view: top level - asdmstman - AsdmStMan.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 169 352 48.0 %
Date: 2025-07-23 00:22:00 Functions: 25 46 54.3 %

          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         117 :   AsdmStMan::AsdmStMan (const String& dataManName)
      58             :   : DataManager    (),
      59         117 :     itsDataManName (dataManName),
      60         117 :     itsBDF         (0),
      61         117 :     itsOpenBDF     (-1),
      62         117 :     itsNBl(0)
      63         117 :   {}
      64             : 
      65           6 :   AsdmStMan::AsdmStMan (const String& dataManName,
      66           6 :                         const Record&)
      67             :   : DataManager    (),
      68           6 :     itsDataManName (dataManName),
      69           6 :     itsBDF         (0),
      70           6 :     itsOpenBDF     (-1),
      71           6 :     itsNBl(0)
      72           6 :   {}
      73             : 
      74           1 :   AsdmStMan::AsdmStMan (const AsdmStMan& that)
      75             :   : DataManager    (),
      76           1 :     itsDataManName (that.itsDataManName),
      77           1 :     itsBDF         (0),
      78           1 :     itsOpenBDF     (-1),
      79           1 :     itsNBl(0)
      80           1 :   {}
      81             : 
      82         131 :   AsdmStMan::~AsdmStMan()
      83             :   {
      84         131 :     for (uInt i=0; i<ncolumn(); i++) {
      85           7 :       delete itsColumns[i];
      86             :     }
      87         124 :     closeBDF();
      88         131 :   }
      89             : 
      90           1 :   DataManager* AsdmStMan::clone() const
      91             :   {
      92           1 :     return new AsdmStMan (*this);
      93             :   }
      94             : 
      95           7 :   String AsdmStMan::dataManagerType() const
      96             :   {
      97           7 :     return "AsdmStMan";
      98             :   }
      99             : 
     100          18 :   String AsdmStMan::dataManagerName() const
     101             :   {
     102          18 :     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           7 :   DataManagerColumn* AsdmStMan::makeIndArrColumn (const String& name,
     126             :                                                   int dtype,
     127             :                                                   const String&)
     128             :   {
     129             :     AsdmColumn* col;
     130           7 :     if (name == "DATA") {
     131           7 :       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           7 :     itsColumns.push_back (col);
     144           7 :     return col;
     145             :   }
     146             : 
     147           6 :   DataManager* AsdmStMan::makeObject (const String& group, const Record& spec)
     148             :   {
     149             :     // This function is called when reading a table back.
     150           6 :     return new AsdmStMan (group, spec);
     151             :   }
     152             : 
     153           4 :   void AsdmStMan::registerClass()
     154             :   {
     155           4 :     DataManager::registerCtor ("AsdmStMan", makeObject);
     156           4 :   }
     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          17 :   void AsdmStMan::addRow (uInt)
     180          17 :   {}
     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           6 :   Bool AsdmStMan::flush (AipsIO&, Bool)
     191             :   {
     192           6 :     return false;
     193             :   }
     194             : 
     195           1 :   void AsdmStMan::create (uInt)
     196           1 :   {}
     197             : 
     198           6 :   void AsdmStMan::open (uInt, AipsIO&)
     199             :   {
     200             :     // Read the index file.
     201           6 :     init();
     202           6 :   }
     203             : 
     204           7 :   void AsdmStMan::prepare()
     205             :   {
     206          14 :     for (uInt i=0; i<ncolumn(); i++) {
     207           7 :       itsColumns[i]->prepareCol();
     208             :     }
     209           7 :   }
     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         132 :   void AsdmStMan::closeBDF()
     225             :   {
     226         132 :     if (itsOpenBDF >= 0) {
     227           8 :       delete itsBDF;
     228           8 :       itsBDF = 0;
     229           8 :       FiledesIO::close (itsFD);
     230           8 :       itsOpenBDF = -1;
     231             :     }
     232         132 :   }
     233             : 
     234           6 :   void AsdmStMan::init()
     235             :   {
     236             :     // Open index file and check version.
     237          12 :     AipsIO aio(fileName() + "asdmindex");
     238           6 :     itsVersion = aio.getstart ("AsdmStMan");
     239           6 :     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           6 :     aio >> asBigEndian >> itsBDFNames;
     245           6 :     aio.get (itsIndex);
     246           6 :     aio.getend();
     247           6 :     itsDoSwap = (asBigEndian != HostInfo::bigEndian());
     248             :     // Fill the vector with rows from the index.
     249           6 :     itsIndexRows.resize (itsIndex.size());
     250        4056 :     for (uInt i=0; i<itsIndex.size(); ++i) {
     251        4050 :       itsIndexRows[i] = itsIndex[i].row;
     252             :     }
     253             :     // Fill the specification record (only used for reporting purposes).
     254           6 :     itsSpec.define ("version", itsVersion);
     255           6 :     itsSpec.define ("bigEndian", asBigEndian);
     256           6 :     itsSpec.define ("BDFs", Vector<String>(itsBDFNames.begin(),itsBDFNames.end()));
     257             :     // Set to nothing read yet.
     258           6 :     itsStartRow   = -1;
     259           6 :     itsEndRow     = -1;
     260           6 :     itsIndexEntry = 0;
     261             : 
     262           6 :     if(itsIndex.size()>0){
     263             :       // test if the referenced ASDM seems to be present
     264             :       try{
     265           6 :         itsFD  = FiledesIO::open (itsBDFNames[0].c_str(), false);
     266           6 :         itsBDF = new FiledesIO (itsFD, itsBDFNames[0]);
     267           6 :         itsOpenBDF = 0;
     268           6 :         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           6 :   }
     286             : 
     287      103437 :   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      103437 :     uInt v = binarySearchBrackets (found, itsIndexRows, rownr,
     297      103437 :                                    itsIndexRows.size());
     298      103437 :     if (!found){
     299      103113 :       if(v>0){
     300      103113 :         v--;
     301             :       }
     302             :       else{
     303           0 :         throw DataManError ("AsdmStMan: index empty.");
     304             :       }
     305             :     }
     306             : 
     307      103437 :     return v;
     308             :   }
     309             : 
     310      103275 :   const AsdmIndex& AsdmStMan::findIndex (Int64 rownr)
     311             :   {
     312             :     // Only get if not current.
     313      103275 :     if (rownr < itsStartRow  ||  rownr >= itsEndRow) {
     314         162 :       itsIndexEntry = searchIndex (rownr);
     315         162 :       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         162 :       itsStartRow = ix.row;
     320         162 :       itsEndRow   = ix.row + ix.nrow();
     321             :     }
     322      103275 :     return itsIndex[itsIndexEntry];
     323             :   }
     324             : 
     325       99225 :   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       99225 :     Short* data = (reinterpret_cast<Short*>(&itsData[0]));
     329       99225 :     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       99225 :     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       99225 :       Float * fbuf = reinterpret_cast<Float*>(buf);
     347     8698725 :       for (uInt j=0; j<ix.nChan * ix.nPol; ++j) {
     348     8599500 :           *fbuf++ = data[0]/ix.scaleFactors[spw];
     349     8599500 :           *fbuf++ = data[1]/ix.scaleFactors[spw];
     350     8599500 :           data += 2;
     351             :       }
     352             :     }
     353       99225 :   }
     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        4050 :   void AsdmStMan::getAuto (const AsdmIndex& ix, Complex* buf, uInt bl)
     410             :   {
     411             :     // Get pointer to the data in the block.
     412        4050 :     Float* data = (reinterpret_cast<Float*>(&(itsData[0])));
     413        4050 :     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        4050 :     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        4050 :       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        4050 :       } 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      355050 :         for (uInt i=0; i<ix.nChan * ix.nPol; ++i) {
     471      351000 :           *buf++ = Complex(data[i]);
     472             :         }
     473             :       }
     474             :     }
     475        4050 :   }
     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      103275 :   IPosition AsdmStMan::getShape (uInt rownr)
     506             :   {
     507             :     // Here determine the shape from the rownr.
     508             :     /// For now fill in some shape.
     509      103275 :     uInt inx = searchIndex (rownr);
     510      103275 :     const AsdmIndex& ix = itsIndex[inx];
     511      103275 :     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      103275 :     return IPosition(2, ix.nPol, ix.nChan);
     516             :   }
     517             : 
     518      103275 :   void AsdmStMan::getData (uInt rownr, Complex* buf)
     519             :   {
     520      103275 :     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      103275 :     if (ix.dataType != 10)
     524       99225 :       if (ix.nBl != itsNBl)
     525           1 :         setTransposeBLNum(ix.nBl);
     526             :   
     527             :     // Open the BDF if needed.
     528      103275 :     if (Int(ix.fileNr) != itsOpenBDF) {
     529           2 :       closeBDF();
     530           2 :       itsFD  = FiledesIO::open (itsBDFNames[ix.fileNr].c_str(), false);
     531           2 :       itsBDF = new FiledesIO (itsFD, itsBDFNames[ix.fileNr]);
     532           2 :       itsOpenBDF = ix.fileNr;
     533           2 :       itsFileOffset = ix.fileOffset;
     534           2 :       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      103273 :     else if ( itsFileOffset != ix.fileOffset ) {
     539         160 :       itsFileOffset = ix.fileOffset;
     540         160 :       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      103275 :     if (itsData.empty()) {
     547         162 :       itsData.resize (ix.dataSize());
     548         162 :       itsBDF->seek (ix.fileOffset);
     549         162 :       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      103275 :     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      103275 :     if (ix.dataType != 10 ) 
     560       99225 :       bl = itsTransposeBLNum_v[rownr - ix.row];
     561             :     else
     562        4050 :       bl = (rownr - ix.row);
     563             : 
     564      103275 :     switch (ix.dataType) {
     565       99225 :     case 0:
     566       99225 :       getShort (ix, buf, bl, spw);
     567       99225 :       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        4050 :     case 10:
     575        4050 :       getAuto (ix, buf, bl);
     576        4050 :       break;
     577           0 :     default:
     578           0 :       throw DataManError ("AsdmStMan: Unknown data type");
     579             :     }
     580      103275 :   }
     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           1 :   void AsdmStMan::setTransposeBLNum(uInt nBl) {
     651             :     
     652           1 :     itsTransposeBLNum_v.clear();
     653             : 
     654             :     // Deduce the number of antennas from the number of baselines
     655           1 :     uInt numAnt = (uInt) (floor((1 + sqrt(1 + 8*nBl)) / 2 + 0.5));
     656             : 
     657             :     //cerr << "AsdmStMan::setTransposeBLNum, numAnt=" << numAnt << endl;
     658             :     
     659           1 :     uInt blNum = 0;
     660           1 :     map<uInt, map<uInt, uInt> > _mm;
     661          50 :     for (uInt i2 = 1; i2 < numAnt; i2++) {
     662          49 :       map<uInt, uInt> _m;
     663        1274 :       for (uInt i1 = 0; i1 < i2; i1++) {
     664        1225 :         _m[i1] = blNum;
     665        1225 :         blNum++;
     666             :       }
     667          49 :       _mm[i2] = _m;
     668          49 :     }
     669             : 
     670          51 :     for (uInt i1 = 0; i1 < numAnt; i1++)
     671        1275 :       for (uInt i2 = i1+1; i2 < numAnt; i2++)
     672        1225 :         itsTransposeBLNum_v.push_back(_mm[i2][i1]);
     673             : 
     674           1 :     itsNBl = nBl;
     675           1 :   }
     676             :   
     677             : } //# end namespace

Generated by: LCOV version 1.16