//# MS2ASDM.h //# //# ALMA - Atacama Large Millimeter Array //# (c) European Southern Observatory, 2002 //# (c) Associated Universities Inc., 2002 //# Copyright by ESO (in the framework of the ALMA collaboration), //# Copyright by AUI (in the framework of the ALMA collaboration), //# All rights reserved. //# //# This library is free software; you can redistribute it and/or //# modify it under the terms of the GNU Lesser General Public //# License as published by the Free software Foundation; either //# version 2.1 of the License, or (at your option) any later version. //# //# This library is distributed in the hope that it will be useful, //# but WITHOUT ANY WARRANTY, without even the implied warranty of //# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //# Lesser General Public License for more details. //# //# You should have received a copy of the GNU Lesser General Public //# License along with this library; if not, write to the Free Software //# Foundation, Inc., 59 Temple Place, Suite 330, Boston, //# MA 02111-1307 USA //# $Id: $ #include <casacore/ms/MeasurementSets/MeasurementSet.h> #include <casacore/ms/MeasurementSets/MSColumns.h> #include <casacore/casa/aips.h> #include <casacore/casa/Arrays/Array.h> #include <casacore/casa/Arrays/Vector.h> #include <map> #include <vector> #include <casacore/casa/OS/Directory.h> #include <alma/ASDM/ASDM.h> #include <alma/ASDM/Tag.h> #include <alma/ASDM/ComplexWrapper.h> #include <alma/ASDM/Frequency.h> #include <alma/ASDM/Angle.h> #include <alma/ASDM/AngularRate.h> #include <alma/ASDM/ArrayTime.h> #include <alma/ASDM/Length.h> #include <alma/ASDM/Temperature.h> #include <alma/ASDM/ArrayTimeInterval.h> #include <alma/ASDM/EntityRef.h> #include <alma/Enumerations/CStokesParameter.h> #include <alma/Enumerations/CAntennaType.h> #include <alma/Enumerations/CBasebandName.h> #include <alma/Enumerations/CNetSideband.h> #include <alma/Enumerations/CFrequencyReferenceCode.h> #include <alma/Enumerations/CReceiverBand.h> #include <alma/Enumerations/CReceiverSideband.h> #include <alma/MS2ASDM/MapWithDefault.h> #ifndef MS2ASDM_MS2ASDM_H #define MS2ASDM_MS2ASDM_H namespace casa { //# NAMESPACE CASA - BEGIN // <summary> // MS2ASDM provides functionalities to create an ASDM (ALMA science data model) // from an existing MS // </summary> // <visibility=export> // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> // </reviewed> // <prerequisite> // <li> MeasurementSet // </prerequisite> // // <etymology> // </etymology> // // <synopsis> // </synopsis> class MS2ASDM : public casacore::MSColumns { public: // construct from an MS MS2ASDM(casacore::MeasurementSet& ms); ~MS2ASDM(); const casacore::String& showversion(); // set verbosity of the write methods void setVerbosity(const casacore::uInt verbosity = 2){ // 0 = only warnings, 1 = most, 2 = everything verbosity_p = verbosity; } void setBaseUid(const casacore::String& baseuid); const casacore::String& getBaseUid(); const std::string& getCurrentUid(); // return currentUid_p with all ":" and "/" characters replaced by "_" const std::string& getCurrentUidAsFileName(); // set maximum duration of a subscan in seconds, 0. == no time limit void setSubScanDuration(const casacore::Double subscanDuration = 24.*3600.){ subscanDuration_p = subscanDuration; } // get maximum duration of a subscan in seconds casacore::Double getSubScanDuration(){ return subscanDuration_p; } // set maximum duration of a Scheduling casacore::Block in seconds void setSBDuration(const casacore::Double sBDuration = 2700.){ // 45 minutes schedBlockDuration_p = sBDuration; } // get maximum duration of a Scheduling casacore::Block in seconds casacore::Double getSBDuration(){ return schedBlockDuration_p; } void setDataAPCorrected(const casacore::Bool isCorrected = true){ dataIsAPCorrected_p = isCorrected; } casacore::Bool dataIsAPCorrected(){ return dataIsAPCorrected_p; } void setObservatoryName(const casacore::String& telName){ telName_p = telName; } void getObservatoryName( casacore::String& telName ){ telName = telName_p; } // convert CASA casacore::Stokes to ASDM Stokes StokesParameterMod::StokesParameter ASDMStokesParameter( casacore::Stokes::StokesTypes s); // convert CASA antenna type string to ASDM antenna type enum AntennaTypeMod::AntennaType ASDMAntennaType( const casacore::String& type ); // convert time in seconds to an array time asdm::ArrayTime ASDMArrayTime( const casacore::Double seconds ){ return asdm::ArrayTime((int64_t) (floor(seconds*asdm::ArrayTime::unitsInASecond))); } // convert array time to time in seconds casacore::Double MSTimeSecs( const asdm::ArrayTime atime ){ return (casacore::Double) atime.get() / (casacore::Double) asdm::ArrayTime::unitsInASecond; } asdm::Interval ASDMInterval( const casacore::Double seconds ){ return asdm::Interval((int64_t) (floor(seconds*asdm::ArrayTime::unitsInASecond))); } // convert casacore::MS style time interval to ASDM ArrayTimeInterval asdm::ArrayTimeInterval ASDMTimeInterval( const casacore::Quantity midpoint, const casacore::Quantity interval); // return start of casacore::MS main table timestamp (seconds) casacore::Double timestampStartSecs(const casacore::uInt mainTabRow){ return timeQuant()(mainTabRow).getValue("s") - intervalQuant()(mainTabRow).getValue("s")/2.; } // return end of casacore::MS main table timestamp (seconds) casacore::Double timestampEndSecs(const casacore::uInt mainTabRow){ return timeQuant()(mainTabRow).getValue("s") + intervalQuant()(mainTabRow).getValue("s")/2.; } // convert casacore::MDirection to a vector of Angles std::vector< asdm::Angle > ASDMAngleV(const casacore::MDirection mDir); // convert casacore::MDirection type to ASDM DirectionReferenceCode DirectionReferenceCodeMod::DirectionReferenceCode ASDMDirRefCode(const casacore::MDirection::Types type); // convert a base band converter number to an ASDM base band name BasebandNameMod::BasebandName ASDMBBName( const casacore::Int bbcNo ); // convert a casacore::MS net sideband no. to an ASDM enum NetSidebandMod::NetSideband ASDMNetSideBand( const casacore::Int netSideband ); // set a representative frequency, the receiver band and receiver sideband based on a frequency refFreq // and the previously set observatory name telName_p, return the band id as an casacore::Int (1 to 10), // -1 if refFreq is outside ALMA bands but observatory is ALMA, 0 if observatory not ALMA casacore::Int setRecBands( const asdm::Frequency refFreq, casacore::Double& frequency, ReceiverBandMod::ReceiverBand& frequencyBand, ReceiverSidebandMod::ReceiverSideband& receiverSideband); FrequencyReferenceCodeMod::FrequencyReferenceCode ASDMFreqRefCode( const casacore::MFrequency::Types refFrame ); casacore::Unit unitASDMFreq(){ return casacore::Unit(casacore::String(asdm::Frequency::unit())); } casacore::Unit unitASDMAngle(){ return casacore::Unit(casacore::String(asdm::Angle::unit())); } casacore::Unit unitASDMAngularRate(){ return casacore::Unit(casacore::String(asdm::AngularRate::unit())); } casacore::Unit unitASDMLength(){ return casacore::Unit(casacore::String(asdm::Length::unit())); } casacore::Unit unitASDMTemp(){ return casacore::Unit(casacore::String(asdm::Temperature::unit())); } asdm::Complex ASDMComplex( casacore::Complex x ){ return asdm::Complex(x.real(), x.imag()); } // write the entire ASDM from scratch casacore::Bool writeASDM(const casacore::String& asdmfile="", const casacore::String& datacolumn="data", const casacore::String& archiveid="S0", const casacore::String& rangeid="X1", const casacore::Bool verbose=true, const casacore::Double maxSubscanDuration = 24.*3600., const casacore::Double maxSchedBlockDuration = 2700., const casacore::Bool msDataIsAPCorrected=true ); private: // *** Private member functions *** casacore::Bool incrementUid(); // returns true if successful casacore::Bool setDirectory(const casacore::String& asdmfile); casacore::Bool writeStation(); casacore::Bool writeAntenna(); casacore::Bool writeSpectralWindow(); casacore::Bool writeSource(); casacore::Bool writePolarization(); casacore::Bool writeCorrelatorMode(); // not called directly but optionally called by writeProcessor() casacore::Bool writeAlmaRadiometer(); // optionally called by writeProcessor() casacore::Bool writeHolography(); // optionally called by writeProcessor() casacore::Bool writeProcessor(); casacore::Bool writeField(); casacore::Bool writeReceiver(); casacore::Bool writeFeed(); casacore::Bool writeDataDescription(); casacore::Bool writeSwitchCycle(); // not yet fully implemented casacore::Bool writeState(); casacore::Bool writeSysCal(); casacore::Bool writeConfigDescription(); // Scheme // 1) We regard one casacore::MS Observation as a set of ASDM ExecBlocks modelled on // a single ASDM Scheduling Block // 2) ALMA ExecBlocks are at most 30 minutes long. // If an casacore::MS Observation is more than 30 Minutes long, it is split up into // several ASDM ExecBlocks each referring to the same Scheduling Block. // 3) Each ASDM ExecBlock contains one or more ASDM Scans based on the casacore::MS scans // 4) Each ASDM Scan contains one or more ASDM Subscans // 5) Each ASDM Subscan is at most subscanduration long. (external parameter) // 6) If an casacore::MS Scan is longer than subscanduration, it is split up into // several ASDM subscans. casacore::Bool writeSBSummaryAndExecBlockStubs(); // "stubs" because these tables will be completed later // with information from the APDM casacore::Bool writeMainAndScanAndSubScan(const casacore::String& datacolumn); // write the Main binary data for one DataDescId/FieldId pair and one SubScan // (return number of integrations written and set the last three parameters in the list) casacore::Int writeMainBinSubScanForOneDDIdFIdPair(const casacore::Int theDDId, const casacore::Int theFieldId, const casacore::String& datacolumn, const casacore::uInt theScan, const casacore::uInt theSubScan, const casacore::uInt startRow, const casacore::uInt endRow, const asdm::Tag eBlockId, int& datasize, asdm::EntityRef& dataOid, std::vector< asdm::Tag >& stateId); casacore::Bool writePointingModel(); // write dummy pointing models casacore::Bool writePointing(); // *** Aux. methods *** // check if vector corrT already contains a stokes type equivalent to st casacore::Bool stokesTypePresent( const casacore::Vector< casacore::Int > corrT, const casacore::Stokes::StokesTypes st ); // *** Member variables *** // Initialized* by ctors. (Maintain order both here and in ctors.) casacore::MeasurementSet ms_p; // the measurement set from which the ASDM is filled asdm::ASDM* ASDM_p; // the new ASDM string asdmVersion_p; // the version of the new ASDM casacore::uInt verbosity_p; // verbosity of the write methods casacore::String baseUid_p; // the part of the UID which is common to all elements of the ASDM, // i.e. typically "uid://archiveid/rangeid/" casacore::uInt runningId_p; // counter for the tables written; starts at 1! // used to construct the UIDs: uid = baseUid_p + (runningId_p converted to unpadded hex string) casacore::String currentUid_p; // the last used uid casacore::String telName_p; // the name of the observatory from first row of casacore::MS observation table casacore::Double subscanDuration_p; // maximum duration of a subscan in seconds casacore::Double schedBlockDuration_p; // maximum duration of a scheduling or exec block in seconds casacore::Bool dataIsAPCorrected_p; // true if the data in the selected casacore::MS data column is // AtmPhaseCorrectionMod::AP_CORRECTED, false if it is // AtmPhaseCorrectionMod::AP_UNCORRECTED string asdmUID_p; // ASDM UID == container ID of all tables casacore::String asdmDir_p; // ASDM output directory name // The default value for the Tag keys is Tag(), so the std::map works as is std::map <casacore::String, asdm::Tag> asdmStationId_p; std::map <casacore::Int, asdm::Tag> asdmAntennaId_p; std::map <casacore::Int, asdm::Tag> asdmSpectralWindowId_p; std::map <casacore::Int, asdm::Tag> asdmPolarizationId_p; std::map <casacore::Int, asdm::Tag> asdmProcessorId_p; std::map <casacore::Int, asdm::Tag> asdmFieldId_p; std::map <casacore::Int, asdm::Tag> asdmEphemerisId_p; std::map <casacore::Int, asdm::Tag> asdmDataDescriptionId_p; std::map <casacore::Int, asdm::Tag> asdmStateId_p; std::map <casacore::uInt, asdm::Tag> asdmConfigDescriptionId_p; // maps from casacore::MS Main rows std::map <casacore::Int, asdm::Tag> asdmSBSummaryId_p; // maps from casacore::MS Observation Id + 10000*SpwId std::map <casacore::Double, asdm::Tag> asdmExecBlockId_p; // maps from casacore::MS Main timestamps // the default value for the int values is -1, needs MapWithDefault MapWithDefault <casacore::Int, int> asdmFeedId_p; // ASDM feed id is not a Tag MapWithDefault <casacore::Int, int> asdmSourceId_p; // neither is the source id MapWithDefault <asdm::Tag, int> asdmPointingModelId_p; // maps ASDM Antenna Id to dummy pointing model std::vector< std::vector< casacore::Bool > > skipCorr_p; // skipCorr_p[j][PolId] indicates that correlation // product j for POLARIZATION_ID PolId should not // be written in the ASDM }; } //# NAMESPACE CASA - END #endif