skymap.cpp

Go to the documentation of this file.
00001 /* ============================================================================
00002 'skymap.cpp' defines the pixel and skymap class methods.  The classes are
00003 defined in 'skymap.h'.
00004 
00005 Written by Nicholas Phillips, December 2006
00006 Adapted for WMAP.  FITS and copy operator added.  Michael R. Greason, ADNET,
00007         27 December 2006.
00008 readFITS modified to support multiple values in a single table cell.
00009     MRG, ADNET, 13 January 2009.
00010 ============================================================================ */
00011 #include <iostream>
00012 #include <math.h>
00013 #include <stdio.h>
00014 #include "skymap.h"
00015 #include "controldialog.h"
00016 #include "enums.h"
00017 
00018 using namespace std;
00019 /*
00020                         Constants.
00021 */
00022 char  ICOLNAME[]  = "TEMPERATURE";
00023 char  QCOLNAME[]  = "Q_POLARISATION";
00024 char  QCOLNAMEA[] = "QPOLARISATION";
00025 char  QCOLNAMEB[] = "Q_POLARIZATION";
00026 char  QCOLNAMEC[] = "QPOLARIZATION";
00027 char  UCOLNAME[]  = "U_POLARISATION";
00028 char  UCOLNAMEA[] = "UPOLARISATION";
00029 char  UCOLNAMEB[] = "U_POLARIZATION";
00030 char  UCOLNAMEC[] = "UPOLARIZATION";
00031 char  NCOLNAME[]  = "N_OBS";
00032 
00033 char  DEFTABLE[]  = "Sky Maps";
00034 char  DEFTUNIT[]  = "mK";
00035 char  DEFNUNIT[]  = "counts";
00036 char  DEFFORM[]   = "E";
00037 
00038 const int maxcols = 5;
00039 /* ============================================================================
00040 The Skymap class defines a collection of pixels to represent a sky map.
00041 This version allows for dynamically selecting how much information is stored 
00042 for each pixel. Can be as simple as just the temperature or up to temperature, 
00043 polarization and number of observations.
00044 ============================================================================ */
00045 BasePixel Skymap::basedummy;
00046 /* ----------------------------------------------------------------------------
00047 'Skymap' is the class constructor that defines an empty map.
00048 
00049 Arguments:
00050         None.
00051 
00052 Returned:
00053         N/A.
00054 ---------------------------------------------------------------------------- */
00055 Skymap::Skymap()
00056 {
00057         init();
00058 }
00059 /* ----------------------------------------------------------------------------
00060 'Skymap' is the class constructor that defines a blank map of a given size and
00061 type.
00062 
00063 Arguments:
00064         n_in    - The number of pixels in the map.
00065         type_in - The type of map.
00066 
00067 Returned:
00068         N/A.
00069 ---------------------------------------------------------------------------- */
00070 Skymap::Skymap(unsigned int n_in, Type type_in)
00071 {
00072         init();
00073         set(n_in, type_in );
00074 }
00075 /* ----------------------------------------------------------------------------
00076 '~Skymap' is the class destructor.
00077 
00078 Arguments:
00079         None.
00080 
00081 Returned:
00082         N/A.
00083 ---------------------------------------------------------------------------- */
00084 Skymap::~Skymap()
00085 {
00086         freeMemory();
00087 }
00088 /* ----------------------------------------------------------------------------
00089 'returnnone' throws an exception indicating that an empty map was accessed.
00090 
00091 Arguments:
00092         i - The index into the map.
00093 
00094 Returned:
00095         A dummy pixel is returned..
00096 ---------------------------------------------------------------------------- */
00097 BasePixel& Skymap::returnnone(unsigned int /*i*/)
00098 {
00099         throw MapException(MapException::InvalidType);
00100         return basedummy;
00101 }
00102 /* ----------------------------------------------------------------------------
00103 'init' initializes an empty map.
00104 
00105 Arguments:
00106         None.
00107 
00108 Returned:
00109         Nothing.
00110 ---------------------------------------------------------------------------- */
00111 void Skymap::init()
00112 {
00113         type_     = none;
00114         n_        = 0;
00115         tpix      = 0;
00116         tppix     = 0;
00117         tnobspix  = 0;
00118         tpnobspix = 0;
00119         returnfct = &Skymap::returnnone;
00120 
00121         minpix.clear();
00122         maxpix.clear();
00123         avgpix.clear();
00124         stdpix.clear();
00125 
00126         return;
00127 }
00128 /* ----------------------------------------------------------------------------
00129 'allocPixMemory' allocates the storage for a blank map.  If an invalid map 
00130 type is supplied an exception is thrown.
00131 
00132 Arguments:
00133         n_in    - The number of pixels in the map.
00134         type_in - The type of map.
00135 
00136 Returned:
00137         Nothing.
00138 ---------------------------------------------------------------------------- */
00139 void Skymap::allocPixMemory(unsigned int n_in, Type type_in)
00140 {
00141         if( n_in == n() && type_in == type() )
00142                 return;
00143         if( n_in == 0 || type_in == none )
00144                 return;
00145                 
00146         type_ = type_in;
00147         if (tpix       ) { delete[] tpix;       tpix       = 0; }
00148         if (tppix      ) { delete[] tppix;      tppix      = 0; }
00149         if (tnobspix   ) { delete[] tnobspix;   tnobspix   = 0; }
00150         if (tpnobspix  ) { delete[] tpnobspix;  tpnobspix  = 0; }
00151         n_ = n_in;
00152         switch( type() ){
00153                 case TPix:
00154                         tpix = new TPixel[n()];
00155                         if (tpix == NULL) throw MapException(MapException::Memory);
00156                         returnfct = &Skymap::returnTpix;
00157                         break;
00158                 case PPix:
00159                         tppix = new TPPixel[n()];
00160                         if (tppix == NULL) throw MapException(MapException::Memory);
00161                         returnfct = &Skymap::returnTPpix;
00162                         break;
00163                 case TnobsPix:
00164                         tnobspix = new TnobsPixel[n()];
00165                         if (tnobspix == NULL) throw MapException(MapException::Memory);
00166                         returnfct = &Skymap::returnTnobspix;                    
00167                         break;
00168                 case TPnobsPix:
00169                         tpnobspix = new TPnobsPixel[n()];
00170                         if (tpnobspix == NULL) throw MapException(MapException::Memory);
00171                         returnfct = &Skymap::returnTPnobspix;
00172                         break;
00173                 default:
00174                         throw MapException(MapException::InvalidType);
00175         }
00176         return;
00177 }
00178 /* ----------------------------------------------------------------------------
00179 'freeMemory' releases the memory associated with the map and resets its
00180 internal storage to show an empty map.
00181 
00182 Arguments:
00183         None.
00184 
00185 Returned:
00186         Nothing.
00187 ---------------------------------------------------------------------------- */
00188 void Skymap::freeMemory()
00189 {
00190         if (tpix       ) { delete[] tpix;       tpix       = 0; }
00191         if (tppix      ) { delete[] tppix;      tppix      = 0; }
00192         if (tnobspix   ) { delete[] tnobspix;   tnobspix   = 0; }
00193         if (tpnobspix  ) { delete[] tpnobspix;  tpnobspix  = 0; }
00194         init();
00195         return;
00196 }
00197 /* ----------------------------------------------------------------------------
00198 'writeHdrDate' writes a DATE card to the header of the current HDU.
00199 
00200 An exception is thrown in the event of a FITS error.
00201 
00202 Arguments:
00203         fitsfile - The handle to the currently open FITS file.
00204 
00205 Returned:
00206         Nothing.
00207 ---------------------------------------------------------------------------- */
00208 void Skymap::writeHdrDate (fitsfile* fptr)
00209 {
00210         char str[48], comm[48], key[] = {"DATE"};
00211         int  flg = 0, status = 0;
00212         if (fits_get_system_time(str, &flg, &status) != 0)
00213                 throw MapException(MapException::FITSError, status);
00214         if (flg == 0) strcpy(comm, "File creation date (YYYY-MM-DDThh:mm:ss UT)");
00215                  else strcpy(comm, "File creation date (YYYY-MM-DDThh:mm:ss)");
00216         if (fits_update_key(fptr, TSTRING, key, str, comm, &status) != 0)
00217                 throw MapException(MapException::FITSError, status);
00218         return;
00219 }
00220 /* ----------------------------------------------------------------------------
00221 'readFITSPrimaryHeader' reads information from the primary FITS header.
00222 
00223 This routine assumes that the current HDU is the primary HDU.
00224 
00225 This routine does nothing; child classes should overload this function as
00226 appropriate.
00227 
00228 An exception is thrown in the event of a FITS error.
00229 
00230 Arguments:
00231         fitsfile - The handle to the currently open FITS file.
00232 
00233 Returned:
00234         Nothing.
00235 ---------------------------------------------------------------------------- */
00236 void Skymap::readFITSPrimaryHeader (fitsfile* /*fptr*/)
00237 {
00238         return;
00239 }
00240 /* ----------------------------------------------------------------------------
00241 'writeFITSPrimaryHeader' writes information to the primary FITS header.
00242 
00243 This routine assumes that the current HDU is the primary HDU.
00244 
00245 This routine simply writes a DATE card to the header; child classes should
00246 overload this function as appropriate.
00247 
00248 An exception is thrown in the event of a FITS error.
00249 
00250 Arguments:
00251         fitsfile - The handle to the currently open FITS file.
00252 
00253 Returned:
00254         Nothing.
00255 ---------------------------------------------------------------------------- */
00256 void Skymap::writeFITSPrimaryHeader (fitsfile* fptr)
00257 {
00258         writeHdrDate(fptr);
00259         return;
00260 }
00261 /* ----------------------------------------------------------------------------
00262 'readFITSExtensionHeader' reads information from the extension FITS header.
00263 
00264 This routine assumes that the current HDU is the correct extension HDU.
00265 
00266 This routine does nothing; child classes should overload this function as
00267 appropriate.
00268 
00269 An exception is thrown in the event of a FITS error.
00270 
00271 Arguments:
00272         fitsfile - The handle to the currently open FITS file.
00273 
00274 Returned:
00275         Nothing.
00276 ---------------------------------------------------------------------------- */
00277 void Skymap::readFITSExtensionHeader (fitsfile* /*fptr*/)
00278 {
00279         return;
00280 }
00281 /* ----------------------------------------------------------------------------
00282 'writeFITSExtensionHeader' writes information to the primary FITS header.
00283 
00284 This routine assumes that the current HDU is the correct extension HDU.
00285 
00286 This routine simply writes a DATE card to the header; child classes should
00287 overload this function as appropriate.
00288 
00289 An exception is thrown in the event of a FITS error.
00290 
00291 Arguments:
00292         fitsfile - The handle to the currently open FITS file.
00293 
00294 Returned:
00295         Nothing.
00296 ---------------------------------------------------------------------------- */
00297 void Skymap::writeFITSExtensionHeader (fitsfile* fptr)
00298 {
00299         writeHdrDate(fptr);
00300         return;
00301 }
00302 /* ----------------------------------------------------------------------------
00303 'set' creates the storage for a blank map.  If an invalid map type is supplied
00304 an exception is thrown.
00305 
00306 Arguments:
00307         n_in    - The number of pixels in the map.
00308         type_in - The type of map.
00309 
00310 Returned:
00311         Nothing.
00312 ---------------------------------------------------------------------------- */
00313 void Skymap::set(unsigned int n_in, Type type_in)
00314 {
00315         if( n_in == n() && type_in == type() ) return;
00316         freeMemory();
00317         allocPixMemory(n_in, type_in);
00318         return;
00319 }
00320 /* ----------------------------------------------------------------------------
00321 'copy' copies the contents of another map into this one.
00322 
00323 Arguments:
00324         imap - The source map.
00325 
00326 Returned:
00327         Nothing.
00328 ---------------------------------------------------------------------------- */
00329 void Skymap::copy(Skymap &imap)
00330 {
00331         unsigned int i;
00332         set(imap.size(), imap.type());
00333         for (i = 0; i < size(); i++)
00334         {
00335                 switch (type())
00336                 {
00337                   case TnobsPix:
00338                         (*this)[i].T()    = imap[i].T();
00339                         (*this)[i].Nobs() = imap[i].Nobs();
00340                         break;
00341                   case TPnobsPix:
00342                         (*this)[i].Nobs() = imap[i].Nobs();
00343                   case PPix:
00344                         (*this)[i].Q()    = imap[i].Q();
00345                         (*this)[i].U()    = imap[i].U();
00346                         (*this)[i].Pmag() = imap[i].Pmag();
00347                         (*this)[i].Pang() = imap[i].Pang();
00348                   case TPix:
00349                         (*this)[i].T() = imap[i].T();
00350                         break;
00351                   default:
00352                         throw MapException(MapException::InvalidType);
00353                 }
00354         }
00355         minpix = imap.minpix;
00356         maxpix = imap.maxpix;
00357         avgpix = imap.avgpix;
00358         stdpix = imap.stdpix;
00359         return;
00360 }
00361 /* ----------------------------------------------------------------------------
00362 'computePolar' computes the polarization magnitude and angle for each pixel.
00363 
00364 This routine should be called anytime the map is modified before the routines
00365 that provide access to these values are called.  It is called at the end
00366 of the 'readFITS' routine.
00367 
00368 A MapException is thrown in the event of an error.
00369 
00370 Arguments:
00371         None.
00372 
00373 Returned:
00374         Nothing.
00375 ---------------------------------------------------------------------------- */
00376 void Skymap::computePolar(void)
00377 {
00378         unsigned int i;
00379         if (! has_Polarization()) return;
00380         for (i = 0; i < size(); i++)
00381         {
00382                 (*this)[i].computePolar();
00383         }
00384 }
00385 /* ----------------------------------------------------------------------------
00386 'calcStats' computes the statistics of the map:  the minimum, maximum, mean,
00387 and standard deviation pixel values.
00388 
00389 This routine must be called anytime the map is modified before the routines
00390 that provide access to these statistics are called.  It is called at the end
00391 of the 'readFITS' routine.
00392 
00393 A MapException is thrown in the event of an error.
00394 
00395 Arguments:
00396         None.
00397 
00398 Returned:
00399         Nothing.
00400 ---------------------------------------------------------------------------- */
00401 void Skymap::calcStats(void)
00402 {
00403         unsigned int i;
00404         double       dn, dns;
00405 /*
00406                         First pixel.
00407 */
00408         i = 0;
00409         switch (type())
00410         {
00411           case TnobsPix:
00412                 avgpix.T()    = maxpix.T()    = minpix.T()    = (*this)[i].T();
00413                 avgpix.Nobs() = maxpix.Nobs() = minpix.Nobs() = (*this)[i].Nobs();
00414                 stdpix.T()    = (*this)[i].T()    * (*this)[i].T();
00415                 stdpix.Nobs() = (*this)[i].Nobs() * (*this)[i].Nobs();
00416                 break;
00417           case TPnobsPix:
00418                 avgpix.Nobs() = maxpix.Nobs() = minpix.Nobs() = (*this)[i].Nobs();
00419                 stdpix.Nobs() = (*this)[i].Nobs() * (*this)[i].Nobs();
00420           case PPix:
00421                 avgpix.Q()    = maxpix.Q()    = minpix.Q()    = (*this)[i].Q();
00422                 avgpix.U()    = maxpix.U()    = minpix.U()    = (*this)[i].U();
00423                 avgpix.Pmag() = maxpix.Pmag() = minpix.Pmag() = (*this)[i].Pmag();
00424                 avgpix.Pang() = maxpix.Pang() = minpix.Pang() = (*this)[i].Pang();
00425                 stdpix.Q()    = (*this)[i].Q()    * (*this)[i].Q();
00426                 stdpix.U()    = (*this)[i].U()    * (*this)[i].U();
00427                 stdpix.Pmag() = (*this)[i].Pmag() * (*this)[i].Pmag();
00428                 stdpix.Pang() = (*this)[i].Pang() * (*this)[i].Pang();
00429           case TPix:
00430                 avgpix.T() = maxpix.T() = minpix.T() = (*this)[i].T();
00431                 stdpix.T() = (*this)[i].T() * (*this)[i].T();
00432                 break;
00433           default:
00434                 throw MapException(MapException::InvalidType);
00435         }
00436 /*
00437                         Accumulate over the rest of the pixels.
00438 */
00439         for (i = 1; i < size(); i++)
00440         {
00441                 switch (type())
00442                 {
00443                   case TnobsPix:
00444                         avgpix.T() += (*this)[i].T();
00445                         stdpix.T() += (*this)[i].T() * (*this)[i].T();
00446                         if ((*this)[i].T() < minpix.T()) minpix.T() = (*this)[i].T();
00447                         if ((*this)[i].T() > maxpix.T()) maxpix.T() = (*this)[i].T();
00448 
00449                         avgpix.Nobs() += (*this)[i].Nobs();
00450                         stdpix.Nobs() += (*this)[i].Nobs() * (*this)[i].Nobs();
00451                         if ((*this)[i].Nobs() < minpix.Nobs()) minpix.Nobs() = (*this)[i].Nobs();
00452                         if ((*this)[i].Nobs() > maxpix.Nobs()) maxpix.Nobs() = (*this)[i].Nobs();
00453                         break;
00454                   case TPnobsPix:
00455                         avgpix.Nobs() += (*this)[i].Nobs();
00456                         stdpix.Nobs() += (*this)[i].Nobs() * (*this)[i].Nobs();
00457                         if ((*this)[i].Nobs() < minpix.Nobs()) minpix.Nobs() = (*this)[i].Nobs();
00458                         if ((*this)[i].Nobs() > maxpix.Nobs()) maxpix.Nobs() = (*this)[i].Nobs();
00459                   case PPix:
00460                         avgpix.Q() += (*this)[i].Q();
00461                         stdpix.Q() += (*this)[i].Q() * (*this)[i].Q();
00462                         if ((*this)[i].Q() < minpix.Q()) minpix.Q() = (*this)[i].Q();
00463                         if ((*this)[i].Q() > maxpix.Q()) maxpix.Q() = (*this)[i].Q();
00464 
00465                         avgpix.U() += (*this)[i].U();
00466                         stdpix.U() += (*this)[i].U() * (*this)[i].U();
00467                         if ((*this)[i].U() < minpix.U()) minpix.U() = (*this)[i].U();
00468                         if ((*this)[i].U() > maxpix.U()) maxpix.U() = (*this)[i].U();
00469 
00470                         avgpix.Pmag() += (*this)[i].Pmag();
00471                         stdpix.Pmag() += (*this)[i].Pmag() * (*this)[i].Pmag();
00472                         if ((*this)[i].Pmag() < minpix.Pmag()) minpix.Pmag() = (*this)[i].Pmag();
00473                         if ((*this)[i].Pmag() > maxpix.Pmag()) maxpix.Pmag() = (*this)[i].Pmag();
00474 
00475                         avgpix.Pang() += (*this)[i].Pang();
00476                         stdpix.Pang() += (*this)[i].Pang() * (*this)[i].Pang();
00477                         if ((*this)[i].Pang() < minpix.Pang()) minpix.Pang() = (*this)[i].Pang();
00478                         if ((*this)[i].Pang() > maxpix.Pang()) maxpix.Pang() = (*this)[i].Pang();
00479                   case TPix:
00480                         avgpix.T() += (*this)[i].T();
00481                         stdpix.T() += (*this)[i].T() * (*this)[i].T();
00482                         if ((*this)[i].T() < minpix.T()) minpix.T() = (*this)[i].T();
00483                         if ((*this)[i].T() > maxpix.T()) maxpix.T() = (*this)[i].T();
00484                         break;
00485                   default:
00486                         throw MapException(MapException::InvalidType);
00487                 }
00488         }
00489 /*
00490                         Compute means and standard deviations.
00491 */
00492         dn  = double(size());
00493         dns = dn * (dn - 1.0);
00494         switch (type())
00495         {
00496           case TnobsPix:
00497                 stdpix.T() = sqrt(((dn * stdpix.T()) - (avgpix.T() * avgpix.T())) / dns);
00498                 avgpix.T() /= dn;
00499 
00500                 stdpix.Nobs() = sqrt(((dn * stdpix.Nobs()) - (avgpix.Nobs() * avgpix.Nobs())) / dns);
00501                 avgpix.Nobs() /= dn;
00502                 break;
00503           case TPnobsPix:
00504                 stdpix.Nobs() = sqrt(((dn * stdpix.Nobs()) - (avgpix.Nobs() * avgpix.Nobs())) / dns);
00505                 avgpix.Nobs() /= dn;
00506           case PPix:
00507                 stdpix.Q() = sqrt(((dn * stdpix.Q()) - (avgpix.Q() * avgpix.Q())) / dns);
00508                 avgpix.Q() /= dn;
00509 
00510                 stdpix.U() = sqrt(((dn * stdpix.U()) - (avgpix.U() * avgpix.U())) / dns);
00511                 avgpix.U() /= dn;
00512 
00513                 stdpix.Pmag() = sqrt(((dn * stdpix.Pmag()) - (avgpix.Pmag() * avgpix.Pmag())) / dns);
00514                 avgpix.Pmag() /= dn;
00515 
00516                 stdpix.Pang() = sqrt(((dn * stdpix.Pang()) - (avgpix.Pang() * avgpix.Pang())) / dns);
00517                 avgpix.Pang() /= dn;
00518           case TPix:
00519                 stdpix.T() = sqrt(((dn * stdpix.T()) - (avgpix.T() * avgpix.T())) / dns);
00520                 avgpix.T() /= dn;
00521                 break;
00522           default:
00523                 throw MapException(MapException::InvalidType);
00524         }
00525         return;
00526 }
00527 /* ----------------------------------------------------------------------------
00528 'readFITS' fills the map from a FITS file. An exception is thrown in the event
00529 of a FITS error or if the appropriate FITS table cannot be found.  There must
00530 be a temperature column!
00531 
00532 Once the map has been read, 'calcStats' is called to compute its statistics.
00533 
00534 Arguments:
00535         filename - The name of the FITS file.  It may be supplied as a char* string,
00536                    string, or QString.
00537         progwin  - A pointer to the file load progress window.
00538 
00539 Returned:
00540         Nothing.
00541 ---------------------------------------------------------------------------- */
00542 #ifdef NONE
00543 void Skymap::readFITS(const char* filename, fileProgress *progwin)
00544 {
00545         fitsfile *fptr;
00546         int      status = 0, icol = 0, qcol = 0, ucol = 0, ncol = 0, scol = 0;
00547         int      i, t, hducnt, hdutype, naxis;
00548         long     numrow, numcol, numpix, naxes[2];
00549         Type     maptyp;
00550         float    *tmp = NULL, nul = -999.;
00551 /*
00552                         Initialize.
00553 */
00554         clear();                // Empty the map.
00555         if (progwin != NULL) progwin->loadFile(filename);
00556 /*
00557                         Try to open and prepare the FITS file for reading.  Find the
00558                         HDU that contains a valid skymap.  Read the headers for 
00559                         interesting information.
00560 */
00561         fits_open_file(&fptr, filename, READONLY, &status);
00562         fits_get_num_hdus(fptr, &hducnt, &status);
00563         if ((status != 0) || (hducnt <= 1))
00564                 throw MapException(MapException::FITSError, status);
00565 
00566         readFITSPrimaryHeader(fptr);
00567 
00568         for (i = 1; ((i <= hducnt) && (icol == 0)); i++)
00569         {
00570                 status = 0;
00571                 if (fits_movabs_hdu(fptr, 2, &hdutype, &status) != 0)
00572                         throw MapException(MapException::FITSError, status);
00573                 if (hdutype != BINARY_TBL) continue;
00574                 fits_get_colnum(fptr, CASEINSEN, ICOLNAME, &t, &status);
00575                 if (status != 0) continue;
00576                 icol = t;
00577         }
00578         if (icol == 0) throw MapException(MapException::InvalidType);
00579 
00580         readFITSExtensionHeader(fptr);
00581 /*
00582                         Determine the size of the map.
00583 */
00584         fits_read_tdim(fptr, icol, 2, &naxis, naxes, &status);
00585         if (status != 0) throw MapException(MapException::FITSError, status);
00586         if (naxis > 1)
00587         {
00588                 numrow = naxes[1];
00589                 numcol = naxes[0];
00590                 numpix = naxes[1] * naxes[0];
00591         }
00592         else
00593         {
00594                 fits_get_num_rows(fptr, &numrow, &status);
00595                 if (status != 0) throw MapException(MapException::FITSError, status);
00596                 numcol = 1;
00597                 numpix = numrow;
00598         }
00599 /*
00600                         Identify the map.  Both Q and U must be supplied for polarization
00601                         data to be stored.  Allocate space.
00602 */
00603         if (fits_get_colnum(fptr, CASEINSEN, NCOLNAME, &t, &status) == 0) ncol = t;
00604 
00605         if (fits_get_colnum(fptr, CASEINSEN, QCOLNAME, &t, &status) == 0) qcol = t;
00606         if ((qcol == 0) && (fits_get_colnum(fptr, CASEINSEN, QCOLNAMEA, &t, &status) == 0)) qcol = t;
00607         if ((qcol == 0) && (fits_get_colnum(fptr, CASEINSEN, QCOLNAMEB, &t, &status) == 0)) qcol = t;
00608         if ((qcol == 0) && (fits_get_colnum(fptr, CASEINSEN, QCOLNAMEC, &t, &status) == 0)) qcol = t;
00609 
00610         if (fits_get_colnum(fptr, CASEINSEN, UCOLNAME, &t, &status) == 0) ucol = t;
00611         if ((ucol == 0) && (fits_get_colnum(fptr, CASEINSEN, UCOLNAMEA, &t, &status) == 0)) ucol = t;
00612         if ((ucol == 0) && (fits_get_colnum(fptr, CASEINSEN, UCOLNAMEB, &t, &status) == 0)) ucol = t;
00613         if ((ucol == 0) && (fits_get_colnum(fptr, CASEINSEN, UCOLNAMEC, &t, &status) == 0)) ucol = t;
00614 
00615         if ((qcol == 0) || (ucol == 0)) qcol = ucol = scol = 0;
00616 
00617         if      ((ncol != 0) && (qcol != 0))                            maptyp = TPnobsPix;
00618         else if  (qcol != 0)                                            maptyp = PPix;
00619         else if  (ncol != 0)                                            maptyp = TnobsPix;
00620         else                                                            maptyp = TPix;
00621         allocPixMemory(numpix, maptyp);
00622         status = 0;
00623 /*
00624                         Fill the columns.
00625 */
00626         if ((tmp = new float[numpix]) == NULL) throw MapException(MapException::Memory);
00627 /*
00628                                 Stokes I/temperature.
00629 */
00630         if (icol != 0)
00631         {
00632                 if (progwin != NULL) progwin->loadTemperature();
00633                 if (fits_read_col(fptr, TFLOAT, icol, 1, 1, numpix, &nul, tmp, &t, &status) != 0)
00634                         throw MapException(MapException::FITSError, status);
00635                 for (i = 0; i < numpix; i++) (*this)[i].T() = tmp[i];
00636         }
00637 /*
00638                                 Stokes Q.
00639 */
00640         if (qcol != 0)
00641         {
00642                 if (progwin != NULL) progwin->loadQPolarization();
00643                 if (fits_read_col(fptr, TFLOAT, qcol, 1, 1, numpix, &nul, tmp, &t, &status) != 0)
00644                         throw MapException(MapException::FITSError, status);
00645                 for (i = 0; i < numpix; i++) (*this)[i].Q() = tmp[i];
00646         }
00647 /*
00648                                 Stokes U.
00649 */
00650         if (ucol != 0)
00651         {
00652                 if (progwin != NULL) progwin->loadUPolarization();
00653                 if (fits_read_col(fptr, TFLOAT, ucol, 1, 1, numpix, &nul, tmp, &t, &status) != 0)
00654                         throw MapException(MapException::FITSError, status);
00655                 for (i = 0; i < numpix; i++) (*this)[i].U() = tmp[i];
00656         }
00657 /*
00658                                 N_Obs.
00659 */
00660         if (ncol != 0)
00661         {
00662                 if (progwin != NULL) progwin->loadNumObs();
00663                 if (fits_read_col(fptr, TFLOAT, ncol, 1, 1, numpix, &nul, tmp, &t, &status) != 0)
00664                         throw MapException(MapException::FITSError, status);
00665                 for (i = 0; i < numpix; i++) (*this)[i].Nobs() = tmp[i];
00666         }
00667 /*
00668                         Done!  Close the file and compute statistics.
00669 */
00670         fits_close_file(fptr, &status);
00671         if (tmp != NULL) delete [] tmp;
00672         if ((qcol != 0) && (ucol != 0) && (progwin != NULL)) progwin->loadPPolarization();
00673         computePolar();
00674         calcStats();
00675         if (progwin != NULL) progwin->finished(this);
00676         return;
00677 }
00678 void Skymap::readFITS(string filename, fileProgress *progwin)
00679 {
00680         readFITS(filename.c_str(), progwin);
00681 }
00682 void Skymap::readFITS(QString filename, fileProgress *progwin)
00683 {
00684         readFITS(filename.toStdString(), progwin);
00685 }
00686 #endif
00687 /* ----------------------------------------------------------------------------
00688 'writeFITS' writes the map to a FITS file. An exception is thrown in the event
00689 of a FITS error.
00690 
00691 Arguments:
00692         filename - The name of the FITS file.  It may be supplied as a char* string,
00693                    string, or QString.
00694         tabname  - The name to assign the binary FITS table.  Defaults to NULL,
00695                    which corresponds to DEFTABLE.
00696 
00697 Returned:
00698         Nothing.
00699 ---------------------------------------------------------------------------- */
00700 void Skymap::writeFITS(const char* filename, char* tabname)
00701 {
00702         char        *ttype[maxcols], *tform[maxcols], *tunit[maxcols];
00703         fitsfile    *fptr;
00704         int          status = 0;
00705         int          ncol, col;
00706         unsigned int i;
00707         float       *tmp = NULL;
00708 /*
00709                         Initialize.
00710 */
00711         if (strlen(tabname) <= 0) tabname = NULL;
00712         if (tabname == NULL) tabname = DEFTABLE;
00713         ncol = 0;
00714         ttype[ncol] = ICOLNAME; tform[ncol] = DEFFORM; tunit[ncol++] = DEFTUNIT;
00715         if ((type() == PPix) || (type() == TPnobsPix))
00716         {
00717                 ttype[ncol] = QCOLNAME; tform[ncol] = DEFFORM; tunit[ncol++] = DEFTUNIT;
00718                 ttype[ncol] = UCOLNAME; tform[ncol] = DEFFORM; tunit[ncol++] = DEFTUNIT;
00719         }
00720         if ((type() == TnobsPix) || (type() == TPnobsPix))
00721         {
00722                 ttype[ncol] = NCOLNAME; tform[ncol] = DEFFORM; tunit[ncol++] = DEFNUNIT;
00723         }
00724 /*
00725                         Try to open and prepare the FITS file for writing.
00726 
00727                                 Try to create a new file.  If it exists, simply open it.  In either
00728                                 case, write additions to the primary header.
00729 */
00730         if (fits_create_file(&fptr, filename, &status) == 0)
00731         {
00732                 fits_create_img(fptr, SHORT_IMG, 0, NULL, &status); // Create an empty primary HDU.
00733         }
00734         else
00735         {
00736                 status = 0;
00737                 fits_open_file(&fptr, filename, READWRITE, &status);
00738         }
00739         if (status != 0) throw MapException(MapException::FITSError, status);
00740         writeFITSPrimaryHeader(fptr);
00741 /*
00742                                 Search the file for named table.  If found, remove it.
00743                                 Create a new binary table HDU and extend its header.
00744 */
00745         fits_movnam_hdu(fptr, BINARY_TBL, tabname, 0, &status);
00746         if ((status != 0) && (status != BAD_HDU_NUM)) throw MapException(MapException::FITSError, status);
00747         if (status == 0)
00748         {
00749                 fits_delete_hdu(fptr, NULL, &status);
00750                 if (status != 0) throw MapException(MapException::FITSError, status);
00751         }
00752         status = 0;
00753         if (fits_create_tbl(fptr, BINARY_TBL, 0, ncol, ttype, tform, tunit, tabname, &status) != 0)
00754                 throw MapException(MapException::FITSError, status);
00755         writeFITSExtensionHeader(fptr);
00756 /*
00757                         Fill the columns.
00758 */
00759         if ((tmp = new float[size()]) == NULL) throw MapException(MapException::Memory);
00760     col = 0;
00761 /*
00762                                 Stokes I/temperature.
00763 */
00764     col++;
00765         for (i = 0; i < size(); i++)
00766         {
00767                 tmp[i] = (*this)[i].T();
00768         }
00769         if (fits_write_col(fptr, TFLOAT, col, 1, 1, size(), tmp, &status) != 0)
00770                 throw MapException(MapException::FITSError, status);
00771 /*
00772                                 Stokes Q.
00773 */
00774         if ((type() == PPix) || (type() == TPnobsPix))
00775         {
00776                 col++;
00777                 for (i = 0; i < size(); i++)
00778                 {
00779                         tmp[i] = (*this)[i].Q();
00780                 }
00781                 if (fits_write_col(fptr, TFLOAT, col, 1, 1, size(), tmp, &status) != 0)
00782                         throw MapException(MapException::FITSError, status);
00783 /*
00784                                 Stokes U.
00785 */
00786                 col++;
00787                 for (i = 0; i < size(); i++)
00788                 {
00789                         tmp[i] = (*this)[i].U();
00790                 }
00791                 if (fits_write_col(fptr, TFLOAT, col, 1, 1, size(), tmp, &status) != 0)
00792                         throw MapException(MapException::FITSError, status);
00793         }
00794 /*
00795                                 N_Obs.
00796 */
00797         if ((type() == TnobsPix) || (type() == TPnobsPix))
00798         {
00799                 col++;
00800                 for (i = 0; i < size(); i++)
00801                 {
00802                         tmp[i] = (*this)[i].Nobs();
00803                 }
00804                 if (fits_write_col(fptr, TFLOAT, col, 1, 1, size(), tmp, &status) != 0)
00805                         throw MapException(MapException::FITSError, status);
00806         }
00807 /*
00808                         Done!
00809 */
00810         fits_close_file(fptr, &status);
00811         if (tmp != NULL) delete [] tmp;
00812         return;
00813 }
00814 void Skymap::writeFITS(string filename, char* tabname)
00815 {
00816   writeFITS(filename.c_str(), tabname);
00817 }
00818 void Skymap::writeFITS(QString filename, char* tabname)
00819 {
00820   writeFITS(filename.toStdString(), tabname);
00821 }
00822 /* ----------------------------------------------------------------------------
00823 'readFITS' fills the map from a FITS file. An exception is thrown in the event
00824 of a FITS error or if the appropriate FITS table cannot be found.  There must
00825 be a temperature column!
00826 
00827 Once the map has been read, 'calcStats' is called to compute its statistics.
00828 
00829 Arguments:
00830         filename - The name of the FITS file.  It may be supplied as a char* string,
00831                    string, or QString.
00832         progwin  - A pointer to the file load progress window.
00833 
00834 Returned:
00835         Nothing.
00836 ---------------------------------------------------------------------------- */
00837 void Skymap::readFITS(const char* filename, ControlDialog *progwin)
00838 {
00839         fitsfile *fptr;
00840         int      status = 0, icol = 0, qcol = 0, ucol = 0, ncol = 0, scol = 0;
00841         int      i, t, hducnt, hdutype, naxis;
00842         long     numrow, numcol, numpix, naxes[2];
00843         Type     maptyp;
00844         float    *tmp = NULL, nul = -999.;
00845 /*
00846                         Initialize.
00847 */
00848         clear();                // Empty the map.
00849         if (progwin != NULL) progwin->loadFile(filename);
00850 /*
00851                         Try to open and prepare the FITS file for reading.  Find the
00852                         HDU that contains a valid skymap.  Read the headers for 
00853                         interesting information.
00854 */
00855         fits_open_file(&fptr, filename, READONLY, &status);
00856         fits_get_num_hdus(fptr, &hducnt, &status);
00857         if ((status != 0) || (hducnt <= 1))
00858                 throw MapException(MapException::FITSError, status);
00859 
00860         readFITSPrimaryHeader(fptr);
00861 
00862         for (i = 1; ((i <= hducnt) && (icol == 0)); i++)
00863         {
00864                 status = 0;
00865                 if (fits_movabs_hdu(fptr, 2, &hdutype, &status) != 0)
00866                         throw MapException(MapException::FITSError, status);
00867                 if (hdutype != BINARY_TBL) continue;
00868                 fits_get_colnum(fptr, CASEINSEN, ICOLNAME, &t, &status);
00869                 if (status != 0) continue;
00870                 icol = t;
00871         }
00872         if (icol == 0) throw MapException(MapException::InvalidType);
00873 
00874         readFITSExtensionHeader(fptr);
00875 /*
00876                         Determine the size of the map.
00877 */
00878         fits_read_tdim(fptr, icol, 2, &naxis, naxes, &status);
00879         fits_get_num_rows(fptr, &numrow, &status);
00880         if (status != 0) throw MapException(MapException::FITSError, status);
00881         numcol = (naxes[0] > 1) ? naxes[0] : 1;
00882         numpix = numcol * numrow;
00883 /*
00884                         Identify the map.  Both Q and U must be supplied for polarization
00885                         data to be stored.  Allocate space.
00886 */
00887         if (fits_get_colnum(fptr, CASEINSEN, NCOLNAME, &t, &status) == 0) ncol = t;
00888 
00889         if (fits_get_colnum(fptr, CASEINSEN, QCOLNAME, &t, &status) == 0) qcol = t;
00890         if ((qcol == 0) && (fits_get_colnum(fptr, CASEINSEN, QCOLNAMEA, &t, &status) == 0)) qcol = t;
00891         if ((qcol == 0) && (fits_get_colnum(fptr, CASEINSEN, QCOLNAMEB, &t, &status) == 0)) qcol = t;
00892         if ((qcol == 0) && (fits_get_colnum(fptr, CASEINSEN, QCOLNAMEC, &t, &status) == 0)) qcol = t;
00893 
00894         if (fits_get_colnum(fptr, CASEINSEN, UCOLNAME, &t, &status) == 0) ucol = t;
00895         if ((ucol == 0) && (fits_get_colnum(fptr, CASEINSEN, UCOLNAMEA, &t, &status) == 0)) ucol = t;
00896         if ((ucol == 0) && (fits_get_colnum(fptr, CASEINSEN, UCOLNAMEB, &t, &status) == 0)) ucol = t;
00897         if ((ucol == 0) && (fits_get_colnum(fptr, CASEINSEN, UCOLNAMEC, &t, &status) == 0)) ucol = t;
00898 
00899         if ((qcol == 0) || (ucol == 0)) qcol = ucol = scol = 0;
00900 
00901         if      ((ncol != 0) && (qcol != 0))                            maptyp = TPnobsPix;
00902         else if  (qcol != 0)                                            maptyp = PPix;
00903         else if  (ncol != 0)                                            maptyp = TnobsPix;
00904         else                                                            maptyp = TPix;
00905         allocPixMemory(numpix, maptyp);
00906         status = 0;
00907 
00908         // Let the progwin know what fields we have
00909         if( progwin != NULL ) {
00910                 progwin->hasField(I, icol != 0 );
00911                 progwin->hasField(Q, qcol != 0 );
00912                 progwin->hasField(U, ucol != 0 );
00913                 progwin->hasField(P, (ucol != 0) || (qcol != 0) );
00914                 progwin->hasField(Nobs, ncol != 0 );
00915         }
00916 /*
00917                         Fill the columns.
00918 */
00919         if ((tmp = new float[numpix]) == NULL) throw MapException(MapException::Memory);
00920 /*
00921                                 Stokes I/temperature.
00922 */
00923         if (icol != 0)
00924         {
00925                 if (progwin != NULL) progwin->loadField(I);
00926                 if (fits_read_col(fptr, TFLOAT, icol, 1, 1, numpix, &nul, tmp, &t, &status) != 0)
00927                         throw MapException(MapException::FITSError, status);
00928                 for (i = 0; i < numpix; i++) (*this)[i].T() = tmp[i];
00929         }
00930 /*
00931                                 Stokes Q.
00932 */
00933         if (qcol != 0)
00934         {
00935                 if (progwin != NULL) progwin->loadField(Q);
00936                 if (fits_read_col(fptr, TFLOAT, qcol, 1, 1, numpix, &nul, tmp, &t, &status) != 0)
00937                         throw MapException(MapException::FITSError, status);
00938                 for (i = 0; i < numpix; i++) (*this)[i].Q() = tmp[i];
00939         }
00940 /*
00941                                 Stokes U.
00942 */
00943         if (ucol != 0)
00944         {
00945                 if (progwin != NULL) progwin->loadField(U);
00946                 if (fits_read_col(fptr, TFLOAT, ucol, 1, 1, numpix, &nul, tmp, &t, &status) != 0)
00947                         throw MapException(MapException::FITSError, status);
00948                 for (i = 0; i < numpix; i++) (*this)[i].U() = tmp[i];
00949         }
00950 /*
00951                                 N_Obs.
00952 */
00953         if (ncol != 0)
00954         {
00955                 if (progwin != NULL) progwin->loadField( Nobs );
00956                 if (fits_read_col(fptr, TFLOAT, ncol, 1, 1, numpix, &nul, tmp, &t, &status) != 0)
00957                         throw MapException(MapException::FITSError, status);
00958                 for (i = 0; i < numpix; i++) (*this)[i].Nobs() = tmp[i];
00959         }
00960 /*
00961                         Done!  Close the file and compute statistics.
00962 */
00963         fits_close_file(fptr, &status);
00964         if (tmp != NULL) delete [] tmp;
00965         if ((qcol != 0) && (ucol != 0) && (progwin != NULL)) progwin->loadField(P);
00966         computePolar();
00967         calcStats();
00968         if (progwin != NULL) progwin->finished(this);
00969         return;
00970 }
00971 void Skymap::readFITS(string filename, ControlDialog *progwin)
00972 {
00973         readFITS(filename.c_str(), progwin);
00974 }
00975 void Skymap::readFITS(QString filename, ControlDialog *progwin)
00976 {
00977         readFITS(filename.toStdString(), progwin);
00978 }

Generated on Fri Feb 6 15:32:42 2009 for Skyviewer by  doxygen 1.4.7