Line data Source code
1 : //# MS2ASDM.h
2 : //#
3 : //# ALMA - Atacama Large Millimeter Array
4 : //# (c) European Southern Observatory, 2002
5 : //# (c) Associated Universities Inc., 2002
6 : //# Copyright by ESO (in the framework of the ALMA collaboration),
7 : //# Copyright by AUI (in the framework of the ALMA collaboration),
8 : //# All rights reserved.
9 : //#
10 : //# This library is free software; you can redistribute it and/or
11 : //# modify it under the terms of the GNU Lesser General Public
12 : //# License as published by the Free software Foundation; either
13 : //# version 2.1 of the License, or (at your option) any later version.
14 : //#
15 : //# This library is distributed in the hope that it will be useful,
16 : //# but WITHOUT ANY WARRANTY, without even the implied warranty of
17 : //# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 : //# Lesser General Public License for more details.
19 : //#
20 : //# You should have received a copy of the GNU Lesser General Public
21 : //# License along with this library; if not, write to the Free Software
22 : //# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23 : //# MA 02111-1307 USA
24 : //# $Id: $
25 : #include <casacore/ms/MeasurementSets/MeasurementSet.h>
26 : #include <casacore/ms/MeasurementSets/MSColumns.h>
27 : #include <casacore/casa/aips.h>
28 : #include <casacore/casa/Arrays/Array.h>
29 : #include <casacore/casa/Arrays/Vector.h>
30 : #include <map>
31 : #include <vector>
32 : #include <casacore/casa/OS/Directory.h>
33 :
34 : #include <alma/ASDM/ASDM.h>
35 : #include <alma/ASDM/Tag.h>
36 : #include <alma/ASDM/ComplexWrapper.h>
37 : #include <alma/ASDM/Frequency.h>
38 : #include <alma/ASDM/Angle.h>
39 : #include <alma/ASDM/AngularRate.h>
40 : #include <alma/ASDM/ArrayTime.h>
41 : #include <alma/ASDM/Length.h>
42 : #include <alma/ASDM/Temperature.h>
43 : #include <alma/ASDM/ArrayTimeInterval.h>
44 : #include <alma/ASDM/EntityRef.h>
45 : #include <alma/Enumerations/CStokesParameter.h>
46 : #include <alma/Enumerations/CAntennaType.h>
47 : #include <alma/Enumerations/CBasebandName.h>
48 : #include <alma/Enumerations/CNetSideband.h>
49 : #include <alma/Enumerations/CFrequencyReferenceCode.h>
50 : #include <alma/Enumerations/CReceiverBand.h>
51 : #include <alma/Enumerations/CReceiverSideband.h>
52 : #include <alma/MS2ASDM/MapWithDefault.h>
53 :
54 :
55 : #ifndef MS2ASDM_MS2ASDM_H
56 : #define MS2ASDM_MS2ASDM_H
57 :
58 : namespace casa { //# NAMESPACE CASA - BEGIN
59 :
60 : // <summary>
61 : // MS2ASDM provides functionalities to create an ASDM (ALMA science data model)
62 : // from an existing MS
63 : // </summary>
64 :
65 : // <visibility=export>
66 :
67 : // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
68 : // </reviewed>
69 :
70 : // <prerequisite>
71 : // <li> MeasurementSet
72 : // </prerequisite>
73 : //
74 : // <etymology>
75 : // </etymology>
76 : //
77 : // <synopsis>
78 : // </synopsis>
79 :
80 : class MS2ASDM : public casacore::MSColumns
81 : {
82 :
83 : public:
84 :
85 : // construct from an MS
86 : MS2ASDM(casacore::MeasurementSet& ms);
87 :
88 : ~MS2ASDM();
89 :
90 : const casacore::String& showversion();
91 :
92 : // set verbosity of the write methods
93 28 : void setVerbosity(const casacore::uInt verbosity = 2){ // 0 = only warnings, 1 = most, 2 = everything
94 28 : verbosity_p = verbosity; }
95 :
96 : void setBaseUid(const casacore::String& baseuid);
97 :
98 : const casacore::String& getBaseUid();
99 :
100 : const std::string& getCurrentUid();
101 :
102 : // return currentUid_p with all ":" and "/" characters replaced by "_"
103 : const std::string& getCurrentUidAsFileName();
104 :
105 : // set maximum duration of a subscan in seconds, 0. == no time limit
106 28 : void setSubScanDuration(const casacore::Double subscanDuration = 24.*3600.){
107 28 : subscanDuration_p = subscanDuration; }
108 :
109 : // get maximum duration of a subscan in seconds
110 : casacore::Double getSubScanDuration(){ return subscanDuration_p; }
111 :
112 : // set maximum duration of a Scheduling casacore::Block in seconds
113 28 : void setSBDuration(const casacore::Double sBDuration = 2700.){ // 45 minutes
114 28 : schedBlockDuration_p = sBDuration; }
115 :
116 : // get maximum duration of a Scheduling casacore::Block in seconds
117 : casacore::Double getSBDuration(){ return schedBlockDuration_p; }
118 :
119 28 : void setDataAPCorrected(const casacore::Bool isCorrected = true){
120 28 : dataIsAPCorrected_p = isCorrected; }
121 :
122 5788 : casacore::Bool dataIsAPCorrected(){ return dataIsAPCorrected_p; }
123 :
124 14 : void setObservatoryName(const casacore::String& telName){
125 14 : telName_p = telName; }
126 :
127 : void getObservatoryName( casacore::String& telName ){
128 : telName = telName_p; }
129 :
130 : // convert CASA casacore::Stokes to ASDM Stokes
131 : StokesParameterMod::StokesParameter ASDMStokesParameter( casacore::Stokes::StokesTypes s);
132 :
133 : // convert CASA antenna type string to ASDM antenna type enum
134 : AntennaTypeMod::AntennaType ASDMAntennaType( const casacore::String& type );
135 :
136 : // convert time in seconds to an array time
137 65474 : asdm::ArrayTime ASDMArrayTime( const casacore::Double seconds ){
138 65474 : return asdm::ArrayTime((int64_t) (floor(seconds*asdm::ArrayTime::unitsInASecond))); }
139 :
140 : // convert array time to time in seconds
141 1323 : casacore::Double MSTimeSecs( const asdm::ArrayTime atime ){
142 1323 : return (casacore::Double) atime.get() / (casacore::Double) asdm::ArrayTime::unitsInASecond; }
143 :
144 70845 : asdm::Interval ASDMInterval( const casacore::Double seconds ){
145 70845 : return asdm::Interval((int64_t) (floor(seconds*asdm::ArrayTime::unitsInASecond))); }
146 :
147 : // convert casacore::MS style time interval to ASDM ArrayTimeInterval
148 : asdm::ArrayTimeInterval ASDMTimeInterval( const casacore::Quantity midpoint, const casacore::Quantity interval);
149 :
150 : // return start of casacore::MS main table timestamp (seconds)
151 2371176 : casacore::Double timestampStartSecs(const casacore::uInt mainTabRow){
152 2371176 : return timeQuant()(mainTabRow).getValue("s") - intervalQuant()(mainTabRow).getValue("s")/2.; }
153 :
154 : // return end of casacore::MS main table timestamp (seconds)
155 12274 : casacore::Double timestampEndSecs(const casacore::uInt mainTabRow){
156 12274 : return timeQuant()(mainTabRow).getValue("s") + intervalQuant()(mainTabRow).getValue("s")/2.; }
157 :
158 : // convert casacore::MDirection to a vector of Angles
159 : std::vector< asdm::Angle > ASDMAngleV(const casacore::MDirection mDir);
160 :
161 : // convert casacore::MDirection type to ASDM DirectionReferenceCode
162 : DirectionReferenceCodeMod::DirectionReferenceCode ASDMDirRefCode(const casacore::MDirection::Types type);
163 :
164 : // convert a base band converter number to an ASDM base band name
165 : BasebandNameMod::BasebandName ASDMBBName( const casacore::Int bbcNo );
166 :
167 : // convert a casacore::MS net sideband no. to an ASDM enum
168 : NetSidebandMod::NetSideband ASDMNetSideBand( const casacore::Int netSideband );
169 :
170 : // set a representative frequency, the receiver band and receiver sideband based on a frequency refFreq
171 : // and the previously set observatory name telName_p, return the band id as an casacore::Int (1 to 10),
172 : // -1 if refFreq is outside ALMA bands but observatory is ALMA, 0 if observatory not ALMA
173 : casacore::Int setRecBands( const asdm::Frequency refFreq,
174 : casacore::Double& frequency,
175 : ReceiverBandMod::ReceiverBand& frequencyBand,
176 : ReceiverSidebandMod::ReceiverSideband& receiverSideband);
177 :
178 : FrequencyReferenceCodeMod::FrequencyReferenceCode ASDMFreqRefCode( const casacore::MFrequency::Types refFrame );
179 :
180 363426 : casacore::Unit unitASDMFreq(){ return casacore::Unit(casacore::String(asdm::Frequency::unit())); }
181 :
182 822080 : casacore::Unit unitASDMAngle(){ return casacore::Unit(casacore::String(asdm::Angle::unit())); }
183 :
184 2572 : casacore::Unit unitASDMAngularRate(){ return casacore::Unit(casacore::String(asdm::AngularRate::unit())); }
185 :
186 14494 : casacore::Unit unitASDMLength(){ return casacore::Unit(casacore::String(asdm::Length::unit())); }
187 :
188 0 : casacore::Unit unitASDMTemp(){ return casacore::Unit(casacore::String(asdm::Temperature::unit())); }
189 :
190 3616 : asdm::Complex ASDMComplex( casacore::Complex x ){ return asdm::Complex(x.real(), x.imag()); }
191 :
192 : // write the entire ASDM from scratch
193 : casacore::Bool writeASDM(const casacore::String& asdmfile="",
194 : const casacore::String& datacolumn="data",
195 : const casacore::String& archiveid="S0",
196 : const casacore::String& rangeid="X1",
197 : const casacore::Bool verbose=true,
198 : const casacore::Double maxSubscanDuration = 24.*3600.,
199 : const casacore::Double maxSchedBlockDuration = 2700.,
200 : const casacore::Bool msDataIsAPCorrected=true
201 : );
202 :
203 : private:
204 : // *** Private member functions ***
205 :
206 : casacore::Bool incrementUid(); // returns true if successful
207 :
208 : casacore::Bool setDirectory(const casacore::String& asdmfile);
209 :
210 :
211 : casacore::Bool writeStation();
212 :
213 : casacore::Bool writeAntenna();
214 :
215 : casacore::Bool writeSpectralWindow();
216 :
217 : casacore::Bool writeSource();
218 :
219 : casacore::Bool writePolarization();
220 :
221 : casacore::Bool writeCorrelatorMode(); // not called directly but optionally called by writeProcessor()
222 : casacore::Bool writeAlmaRadiometer(); // optionally called by writeProcessor()
223 : casacore::Bool writeHolography(); // optionally called by writeProcessor()
224 :
225 : casacore::Bool writeProcessor();
226 :
227 : casacore::Bool writeField();
228 :
229 : casacore::Bool writeReceiver();
230 :
231 : casacore::Bool writeFeed();
232 :
233 : casacore::Bool writeDataDescription();
234 :
235 : casacore::Bool writeSwitchCycle(); // not yet fully implemented
236 :
237 : casacore::Bool writeState();
238 :
239 : casacore::Bool writeSysCal();
240 :
241 : casacore::Bool writeConfigDescription();
242 :
243 : // Scheme
244 : // 1) We regard one casacore::MS Observation as a set of ASDM ExecBlocks modelled on
245 : // a single ASDM Scheduling Block
246 : // 2) ALMA ExecBlocks are at most 30 minutes long.
247 : // If an casacore::MS Observation is more than 30 Minutes long, it is split up into
248 : // several ASDM ExecBlocks each referring to the same Scheduling Block.
249 : // 3) Each ASDM ExecBlock contains one or more ASDM Scans based on the casacore::MS scans
250 : // 4) Each ASDM Scan contains one or more ASDM Subscans
251 : // 5) Each ASDM Subscan is at most subscanduration long. (external parameter)
252 : // 6) If an casacore::MS Scan is longer than subscanduration, it is split up into
253 : // several ASDM subscans.
254 :
255 : casacore::Bool writeSBSummaryAndExecBlockStubs(); // "stubs" because these tables will be completed later
256 : // with information from the APDM
257 : casacore::Bool writeMainAndScanAndSubScan(const casacore::String& datacolumn);
258 :
259 : // write the Main binary data for one DataDescId/FieldId pair and one SubScan
260 : // (return number of integrations written and set the last three parameters in the list)
261 : casacore::Int writeMainBinSubScanForOneDDIdFIdPair(const casacore::Int theDDId, const casacore::Int theFieldId,
262 : const casacore::String& datacolumn,
263 : const casacore::uInt theScan, const casacore::uInt theSubScan,
264 : const casacore::uInt startRow, const casacore::uInt endRow,
265 : const asdm::Tag eBlockId,
266 : int& datasize, asdm::EntityRef& dataOid,
267 : std::vector< asdm::Tag >& stateId);
268 :
269 : casacore::Bool writePointingModel(); // write dummy pointing models
270 :
271 : casacore::Bool writePointing();
272 :
273 : // *** Aux. methods ***
274 :
275 : // check if vector corrT already contains a stokes type equivalent to st
276 : casacore::Bool stokesTypePresent( const casacore::Vector< casacore::Int > corrT, const casacore::Stokes::StokesTypes st );
277 :
278 : // *** Member variables ***
279 :
280 : // Initialized* by ctors. (Maintain order both here and in ctors.)
281 : casacore::MeasurementSet ms_p; // the measurement set from which the ASDM is filled
282 :
283 : asdm::ASDM* ASDM_p; // the new ASDM
284 :
285 : string asdmVersion_p; // the version of the new ASDM
286 :
287 : casacore::uInt verbosity_p; // verbosity of the write methods
288 :
289 : casacore::String baseUid_p; // the part of the UID which is common to all elements of the ASDM,
290 : // i.e. typically "uid://archiveid/rangeid/"
291 :
292 : casacore::uInt runningId_p; // counter for the tables written; starts at 1!
293 : // used to construct the UIDs: uid = baseUid_p + (runningId_p converted to unpadded hex string)
294 :
295 : casacore::String currentUid_p; // the last used uid
296 :
297 : casacore::String telName_p; // the name of the observatory from first row of casacore::MS observation table
298 :
299 : casacore::Double subscanDuration_p; // maximum duration of a subscan in seconds
300 :
301 : casacore::Double schedBlockDuration_p; // maximum duration of a scheduling or exec block in seconds
302 :
303 : casacore::Bool dataIsAPCorrected_p; // true if the data in the selected casacore::MS data column is
304 : // AtmPhaseCorrectionMod::AP_CORRECTED, false if it is
305 : // AtmPhaseCorrectionMod::AP_UNCORRECTED
306 :
307 : string asdmUID_p; // ASDM UID == container ID of all tables
308 :
309 : casacore::String asdmDir_p; // ASDM output directory name
310 :
311 : // The default value for the Tag keys is Tag(), so the std::map works as is
312 : std::map <casacore::String, asdm::Tag> asdmStationId_p;
313 : std::map <casacore::Int, asdm::Tag> asdmAntennaId_p;
314 : std::map <casacore::Int, asdm::Tag> asdmSpectralWindowId_p;
315 : std::map <casacore::Int, asdm::Tag> asdmPolarizationId_p;
316 : std::map <casacore::Int, asdm::Tag> asdmProcessorId_p;
317 : std::map <casacore::Int, asdm::Tag> asdmFieldId_p;
318 : std::map <casacore::Int, asdm::Tag> asdmEphemerisId_p;
319 : std::map <casacore::Int, asdm::Tag> asdmDataDescriptionId_p;
320 : std::map <casacore::Int, asdm::Tag> asdmStateId_p;
321 : std::map <casacore::uInt, asdm::Tag> asdmConfigDescriptionId_p; // maps from casacore::MS Main rows
322 : std::map <casacore::Int, asdm::Tag> asdmSBSummaryId_p; // maps from casacore::MS Observation Id + 10000*SpwId
323 : std::map <casacore::Double, asdm::Tag> asdmExecBlockId_p; // maps from casacore::MS Main timestamps
324 : // the default value for the int values is -1, needs MapWithDefault
325 : MapWithDefault <casacore::Int, int> asdmFeedId_p; // ASDM feed id is not a Tag
326 : MapWithDefault <casacore::Int, int> asdmSourceId_p; // neither is the source id
327 : MapWithDefault <asdm::Tag, int> asdmPointingModelId_p; // maps ASDM Antenna Id to dummy pointing model
328 :
329 : std::vector< std::vector< casacore::Bool > > skipCorr_p; // skipCorr_p[j][PolId] indicates that correlation
330 : // product j for POLARIZATION_ID PolId should not
331 : // be written in the ASDM
332 :
333 : };
334 :
335 :
336 : } //# NAMESPACE CASA - END
337 :
338 : #endif
339 :
|