LCOV - code coverage report
Current view: top level - synthesis/CalTables - CalSummary.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 0 562 0.0 %
Date: 2024-12-11 20:54:31 Functions: 0 21 0.0 %

          Line data    Source code
       1             : //# CalSummary.cc:  Helper class for listing a CalTable
       2             : //# Copyright (C) 2018
       3             : //# Associated Universities, Inc. Washington DC, USA.
       4             : //#
       5             : //# This library is free software; you can redistribute it and/or modify it
       6             : //# under the terms of the GNU Library General Public License as published by
       7             : //# the Free Software Foundation; either version 2 of the License, or (at your
       8             : //# option) any later version.
       9             : //#
      10             : //# This library is distributed in the hope that it will be useful, but WITHOUT
      11             : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12             : //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
      13             : //# License for more details.
      14             : //#
      15             : //# You should have received a copy of the GNU Library General Public License
      16             : //# along with this library; if not, write to the Free Software Foundation,
      17             : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      18             : //#
      19             : //# Correspondence concerning AIPS++ should be addressed as follows:
      20             : //#        Internet email: casa-feedback@nrao.edu.
      21             : //#        Postal address: AIPS++ Project Office
      22             : //#                        National Radio Astronomy Observatory
      23             : //#                        520 Edgemont Road
      24             : //#                        Charlottesville, VA 22903-2475 USA
      25             : //#
      26             : //#
      27             : 
      28             : #include <synthesis/CalTables/CalSummary.h>
      29             : #include <synthesis/CalTables/CalMainColumns.h>
      30             : #include <synthesis/CalTables/CalDescColumns.h>
      31             : #include <synthesis/CalTables/CalIter.h>
      32             : #include <synthesis/CalTables/CalBuffer.h>
      33             : #include <synthesis/CalTables/CalSetMetaInfo.h>
      34             : #include <synthesis/MeasurementComponents/MSMetaInfoForCal.h>
      35             : 
      36             : #include <casacore/casa/Quanta/QVector.h>
      37             : #include <casacore/casa/iomanip.h>
      38             : #include <casacore/casa/iostream.h>
      39             : #include <casacore/casa/OS/Path.h>
      40             : #include <casacore/measures/Measures/MeasTable.h>
      41             : #include <casacore/ms/MSOper/MSMetaData.h>
      42             : #include <casacore/tables/Tables/TableRecord.h>
      43             : #include <casacore/casa/Utilities/GenSort.h>
      44             : 
      45             : using namespace casacore;
      46             : namespace casa { //# NAMESPACE CASA - BEGIN
      47             : 
      48             : //
      49             : // Constructor assigns pointer.  If CT goes out of scope you
      50             : // will get rubbish.  Also sets string to separate subtable output.
      51             : //
      52           0 : CalSummary::CalSummary (CalTable& ct)
      53           0 : : pCT(&ct),
      54           0 :   msname_p(""),
      55           0 :   haveMS_p(false),
      56           0 :   dashlin1(replicate("-",80)),
      57           0 :   dashlin2(replicate("=",80))
      58           0 : { setMSname(); }
      59             : 
      60           0 : CalSummary::CalSummary (CalTable* ct)
      61           0 : : pCT(ct), 
      62           0 :   msname_p(""),
      63           0 :   haveMS_p(false),
      64           0 :   dashlin1(replicate("-",80)),
      65           0 :   dashlin2(replicate("=",80))
      66           0 : { setMSname(); }
      67             : 
      68           0 : CalSummary::~CalSummary () { }
      69             : 
      70             : 
      71             : //
      72             : // Retrieve number of rows
      73             : //
      74           0 : Int CalSummary::nrow () const
      75             : {
      76           0 :     return pCT->nRowMain();
      77             : }
      78             : 
      79             : 
      80             : //
      81             : // Get cal table name
      82             : //
      83           0 : const String CalSummary::name () const
      84             : {
      85           0 :     return pCT->tableName();
      86             : }
      87             : 
      88             : 
      89             : //
      90             : // Reassign pointer.
      91             : //
      92           0 : Bool CalSummary::setCT (CalTable& ct)
      93             : {
      94             :     CalTable* pTemp;
      95           0 :     pTemp = &ct;
      96           0 :     if (pTemp == 0) {
      97           0 :         return False;
      98             :     } else {
      99           0 :         pCT = pTemp;
     100           0 :         setMSname();
     101           0 :         return True;
     102             :     }
     103             : }
     104             : 
     105           0 : void CalSummary::setMSname() {
     106           0 :   ROCalDescColumns calDescCol(*pCT);
     107           0 :   Path filepath(name());
     108           0 :   String msname(calDescCol.msName()(0)), path(filepath.dirName());
     109           0 :   if (!path.empty())
     110           0 :     path += "/";
     111           0 :   String fullmsname = path + msname;
     112           0 :   if (!msname.empty() && Table::isReadable(fullmsname)) {
     113           0 :     msname_p = fullmsname;
     114           0 :     haveMS_p = true;
     115             :   } else {
     116           0 :     haveMS_p = false;
     117             :   }
     118           0 : }
     119             : 
     120             : //
     121             : // List information about a ct to the logger
     122             : //
     123           0 : void CalSummary::list (LogIO& os, Bool verbose) const
     124             : {
     125             :     // List a title for the Summary
     126           0 :     listTitle (os);
     127             :     // List the main table and subtables in a useful order and format
     128           0 :     listWhere(os, verbose);
     129           0 :     os << dashlin1 << endl;
     130           0 :     listWhat(os, verbose);
     131           0 :     os << dashlin1 << endl;
     132           0 :     listHow(os, verbose);
     133           0 :     os << dashlin1 << endl;
     134             :     // Post it
     135           0 :     os.post();
     136           0 : }
     137             : 
     138             : //
     139             : // List a title for the Summary
     140             : //
     141           0 : void CalSummary::listTitle (LogIO& os) const
     142             : {
     143           0 :     os << LogIO::NORMAL;
     144             :     // Type of cal table
     145           0 :     casacore::String type("unknown");
     146           0 :     os << dashlin2 << endl << "Cal Table Name: " << this->name();
     147           0 :     type = pCT->type();
     148           0 :     os << "   Cal Type: " << type;
     149           0 :     os << endl << dashlin2 << endl;
     150           0 : }
     151             : 
     152             : 
     153             : //
     154             : // Convenient table groupings
     155             : //
     156           0 : void CalSummary::listWhere (LogIO& os, Bool verbose) const
     157             : {
     158           0 :     listObservation (os,verbose);
     159           0 : }
     160             : 
     161           0 : void CalSummary::listWhat (LogIO& os, Bool verbose) const
     162             : {
     163           0 :     listMain(os, verbose);
     164           0 :     os << dashlin1 << endl;
     165           0 :     listField(os, verbose);
     166           0 : }
     167             : 
     168           0 : void CalSummary::listHow (LogIO& os, Bool verbose) const
     169             : {
     170           0 :     listSpectralWindow(os, verbose);
     171           0 :     os << dashlin1 << endl;
     172           0 :     listAntenna(os, verbose);
     173           0 : }
     174             : 
     175             : //
     176             : // SUBTABLES
     177             : //
     178           0 : void CalSummary::listMain (LogIO& os, Bool verbose) const
     179             : {
     180           0 :     if (nrow() <= 0) {
     181           0 :         os << "The MAIN table is empty: there are no data!!!" << endl << LogIO::POST;
     182           0 :         return;
     183             :     }
     184             :     // to get columns from main and subtables
     185           0 :     ROCalMainColumns ctmain(*pCT);
     186           0 :     ROCalDescColumns ctdesc(*pCT);
     187             : 
     188             :     // Time:
     189           0 :     casacore::Vector<casacore::Double> times = ctmain.time().getColumn();
     190           0 :     casacore::Double startTime = times(0);
     191           0 :     casacore::Double stopTime = times(times.size()-1);
     192           0 :     casacore::Double exposTime = stopTime - startTime;
     193           0 :     casacore::String timeref = ctmain.time().keywordSet().subRecord("MEASINFO").asString("Ref");
     194             :     // Output info
     195             :     os << "  Data records: " << nrow() << "       Total elapsed time = "
     196             :        << exposTime << " seconds" << endl
     197             :        << "   Observed from   "
     198           0 :        << MVTime(startTime/C::day).string(MVTime::DMY,7)
     199             :        << "   to   "
     200           0 :        << MVTime(stopTime/C::day).string(MVTime::DMY,7)
     201             :        << " (" << timeref << ")"
     202           0 :        << endl << endl;
     203           0 :     os << LogIO::POST;
     204             : 
     205           0 :     if (verbose) {
     206             :         // Field names from MS:
     207           0 :         casacore::Vector<casacore::String> fieldnames;
     208           0 :         if (haveMS_p) {
     209           0 :           MSMetaInfoForCal msmeta(msname_p);
     210           0 :           msmeta.fieldNames(fieldnames);
     211           0 :         }
     212             :         // Spw Ids from CAL_DESC table
     213           0 :         casacore::Array<casacore::Int> spwids(ctdesc.spwId().getColumn());
     214             : 
     215             :         // Field widths for printing:
     216           0 :         casacore::Int width_lead(2),
     217           0 :             width_scan(4),
     218           0 :             width_time(22),
     219           0 :             width_fieldId(5),
     220           0 :             width_fieldname(20),
     221           0 :             width_nrow(10);
     222             : 
     223             :         // Sort order
     224           0 :         casacore::Vector<casacore::Int> icols(3);
     225           0 :         icols[0] = MSC::OBSERVATION_ID;
     226           0 :         icols[1] = MSC::SCAN_NUMBER;
     227           0 :         icols[2] = MSC::FIELD_ID;
     228           0 :         CalIter* iter = new CalIter(*pCT, icols);
     229           0 :         CalBuffer* buff = new CalBuffer(*iter);
     230             :         // values from main table
     231           0 :         casacore::Vector<casacore::Int> obs = buff->obsId();
     232           0 :         casacore::Vector<casacore::Double> times = buff->time();
     233           0 :         casacore::Vector<casacore::Int> scans = buff->scanNo();
     234           0 :         casacore::Vector<casacore::Int> fieldIds = buff->fieldId();
     235           0 :         casacore::Vector<casacore::Double> intervals = buff->interval();
     236           0 :         casacore::Vector<casacore::Int> calDescIds = buff->calDescId();
     237           0 :         casacore::Int lastobs(-2);     // print obsid when changes
     238           0 :         casacore::Double lastday(0.0), lastTime(0.0); // print date when changes
     239           0 :         casacore::Int lastScan(-2), lastField(-2), lastCaldesc(-1), lastInt(-1);
     240           0 :         casacore::Int rowTotal(1);
     241           0 :         delete iter;
     242           0 :         delete buff;
     243           0 :         for (uInt i=0; i<obs.size(); ++i) {
     244           0 :             Int thisobs = obs(i);
     245             :             // print heading for each obs id
     246           0 :             if (thisobs != lastobs) {
     247           0 :                 lastobs = thisobs;
     248           0 :                 lastday = 0.0; // force printing date
     249           0 :                 os << endl << "   ObservationID = " << thisobs << endl;
     250           0 :                 os << LogIO::POST;
     251             :                 // print header for output columns
     252           0 :                 casacore::String datetime = "  Date        Time ( ";
     253             :                 // variable-len timeref string
     254           0 :                 datetime.replace(20,timeref.length(),timeref);
     255           0 :                 datetime.replace(20+timeref.length(),1,")");
     256           0 :                 os << datetime;
     257           0 :                 os << "  Scan  FldId FieldName           nRows       ";
     258           0 :                 os << "SpwIds   Interval" << endl;
     259           0 :                 os << LogIO::POST;
     260           0 :             }
     261             : 
     262             :             // get values for this iteration
     263           0 :             Double time = times(i);
     264           0 :             casacore::Double day = floor(MVTime(time/C::day).day());
     265           0 :             casacore::Int scan = scans(i);
     266           0 :             casacore::Int fieldid = fieldIds(i);
     267           0 :             casacore::Int caldescid = calDescIds(i);
     268           0 :             casacore::Int interval = intervals(i);
     269             : 
     270           0 :             bool lastrow = (i==obs.size()-1);
     271             :             // print line when something changes and at end
     272           0 :             if ((time!=lastTime) || (scan!=lastScan) || (fieldid!=lastField) ||
     273           0 :                 (caldescid!=lastCaldesc) || (interval!=lastInt) || lastrow) {
     274           0 :               if (rowTotal>1) { // but not first row
     275           0 :                 os.output().precision(3);
     276           0 :                 os.output().setf(ios::right, ios::adjustfield);
     277           0 :                 os.output().width(width_lead); os << "  ";
     278             :                 // Timerange beginning time
     279           0 :                 os.output().width(width_time);
     280           0 :                 if (day!=lastday) { // print date
     281           0 :                   os << MVTime(lastTime/C::day).string(MVTime::DMY,7);
     282             :                 } else {            // omit date
     283           0 :                   os << MVTime(lastTime/C::day).string(MVTime::TIME,7);
     284             :                 }
     285             :                 // Scan
     286           0 :                 os.output().width(width_lead); os << "  ";
     287           0 :                 os.output().setf(ios::right, ios::adjustfield);
     288           0 :                 os.output().width(width_scan);
     289           0 :                 os << lastScan;
     290             :                 // FldId
     291           0 :                 os.output().width(width_lead); os << "  ";
     292           0 :                 os.output().setf(ios::right, ios::adjustfield);
     293           0 :                 os.output().width(width_fieldId);
     294           0 :                 casacore::String fieldname("");
     295           0 :                 os << lastField << " ";
     296           0 :                 if (lastField >= 0 && !fieldnames.empty())
     297           0 :                     fieldname = fieldnames(lastField);
     298             :                 // FieldName
     299           0 :                 os.output().setf(ios::left, ios::adjustfield);
     300           0 :                 if (fieldname.length()>20)
     301           0 :                   fieldname.replace(19,1,'*');
     302           0 :                 os.output().width(width_fieldname);
     303           0 :                 os << fieldname.at(0,20);
     304             :                 // nRows
     305           0 :                 os.output().width(width_nrow);
     306           0 :                 os.output().setf(ios::left, ios::adjustfield);
     307           0 :                 if (!lastrow) --rowTotal;
     308           0 :                 os << rowTotal;
     309             :                 // SpwIds
     310           0 :                 os.output().width(width_lead); os << "  ";
     311           0 :                 Slicer spwSlicer = Slicer(Slice(), Slice(lastCaldesc));
     312           0 :                 casacore::Vector<casacore::Int> spws = spwids(spwSlicer);
     313           0 :                 os << spws;
     314             :                 // Interval
     315           0 :                 os.output().width(width_lead); os << "  ";
     316           0 :                 os << "   " << interval;
     317           0 :                 os << endl;
     318           0 :                 os << LogIO::POST;
     319             : 
     320           0 :                 lastday = day; // next lastday is this day
     321           0 :                 rowTotal = 1;  // restart counter
     322           0 :               }
     323           0 :               lastTime = time;
     324           0 :               lastScan = scan;
     325           0 :               lastField = fieldid;
     326           0 :               lastCaldesc = caldescid;
     327           0 :               lastInt = interval;
     328             :             }
     329           0 :             ++rowTotal;
     330             :         }
     331           0 :         os << LogIO::POST;
     332           0 :     }
     333           0 :     clearFormatFlags(os);
     334           0 : }
     335             : 
     336           0 : void CalSummary::listAntenna (LogIO& os, Bool verbose) const
     337             : {
     338             :     // Get unique antenna ids  present in the main table
     339           0 :     ROCalMainColumns ctmain(*pCT);
     340           0 :     std::vector<casacore::Int> ant1col = ctmain.antenna1().getColumn().tovector();
     341           0 :     std::set<casacore::Int> antIds = std::set<casacore::Int>(ant1col.begin(), ant1col.end());
     342           0 :     uInt nAnt = antIds.size();
     343           0 :     os << "Antennas: " << nAnt << endl;
     344             : 
     345             :     // Antenna info from MS
     346           0 :     casacore::Vector<casacore::String> antnames, stations;
     347           0 :     if (!haveMS_p) {
     348           0 :       os << "MS is not available for detailed antenna listing" << LogIO::POST;
     349             :     } else {
     350           0 :       MSMetaInfoForCal msmeta(msname_p);
     351           0 :       msmeta.antennaNames(antnames);
     352           0 :       stations = casacore::Vector<casacore::String>(msmeta.msmd().getAntennaStations());
     353             : 
     354           0 :       if (verbose) {
     355             :         // Detailed antenna list
     356           0 :         casacore::String indent("  ");
     357           0 :         casacore::uInt indwidth(5),
     358           0 :             namewidth(6),
     359           0 :             statwidth(10),
     360           0 :             diamwidth(5),
     361           0 :             latwidth(13),
     362           0 :             longwidth(14),
     363           0 :             offsetwidth(14),
     364           0 :             positionwidth(17);
     365           0 :         casacore::Int diamprec(1);
     366             : 
     367             :         // Antenna info from MS
     368           0 :         MSMetaInfoForCal msmeta(msname_p);
     369           0 :         QVector<Double> diameters = msmeta.msmd().getAntennaDiameters();
     370           0 :         vector<MPosition> positions = msmeta.msmd().getAntennaPositions();
     371           0 :         vector<QVector<Double> > offsets = msmeta.msmd().getAntennaOffsets();
     372           0 :         Bool posIsITRF = (positions[0].getRef().getType() == MPosition::ITRF);
     373             : 
     374             :         // Get observatory position info for antenna offsets 
     375             :         // *not read from antenna table OFFSET column!*
     376           0 :         casacore::MPosition obsPos;
     377           0 :         casacore::String telname;
     378           0 :         bool doOffset = getObservatoryPosition(obsPos, telname);
     379           0 :         casacore::Double rObs = 0.0, longObs = 0.0, latObs = 0.0;
     380           0 :         if (!doOffset) {
     381           0 :             os << "Warning: Telescope name '" << telname << "' is not recognized by CASA.  Cannot compute offsets." << endl << endl;
     382             :         } else {
     383           0 :             casacore::Vector<casacore::Double> obsXYZ = obsPos.get("m").getValue();
     384           0 :             casacore::Double xo(obsXYZ[0]), yo(obsXYZ[1]), zo(obsXYZ[2]);
     385           0 :             rObs = sqrt(xo*xo + yo*yo + zo*zo);
     386           0 :             casacore::Vector<casacore::Double> obsLongLat = obsPos.getAngle("rad").getValue();
     387           0 :             longObs = obsLongLat[0];
     388           0 :             latObs = obsLongLat[1];
     389           0 :         }
     390             : 
     391           0 :         os.output().setf(ios::fixed, ios::floatfield);
     392           0 :         os.output().setf(ios::left, ios::adjustfield);
     393             :         // Write the column headings:
     394           0 :         os << indent;
     395           0 :         os.output().width(indwidth);    os << "ID";
     396           0 :         os.output().width(namewidth);   os << "Name";
     397           0 :         os.output().width(statwidth);   os << "Station";
     398           0 :         os.output().width(diamwidth+4); os << "Diam.";
     399           0 :         os.output().width(longwidth);   os << "Long.";
     400           0 :         os.output().width(latwidth);    os << "Lat.";
     401           0 :         if (doOffset) {
     402           0 :             os.output().width(3 * offsetwidth);
     403           0 :             os << "       Offset from array center (m)";
     404             :         }
     405           0 :         os.output().width(3 * positionwidth);
     406           0 :         os << "         ITRF Geocentric coordinates (m)";
     407           0 :         os << endl << indent;
     408           0 :         os.output().width(indwidth + namewidth + statwidth + diamwidth + 4 + longwidth + latwidth);
     409           0 :         os << " ";
     410           0 :         os.output().setf(ios::right, ios::adjustfield);
     411           0 :         if (doOffset) {
     412           0 :             os.output().width(offsetwidth); os << "East";
     413           0 :             os.output().width(offsetwidth); os << "North";
     414           0 :             os.output().width(offsetwidth); os << "Elevation";
     415             :         }
     416           0 :         os.output().width(positionwidth); os << "x";
     417           0 :         os.output().width(positionwidth); os << "y";
     418           0 :         os.output().width(positionwidth); os << "z";
     419           0 :         os << endl;
     420             :         // Iterator through antennas and log info for each
     421           0 :         const static Unit diamUnit("m");
     422           0 :         std::set<Int>::const_iterator iter = antIds.begin();
     423           0 :         std::set<Int>::const_iterator end = antIds.end();
     424           0 :         for (; iter!=end; ++iter) {
     425           0 :           Int antId = *iter;
     426             :           // diameter
     427           0 :           const Quantity& diam = diameters[antId];
     428             :           // xyz
     429           0 :           casacore::Vector<casacore::Double> xyz = positions[antId].get("m").getValue();
     430           0 :           casacore::Double x = xyz(0);
     431           0 :           casacore::Double y = xyz(1);
     432           0 :           casacore::Double z = xyz(2);
     433           0 :           casacore::Double rAnt = sqrt(x*x + y*y + z*z);
     434             :           // offsets
     435           0 :           const MPosition& mLongLat = positions[antId];
     436           0 :           casacore::Vector<casacore::Double> antOffset;
     437           0 :           if (doOffset) {
     438           0 :               casacore::Vector<casacore::Double> longLatRad = mLongLat.getAngle("rad").getValue();
     439           0 :               casacore::Double longAnt = longLatRad(0);
     440           0 :               casacore::Double latAnt = longLatRad(1);
     441           0 :               casacore::Vector<casacore::Double> offset(3);
     442           0 :               offset[0] = (longAnt - longObs) * rObs * cos(latObs);
     443           0 :               offset[1] = (latAnt - latObs) * rObs;
     444           0 :               offset[2] = rAnt - rObs;
     445           0 :               casacore::QVD qoffset(offset, "m");
     446           0 :               antOffset = qoffset.getValue("m");
     447           0 :           }
     448             :           // lat/long
     449           0 :           MVAngle mvLong = mLongLat.getAngle().getValue()(0);
     450           0 :           MVAngle mvLat = mLongLat.getAngle().getValue()(1);
     451           0 :           if (!posIsITRF) {
     452           0 :               MeasConvert<MPosition> toItrf(positions[antId], MPosition::ITRF);
     453           0 :               positions[antId] = toItrf(positions[antId]);
     454           0 :           }
     455             :           // write the row
     456           0 :           os.output().setf(ios::left, ios::adjustfield);
     457           0 :           os << indent;
     458             :           // ID, Name, Station
     459           0 :           os.output().width(indwidth);  os << antId;
     460           0 :           os.output().width(namewidth); os << antnames(antId);
     461           0 :           os.output().width(statwidth); os << stations(antId);
     462             :           // Diam.
     463           0 :           os.output().precision(diamprec);
     464           0 :           os.output().width(diamwidth);
     465           0 :           os << diam.getValue(diamUnit) << "m   ";
     466             :           // Long. and Lat.
     467           0 :           os.output().width(longwidth);
     468           0 :           os << mvLong.string(MVAngle::ANGLE,7);
     469           0 :           os.output().width(latwidth);
     470           0 :           os << mvLat.string(MVAngle::DIG2,7);
     471           0 :           if (doOffset) {
     472             :               // Offset from array center (m) (East, North, Elevation)
     473           0 :               os.output().setf(ios::right, ios::adjustfield);
     474           0 :               os.output().precision(4);
     475           0 :               os.output().width(offsetwidth); os << antOffset(0);
     476           0 :               os.output().width(offsetwidth); os << antOffset(1);
     477           0 :               os.output().width(offsetwidth); os << antOffset(2);
     478             :           }
     479             :           // ITRF Geocentric coordinates (m) (x, y, z)
     480           0 :           os.output().precision(6);
     481           0 :           os.output().width(positionwidth); os << x;
     482           0 :           os.output().width(positionwidth); os << y;
     483           0 :           os.output().width(positionwidth); os << z;
     484           0 :           os << endl;
     485           0 :         }
     486           0 :       } else {
     487             :         // Horizontal list of the stations names:
     488           0 :             os << " ('name'@'station') " <<  endl;
     489           0 :         casacore::String line, leader;
     490             :         // track last id of previous line for leader
     491           0 :         casacore::Int lastIdInLine = *antIds.begin() - 1;
     492           0 :         std::set<casacore::Int>::const_iterator iter = antIds.begin();
     493           0 :         std::set<casacore::Int>::const_iterator end = antIds.end();
     494           0 :         casacore::Int maxAnt = *std::max_element(antIds.begin(), antIds.end());
     495           0 :         for (; iter!=end; ++iter) {
     496           0 :             Int antId = *iter;
     497             :             // Build the line
     498           0 :             if (!antnames.empty()) 
     499           0 :                 line = line + "'" + antnames(antId) + "'" + "@";
     500           0 :             if (!stations.empty()) 
     501           0 :                 line = line + "'" + stations(antId) + "'";
     502             :             // Add comma if not at the end
     503           0 :             if (antId != maxAnt)  line = line + ", ";
     504           0 :             if (line.length() > 55 || antId == maxAnt) {
     505             :                 // This line is finished, dump it after the line leader
     506           0 :                 leader = String::toString(lastIdInLine+1) + "-" + String::toString(antId) +": ";
     507           0 :                 os << "   ID=";
     508           0 :                 os.output().setf(ios::right, ios::adjustfield);
     509           0 :                 os.output().width(8); os << leader;
     510           0 :                 os << line << endl;
     511           0 :                 line = "";
     512           0 :                 lastIdInLine = antId;
     513             :             }
     514             :         }
     515           0 :     }
     516           0 :   }
     517           0 :   os << LogIO::POST;
     518           0 :   clearFormatFlags(os);
     519           0 : }
     520             : 
     521           0 : bool CalSummary::getObservatoryPosition(casacore::MPosition& obspos,
     522             :         casacore::String& name) const {
     523             :     // Returns observatory position in ITRF
     524           0 :     bool obsposOk(false);
     525           0 :     MSMetaInfoForCal msmeta(msname_p);
     526             :     // get telescope name
     527           0 :     name = msmeta.msmd().getObservatoryNames()[0];
     528           0 :     obsposOk = MeasTable::Observatory(obspos, name);
     529           0 :     if (obsposOk && (obspos.getRef().getType() != MPosition::ITRF)) {
     530           0 :         MeasConvert<MPosition> toItrf(obspos, MPosition::ITRF);
     531           0 :         obspos = toItrf(obspos);
     532           0 :     }
     533           0 :     return obsposOk;
     534           0 : }
     535             : 
     536           0 : void CalSummary::listField (LogIO& os, Bool /*verbose*/) const
     537             : {
     538             :   // Get unique field ids  present in the main table
     539           0 :   ROCalMainColumns ctmain(*pCT);
     540           0 :   std::vector<casacore::Int> fieldcol = ctmain.fieldId().getColumn().tovector();
     541           0 :   std::set<casacore::Int> fieldIds = std::set<casacore::Int>(fieldcol.begin(), fieldcol.end());
     542           0 :   uInt nfield = fieldIds.size();
     543             : 
     544           0 :   os << "Fields: " << nfield << endl;
     545           0 :   if (!haveMS_p)
     546           0 :       os << "MS is not available for detailed field listing" << LogIO::POST;
     547             :   else {
     548           0 :     casacore::Int widthLead(2),
     549           0 :         widthField(6),
     550           0 :         widthCode(5),
     551           0 :         widthName(20),
     552           0 :         widthRA(16),
     553           0 :         widthDec(16),
     554           0 :         widthType(8),
     555           0 :         widthSrc(6);
     556             : 
     557             :     // Print heading
     558           0 :     os.output().setf(ios::left, ios::adjustfield);
     559           0 :     os.output().width(widthLead);   os << "  ";
     560           0 :     os.output().width(widthField);  os << "FldId";
     561           0 :     if (haveMS_p) {
     562           0 :       os.output().width(widthCode);   os << "Code";
     563           0 :       os.output().width(widthName);   os << "Name";
     564           0 :       os.output().width(widthRA);     os << "RA";
     565           0 :       os.output().width(widthDec);    os << " Decl";
     566           0 :       os.output().width(widthType);   os << "Epoch";
     567           0 :       os.output().width(widthSrc);    os << "SrcId";
     568             :     }
     569           0 :     os << endl;
     570             : 
     571             :     // get values from MS
     572           0 :     casacore::Vector<casacore::String> fieldNames, codes;
     573           0 :     vector<MDirection> phaseDirs;
     574           0 :     vector<Int> sourceIds;
     575           0 :     if (haveMS_p) {
     576           0 :       MSMetaInfoForCal msmeta(msname_p);
     577           0 :       msmeta.fieldNames(fieldNames);
     578           0 :       codes = casacore::Vector<casacore::String>(msmeta.msmd().getFieldCodes());
     579           0 :       phaseDirs = msmeta.msmd().getPhaseDirs();
     580           0 :       sourceIds = msmeta.msmd().getFieldTableSourceIDs();
     581           0 :     } 
     582             : 
     583             :     // loop through fields
     584           0 :     std::set<Int>::const_iterator fiter = fieldIds.begin();
     585           0 :     std::set<Int>::const_iterator fend = fieldIds.end();
     586           0 :     static const MEpoch ezero(Quantity(0, "s"));
     587           0 :     for (; fiter!=fend; ++fiter) {
     588           0 :         Int fieldId = *fiter;
     589           0 :         if (fieldId >=0) {
     590           0 :             os.output().setf(ios::left, ios::adjustfield);
     591           0 :             os.output().width(widthLead);  os << "  ";
     592           0 :             os.output().width(widthField); os << fieldId;
     593           0 :             if (haveMS_p) {
     594           0 :               casacore::MDirection mRaDec = phaseDirs[fieldId];
     595           0 :               MVAngle mvRa = mRaDec.getAngle().getValue()(0);
     596           0 :               MVAngle mvDec = mRaDec.getAngle().getValue()(1);
     597           0 :               String name = fieldNames(fieldId);
     598           0 :               if (name.length()>20) 
     599           0 :                 name.replace(19,1,"*");
     600           0 :               os.output().width(widthCode);  os << codes(fieldId);
     601           0 :               os.output().width(widthName);  os << name.at(0,20);
     602           0 :               os.output().width(widthRA);    os << mvRa(0.0).string(MVAngle::TIME,12);
     603           0 :               os.output().width(widthDec);   os << mvDec.string(MVAngle::DIG2,11);
     604           0 :               os.output().width(widthType);
     605           0 :               os << MDirection::showType(mRaDec.getRefPtr()->getType());
     606           0 :               os.output().width(widthSrc);  os << sourceIds[fieldId];
     607           0 :             }
     608           0 :             os << endl;
     609             :         } else {
     610           0 :             os.output().setf(ios::left, ios::adjustfield);
     611           0 :             os.output().width(widthLead);  os << "  ";
     612           0 :             os.output().width(widthField); os << fieldId;
     613           0 :             os << endl;
     614             :         }
     615             :     }
     616           0 :     os << LogIO::POST;
     617           0 :   }
     618           0 :   clearFormatFlags(os);
     619           0 : }
     620             : 
     621           0 : void CalSummary::listObservation (LogIO& os, Bool /*verbose*/) const
     622             : {
     623             :     // Get unique obs ids  present in the main table
     624           0 :     ROCalMainColumns ctmain(*pCT);
     625           0 :     std::vector<casacore::Int> obscol = ctmain.obsId().getColumn().tovector();
     626           0 :     std::set<casacore::Int> obsIds = std::set<casacore::Int>(obscol.begin(), obscol.end());
     627           0 :     os << "Observation IDs in main table: " << obsIds << endl;
     628             : 
     629           0 :     Int nrow = pCT->nRowObservation();
     630           0 :     if (nrow <= 0) {
     631           0 :         os << "The OBSERVATION table is empty";
     632             :     } else {
     633           0 :         os << "Observation table entries: " << nrow << LogIO::POST;
     634           0 :         for (Int irow=0 ; irow < nrow; irow++) {
     635           0 :             Record obsRow = pCT->getRowObservation(irow);
     636           0 :             String observer = obsRow.asString("OBSERVER");
     637           0 :             if (!observer.empty())
     638           0 :                 os << "   Observer: " << observer;
     639           0 :             String project = obsRow.asString("PROJECT");
     640           0 :             if (!project.empty())
     641           0 :                 os << "   Project: " << project;
     642           0 :             String telescope = obsRow.asString("TELESCOPE_NAME");
     643           0 :             if (!telescope.empty())
     644           0 :                 os << "   Telescope: " << telescope;
     645             :                         // TIME_RANGE values don't match main table or ms!
     646           0 :         }
     647             :     }
     648           0 :     os << LogIO::POST;
     649           0 :     clearFormatFlags(os);
     650           0 : }
     651             : 
     652           0 : void CalSummary::listHistory (LogIO& os) const
     653             : {
     654           0 :     Int nrow = pCT->nRowHistory();
     655           0 :     if (nrow <= 0) {
     656           0 :         os << "The HISTORY table is empty" << endl;
     657             :     } else {
     658           0 :         os << "History table entries: " << nrow << endl << LogIO::POST;
     659           0 :         for (Int irow=0 ; irow < nrow; irow++) {
     660           0 :             Record histRow = pCT->getRowHistory(irow);
     661           0 :             os << "ROW " << irow << "  ";
     662           0 :             os << "PARMS: " << histRow.asString("CAL_PARMS") << endl;
     663           0 :             os << "TABLES: " << histRow.asString("CAL_TABLES") << endl;
     664           0 :             os << "SELECT: " << histRow.asString("CAL_SELECT") << endl;
     665           0 :             os << "NOTES: " << histRow.asString("CAL_NOTES") << endl;
     666           0 :         }
     667             :     }
     668           0 :     os << LogIO::POST;
     669           0 : }
     670             : 
     671           0 : void CalSummary::listSpectralWindow (LogIO& os, Bool /*verbose*/) const
     672             : {
     673           0 :     ROCalDescColumns ctdesc(*pCT);
     674           0 :         casacore::Array<casacore::Int> spwIdArray = ctdesc.spwId().getColumn();
     675           0 :         IPosition vshape(1, spwIdArray.nelements());
     676           0 :         casacore::Vector<casacore::Int> spwIds(spwIdArray.reform(vshape));
     677           0 :     Int nSpws = GenSort<Int>::sort(spwIds, Sort::Ascending, Sort::NoDuplicates);
     678           0 :     spwIds.resize(nSpws, true);
     679           0 :     os << "Spectral Windows: " << nSpws;
     680           0 :         Bool noSpws = (nSpws==1 && spwIds(0)==-1);
     681           0 :         if (noSpws)
     682           0 :       os << " " << spwIds;
     683           0 :         os << endl;
     684             : 
     685           0 :         if (!noSpws) {
     686           0 :           if (haveMS_p) {
     687           0 :         MSMetaInfoForCal msmeta(msname_p);
     688           0 :         vector<MFrequency> refFreqs = msmeta.msmd().getRefFreqs();
     689           0 :             vector<uInt> nChans = msmeta.msmd().nChans();
     690           0 :             vector<Double> totalBWs = msmeta.msmd().getBandWidths();
     691           0 :             vector<QVD> resolution = msmeta.msmd().getChanResolutions(False);
     692             : 
     693             :         // Header: SpwId  Ref.Freq    #Chans  Resolution  TotalBW
     694           0 :         casacore::Int widthLead(2), widthId(7), widthFreq(13), widthFrqNum(7), widthNumChan(8);
     695           0 :         os.output().setf(ios::left, ios::adjustfield);
     696           0 :         os.output().width(widthLead);    os << "  ";
     697           0 :         os.output().width(widthId); os << "SpwId";
     698           0 :         os.output().width(widthFreq);    os << "Ref.Freq";
     699           0 :         os.output().width(widthNumChan); os << "#Chans";
     700           0 :         os.output().width(widthFreq);    os << "Resolution";
     701           0 :         os.output().width(widthFreq);    os << "TotalBW";
     702           0 :         os << endl;
     703             : 
     704           0 :         for (Int ispw=0; ispw<nSpws; ispw++) {
     705           0 :                   Int spwId = spwIds(ispw);
     706           0 :           os.output().setf(ios::left, ios::adjustfield);
     707           0 :           os.output().width(widthLead); os << "  ";
     708           0 :           os.output().width(widthId); os << spwId;
     709           0 :                   if (spwId >= 0) {
     710           0 :             os.output().width(widthFrqNum);
     711           0 :             os << refFreqs[spwId].get("MHz");   // MFreqency
     712           0 :             os.output().width(widthLead); os << "  ";
     713           0 :             os.output().width(widthNumChan);
     714           0 :             os << nChans[spwId];
     715           0 :             os.output().width(widthFrqNum);
     716           0 :             os << resolution[spwId][0].get("kHz");  // QVD
     717           0 :             os.output().width(widthLead);    os << "  ";
     718           0 :             os.output().width(widthLead);    os << "  ";
     719           0 :             os.output().width(widthFrqNum);
     720           0 :             os << totalBWs[spwId] / 1000.0;  // convert Hz to kHz
     721           0 :                         os << " kHz";
     722           0 :             os << endl;
     723             :           }
     724             :         }
     725           0 :       } else {
     726           0 :         os << "MS is not available for detailed spw listing" << endl;
     727             :           }
     728             :         }
     729           0 :     os << LogIO::POST;
     730           0 :     clearFormatFlags(os);
     731           0 : }
     732             : 
     733           0 : void CalSummary::listTables (LogIO& os, Bool verbose) const
     734             : {
     735             :     // Get nrows for each table (=-1 if table absent)
     736           0 :     uInt nTables = 4;
     737           0 :     casacore::Vector<casacore::Int> tableRows(nTables);
     738           0 :     tableRows(0) = pCT->nRowMain();
     739           0 :     tableRows(1) = pCT->nRowDesc();
     740           0 :     tableRows(2) = pCT->nRowHistory();
     741           0 :     tableRows(3) = pCT->nRowObservation();
     742             : 
     743           0 :     casacore::Vector<casacore::String> tableStrings(nTables);
     744           0 :     tableStrings(0) = "MAIN";
     745           0 :     tableStrings(1) = "CAL_DESC";
     746           0 :     tableStrings(2) = "CAL_HISTORY";
     747           0 :     tableStrings(3) = "OBSERVATION";
     748             : 
     749             :     // Just to make things read better
     750           0 :     casacore::Vector<casacore::String> rowStrings(6);
     751           0 :     rowStrings = " rows";
     752           0 :     for (uInt i=0; i<nTables; i++) {
     753           0 :         if (tableRows(i)==1) rowStrings(i) = " row";
     754             :         // if table exists, but empty:
     755           0 :         if (tableRows(i)==0) rowStrings(i) = " <empty>";
     756             :         // if table absent:
     757           0 :         if (tableRows(i)==-1) rowStrings(i) = "<absent>";
     758             :     }
     759             : 
     760           0 :     if (verbose) {
     761           0 :         os << "   Tables" << endl;
     762           0 :         for (uInt i=0; i<nTables; i++) {
     763           0 :             os.output().setf(ios::left, ios::adjustfield);
     764           0 :             os.output().width(3);  os << "   ";
     765           0 :             os.output().width(20); os << tableStrings(i);
     766           0 :             os.output().setf(ios::right, ios::adjustfield);
     767           0 :             os.output().width(8);  os << tableRows(i);
     768           0 :             os.output().setf(ios::left, ios::adjustfield);
     769           0 :             os.output().width(10); os << rowStrings(i);
     770           0 :             os << endl;
     771             :         }
     772             :     } else {
     773           0 :         os << "   Tables (rows):    (-1 = table absent)" << endl;
     774           0 :         for (uInt i=0; i<nTables; i++) {
     775           0 :             casacore::String tableinfo = tableStrings(i) + " (" +
     776           0 :                 casacore::String::toString(tableRows(i)) + ")";
     777           0 :             os.output().setf(ios::left, ios::adjustfield);
     778           0 :             casacore::Int infowidth = 15;
     779           0 :             if (i==1 || i==4) infowidth = 25;
     780           0 :             os.output().width(infowidth);
     781           0 :             os << tableinfo;
     782           0 :             if ((i+1) % 3==0) os << endl;
     783           0 :         }
     784             :     }
     785           0 :     os << LogIO::POST;
     786           0 :     clearFormatFlags(os);
     787           0 : }
     788             : 
     789             : //
     790             : // Clear all the formatting flags
     791             : //
     792           0 : void CalSummary::clearFormatFlags(LogIO& os) const
     793             : {
     794           0 :     os.output().unsetf(ios::left);
     795           0 :     os.output().unsetf(ios::right);
     796           0 :     os.output().unsetf(ios::internal);
     797             : 
     798           0 :     os.output().unsetf(ios::dec);
     799           0 :     os.output().unsetf(ios::oct);
     800           0 :     os.output().unsetf(ios::hex);
     801             : 
     802           0 :     os.output().unsetf(ios::showbase | ios::showpos | ios::uppercase | ios::showpoint);
     803             : 
     804           0 :     os.output().unsetf(ios::scientific);
     805           0 :     os.output().unsetf(ios::fixed);
     806           0 : }
     807             : 
     808             : } //# NAMESPACE CASA - END
     809             : 

Generated by: LCOV version 1.16