00001 //# FillMetadata.h: this defines container classes used while actually filling data 00002 //# Copyright (C) 2000,2001,2002 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have received a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# 00027 //# $Id: FillMetadata.h,v 1.3 2011/08/11 18:03:53 pteuben Exp $ 00028 00029 #ifndef BIMA_FILLMETADATA_H 00030 #define BIMA_FILLMETADATA_H 00031 00032 #include <casa/Containers/List.h> 00033 #include <casa/Containers/OrderedPair.h> 00034 #include <casa/Containers/OrderedMap.h> 00035 #include <casa/Containers/HashMap.h> 00036 #include <casa/Containers/HashMapIter.h> 00037 #include <casa/Arrays/Vector.h> 00038 #include <measures/Measures/Stokes.h> 00039 #include <miriad/Filling/MirTypeAssert.h> 00040 #include <miriad/Filling/IDIndex.h> 00041 #include <miriad/Filling/DataLoadingBuf.h> 00042 #include <measures/Measures.h> 00043 00044 #include <casa/namespace.h> 00045 //# Forward Declarations 00046 namespace casa { //# NAMESPACE CASA - BEGIN 00047 class MeasurementSet; 00048 class MSColumns; 00049 } //# NAMESPACE CASA - END 00050 00051 00052 // <summary> 00053 // an abstract base for classes that contain information about some 00054 // part of a Miriad Dataset 00055 // </summary> 00056 // 00057 // <use visibility=local> 00058 // 00059 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00060 // </reviewed> 00061 // 00062 // <etymology> 00063 // subclasses contain information about a Miriad dataset 00064 // </etymology> 00065 // 00066 // <synopsis> 00067 // This class provides a common type and interface for classes that organize 00068 // some collection of related information in a Miriad dataset. 00069 // </synopsis> 00070 // 00071 // <motivation> 00072 // 00073 // </motivation> 00074 // 00075 class MirInfo : MirTypeAssert { 00076 public: 00077 MirInfo(); 00078 virtual ~MirInfo(); 00079 protected: 00080 }; 00081 00082 // <summary> 00083 // a container for field information 00084 // </summary> 00085 // 00086 // <use visibility=local> 00087 // 00088 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00089 // </reviewed> 00090 // 00091 // <etymology> 00092 // a Miriad observing field is expressed as an offset from a reference position 00093 // </etymology> 00094 // 00095 // <synopsis> 00096 // MirField is a helper class used by MirFiller and FillMetadata to hold 00097 // the data describing an observing field in a single container. Most of the 00098 // interaction with this class is through public data members (for programming 00099 // and runtime efficiency); thus, this class is not appropriate for use outside 00100 // of this module. A few helper funtions are provided to aid in utilizing the 00101 // information (mainly for comparison with other MirField objects). 00102 // </synopsis> 00103 // 00104 // <motivation> 00105 // A Miriad dataset can contain a number of observing fields, described as offsets 00106 // from a reference position. When scanning a multi-field dataset, one usually 00107 // will encounter data each field as the observations cycles through the set of 00108 // pointings. Thus, the filler must keep a list of unique fields that can be 00109 // matched against the current field. 00110 // </motivation> 00111 // 00112 class MirField : public MirInfo 00113 { 00114 public: 00115 // the position offsets 00116 Float dra, ddec; 00117 00118 // the ID assigned to this field within the MeasurementSet being filled. 00119 // A value of -1 means that the ID has not yet been assigned. 00120 Int id; 00121 00122 // create a new field description 00123 MirField(Float delra, Float deldec, Int fid=-1); 00124 00125 // delete this field 00126 virtual ~MirField(); 00127 00128 // return true if this field's offsets match those of another 00129 Bool operator==(const MirField &that) { 00130 return (dra==that.dra && ddec==that.ddec); 00131 } 00132 00133 // return false if this field's offsets match those of another 00134 Bool operator!=(const MirField &that) { 00135 return ! (*this == that); 00136 } 00137 00138 // return a pointer to a field in a given list of fields that is equal 00139 // to this field. 00140 MirField *findIn(List<MirField*> &fldlist) { 00141 ListIter<MirField*> li(fldlist); 00142 while (! li.atEnd() && *(li.getRight()) != *this) li++; 00143 return ((li.atEnd()) ? NULL : li.getRight()); 00144 } 00145 00146 // clear the ID values for all the fields in a field list by setting them 00147 // to -1. 00148 static void clearIDs(List<MirField*> &fldlist) { 00149 for(ListIter<MirField*> li(fldlist); ! li.atEnd(); ++li) 00150 li.getRight()->id = -1; 00151 } 00152 00153 }; 00154 00155 // <summary> 00156 // A description of a Miriad spectroscopy (correlator) setup 00157 // </summary> 00158 // 00159 // <use visibility=local> 00160 // 00161 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00162 // </reviewed> 00163 // 00164 // <etymology> 00165 // a description of the frequency setup used by a Miriad dataset 00166 // </etymology> 00167 // 00168 // <synopsis> 00169 // This class contains the data describing the frequency domain of a 00170 // portion of the dataset. <p> 00171 // 00172 // Most of the interaction with this class is through public data members (for 00173 // programming and runtime efficiency); thus, this class is not appropriate for 00174 // use outside of this module. A few helper funtions are provided to aid in 00175 // utilizing the information (mainly for comparison with other MirFreqSetup objects). 00176 // </synopsis> 00177 // 00178 // <motivation> 00179 // a Miriad dataset may switch back and forth between different correlator 00180 // configurations. The filler must keep track of them, and recognize them 00181 // when the are reused. 00182 // </motivation> 00183 // 00184 class MirFreqSetup : public MirInfo { 00185 public: 00186 00187 // the correlator mode 00188 Int mode; 00189 00190 // the correlator filter bandwidths 00191 Float *corbw; 00192 00193 // the correlator LO frequencies 00194 Float *corf; 00195 00196 // the number of spectral windows 00197 Int nspect; 00198 00199 // the number of wideband channels 00200 Int nwide; 00201 00202 // the total number of spectral line channels 00203 Int nchan; 00204 00205 // the number of channels in each window 00206 Int *nschan; 00207 00208 // the number of the first channel in each window 00209 Int *ischan; 00210 00211 // the frequency of the first channel in each window 00212 Double *sfreq; 00213 00214 // the frequency separation between channels in each window 00215 Double *sdf; 00216 00217 // the rest frequency for each window 00218 Double *rfreq; 00219 00220 // the center frequency of each wideband channel 00221 Float *wfreq; 00222 00223 // the bandwidth of each wideband channel 00224 Float *wwidth; 00225 00226 // the reference frequency for this setup. Usually the rest frequency 00227 // of the primary line of the observations. 00228 Double freq; 00229 00230 // the ID assigned to this setup within the MeasurementSet being filled. 00231 // A value of -1 means that the ID has not yet been assigned. 00232 Int id; 00233 00234 // the narrow window mapping index. This maps 00235 // Miriad window numbers to MS spectral window IDs. 00236 IDIndex nfidx; 00237 00238 // the wideband mapping index. This maps 00239 // Miriad wideband channel numbers to MS spectral window IDs. 00240 IDIndex wfidx; 00241 00242 // create a new setup by reading the relevent variable data from 00243 // the given miriad dataset handle 00244 MirFreqSetup(Int mir_handle); 00245 00246 virtual ~MirFreqSetup(); 00247 00248 // return true if this setup is the same as another. 00249 // Two setups will be considered equal if the mode, nwide, nspect, 00250 // corfs and corbws are identical. (The window starting frequencies can 00251 // change as they are topocentric; this may cause problems for miriad 00252 // data that did not originate from BIMA.) 00253 Bool operator==(MirFreqSetup &that); 00254 00255 // return false if this setup is the same as another. 00256 Bool operator!=(MirFreqSetup &that) { 00257 return ! (*this == that); 00258 } 00259 00260 // clear the id and index maps 00261 void clear() { 00262 id = -1; 00263 nfidx.clear(); 00264 wfidx.clear(); 00265 } 00266 00267 // return a pointer to a setup in a given list of setups that is equal 00268 // to this setup. 00269 MirFreqSetup *findIn(List<MirFreqSetup*> &setuplist) { 00270 ListIter<MirFreqSetup*> li(setuplist); 00271 while (! li.atEnd() && *(li.getRight()) != *this) li++; 00272 return ((li.atEnd()) ? NULL : li.getRight()); 00273 } 00274 00275 // clear the ID values for all the setups in a setup list by setting them 00276 // to -1. 00277 static void clearIDs(List<MirFreqSetup*> &setuplist) { 00278 for(ListIter<MirFreqSetup*> li(setuplist); ! li.atEnd(); ++li) 00279 li.getRight()->clear(); 00280 } 00281 }; 00282 00283 // <summary> 00284 // a container for a single Miriad polarization correlation 00285 // </summary> 00286 // 00287 // <use visibility=local> 00288 // 00289 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00290 // </reviewed> 00291 // 00292 // <etymology> 00293 // the name is short for Miriad Polarization Correlation. A polarization 00294 // correlation type refers to the combination (via cross-correlation) of two 00295 // polarizations. 00296 // </etymology> 00297 // 00298 // <synopsis> 00299 // This class contains a polarization cross-correlation combination. It 00300 // provides methods for determining the constituent polarization types. An 00301 // integer Id can be associated with it as well; this is used by the MirFiller 00302 // class to remember what table entry it is associated with. 00303 // </synopsis> 00304 // 00305 // <motivation> 00306 // Miriad datasets record different polarization measurements in seperate 00307 // records; thus, there is a notion of a current polarization among several 00308 // being read. Furthermore, you usually don't know which polarizations 00309 // are in the dataset until you've read at least one record with each kind 00310 // of polarization. You do usually know the total number of different 00311 // polarizations after reading the first record. 00312 // </motivation> 00313 // 00314 // 00315 class MirPolCorr : public MirInfo { 00316 private: 00317 Int corr; 00318 mutable Int id; 00319 00320 static const Stokes::StokesTypes corratopol[]; 00321 static const Stokes::StokesTypes corrbtopol[]; 00322 00323 public: 00324 // create a container. Poltype is the polarization type in the Miriad 00325 // convention (i.e. as read from the "pol" variable in a Miriad dataset). 00326 MirPolCorr(Int poltype); 00327 00328 // create a copy of a container. 00329 MirPolCorr(const MirPolCorr& that) : id(-1) { corr = that.corr; } 00330 00331 // delete the container 00332 virtual ~MirPolCorr(); 00333 00334 Bool operator==(const MirPolCorr& that) const { return corr == that.corr; } 00335 Bool operator==(Int poltype) const { return corr == poltype; } 00336 00337 // set the independent ID. A value less than zero should be interpreted 00338 // as meaning unset. 00339 void setID(Int val) const { id = val; } 00340 00341 // return the independent ID. A value less than zero should be interpreted 00342 // as meaning unset. 00343 Int getID() const { return id; } 00344 00345 // clear the independent ID value 00346 void clearID() const { id = -1; } 00347 00348 // return the polarization correlation type in the Miriad 00349 // convention (i.e. as read from the "pol" variable in a Miriad dataset). 00350 Int getType() const { return corr; } 00351 00352 // return the polarization type associated with the first 00353 // receptor for this correlation type. The returned StokesType for 00354 // non-true Stokes types will be that for a single type cross-correlated 00355 // with itself. 00356 Stokes::StokesTypes getFirstPolType() const { 00357 return corratopol[corr+8]; 00358 } 00359 00360 // return the polarization type associated with the second 00361 // receptor for the given correlation type. The returned StokesType for 00362 // non-true Stokes types will be that for a single type cross-correlated 00363 // with itself. 00364 Stokes::StokesTypes getSecondPolType() const { 00365 return corrbtopol[corr+8]; 00366 } 00367 00368 // return True if the given single polarization type is one of the 00369 // components of this correlation type 00370 Bool hasPol(Stokes::StokesTypes pol) const { 00371 return (getFirstPolType() == pol || getSecondPolType() == pol); 00372 } 00373 00374 // convert the Miriad polarization code to the AIPS 00375 static Stokes::StokesTypes toAips(Int pol); 00376 00377 // convert the Aips Stokes polarization code to the Miriad convention 00378 static Int toMiriad(Stokes::StokesTypes pol); 00379 00380 // return the AIPS++ Stokes type for the current polarization 00381 Stokes::StokesTypes getAipsType() const { return toAips(corr); } 00382 00383 // return a string representation of this polarization 00384 String toString() const { return Stokes::name(getAipsType()); } 00385 }; 00386 00387 // <summary> 00388 // a static container for a set of Miriad polarization correlation types 00389 // </summary> 00390 // 00391 // <use visibility=local> 00392 // 00393 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00394 // </reviewed> 00395 // 00396 // <etymology> 00397 // the name is short for Constant Miriad Polarization Setup. 00398 // </etymology> 00399 // 00400 // <synopsis> 00401 // This class contains a list of polarization cross-correlation combinations. 00402 // New correlations cannot be added to this list. 00403 // </synopsis> 00404 // 00405 // <motivation> 00406 // Miriad datasets record different polarization measurements in seperate 00407 // records; thus, there is a notion of a current polarization among several 00408 // being read. Furthermore, you usually don't know which polarizations 00409 // are in the dataset until you've read at least one record with each kind 00410 // of polarization. You do usually know the total number of different 00411 // polarizations after reading the first record. 00412 // </motivation> 00413 // 00414 // 00415 class ConstMirPolSetup : public MirInfo { 00416 public: 00417 virtual ~ConstMirPolSetup(); 00418 00419 protected: 00420 List<MirPolCorr> corrs; 00421 ListIter<MirPolCorr> iter; 00422 00423 ConstMirPolSetup(); 00424 ConstMirPolSetup(ConstMirPolSetup& other); 00425 Bool find(Int poltype, ConstListIter<MirPolCorr>& li); 00426 00427 public: 00428 00429 // return the number of polarization correlation types in this setup 00430 uInt getCorrCount() { return corrs.len(); } 00431 00432 // set the current polarization correlation to the given type. True 00433 // is returned if the type is found; if it is not, the current 00434 // polarization is unchanged. 00435 Bool setCorr(Int poltype) { 00436 // Note: this has been made non-virtual on purpose 00437 return find(poltype, iter); 00438 } 00439 00440 // return True if the given polarization correlation type is a member 00441 // of this set 00442 Bool hasCorr(Int poltype) { 00443 ConstListIter<MirPolCorr> li(corrs); 00444 return find(poltype, li); 00445 } 00446 00447 // clear all the IDs associated with the polarization correlation types 00448 // in this list 00449 void clearIDs() { 00450 ConstListIter<MirPolCorr> li(corrs); 00451 for(li.toStart(); ! li.atEnd(); ++li) { 00452 li.getRight().clearID(); 00453 } 00454 } 00455 00456 // return the list of polarization correlation types stored in this set 00457 const List<MirPolCorr>& getCorrs() { return corrs; } 00458 00459 // return the currently selected polarization 00460 MirPolCorr& getCurrent() { return iter.getRight(); } 00461 00462 // return the AIPS type for the current polarization. If no 00463 // current polarization correlation type is set, YY is returned 00464 Stokes::StokesTypes getCurrentAipsType() { 00465 return ((iter.atEnd()) ? Stokes::YY : iter.getRight().getAipsType()); 00466 } 00467 }; 00468 00469 // <summary> 00470 // an editable container for a set of Miriad polarization correlation types 00471 // </summary> 00472 // 00473 // <use visibility=local> 00474 // 00475 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00476 // </reviewed> 00477 // 00478 // <etymology> 00479 // the name is short for Miriad Polarization Setup. 00480 // </etymology> 00481 // 00482 // <synopsis> 00483 // This class contains a list of polarization cross-correlation combinations. 00484 // This version allows new values to be added to the list. 00485 // </synopsis> 00486 // 00487 // <motivation> 00488 // Miriad datasets record different polarization measurements in seperate 00489 // records; thus, there is a notion of a current polarization among several 00490 // being read. Furthermore, you usually don't know which polarizations 00491 // are in the dataset until you've read at least one record with each kind 00492 // of polarization. You do usually know the total number of different 00493 // polarizations after reading the first record. 00494 // </motivation> 00495 // 00496 // 00497 class MirPolSetup : public ConstMirPolSetup { 00498 private: 00499 // add a new correlation type to this list. This function assumes that 00500 // the type does not already exist in the list. 00501 void addCorr(Int poltype); 00502 00503 public: 00504 MirPolSetup(); 00505 MirPolSetup(ConstMirPolSetup& other); 00506 virtual ~MirPolSetup(); 00507 00508 // set the current polarization correlation to the given type. If 00509 // the type is not already part of this set, it will be added. True 00510 // is returned if the type is found without having to add it. 00511 Bool setCorr(Int poltype) { 00512 if (! find(poltype, iter)) { 00513 addCorr(poltype); 00514 return False; 00515 } 00516 return True; 00517 } 00518 00519 }; 00520 00521 // <summary> 00522 // a container for a set of Miriad (single-) polarization receptor types 00523 // </summary> 00524 // 00525 // <use visibility=local> 00526 // 00527 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00528 // </reviewed> 00529 // 00530 // <etymology> 00531 // the name is short for Miriad Polarization Receptors 00532 // </etymology> 00533 // 00534 // <synopsis> 00535 // This class contains a list of single-polarization types that correspond 00536 // the types of polarizations a group of receptors are sensitive to. 00537 // 00538 // Single Polarization types are identified using the AIPS' StokesTypes 00539 // enumeration. For non-true Stokes types, the value for the polarization 00540 // cross-correlated with itself is used. 00541 // </synopsis> 00542 // 00543 // <motivation> 00544 // Miriad datasets record different polarization measurements in seperate 00545 // records; thus, there is a notion of a current polarization among several 00546 // being read. Furthermore, you usually don't know which polarizations 00547 // are in the dataset until you've read at least one record with each kind 00548 // of polarization. You do usually know the total number of different 00549 // polarizations after reading the first record. 00550 // </motivation> 00551 // 00552 // 00553 class MirPolRecps : public MirInfo { 00554 private: 00555 List<Stokes::StokesTypes> pols; 00556 mutable ListIter<Stokes::StokesTypes> iter; 00557 00558 public: 00559 MirPolRecps() : pols(), iter(pols) { } 00560 virtual ~MirPolRecps(); 00561 00562 // return the number of distinct single polarization that make up 00563 // this setup 00564 uInt getPolCount() const { return pols.len(); } 00565 00566 // add a polarization type if it isn't already added. 00567 void addPol(Stokes::StokesTypes pol) { 00568 if (! hasPol(pol)) { 00569 iter.toEnd(); 00570 iter.addRight(pol); 00571 } 00572 } 00573 00574 // add the polarization types involved in the cross-correlation represented 00575 // by the given correlation type 00576 void addPolsFor(const MirPolCorr &pol) { 00577 addPol(pol.getFirstPolType()); 00578 addPol(pol.getSecondPolType()); 00579 } 00580 00581 // add the polarization types involved in the cross-correlations 00582 // represented by the correlation types in the given list 00583 void addPolsFor(ConstMirPolSetup &pol) { 00584 ConstListIter<MirPolCorr> li(pol.getCorrs()); 00585 for(li.toStart(); ! li.atEnd(); ++li) 00586 addPolsFor(li.getRight()); 00587 } 00588 00589 // return the i-th polarization 00590 Stokes::StokesTypes getPol(Int i) const { 00591 iter.pos(i); 00592 return iter.getRight(); 00593 } 00594 00595 // find the position of the given polarization type. -1 is returned 00596 // if the polarization is not found 00597 Int find(Stokes::StokesTypes pol) { 00598 for(iter.toStart(); ! iter.atEnd(); ++iter) { 00599 if (iter.getRight() == pol) return iter.pos(); 00600 } 00601 return -1; 00602 } 00603 00604 // return True if the given polarization is present in this list 00605 Bool hasPol(Stokes::StokesTypes pol) { return (find(pol) >= 0); } 00606 00607 // return the unique list of single polarization types that comprise 00608 // the correlation types. 00609 const List<Stokes::StokesTypes>& getPols() const { return pols; } 00610 00611 // return a string representing the i-th polarization 00612 String toString(Int i) const { return polToString(getPol(i)); } 00613 00614 // return a string representing the given polarization 00615 static String polToString(Stokes::StokesTypes pol) { 00616 return String( (Stokes::name(pol)).at(0,1) ); 00617 } 00618 }; 00619 00620 00621 // <summary> 00622 // a container for source information 00623 // </summary> 00624 // 00625 // <use visibility=local> 00626 // 00627 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00628 // </reviewed> 00629 // 00630 // <etymology> 00631 // a description of a source and its position as stored in a Miriad dataset 00632 // </etymology> 00633 // 00634 // <synopsis> 00635 // This class contains the data describing a source from a Miriad dataset. <p> 00636 // 00637 // Most of the interaction with this class is through public data members (for 00638 // programming and runtime efficiency); thus, this class is not appropriate for 00639 // use outside of this module. A few helper funtions are provided to aid in 00640 // utilizing the information (mainly for comparison with other MirSource objects). 00641 // </synopsis> 00642 // 00643 // <motivation> 00644 // a Miriad dataset may switch back and forth between different sources. 00645 // The filler must keep track of them, and recognize them when the are reused. 00646 // </motivation> 00647 // 00648 class MirSource : public MirInfo { 00649 public: 00650 enum SolSysObject { 00651 MERCURY, 00652 VENUS, 00653 MARS, 00654 JUPITER, 00655 SATURN, 00656 URANUS, 00657 NEPTUNE, 00658 PLUTO, 00659 SUN, 00660 MOON, 00661 N_Objects 00662 }; 00663 00664 // the source name 00665 String name; 00666 00667 // the initial source position 00668 Double ra, dec; 00669 00670 // the position epoch 00671 Float epoch; 00672 00673 // the time of first observation 00674 Double time; 00675 00676 // the source id 00677 Int id; 00678 00679 // the first row of this source record appears in the SOURCE table. 00680 Int row; 00681 00682 // a planet identifier 00683 SolSysObject solsys; 00684 00685 // Planet names 00686 static const String solSysNames[]; 00687 00688 // a list of fields 00689 List<MirField*> flds; 00690 00691 MirSource(String source, Double sra, Double sdec, Float sepoch, 00692 Double stime=0, Int sid=-1); 00693 MirSource(int mirh, Double stime=0); 00694 virtual ~MirSource(); 00695 00696 // return true if this source is the same as another. 00697 // Two sources are considered the same if they have the same name and 00698 // position epoch. 00699 Bool operator==(const MirSource &that) { 00700 return (name==that.name && epoch==that.epoch); 00701 } 00702 00703 // return false if this source is the same as another. 00704 Bool operator!=(const MirSource &that) { 00705 return ! (*this == that); 00706 } 00707 00708 // return a pointer to a source in a given list of source that is equal 00709 // to this source. 00710 MirSource *findIn(List<MirSource*> &srclist) { 00711 ListIter<MirSource*> li(srclist); 00712 while (! li.atEnd() && *(li.getRight()) != *this) li++; 00713 return ((li.atEnd()) ? NULL : li.getRight()); 00714 } 00715 00716 // return a pointer to a source in a given list of source that has the same 00717 // name as this source. 00718 MirSource *findNameIn(List<MirSource*> &srclist) { 00719 ListIter<MirSource*> li(srclist); 00720 while (! li.atEnd() && li.getRight()->name != this->name) li++; 00721 return ((li.atEnd()) ? NULL : li.getRight()); 00722 } 00723 00724 // clear the ID values for all the source in a source list by setting them 00725 // to -1. 00726 static void clearIDs(List<MirSource*> &srclist) { 00727 for(ListIter<MirSource*> li(srclist); ! li.atEnd(); ++li) { 00728 li.getRight()->id = -1; 00729 if (li.getRight()->flds.len() > 0) { 00730 MirField::clearIDs(li.getRight()->flds); 00731 } 00732 } 00733 } 00734 00735 // return True if this source is a moving object (by virtue of having 00736 // multiple positions added to this container). 00737 Bool isMoving() { return (motion_p != 0); } 00738 00739 // return True if this source is identified as a major solar system object 00740 Bool isSolSysObj() { return (solsys < N_Objects); } 00741 00742 // return True if this source is identified as a planet 00743 Bool isPlanet() { return (solsys < SUN); } 00744 00745 // return True if any of the fields is pointed off the main source 00746 // position (as given by ra and dec) 00747 Bool offSource() { 00748 if (flds.len() > 1) return True; 00749 ListIter<MirField*> f(flds); 00750 return (f.getRight()->dra != 0 || f.getRight()->ddec != 0); 00751 } 00752 00753 // add a new position for this source 00754 void addPosition(Double mtime, Double mra, Double mdec) { 00755 if (! motion_p) { 00756 motion_p = new OrderedMap<Double, OrderedPair<Double, Double> >( 00757 OrderedPair<Double,Double>(0,0), 2); 00758 motion_p->define(time, OrderedPair<Double, Double>(ra, dec)); 00759 } 00760 if (! motion_p->isDefined(mtime)) 00761 motion_p->define(mtime, OrderedPair<Double, Double>(mra, mdec)); 00762 } 00763 00764 // load the motion data into the given arrays 00765 void getMotion(Vector<Double> &time, 00766 Vector<Double> &ra, Vector<Double> &dec) 00767 { 00768 if (! motion_p) return; 00769 uInt n = motion_p->ndefined(); 00770 time.resize(n); 00771 ra.resize(n); 00772 dec.resize(n); 00773 00774 MapIter<Double, OrderedPair<Double, Double> > iter(*motion_p); 00775 for(uInt i=0; ! iter.atEnd(); ++iter, ++i) { 00776 time(i) = iter.getKey(); 00777 ra(i) = iter.getVal().x(); 00778 dec(i) = iter.getVal().y(); 00779 } 00780 } 00781 00782 static SolSysObject matchSolSysObj(const String &name); 00783 00784 static Int nextID() { 00785 Int out = nxtid_p; 00786 nxtid_p++; 00787 return out; 00788 } 00789 00790 private: 00791 OrderedMap<Double, OrderedPair<Double, Double> > *motion_p; 00792 static Int nxtid_p; 00793 }; 00794 00795 // <summary> 00796 // a pair of indicies identifying the spectral window and polarization ids 00797 // that make up a data description ID 00798 // </summary> 00799 // 00800 // <use visibility=local> 00801 // 00802 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00803 // </reviewed> 00804 // 00805 // <etymology> 00806 // The Data Description subtable record has two main components: a spectral 00807 // window ID and a polarization ID. 00808 // </etymology> 00809 // 00810 // <synopsis> 00811 // This class holds two IDs that make up the "data description" of a record 00812 // in an MS MAIN table: the spectral window ID and the polarization ID. 00813 // </synopsis> 00814 // 00815 // <motivation> 00816 // Records in the MAIN MS table are linked to rows in the SPECTRAL_WINDOW and 00817 // POLARIZATION subtables via a single DATA_DESC_ID; this class collects the 00818 // indicies into those two subtables into a single class that can be linked to 00819 // an ID in the DATA_DESCRIPTION subtable (via a Map). 00820 // </motivation> 00821 // 00822 class DataDescComponents { 00823 private: 00824 Int spw; 00825 Int pol; 00826 public: 00827 DataDescComponents(Int spwid=-1, Int polid=-1) : spw(spwid), pol(polid) { } 00828 ~DataDescComponents() { } 00829 00830 // return the spectral window ID component 00831 Int getSpectralWindowID() const { return spw; } 00832 00833 // return the polarization ID component 00834 Int getPolarizationID() const { return pol; } 00835 00836 Bool operator==(const DataDescComponents& other) const { 00837 return (spw == other.spw && pol == other.pol); 00838 } 00839 00840 Bool exists() const { return (spw >= 0 && pol >= 0); } 00841 }; 00842 00843 extern uInt hashFunc(const DataDescComponents& key); 00844 00845 // <summary> 00846 // a container for storing the Miriad metadata that must be tracked while 00847 // filling 00848 // </summary> 00849 00850 // <use visibility=local> 00851 00852 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00853 // </reviewed> 00854 00855 // <prerequisite> 00856 // <li> <linkto class="MirFiller">MirFiller</linkto> 00857 // </prerequisite> 00858 // 00859 // <etymology> 00860 // This stores the metadata from an input Miriad dataset (e.g. Miriad variable 00861 // values) that are important for orchestrating its filling into a measurement 00862 // set. 00863 // </etymology> 00864 // 00865 // <synopsis> 00866 // This class is a container for various information gleaned from the Miriad 00867 // dataset that is important for organizing the data into a Measurement Set. 00868 // It essentially holds all state information needed by MirFiller's functions 00869 // during filling. <p> 00870 // 00871 // Most of the interaction with this class is through public data members (for 00872 // programming and runtime efficiency); thus, this class is not appropriate for 00873 // use outside of this module. A few helper funtions are provided to aid in 00874 // utilizing the information. 00875 // </synopsis> 00876 // 00877 // <motivation> 00878 // This allows MirFiller to pass the state of the filling process to its internal 00879 // functions rather than storing it as a member object. Thus, if one attempt 00880 // to fill fails half way, MirFiller does not have to worry about cleaning up 00881 // its internal state. 00882 // </motivation> 00883 // 00884 // 00885 class FillMetadata { 00886 public: 00887 00888 // info that doesn't change during filling 00889 MeasurementSet *ms; // the output ms 00890 MSColumns *msc; // a pointer to its columns 00891 String outname; 00892 00893 // output MS info that can vary during filling process 00894 Int obsid; // ids & offsets 00895 Float inttime; // the current integration time 00896 Float jyperk; 00897 Float plangle, plmaj, plmin, pltb; // miriad planet variables 00898 Double freq; // rest frequency of the primary line -- used to convert 00899 // pltb to flux using Raleigh-Jeans appx to BB. 00900 String telescope, project; 00901 Bool obsupd; 00902 Int nants, narrays, arrayAnt; 00903 Vector<Double> antpos; 00904 Vector<Double> arrayXYZ; 00905 Int *mount; 00906 Double *diam; 00907 Double starttime, obstime, feedtime, modeltime, lasttime; 00908 00909 MirFreqSetup *fsetup; 00910 // ListIter<MirFreqSetup *> fsiter; 00911 // IDIndex wfidx; // moved to MirFreqSetup 00912 // IDIndex nfidx; 00913 00914 MirSource *source; 00915 Bool movingsrc; 00916 // const List<MirSource*> *srclist; 00917 00918 // ListIter<MirField *> flditer; 00919 MirField *field; 00920 00921 ConstMirPolSetup *pol; 00922 MirPolRecps *polrecp; 00923 Bool polotf; // set to true if loading polarizations on the fly 00924 // PJT 00925 //HashMap<DataDescComponents, Int> ddids; 00926 00927 Matrix<Float> nsystemp; 00928 Matrix<Float> wsystemp; 00929 Int tsyscorrect; 00930 00931 // data-loading buffers 00932 DataLoadingBuf buf; 00933 00934 static const String HATCREEK; // "HATCREEK" 00935 static const String BIMA; // "BIMA" 00936 static const String CARMA; // "CARMA" 00937 static const String ATCA; // "ATCA" 00938 static const String VLA; // "VLA" 00939 00940 FillMetadata(const String &msfile=""); 00941 ~FillMetadata(); 00942 00943 // return the antenna id for a given miriad antenna number. 00944 Int getAntennaID(Int antnum) { return arrayAnt+antnum-1; } 00945 00946 // return the data description id for a given spectral window id. 00947 Int getDataDescID(Int /*sid*/=0, Int /*pid*/=0) { 00948 #if 0 00949 DataDescComponents ddid(sid, pid); 00950 return (ddids.isDefined(ddid) ? ddids(ddid) : -1); 00951 #else 00952 return -1; 00953 #endif 00954 } 00955 00956 // set all fiducial times to the given time 00957 void inittime(Double time, Double updmodelint=0) { 00958 lasttime = feedtime = obstime = starttime = time; 00959 modeltime = time - updmodelint; 00960 } 00961 00962 // set the telescope. This will also set the telescope location if 00963 // it is known. 00964 void setTelescope(String tel); 00965 00966 Int bimaAntCount() { 00967 Int i; 00968 for(i=nants-1; i >= 0; i--) { 00969 if (antpos(i) != 999 || 00970 antpos(i+nants) != 999 || 00971 antpos(i+2*nants) != 999 ) break; 00972 } 00973 return ((i >= 0) ? i+1 : nants); 00974 } 00975 }; 00976 00977 #endif 00978 00979