ViImplementation2.h

Go to the documentation of this file.
00001 //# VisibilityIterator.h: Step through the MeasurementEquation by visibility
00002 //# Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003
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 //# $Id: VisibilityIterator2.h,v 19.14 2006/02/28 04:48:58 mvoronko Exp $
00027 
00028 #if ! defined (MSVIS_ViImplementation2_H_121115_0950)
00029 #define MSVIS_ViImplementation2_H_121115_0950
00030 
00031 #include <casa/aips.h>
00032 #include <casa/BasicSL.h>
00033 #include <msvis/MSVis/VisBufferComponents2.h>
00034 #include <measures/Measures/MFrequency.h>
00035 #include <measures/Measures/Stokes.h>
00036 
00037 #include <map>
00038 #include <vector>
00039 
00040 namespace casa { //# NAMESPACE CASA - BEGIN
00041 
00042 template <typename T> class Array;
00043 template <typename T> class Block;
00044 //class CStokesVector;
00045 template <typename T> class Cube;
00046 template <typename T> class Matrix;
00047 class MDirection;
00048 class MeasurementSet;
00049 class MEpoch;
00050 class MPosition;
00051 class MSDerivedValues;
00052 class RecordInterface;
00053 template <typename T, Int n> class RigidVector;
00054 class Slice;
00055 class String;
00056 template <typename T, Int n> class SquareMatrix;
00057 template <typename T> class Vector;
00058 class VisImagingWeight;
00059 
00060 namespace vi {
00061 
00062 
00063 //# forward decl
00064 
00065 class ChannelSelector;
00066 class ChannelSelectorCache;
00067 class FrequencySelections;
00068 class SortColumns;
00069 class SpectralWindowChannels;
00070 class SpectralWindowChannelsCache;
00071 class Subchunk;
00072 class SubtableColumns;
00073 class VisBuffer2;
00074 class VisibilityIterator2;
00075 class WeightScaling;
00076 enum VisBufferType : int;
00077 enum VisBufferOptions : int;
00078 
00079 // <summary>
00080 // VisibilityIterator2 iterates through one or more readonly MeasurementSets
00081 // </summary>
00082 
00083 // <use visibility=export>
00084 
00085 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00086 // </reviewed>
00087 
00088 // <prerequisite>
00089 //   <li> <linkto class="MSIter">MSIter</linkto>
00090 //   <li> <linkto class="MeasurementSet">MeasurementSet</linkto>
00091 //   <li> <linkto class="VisSet">VisSet</linkto>
00092 // </prerequisite>
00093 //
00094 // <etymology>
00095 // The VisibilityIterator2 is a readonly iterator returning visibilities
00096 // </etymology>
00097 //
00098 // <synopsis>
00099 // VisibilityIterator2 provides iteration with various sort orders
00100 // for one or more MSs. It has member functions to retrieve the fields
00101 // commonly needed in synthesis calibration and imaging.
00102 //
00103 // One should use <linkto class="VisBuffer">VisBuffer</linkto>
00104 // to access chunks of data.
00105 // </synopsis>
00106 //
00107 // <example>
00108 // <code>
00109 // //
00110 // </code>
00111 // </example>
00112 //
00113 // <motivation>
00114 // For imaging and calibration you need to access an MS in some consistent
00115 // order (by field, spectralwindow, time interval etc.). This class provides
00116 // that access.
00117 // </motivation>
00118 //
00119 // <thrown>
00120 //    <li>
00121 //    <li>
00122 // </thrown>
00123 //
00124 // <todo asof="1997/05/30">
00125 //   <li> cleanup the currently dual interface for visibilities and flags
00126 //   <li> sort out what to do with weights when interpolating
00127 // </todo>
00128 
00129 class ViImplementation2 {
00130 
00131     friend class VisibilityIterator2;
00132 
00133 public:
00134 
00135     // make noncopyable...
00136     ViImplementation2( const ViImplementation2& ) = delete;
00137     ViImplementation2& operator=( const ViImplementation2& ) = delete;
00138     ViImplementation2 () {}
00139 
00140     // Destructor
00141 
00142     virtual ~ViImplementation2 () {}
00143 
00144     // Report the the ViImplementation type
00145     virtual String ViiType() const = 0;
00146 
00147     //   +==================================+
00148     //   |                                  |
00149     //   | Iteration Control and Monitoring |
00150     //   |                                  |
00151     //   +==================================+
00152 
00153     // Methods to control and monitor subchunk iteration
00154 
00155     virtual void origin () = 0;
00156     virtual Bool more () const = 0;
00157     virtual void next () = 0;
00158     virtual Subchunk getSubchunkId () const = 0;
00159 
00160     // Methods to control chunk iterator
00161 
00162     virtual void originChunks (Bool forceRewind = False) = 0;
00163     virtual Bool moreChunks () const = 0;
00164     virtual void nextChunk () = 0;
00165 
00166     virtual Bool isWritable () const = 0;
00167 
00168     // Return the time interval (in seconds) used for iteration.
00169     // This is not the same as the INTERVAL column.  Setting the
00170     // the interval requires calling origin chunks before performing
00171     // further iterator.
00172 
00173     virtual Double getInterval() const = 0;
00174     virtual void setInterval (Double timeInterval) = 0;
00175 
00176     // Select the channels to be returned.  Requires calling originChunks before
00177     // performing additional iteration.
00178 
00179     virtual void setFrequencySelections (const FrequencySelections & selection) = 0;
00180 
00181     // Set the 'blocking' size for returning data.
00182     // With the default (0) only a single integration is returned at a time, this
00183     // is what is currently required for the calibration software. With blocking
00184     // set, up to nRows can be returned in one go. The chunk
00185     // size determines the actual maximum.
00186 
00187     virtual void setRowBlocking (Int nRows = 0) = 0;
00188 
00189     virtual Bool existsColumn (VisBufferComponent2 id) const = 0;
00190 
00191     virtual const SortColumns & getSortColumns() const = 0;
00192 
00193     virtual Bool isNewArrayId () const = 0;
00194     virtual Bool isNewFieldId () const = 0;
00195     virtual Bool isNewMs () const = 0;
00196     virtual Bool isNewSpectralWindow () const = 0;
00197 
00198     // Return the number of rows in the current iteration
00199 
00200     virtual Int nRows () const = 0;
00201 
00202     // Return the row ids as from the original root table. This is useful
00203     // to find correspondance between a given row in this iteration to the
00204     // original ms row
00205 
00206     virtual void getRowIds (Vector<uInt> & rowids) const = 0;
00207 
00208     virtual VisBuffer2 * getVisBuffer (const VisibilityIterator2 *) = 0;
00209     virtual VisBuffer2 * getVisBuffer () = 0;
00210 
00211 
00212     //   +=========================+
00213     //   |                         |
00214     //   | Subchunk Data Accessors |
00215     //   |                         |
00216     //   +=========================+
00217 
00218     // Return antenna1
00219 
00220     virtual void antenna1 (Vector<Int> & ant1) const = 0;
00221 
00222     // Return antenna2
00223 
00224     virtual void antenna2 (Vector<Int> & ant2) const = 0;
00225 
00226     // Return the correlation type (returns Stokes enums)
00227 
00228     virtual void corrType (Vector<Int> & corrTypes) const = 0;
00229 
00230     // Return current DataDescription Id
00231 
00232     virtual Int dataDescriptionId () const = 0;
00233 
00234     virtual void dataDescriptionIds (Vector<Int> & ddis) const = 0;
00235 
00236     // Return actual time interval
00237 
00238     virtual void  exposure (Vector<Double> & expo) const = 0;
00239 
00240     // Return feed1
00241 
00242     virtual void feed1 (Vector<Int> & fd1) const = 0;
00243 
00244     // Return feed2
00245 
00246     virtual void feed2 (Vector<Int> & fd2) const = 0;
00247 
00248     // Return the current FieldId
00249 
00250     virtual void fieldIds (Vector<Int>&) const = 0;
00251 
00252     // Return the current ArrayId
00253 
00254     virtual void arrayIds (Vector<Int>&) const = 0;
00255 
00256     // Return the current Field Name
00257 
00258     virtual String fieldName () const = 0;
00259 
00260     // Return flag for each polarization, channel and row
00261 
00262     virtual void flag (Cube<Bool> & flags) const = 0;
00263 
00264     // Return flag for each channel & row
00265 
00266     virtual void flag (Matrix<Bool> & flags) const = 0;
00267 
00268     // Determine whether FLAG_CATEGORY is valid.
00269 
00270     virtual Bool flagCategoryExists () const = 0;
00271 
00272     // Return flags for each polarization, channel, category, and row.
00273 
00274     virtual void flagCategory (Array<Bool> & flagCategories) const = 0;
00275 
00276     // Return row flag
00277 
00278     virtual void flagRow (Vector<Bool> & rowflags) const = 0;
00279 
00280     // Return the OBSERVATION_IDs
00281 
00282     virtual void observationId (Vector<Int> & obsids) const = 0;
00283 
00284     // Return current Polarization Id
00285 
00286     virtual Int polarizationId () const = 0;
00287 
00288     // Return the PROCESSOR_IDs
00289 
00290     virtual void processorId (Vector<Int> & procids) const = 0;
00291 
00292     // Return scan number
00293 
00294     virtual void scan (Vector<Int> & scans) const = 0;
00295 
00296     // Return the current Source Name
00297 
00298     virtual String sourceName () const = 0;
00299 
00300     // Return the STATE_IDs
00301 
00302     virtual void stateId (Vector<Int> & stateids) const = 0;
00303 
00304 
00305     // Return feed configuration matrix for specified antenna
00306 
00307     virtual void jonesC (Vector<SquareMatrix<Complex, 2> > & cjones) const = 0;
00308 
00309     // Return frame for polarization (returns PolFrame enum)
00310 
00311     virtual Int polFrame () const = 0;
00312 
00313     // Return sigma
00314 
00315     virtual void sigma (Matrix<Float> & sigmat) const = 0;
00316 
00317     // Return current SpectralWindow
00318 
00319     virtual Int spectralWindow () const = 0;
00320 
00321     virtual void spectralWindows (Vector<Int> & spws) const = 0;
00322 
00323     // Return MJD midpoint of interval.
00324 
00325     virtual void time (Vector<Double> & t) const = 0;
00326 
00327     // Return MJD centroid of interval.
00328 
00329     virtual void timeCentroid (Vector<Double> & t) const = 0;
00330 
00331     // Return nominal time interval
00332 
00333     virtual void timeInterval (Vector<Double> & ti) const = 0;
00334 
00335     // Return u,v and w (in meters)
00336 
00337     virtual void uvw (Matrix<Double> & uvwmat) const = 0;
00338 
00339     // Return the visibilities as found in the MS, Cube (npol,nchan,nrow).
00340 
00341     virtual void visibilityCorrected (Cube<Complex> & vis) const = 0;
00342     virtual void visibilityModel (Cube<Complex> & vis) const = 0;
00343     virtual void visibilityObserved (Cube<Complex> & vis) const = 0;
00344 
00345     // Return FLOAT_DATA as a Cube (npol, nchan, nrow) if found in the MS.
00346 
00347     virtual void floatData (Cube<Float> & fcube) const = 0;
00348 
00349     // Return the visibility 4-vector of polarizations for each channel.
00350     // If the MS doesn't contain all polarizations, it is assumed it
00351     // contains one or two parallel hand polarizations.
00352 
00353 //    virtual void visibilityCorrected (Matrix<CStokesVector> & vis) const = 0;
00354 //    virtual void visibilityModel (Matrix<CStokesVector> & vis) const = 0;
00355 //    virtual void visibilityObserved (Matrix<CStokesVector> & vis) const = 0;
00356 
00357     // Return the shape of the visibility Cube
00358 
00359     virtual IPosition visibilityShape () const = 0;
00360 
00361     // Return weight
00362 
00363     virtual void weight (Matrix<Float> & wtmat) const = 0;
00364 
00365     // Determine whether WEIGHT_SPECTRUM exists.
00366 
00367     virtual Bool weightSpectrumExists () const = 0;
00368 
00369     // Determine whether SIGMA_SPECTRUM exists.
00370 
00371     virtual Bool sigmaSpectrumExists () const = 0;
00372 
00373     // Return weightspectrum (a weight for each channel)
00374 
00375     virtual void weightSpectrum (Cube<Float> & wtsp) const = 0;
00376 
00377     // Return sgimaspectrum (a sigma for each channel)
00378 
00379     virtual void sigmaSpectrum (Cube<Float> & wtsp) const = 0;
00380 
00381 
00382     virtual void setWeightScaling (CountedPtr<WeightScaling> weightscaling) = 0;
00383     virtual Bool hasWeightScaling () const = 0;
00384     virtual CountedPtr<WeightScaling> getWeightScaling () const = 0;
00385 
00386     // Return the number of sub-intervals in the current chunk
00387 
00388     //   +------------------------+
00389     //   |                        |
00390     //   | Angular Data Providers |
00391     //   |                        |
00392     //   +------------------------+
00393 
00394     // True if all elements of the cube returned by getBeamOffsets are zero
00395 
00396     virtual Bool allBeamOffsetsZero () const = 0;
00397 
00398     // Return the antenna AZ/EL Vector (nant)
00399 
00400     virtual MDirection azel0 (Double time) const = 0;
00401     static void azel0Calculate (Double time, MSDerivedValues & msd,
00402                                 MDirection & azel0, const MEpoch & mEpoch0);
00403 
00404     virtual const Vector<MDirection> & azel (Double time) const = 0;
00405     static void azelCalculate (Double time, MSDerivedValues & msd, Vector<MDirection> & azel,
00406                                Int nAnt, const MEpoch & mEpoch0);
00407 
00408     // Return feed parallactic angles Vector (nant) (1 feed/ant)
00409 
00410     virtual const Vector<Float> & feed_pa (Double time) const = 0;
00411     static Vector<Float> feed_paCalculate (Double time, MSDerivedValues & msd,
00412                                            Int nAntennas, const MEpoch & mEpoch0,
00413                                            const Vector<Float> & receptor0Angle);
00414 
00415     // Return a cube containing pairs of coordinate offsets for each
00416     // receptor of each feed (values are in radians, coordinate system is fixed
00417     // with antenna and is the same one as used to define the BEAM_OFFSET
00418     // parameter in the feed table). The cube axes are receptor, antenna, feed.
00419 
00420     virtual const Cube<RigidVector<Double, 2> > & getBeamOffsets () const = 0;
00421 
00422     // Return the hour angle for the specified time
00423 
00424     virtual Double hourang (Double time) const = 0;
00425     static Double hourangCalculate (Double time, MSDerivedValues & msd, const MEpoch & mEpoch0);
00426 
00427     // Return nominal parallactic angle at specified time
00428     // (does not include feed position angle offset--see feed_pa)
00429     // A global value for all antennas (e.g., small array)
00430 
00431     virtual const Float & parang0 (Double time) const = 0;
00432     static Float parang0Calculate (Double time, MSDerivedValues & msd, const MEpoch & epoch0);
00433 
00434     // Per antenna:
00435 
00436     virtual const Vector<Float> & parang (Double time) const = 0;
00437     static Vector<Float> parangCalculate (Double time, MSDerivedValues & msd,
00438                                           int nAntennas, const MEpoch mEpoch0);
00439 
00440     // Return the current phase center as an MDirection
00441 
00442     virtual const MDirection & phaseCenter () const = 0;
00443 
00444     // Return receptor angles for all antennae and feeds
00445     // First axis of the cube is a receptor number,
00446     // 2nd is antennaId, 3rd is feedId
00447     // Note: the method is intended to provide an access to MSIter::receptorAngles
00448     // for VisBuffer in the multi-feed case. It may be worth to change the
00449     // interface of feed_pa to return the information for all feeds.
00450 
00451     virtual const Cube<Double> & receptorAngles () const = 0;
00452 
00453     //   +=========================+
00454     //   |                         |
00455     //   | Chunk and MS Level Data |
00456     //   |                         |
00457     //   +=========================+
00458 
00459     // return a string mount identifier for each antenna
00460 
00461     virtual const Vector<String> & antennaMounts () const = 0;
00462 
00463     virtual MEpoch getEpoch () const = 0;
00464 
00465     // Return imaging weight (a weight for each channel)
00466     //virtual Matrix<Float> & imagingWeight (Matrix<Float> & wt) const = 0;
00467 
00468     virtual const VisImagingWeight & getImagingWeightGenerator () const = 0;
00469 
00470     virtual MFrequency::Types getObservatoryFrequencyType () const = 0; //???
00471     virtual MPosition getObservatoryPosition () const = 0;
00472     virtual Vector<Float> getReceptor0Angle () = 0;
00473 
00474     virtual Int getReportingFrameOfReference () const = 0;
00475     virtual void setReportingFrameOfReference (Int frame) = 0;
00476 
00477     virtual Vector<Int> getCorrelations () const = 0;
00478     virtual Vector<Stokes::StokesTypes> getCorrelationTypesDefined () const = 0;
00479     virtual Vector<Stokes::StokesTypes> getCorrelationTypesSelected () const = 0;
00480 
00481     virtual Vector<Int> getChannels (Double time, Int frameOfReference, Int spectralWndow = -1,
00482                                      Int msId = -1) const = 0;
00483     virtual Vector<Double> getFrequencies (Double time, Int frameOfReference, Int spectralWndow = -1,
00484                                            Int msId = -1) const = 0;
00485 
00486 
00487     //reference to actual ms in interator
00488 
00489     virtual Int msId () const = 0; // zero-based index of current MS in set of MSs
00490     virtual const MeasurementSet & ms () const = 0;
00491     virtual Int getNMs () const = 0;
00492 
00493     // Name of current nominal MS
00494     virtual String msName() const = 0;
00495 
00496     // Call to use the slurp i/o method for all scalar columns. This
00497     // will set the BucketCache cache size to the full column length
00498     // and cause the full column to be cached in memory, if
00499     // any value of the column is used. In case of out-of-memory,
00500     // it will automatically fall-back on the smaller cache size.
00501     // Slurping the column is to be considered as a work-around for the
00502     // Table i/o code, which uses BucketCache and performs extremely bad
00503     // for random access. Slurping is useful when iterating non-sequentially
00504     // an MS or parts of an MS, it is not tested with multiple MSs.
00505 
00506     virtual void slurp () const = 0;
00507 
00508     // Access the current ROMSColumns object in MSIter
00509 
00510     virtual const vi::SubtableColumns & subtableColumns () const = 0;
00511 
00512     // get back the selected spectral windows and spectral channels for
00513     // current ms
00514 
00515     virtual const SpectralWindowChannels & getSpectralWindowChannels (Int msId, Int spectralWindowId) const = 0;
00516 
00517     //assign a VisImagingWeight object to this iterator
00518 
00519     virtual void useImagingWeight (const VisImagingWeight & imWgt) = 0;
00520 
00521     // Return number of antennasm spws, polids, ddids
00522 
00523     virtual Int nAntennas () const = 0;
00524     virtual Int nDataDescriptionIds () const = 0;
00525     virtual Int nPolarizationIds () const = 0;
00526     virtual Int nRowsInChunk () const = 0; // number rows in current chunk
00527     virtual Int nRowsViWillSweep () const = 0; // number of rows in all selected ms's
00528     virtual Int nSpectralWindows () const = 0;
00529 
00530     //   +-------------------+
00531     //   |                   |
00532     //   | Writeback Methods |
00533     //   |                   |
00534     //   +-------------------+
00535 
00536     // This method writes back any changed (dirty) components of the provided
00537     // VisBuffer and is the preferred method for writing data out.
00538 
00539     virtual void writeBackChanges (VisBuffer2 * vb) = 0;
00540 
00541     // Write/modify the flags in the data.
00542     // This will flag all channels in the original data that contributed to
00543     // the output channel in the case of channel averaging.
00544     // All polarizations have the same flag value.
00545 //    virtual void writeFlag (const Matrix<Bool> & flag) = 0;
00546 
00547     // Write/modify the flags in the data.
00548     // This writes the flags as found in the MS, Cube (npol,nchan,nrow),
00549     // where nrow is the number of rows in the current iteration (given by
00550     // nRow ()).
00551     virtual void writeFlag (const Cube<Bool> & flag) = 0;
00552 
00553     // Write/modify the flag row column = 0; dimension Vector (nrow)
00554     virtual void writeFlagRow (const Vector<Bool> & rowflags) = 0;
00555 
00556     virtual void writeFlagCategory(const Array<Bool>& fc) = 0;
00557 
00558     // Write/modify the visibilities.
00559     // This is possibly only for a 'reference' MS which has a new DATA column.
00560     // The first axis of the matrix should equal the selected number of channels
00561     // in the original MS.
00562     // If the MS does not contain all polarizations, only the parallel
00563     // hand polarizations are used.
00564 //    virtual void writeVisCorrected (const Matrix<CStokesVector> & visibilityStokes) = 0;
00565 //    virtual void writeVisModel (const Matrix<CStokesVector> & visibilityStokes) = 0;
00566 //    virtual void writeVisObserved (const Matrix<CStokesVector> & visibilityStokes) = 0;
00567 
00568     // Write/modify the visibilities
00569     // This writes the data as found in the MS, Cube (npol,nchan,nrow).
00570     virtual void writeVisCorrected (const Cube<Complex> & vis) = 0;
00571     virtual void writeVisModel (const Cube<Complex> & vis) = 0;
00572     virtual void writeVisObserved (const Cube<Complex> & vis) = 0;
00573 
00574     // Write/modify the weights
00575     virtual void writeWeight (const Matrix<Float> & wt) = 0;
00576 
00577     // Write/modify the weightMat
00578     //virtual void writeWeightMat (const Matrix<Float> & wtmat) = 0;
00579 
00580     // Write/modify the weightSpectrum
00581     virtual void writeWeightSpectrum (const Cube<Float> & wtsp) = 0;
00582 
00583     // Initialize the weightSpectrum
00584     virtual void initWeightSpectrum (const Cube<Float> & /* wtsp */) {};
00585 
00586     // Write/modify the sigmaSpectrum
00587     virtual void writeSigmaSpectrum (const Cube<Float> & sigsp) = 0;
00588 
00589     // Initialize the sigmaSpectrum
00590     virtual void initSigmaSpectrum (const Cube<Float> & /* sigsp */) {};
00591 
00592     // Write/modify the Sigma
00593     virtual void writeSigma (const Matrix<Float> & sig) = 0;
00594 
00595     // Write/modify the ncorr x nrow SigmaMat.
00596     //virtual void writeSigmaMat (const Matrix<Float> & sigmat) = 0;
00597 
00598     // Write the information needed to generate on-the-fly model visibilities.
00599 
00600     virtual void writeModel(const RecordInterface& rec, Bool iscomponentlist=True,
00601                             Bool incremental=False) = 0;
00602 
00603 
00604 protected:
00605 
00606     void associateVbWithVi2 (VisBuffer2 * vb, const VisibilityIterator2 * vi);
00607     VisBuffer2 * createAttachedVisBuffer (VisBufferType t, VisBufferOptions options);
00608 
00609 
00610     static void doWeightScaling (Bool hasWeightScaling,
00611                                  WeightScaling * scaling,
00612                                  const Array<Float>& unscaled,
00613                                  Array<Float>& scaled);
00614 
00615 };
00616 
00617 } // end namespace vi
00618 
00619 } //# NAMESPACE CASA - END
00620 
00621 #endif // ! defined (MSVIS_ViImplementation2_H_121115_0950)
00622 
00623 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1