M3_format_LevelS.c

00001 /*******************************************************************************
00002 *   M3:  M3_format_LevelS.c                                                    *
00003 *                                                                              *
00004 *   Version 2.0 April 2007                                                     *
00005 *                                                                              *
00006 *   Copyright (C) 2004  C.M. Cantalupo                                         *
00007 *                                                                              *
00008 *   This program is free software; you can redistribute it and/or modify       *
00009 *   it under the terms of the GNU General Public License as published by       *
00010 *   the Free Software Foundation; either version 2 of the License, or          *
00011 *   (at your option) any later version.                                        *
00012 *                                                                              *
00013 *   This program is distributed in the hope that it will be useful,            *
00014 *   but WITHOUT ANY WARRANTY; without even the implied warranty of             *
00015 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
00016 *   GNU General Public License for more details.                               *
00017 *                                                                              *
00018 *   You should have received a copy of the GNU General Public License          *
00019 *   along with this program; if not, write to the Free Software                *
00020 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  *
00021 *                                                                              *
00022 *******************************************************************************/
00023 
00024 #include "M3.h"
00025 #include "M3_internal.h"
00026 #include "M3_gcp.h"
00027 #include "M3_system.h"
00028 #include "M3_format_LevelS.h"
00029 #include "fitsio.h"
00030 #include "fftw3.h"
00031 #include <ctype.h>
00032 #include <stdlib.h>
00033 #include <stdio.h>
00034 #include <time.h>
00035 
00036 #include "chealpix.h"
00037 #include "rotateCoords.h"
00038 
00039 #define M3_CONTENT_LENGTH 256
00040 #define M3_NOISE_GEN_CORRFACTOR 8
00041 #define M3_NOISE_GEN_MINIMUM 32768
00042 
00043 void M3_File_parseFormatString_LevelS( M3_File *theFile, M3_FormatStruct_LevelS *out )
00044 {
00045   /* Converts the format string from theFile into the format structure including setting default values. */
00046 
00047   char *s1, *s2;
00048   char errorString[M3_CONTENT_LENGTH];
00049   char errorString2[M3_CONTENT_LENGTH];
00050   int n;
00051   static char lastFormatString[M3_CONTENT_LENGTH] = {0};
00052   static M3_FormatStruct_LevelS lastFormatStruct;
00053 
00054   /* Build in a last call cache, as we will often be parsing the same format strings over and over again.  */
00055   if( strcmp( theFile->format, lastFormatString ) == 0 )
00056   {
00057     *out = lastFormatStruct;
00058     return;
00059   }
00060 
00061   /* Set the default values.  */
00062   out->template = 0;
00063   out->pixelType = M3_DEFAULT_PIXEL_TYPE;
00064   out->psiPol = 0;
00065   out->rotateDirection[0] = '\0';
00066   out->pixelScheme = 'r';
00067   strcpy( out->rotateEquinox, "J2000");
00068   out->simmission2006 = 0;
00069   out->header2007 = 0;
00070   out->numPeriod = 0;
00071   out->detectorID[0] = '\0';
00072   if( theFile->fileType == M3_TOD_FILE_TYPE )
00073     out->firstSample = INT64_MAX;
00074   else
00075     out->firstSample = 0;
00076   out->lastSample = INT64_MAX;
00077   out->corLength = 65536;
00078   out->nside = 0;
00079   out->spinAxis = '\0';
00080   out->LFI = 0;
00081 
00082   /* LevelS_pixelType=I_nside=256_pixelScheme=ring_psiPol=0_template_rotateDirection=radec2gal_rotateEquinox=J2000_simmission2006_numPeriod=61_header2007*/
00083 
00084   /* Set error string.  */
00085   sprintf( errorString, "Error interpreting format string: \"%s\"", theFile->format );
00086 
00087   /* Advance to the first parameter */
00088   s1 = strchr( theFile->format, '_');
00089 
00090   /* Loop over the paramters in the format string */
00091   while( s1 )
00092   {
00093     /* Skip '_' character */
00094     s1++;
00095 
00096     /* Switch over all of the parameters */
00097     if( strncmp( s1, "pixelType", 9 ) == 0 )
00098     {
00099       s1 += 9;
00100       M3_ErrorCheck( -1, errorString, *s1 == '=', M3_EFLAG_DEFAULT );
00101       s1++;
00102       if( strncmp( s1, "I", 1 ) == 0 )
00103         out->pixelType = M3_CMB_I_PIXEL_TYPE;
00104       else if( strncmp( s1, "Q", 1 ) == 0 )
00105         out->pixelType = M3_CMB_Q_PIXEL_TYPE;
00106       else if( strncmp( s1, "U", 1 ) == 0 )
00107         out->pixelType = M3_CMB_U_PIXEL_TYPE;
00108       else 
00109         out->pixelType = M3_DEFAULT_PIXEL_TYPE;      
00110     }
00111     else if( strncmp( s1, "nside", 5) == 0 )
00112     {
00113       s1 += 5;
00114       M3_ErrorCheck( -1, errorString, *s1 == '=', M3_EFLAG_DEFAULT );
00115       s1++;
00116       out->nside = atoi( s1 );
00117     }
00118     else if( strncmp( s1, "pixelScheme", 11 ) == 0 )
00119     {
00120       s1 += 11;
00121       M3_ErrorCheck( -1, errorString, *s1 == '=', M3_EFLAG_DEFAULT );
00122       s1++;
00123       if( strncmp( s1, "ring", 4) == 0 )
00124         out->pixelScheme = 'r';
00125       else if( strncmp( s1, "nest", 4) == 0 )
00126         out->pixelScheme = 'n';
00127       else
00128         M3_ErrorCheck( -1, errorString, 0, M3_EFLAG_DEFAULT );
00129     }
00130     else if( strncmp( s1, "psiPol", 6) == 0 )
00131     {
00132       s1 += 6;
00133       M3_ErrorCheck( -1, errorString, *s1 == '=', M3_EFLAG_DEFAULT );
00134       s1++;
00135       out->psiPol = atof(s1);
00136     }
00137     else if( strncmp( s1, "template", 8) == 0 )
00138     {
00139       out->template = 1;
00140     }
00141     else if( strncmp( s1, "rotateDirection", 15 ) == 0 )
00142     {
00143       s1 += 15;
00144       M3_ErrorCheck( -1, errorString, *s1 == '=', M3_EFLAG_DEFAULT );
00145       s1++;
00146       s2 = strchr( s1, '_');
00147       if( s2 == NULL )
00148         n = strlen(s1);
00149       else
00150         n = (size_t)(s2)-(size_t)(s1);
00151 
00152       sprintf( errorString2, "Error interpreting format string: \"%s\" rotateDirection too long", theFile->format ); 
00153       M3_ErrorCheck( -1, errorString2, n < 128, M3_EFLAG_DEFAULT );
00154 
00155       strncpy( out->rotateDirection, s1, n);
00156       out->rotateDirection[n] = '\0';
00157     }
00158     else if( strncmp( s1, "rotateEquinox", 13 ) == 0 )
00159     {
00160       s1 += 13;
00161       M3_ErrorCheck( -1, errorString, *s1 == '=', M3_EFLAG_DEFAULT );
00162       s1++;
00163       s2 = strchr( s1, '_');
00164       if( s2 == NULL )
00165         n = strlen(s1);
00166       else
00167         n = (size_t)(s2)-(size_t)(s1);
00168       
00169       sprintf( errorString2, "Error interpreting format string: \"%s\" rotateEquinox too long", theFile->format ); 
00170       M3_ErrorCheck( -1, errorString2, n < 128, M3_EFLAG_DEFAULT );
00171 
00172       strncpy( out->rotateEquinox, s1, n);
00173       out->rotateEquinox[n] = '\0';
00174     }
00175     else if( strncmp( s1, "simmission2006", 14 ) == 0 )
00176     {
00177       out->simmission2006 = 1;
00178     }
00179     else if( strncmp( s1, "numPeriod", 9 ) == 0 )
00180     {
00181       s1 += 9;
00182       M3_ErrorCheck( -1, errorString, *s1 == '=', M3_EFLAG_DEFAULT );
00183       s1++;
00184       out->numPeriod = atoi(s1);
00185     }
00186     else if( strncmp( s1, "header2007", 10 ) == 0 )
00187     {
00188       out->header2007 = 1;
00189     }
00190     else if( strncmp( s1, "firstSample", 11 ) == 0 )
00191     {
00192       s1 += 11;
00193       M3_ErrorCheck( -1, errorString, *s1 == '=', M3_EFLAG_DEFAULT);
00194       s1++;
00195       out->firstSample = strtoll(s1, NULL, 10 );
00196     }
00197     else if( strncmp( s1, "lastSample", 10 ) == 0 )
00198     {
00199       s1 += 10;
00200       M3_ErrorCheck( -1, errorString, *s1 == '=', M3_EFLAG_DEFAULT);
00201       s1++;
00202       out->lastSample = strtoll(s1, NULL, 10 );
00203     }
00204     else if( strncmp( s1, "corLength", 9 ) == 0 )
00205     {
00206       s1 += 9;
00207       M3_ErrorCheck( -1, errorString, *s1 == '=', M3_EFLAG_DEFAULT);
00208       s1++;
00209       out->corLength = strtoll(s1, NULL, 10 );
00210     }
00211     else if( strncmp( s1, "detectorID", 10 ) == 0 )
00212     {
00213       s1 += 10;
00214       M3_ErrorCheck(-1, errorString, *s1 == '=', M3_EFLAG_DEFAULT);
00215       s1++;
00216       s2 = strchr( s1, '_');
00217       if( s2 == NULL )
00218         n = strlen(s1);
00219       else
00220         n = (size_t)(s2)-(size_t)(s1);
00221       sprintf( errorString2, "Error interpreting format string: \"%s\" detectorID too long", theFile->format ); 
00222       M3_ErrorCheck( -1, errorString2, n < 128, M3_EFLAG_DEFAULT );
00223       strncpy( out->detectorID, s1, n);
00224       out->detectorID[n] = '\0';
00225     }
00226     else if( strncmp( s1, "detID", 5 ) == 0 )
00227     {
00228       s1 += 5;
00229       M3_ErrorCheck(-1, errorString, *s1 == '=', M3_EFLAG_DEFAULT);
00230       s1++;
00231       s2 = strchr( s1, '_');
00232       if( s2 == NULL )
00233         n = strlen(s1);
00234       else
00235         n = (size_t)(s2)-(size_t)(s1);
00236       sprintf( errorString2, "Error interpreting format string: \"%s\" detectorID too long", theFile->format ); 
00237       M3_ErrorCheck( -1, errorString2, n < 128, M3_EFLAG_DEFAULT );
00238       strncpy( out->detectorID, s1, n);
00239       out->detectorID[n] = '\0';
00240     }
00241     else if( strncmp( s1, "spinAxis", 8 ) == 0 )
00242     {
00243       s1 += 8;
00244       M3_ErrorCheck( -1, errorString, *s1 == '=', M3_EFLAG_DEFAULT );
00245       s1++;
00246       if( *s1 == 'x' || *s1 == 'X' )
00247         out->spinAxis = 'x';
00248       if( *s1 == 'z' || *s1 == 'Z' )
00249         out->spinAxis = 'z';
00250     }
00251     else if( strncmp( s1, "LFI", 3 ) == 0 )
00252     {
00253       out->LFI = 1;
00254     }
00255 
00256     s1 = strchr( s1, '_');
00257   }
00258   
00259   /* Set last call cache */
00260   strcpy( lastFormatString, theFile->format );
00261   lastFormatStruct = *out;
00262 }
00263 
00264 
00265 
00266 
00267 
00268 void M3_File_readHeader_LevelS( M3_File *theFile, void *data )
00269 {
00270   /* Simple switch over sub-functions for each file type */
00271   switch( theFile->fileType )
00272   {
00273     case M3_TOD_FILE_TYPE:
00274       M3_File_readHeader_LevelS_tod( theFile, (M3_TODheader *)data );
00275       break;
00276     case M3_POINTING_FILE_TYPE:
00277       M3_File_readHeader_LevelS_pointing( theFile, (M3_PointingHeader *)data );
00278       break;
00279     case M3_GCPOINTING_FILE_TYPE:
00280       M3_File_readHeader_LevelS_gcpointing( theFile, (M3_GCPointingHeader *)data );
00281       break;
00282     case M3_AUX_FILE_TYPE:
00283       M3_File_readHeader_LevelS_aux( theFile, (M3_AuxHeader *)data );
00284       break;
00285     case M3_NOISE_FILE_TYPE:
00286       M3_File_readHeader_LevelS_noise( theFile, (M3_NoiseHeader *)data );
00287       break;
00288     default:
00289       M3_ErrorCheck(-1, "M3 can only read LevelS files for tod, pointing, gcpointing, and aux file types", 0, M3_EFLAG_DEFAULT );
00290       break;
00291   }
00292 }
00293 
00294 
00295 void M3_File_readData_LevelS( M3_File *theFile, void *readArg, void *data )
00296 {
00297   /* Simple switch over sub-functions for each file type */
00298   switch( theFile->fileType )
00299   {
00300     case M3_TOD_FILE_TYPE:
00301       M3_File_readData_LevelS_tod( theFile, (M3_Interval*)readArg, (double *)data );
00302       break;
00303     case M3_POINTING_FILE_TYPE:
00304       M3_File_readData_LevelS_pointing( theFile, (M3_Interval*)readArg, (M3_PointingEl *)data );
00305       break;
00306     case M3_GCPOINTING_FILE_TYPE:
00307       M3_File_readData_LevelS_gcpointing( theFile, (M3_Interval*)readArg, (double *)data );
00308       break;
00309     case M3_AUX_FILE_TYPE:
00310       M3_File_readData_LevelS_aux( theFile, (M3_planckAux *)data );
00311       break;
00312     case M3_NOISE_FILE_TYPE:
00313       M3_File_readData_LevelS_noise( theFile, (double *)data );
00314       break;
00315     default:
00316       M3_ErrorCheck(-1, "M3 can only read LevelS files for tod, pointing, gcpointing, and aux file types", 0, M3_EFLAG_DEFAULT );
00317       break;
00318   }
00319 }
00320 
00321 
00322 
00323 void M3_File_readHeader_LevelS_tod( M3_File *theFile, M3_TODheader *data )
00324 {
00325   int64_t firstPeriod, lastPeriod, samplesPerPeriod, numSample, naxis1;
00326   fitsfile *thisFitsFile;
00327   int status = 0;
00328   M3_FormatStruct_LevelS formatStruct;
00329   char *s1;
00330   char strBuffer[M3_CONTENT_LENGTH];
00331   char errorString[M3_CONTENT_LENGTH];
00332 
00333   M3_File_parseFormatString_LevelS( theFile, &formatStruct );
00334 
00335   fits_open_file( &thisFitsFile, theFile->name, READONLY, &status);
00336   M3_ErrorCheck(-1, theFile->name, status == 0, M3_EFLAG_FOPEN_READ );
00337 
00338   /* First look to see if "firstSample" was specified in format string, this over rides other derivations */  
00339   fits_movabs_hdu( thisFitsFile, 2, NULL, &status);
00340   sprintf( errorString, "Error going to second fits header in file %s", theFile->name );
00341   M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
00342   
00343   fits_read_key_str( thisFitsFile, "NAXIS2", strBuffer, NULL, &status );
00344   sprintf( errorString, "Could not read NAXIS2 flag from second header unit in 2007 style header in file %s", theFile->name );
00345   M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00346   numSample = strtoll(strBuffer, NULL, 10);
00347 
00348   if( formatStruct.firstSample != INT64_MAX )
00349   {
00350     data->firstSample = formatStruct.firstSample;
00351     data->lastSample = formatStruct.firstSample + numSample - 1;
00352 
00353     fits_close_file( thisFitsFile, &status);
00354     sprintf( errorString, "Error closing fits file named %s", theFile->name );
00355     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00356 
00357     return;
00358   }
00359 
00360   /* Next check to see if we can find "first_sample" in the second header data unit.  */
00361   fits_movabs_hdu( thisFitsFile, 2, NULL, &status);
00362   sprintf( errorString, "Error going to second fits header in file %s", theFile->name );
00363   M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
00364   fits_read_key_str(thisFitsFile, "first_sample", strBuffer, NULL, &status);
00365   if( status == 0 )
00366   {
00367     data->firstSample = strtoll(strBuffer, NULL, 10);
00368     
00369     fits_read_key_str(thisFitsFile, "last_sample", strBuffer, NULL, &status);
00370     if( status == 0 )
00371       data->lastSample = strtoll(strBuffer, NULL, 10);
00372     else
00373     {
00374       data->lastSample = data->firstSample + numSample - 1;
00375       status = 0;
00376     }
00377     fits_close_file( thisFitsFile, &status);
00378     sprintf( errorString, "Error closing fits file named %s", theFile->name );
00379     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00380 
00381     return;
00382   }
00383   status = 0;
00384 
00385   /* If we can't find out about samples, figure out pointing periods.  */
00386   if( formatStruct.header2007 )
00387   {
00388     fits_movabs_hdu( thisFitsFile, 1, NULL, &status );
00389     sprintf( errorString, "Could not go to first fits header in file %s", theFile->name );
00390     M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
00391 
00392     fits_read_key_str( thisFitsFile, "first_pointing", strBuffer, NULL, &status );
00393     sprintf( errorString, "Could not read first_pointing flag from 2007 style header in file %s", theFile->name );
00394     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00395     firstPeriod = atoi( strBuffer );
00396 
00397     fits_read_key_str( thisFitsFile, "last_pointing", strBuffer, NULL, &status );
00398     sprintf( errorString, "Could not read last_pointing flag from 2007 style header in file %s", theFile->name );
00399     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00400     lastPeriod = atoi( strBuffer );
00401 
00402     fits_movabs_hdu( thisFitsFile, 2, NULL, &status);
00403     sprintf( errorString, "Error going to second fits header in file %s", theFile->name );
00404     M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
00405 
00406     fits_read_key_str( thisFitsFile, "NAXIS2", strBuffer, NULL, &status );
00407     sprintf( errorString, "Could not read NAXIS2 flag from second header unit in 2007 style header in file %s", theFile->name );
00408     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00409     numSample = strtoll(strBuffer, NULL, 10);
00410   }
00411   else
00412   {
00413     fits_movabs_hdu( thisFitsFile, 2, NULL, &status );
00414     sprintf( errorString, "Error in skipping first fits header in file %s", theFile->name );
00415     M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
00416 
00417     fits_read_key_str( thisFitsFile, "NAXIS2", strBuffer, NULL, &status );
00418     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00419     numSample = strtoll(strBuffer, NULL, 10);
00420 
00421     /* Fix for Torsti's sorption cooler files. */
00422     fits_read_key_str(thisFitsFile, "NAXIS1", strBuffer, NULL, &status);
00423     sprintf( errorString, "Error reading NAXIS1 key from fits header of file %s", theFile->name);
00424     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00425     naxis1 = strtoll(strBuffer, NULL, 10 );
00426 
00427     if( naxis1 == 48000 )
00428       numSample *= naxis1/4;
00429     
00430     status = 0;
00431     fits_read_key_str(thisFitsFile, "FIRSTPNT", strBuffer, NULL, &status);
00432     
00433     if( status != 0 )
00434     {
00435       sprintf( errorString, "FIRSTPNT key not found, and format string does not specify numPeriod in file %s", theFile->name );
00436       M3_ErrorCheck( -1, errorString, formatStruct.numPeriod, M3_EFLAG_DEFAULT );
00437       s1 = strstr( theFile->name, "_tod_" );
00438       if( s1 && isdigit( s1[5] ) )
00439       {
00440         firstPeriod = atoi(s1+5) + 1;
00441         lastPeriod = firstPeriod + formatStruct.numPeriod-1;
00442       }
00443       else 
00444       {
00445         s1 = strstr( theFile->name, ".fits");
00446         if( s1 )
00447         {
00448           s1--;
00449           while( s1 >= theFile->name && isdigit(*s1) )
00450             s1--;
00451           s1++;
00452           if( isdigit(*s1))
00453             firstPeriod = atoi(s1) + 1;
00454         }
00455         else
00456         {
00457           sprintf( errorString, "FIRSTPNT key not found and could not find pointing period in file name: %s", theFile->name );
00458           M3_ErrorCheck( -1, errorString, 0, M3_EFLAG_DEFAULT);
00459         }
00460       }
00461       status = 0;
00462     }
00463     else
00464     {
00465       firstPeriod = strtoll(strBuffer, NULL, 10);
00466     }
00467     
00468     fits_read_key_str(thisFitsFile, "LASTPNT", strBuffer, NULL, &status);
00469     if( status != 0 )
00470     {
00471       sprintf( errorString, "LASTPNT key not found, and format string does not specify numPeriod in file %s", theFile->name );
00472       M3_ErrorCheck( -1, errorString, formatStruct.numPeriod, M3_EFLAG_DEFAULT );
00473       status = 0;
00474       lastPeriod = firstPeriod + formatStruct.numPeriod - 1;
00475     }
00476     else
00477     {
00478       lastPeriod = strtoll(strBuffer, NULL, 10);
00479     }    
00480   }
00481 
00482   fits_close_file( thisFitsFile, &status);
00483   sprintf( errorString, "Error closing fits file named %s", theFile->name );
00484   M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00485 
00486 
00487   if( firstPeriod != 1 )
00488   {
00489     sprintf( errorString, "Number of samples is not divisable  by number of periods in file named %s", theFile->name );
00490     M3_ErrorCheck( -1, errorString, numSample%(lastPeriod - firstPeriod + 1) == 0, M3_EFLAG_DEFAULT );
00491     samplesPerPeriod = numSample/(lastPeriod - firstPeriod + 1);
00492 
00493     data->firstSample = samplesPerPeriod*(firstPeriod - 1);
00494     data->lastSample = samplesPerPeriod*lastPeriod - 1;
00495   }
00496   else
00497   {
00498     data->firstSample = 0;
00499     data->lastSample = numSample - 1;
00500   }
00501 }  
00502 
00503 
00504 void M3_File_readHeader_LevelS_pointing( M3_File *theFile, M3_PointingHeader *data )
00505 {
00506   int64_t firstPeriod, lastPeriod, samplesPerPeriod, numSample, naxis1;
00507   fitsfile *thisFitsFile;
00508   int status = 0;
00509   M3_FormatStruct_LevelS formatStruct;
00510   char *s1;
00511   char strBuffer[M3_CONTENT_LENGTH];
00512   char errorString[M3_CONTENT_LENGTH];
00513 
00514   M3_File_parseFormatString_LevelS( theFile, &formatStruct );
00515 
00516   fits_open_file( &thisFitsFile, theFile->name, READONLY, &status);
00517   M3_ErrorCheck(-1, theFile->name, status == 0, M3_EFLAG_FOPEN_READ );
00518   
00519   if( formatStruct.firstSample != INT64_MAX )
00520   {
00521     fits_movabs_hdu( thisFitsFile, 2, NULL, &status);
00522     sprintf( errorString, "Error going to second fits header in file %s", theFile->name );
00523     M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
00524 
00525     fits_read_key_str( thisFitsFile, "NAXIS2", strBuffer, NULL, &status );
00526     sprintf( errorString, "Could not read NAXIS2 flag from second header unit in 2007 style header in file %s", theFile->name );
00527     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00528     numSample = strtoll(strBuffer, NULL, 10);
00529     data->firstSample = formatStruct.firstSample;
00530     data->lastSample = formatStruct.firstSample + numSample - 1;
00531     data->numPixelInClass = formatStruct.nside*formatStruct.nside*12;
00532     data->numNZ = 1;
00533 
00534     fits_close_file( thisFitsFile, &status);
00535     sprintf( errorString, "Error closing fits file named %s", theFile->name );
00536     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00537 
00538     return;
00539   }
00540 
00541   if( formatStruct.header2007 )
00542   {
00543     fits_movabs_hdu( thisFitsFile, 1, NULL, &status );
00544     sprintf( errorString, "Could not go to first fits header in file %s", theFile->name );
00545     M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
00546 
00547     fits_read_key_str( thisFitsFile, "first_pointing", strBuffer, NULL, &status );
00548     sprintf( errorString, "Could not read first_pointing flag from 2007 style header in file %s", theFile->name );
00549     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00550     firstPeriod = strtoll( strBuffer, NULL, 10 );
00551 
00552     fits_read_key_str( thisFitsFile, "last_pointing", strBuffer, NULL, &status );
00553     sprintf( errorString, "Could not read last_pointing flag from 2007 style header in file %s", theFile->name );
00554     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00555     lastPeriod = strtoll( strBuffer, NULL, 10 );
00556 
00557     fits_movabs_hdu( thisFitsFile, 2, NULL, &status);
00558     sprintf( errorString, "Error going to second fits header in file %s", theFile->name );
00559     M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
00560 
00561     fits_read_key_str( thisFitsFile, "NAXIS2", strBuffer, NULL, &status );
00562     sprintf( errorString, "Could not read NAXIS2 flag from second header unit in 2007 style header in file %s", theFile->name );
00563     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00564     numSample = strtoll(strBuffer, NULL, 10);
00565   }
00566   else
00567   {
00568     fits_movabs_hdu( thisFitsFile, 2, NULL, &status );
00569     sprintf( errorString, "Error in skipping first fits header in file %s", theFile->name );
00570     M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
00571 
00572     fits_read_key_str( thisFitsFile, "NAXIS2", strBuffer, NULL, &status );
00573     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00574     numSample = strtoll(strBuffer, NULL, 10);
00575 
00576     fits_read_key_str(thisFitsFile, "FIRSTPNT", strBuffer, NULL, &status);
00577     if( status != 0 )
00578     {
00579       sprintf( errorString, "FIRSTPNT key not found, and format string does not specify numPeriod in file %s", theFile->name );
00580       M3_ErrorCheck( -1, errorString, formatStruct.numPeriod, M3_EFLAG_DEFAULT );
00581 
00582       s1 = strstr( theFile->name, "_pointing_" );
00583       if( s1 && isdigit( s1[5] ) )
00584       {
00585         firstPeriod = strtoll(s1+5, NULL, 10) + 1;
00586         lastPeriod = firstPeriod + formatStruct.numPeriod-1;
00587       }
00588       else 
00589       {
00590         s1 = strstr( theFile->name, ".fits");
00591         if( s1 )
00592         {
00593           s1--;
00594           while( s1 >= theFile->name && isdigit(*s1) )
00595             s1--;
00596           s1++;
00597           if( isdigit(*s1))
00598             firstPeriod = strtoll(s1, NULL, 10) + 1;
00599         }
00600         else
00601         {
00602           sprintf( errorString, "FIRSTPNT key not found and could not find pointing period in file name: %s", theFile->name );
00603           M3_ErrorCheck( -1, errorString, 0, M3_EFLAG_DEFAULT);
00604         }
00605       }
00606       status = 0;
00607     }
00608     else
00609     {
00610       firstPeriod = strtoll(strBuffer, NULL, 10);
00611     }
00612 
00613     fits_read_key_str(thisFitsFile, "LASTPNT", strBuffer, NULL, &status);
00614     if( status != 0 )
00615     {
00616       sprintf( errorString, "LASTPNT key not found, and format string does not specify numPeriod in file %s", theFile->name );
00617       M3_ErrorCheck( -1, errorString, formatStruct.numPeriod, M3_EFLAG_DEFAULT );
00618       status = 0;
00619       lastPeriod = firstPeriod + formatStruct.numPeriod - 1;
00620     }
00621     else
00622     {
00623       lastPeriod = strtoll(strBuffer, NULL, 10);
00624     }
00625   }
00626 
00627   fits_close_file( thisFitsFile, &status);
00628   sprintf( errorString, "Error closing fits file named %s", theFile->name );
00629   M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00630 
00631   if( firstPeriod != 1 )
00632   {
00633     sprintf( errorString, "Number of samples is not divisable  by number of periods in file named %s", theFile->name );
00634     M3_ErrorCheck( -1, errorString, numSample%(lastPeriod - firstPeriod + 1) == 0, M3_EFLAG_DEFAULT );
00635     samplesPerPeriod = numSample/(lastPeriod - firstPeriod + 1);
00636 
00637     data->firstSample = samplesPerPeriod*(firstPeriod - 1);
00638     data->lastSample = samplesPerPeriod*lastPeriod - 1;
00639   }
00640   else
00641   {
00642     data->firstSample = 0;
00643     data->lastSample = numSample - 1;
00644   }
00645 
00646   data->numPixelInClass = formatStruct.nside*formatStruct.nside*12;
00647   data->numNZ = 1;
00648 }  
00649 
00650 time_t my_timegm (struct tm *tm) 
00651 {
00652   time_t ret;
00653   char *tz;
00654   
00655   tz = getenv("TZ");
00656   setenv("TZ", "", 1);
00657   tzset();
00658   ret = mktime(tm);
00659   if (tz)
00660     setenv("TZ", tz, 1);
00661   else
00662     unsetenv("TZ");
00663   tzset();
00664   return ret;
00665 }
00666 
00667 void M3_TimeEl_convertKeys( M3_TimeEl *outTime, char *dateKey, char *timeKey ) 
00668 {
00669   char tempBuffer[M3_CONTENT_LENGTH];
00670   char *strPtr;
00671   struct tm timeStruct;
00672 
00673   strPtr = dateKey;
00674 
00675   memcpy( tempBuffer, strPtr, 4);
00676   tempBuffer[4] = 0;
00677   timeStruct.tm_year = atoi(tempBuffer) - 1900;
00678     
00679   memcpy( tempBuffer, strPtr+4, 2);
00680   tempBuffer[2] = 0;
00681   timeStruct.tm_mon = atoi(tempBuffer) - 1;
00682     
00683   memcpy( tempBuffer, strPtr+6, 2);
00684   tempBuffer[2] = 0;
00685   timeStruct.tm_mday = atoi(tempBuffer);
00686     
00687   strPtr = timeKey;
00688 
00689   memcpy( tempBuffer, strPtr, 2);
00690   tempBuffer[2] = 0;
00691   timeStruct.tm_hour = atoi( tempBuffer );
00692   
00693   memcpy( tempBuffer, strPtr+2, 2);
00694   tempBuffer[2] = 0;
00695   timeStruct.tm_min = atoi( tempBuffer );
00696   
00697   strcpy( tempBuffer, strPtr+4);
00698   timeStruct.tm_sec = atoi( tempBuffer );
00699 
00700   outTime->sec = my_timegm(&timeStruct);        
00701   outTime->nsec = 1e9*(atof(tempBuffer) - timeStruct.tm_sec);
00702 }
00703 
00704 
00705 void M3_File_readHeader_LevelS_gcpointing( M3_File *theFile, M3_GCPointingHeader *data )
00706 {
00707   M3_FormatStruct_LevelS formatStruct;
00708   fitsfile *thisFitsFile;
00709   int status = 0;
00710   char errorString[M3_CONTENT_LENGTH];
00711   char temp[M3_CONTENT_LENGTH];
00712   char dateKey[M3_CONTENT_LENGTH];
00713   char timeKey[M3_CONTENT_LENGTH];
00714   char strBuffer[M3_CONTENT_LENGTH];
00715   char *strPtr;
00716   int64_t firstPeriod, lastPeriod;
00717   struct tm timeStruct;
00718   M3_TimeEl firstTime, secondTime, lastTime;
00719   int64_t numSample, numRow, n12;
00720   double tempd, sampleRate;
00721 
00722   M3_File_parseFormatString_LevelS( theFile, &formatStruct );
00723 
00724   fits_open_file( &thisFitsFile, theFile->name, READONLY, &status);
00725   M3_ErrorCheck(-1, theFile->name, status == 0, M3_EFLAG_FOPEN_READ );
00726 
00727   if( formatStruct.simmission2006 ) 
00728   {
00729     fits_movabs_hdu( thisFitsFile, 3, NULL, &status );
00730     sprintf( errorString, "Could not go to third fits HDU in file %s", theFile->name );
00731     M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
00732   } 
00733   else 
00734   {
00735     fits_movabs_hdu( thisFitsFile, 2, NULL, &status );
00736     sprintf( errorString, "Could not go to second fits HDU in file %s", theFile->name );
00737     M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT ); 
00738   }
00739     
00740   fits_read_key_str( thisFitsFile, "NAXIS2", strBuffer, NULL, &status );
00741   sprintf( errorString, "Could not read NAXIS2 flag from third header unit in file:  %s", theFile->name );
00742   M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00743   numSample = strtoll(strBuffer, NULL, 10);
00744   
00745   if( formatStruct.simmission2006 )
00746   {
00747     fits_movabs_hdu( thisFitsFile, 2, NULL, &status );
00748     sprintf( errorString, "Could not go to second fits header in file %s", theFile->name );
00749     M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
00750 
00751     fits_read_key_str( thisFitsFile, "NAXIS2", strBuffer, NULL, &status );
00752     sprintf( errorString, "Could not read NAXIS2 flag from second header unit of file: %s", theFile->name );
00753     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00754     numRow = strtoll(strBuffer, NULL, 10);
00755 
00756     fits_read_col( thisFitsFile, TDOUBLE, 1, 1, 1, 1, NULL, &tempd, NULL, &status );
00757     firstTime.sec = tempd;
00758     fits_read_col( thisFitsFile, TDOUBLE, 2, 1, 1, 1, NULL, &tempd, NULL, &status );
00759     firstTime.nsec = tempd*1e9;
00760 
00761     fits_read_col( thisFitsFile, TDOUBLE, 13, 1, 1, 1, NULL, &tempd, NULL, &status );
00762     secondTime.sec = tempd;
00763     fits_read_col( thisFitsFile, TDOUBLE, 14, 1, 1, 1, NULL, &tempd, NULL, &status );
00764     secondTime.nsec = tempd*1e9;
00765 
00766     fits_read_col( thisFitsFile, TDOUBLE, 13, numRow, 1, 1, NULL, &tempd, NULL, &status );
00767     lastTime.sec = tempd;
00768     fits_read_col( thisFitsFile, TDOUBLE, 14, numRow, 1, 1, NULL, &tempd, NULL, &status );
00769     lastTime.nsec = tempd*1e9;
00770 
00771     /* If the file has variable pointing periods, then use the first period 
00772        to determine the rate to avoid using times with round off errors.  */
00773     fits_read_col( thisFitsFile, TLONGLONG, 18, 1, 1, 1, NULL, &n12, NULL, &status );
00774     if( status == 0 )
00775       sampleRate = n12/M3_TimeEl_Difference( secondTime, firstTime );
00776     else
00777     {
00778       status = 0;
00779       sampleRate = numSample/M3_TimeEl_Difference( lastTime, firstTime );
00780     }
00781   }
00782   else
00783   {
00784     fits_read_key_str(thisFitsFile, "FIRSTPT", strBuffer, NULL, &status);
00785     if( status != 0 )
00786     {
00787       firstPeriod = 0;
00788       status = 0;
00789     }
00790     fits_read_key_str(thisFitsFile, "LASTPT", strBuffer, NULL, &status);
00791     if( status != 0 )
00792     {
00793       lastPeriod = 8783;
00794       status = 0;
00795     }
00796 
00797     sprintf(temp, "SI%6lld", firstPeriod);
00798     fits_read_key_str(thisFitsFile, temp, strBuffer, NULL, &status );
00799     sprintf(errorString, "Error reading %s key from fits header of file %s", temp, theFile->name);
00800     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT);
00801     firstTime.sec = (int64_t)atof(strBuffer);
00802 
00803     sprintf(temp, "SF%6lld", firstPeriod);
00804     fits_read_key_str(thisFitsFile, temp, strBuffer, NULL, &status );
00805     sprintf(errorString, "Error reading %s key from fits header of file %s", theFile->name, temp);
00806     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT);      
00807     firstTime.nsec = 1e9*atof(strBuffer);
00808 
00809     sprintf(temp, "EI%6lld", lastPeriod);
00810     fits_read_key_str(thisFitsFile, temp, strBuffer, NULL, &status );
00811     sprintf(errorString, "Error reading %s key from fits header of file %s", temp, theFile->name);
00812     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT);
00813     lastTime.sec = (int64_t)atof(strBuffer);
00814     
00815     sprintf(temp, "EF%6lld", lastPeriod);
00816     fits_read_key_str(thisFitsFile, temp, strBuffer, NULL, &status );
00817     sprintf(errorString, "Error reading %s key from fits header of file %s", temp, theFile->name);
00818     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT);
00819     lastTime.nsec = 1e9*atof(strBuffer);
00820 
00821     sampleRate = numSample/M3_TimeEl_Difference( lastTime, firstTime );
00822 
00823   }
00824 
00825   fits_close_file( thisFitsFile, &status);
00826   sprintf( errorString, "Error closing fits file named %s", theFile->name );
00827   M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00828 
00829   data->firstTime_sec = firstTime.sec;
00830   data->firstTime_nsec = firstTime.nsec;
00831   data->numSample = numSample;
00832   data->sampleRate = sampleRate;
00833   data->numDataPerSample = 6;
00834 
00835 }
00836 
00837 void M3_File_readHeader_LevelS_aux( M3_File *theFile, M3_AuxHeader *data )
00838 {
00839   int64_t tableLength, tableWidth;
00840   M3_FormatStruct_LevelS formatStruct;
00841   fitsfile *thisFitsFile;
00842   int status = 0;
00843   char errorString[M3_CONTENT_LENGTH];
00844   char strBuffer[M3_CONTENT_LENGTH];
00845 
00846   M3_File_parseFormatString_LevelS( theFile, &formatStruct );
00847 
00848   fits_open_file( &thisFitsFile, theFile->name, READONLY, &status);
00849   M3_ErrorCheck(-1, theFile->name, status == 0, M3_EFLAG_FOPEN_READ );
00850 
00851   fits_movabs_hdu( thisFitsFile, 2, NULL, &status );
00852   sprintf( errorString, "Could not go to second fits header in file %s", theFile->name );
00853   M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
00854 
00855   fits_read_key_str(thisFitsFile, "NAXIS1", strBuffer, NULL, &status);
00856   sprintf( errorString, "Error reading NAXIS1 key from second HDU of fits header of file %s", theFile->name);  
00857   M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00858   tableWidth = strtoll(strBuffer, NULL, 10);
00859 
00860   fits_read_key_str(thisFitsFile, "NAXIS2", strBuffer, NULL, &status);
00861   sprintf( errorString, "Error reading NAXIS2 key from second HDU of fits header of file %s", theFile->name);
00862   M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00863   tableLength = strtoll(strBuffer, NULL, 10);
00864 
00865   data->size = sizeof(M3_planckAux) + tableLength*(sizeof(M3_planckDetector) + 8);
00866 
00867   fits_close_file( thisFitsFile, &status);
00868   sprintf( errorString, "Error closing fits file named %s", theFile->name );
00869   M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00870 }
00871 
00872 
00873 void M3_File_readHeader_LevelS_noise( M3_File *theFile, M3_NoiseHeader *header )
00874 {
00875   M3_FormatStruct_LevelS formatStruct;
00876 
00877   M3_File_parseFormatString_LevelS( theFile, &formatStruct );
00878   header->firstSample = formatStruct.firstSample;
00879   header->lastSample = formatStruct.lastSample;
00880   header->corLength = formatStruct.corLength;
00881 }
00882 
00883 void M3_File_readData_LevelS_tod( M3_File *theFile, M3_Interval *readInterval, double *data )
00884 {
00885   M3_FormatStruct_LevelS formatStruct;
00886   float *fltPtr;
00887   int64_t readLength, offset, i;
00888   FILE *fid;
00889   int isBigEndian;
00890   int status = 0;
00891   fitsfile *thisFitsFile;
00892   int colnums;
00893   char errorString[M3_CONTENT_LENGTH];
00894 
00895   M3_File_parseFormatString_LevelS( theFile, &formatStruct );
00896 
00897   if (formatStruct.LFI) {
00898 
00899     colnums = 3;
00900 
00901     fits_open_file( &thisFitsFile, theFile->name, READONLY, &status );
00902 
00903     fits_movabs_hdu( thisFitsFile, 2, NULL, &status );
00904     sprintf( errorString, "Could not go to second fits HDU in file %s", theFile->name );
00905     M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
00906 
00907     status = read_fits_tableblock(thisFitsFile, readInterval->firstSample, readInterval->lastSample, NULL, 1, FITS_BLOCK_NUMS, NULL, &colnums, data );
00908 
00909     sprintf( errorString, "Could not read samples %lld to %lld of LevelS TOD %s", readInterval->firstSample, readInterval->lastSample, theFile->name );
00910     M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
00911 
00912     fits_close_file( thisFitsFile, &status );
00913     sprintf( errorString, "Error closing fits file named %s", theFile->name );
00914     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00915 
00916   } else {
00917 
00918     fid = fopen( theFile->name, "r");
00919     M3_ErrorCheck( -1, theFile->name, fid, M3_EFLAG_FOPEN_READ );
00920     skipFitsHeaders( fid, 2);
00921     isBigEndian = testEndian();
00922 
00923     readLength = readInterval->lastSample - readInterval->firstSample + 1;
00924     offset = sizeof(float)*(readInterval->firstSample - theFile->param.tod.interval.firstSample );
00925     fseeko64(fid, offset, SEEK_CUR);
00926     fltPtr = ((float*)data) + readLength;
00927     fread(fltPtr, sizeof(float), readLength, fid);
00928     if( !isBigEndian )
00929       flipByteOrder( fltPtr, readLength, sizeof(float));
00930     for( i = 0; i < readLength; i++ )
00931       data[i] = (double)(fltPtr[i]);
00932     fclose(fid);
00933 
00934   }
00935 
00936   return;
00937 }
00938 
00939 
00940 #ifdef UNDEFINED
00941 void M3_File_readData_LevelS_tod( M3_File *theFile, M3_Interval *readInterval, double *data )
00942 {
00943   float *fltPtr;
00944   int64_t readLength, offset, i;
00945   FILE *fid;
00946   int isBigEndian;
00947   int status = 0;
00948   fitsfile *thisFitsFile;
00949   int colnums = 0;
00950   char errorString[M3_CONTENT_LENGTH];
00951   M3_FormatStruct_LevelS formatStruct;
00952 
00953   M3_File_parseFormatString_LevelS( theFile, &formatStruct );
00954 
00955   fits_open_file( &thisFitsFile, theFile->name, READONLY, &status );
00956 
00957   fits_movabs_hdu( thisFitsFile, 2, NULL, &status );
00958   sprintf( errorString, "Could not go to second fits HDU in file %s", theFile->name );
00959   M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
00960     
00961   if( formatStruct.LFI )
00962     colnums = 3;
00963   else
00964     colnums = 0;
00965 
00966   status = read_fits_tableblock(thisFitsFile, readInterval->firstSample, readInterval->lastSample, NULL, 1, FITS_BLOCK_NUMS, NULL, &colnums, data );
00967 
00968   sprintf( errorString, "Could not read samples %lld to %lld of LevelS TOD %s", readInterval->firstSample, readInterval->lastSample, theFile->name );
00969   M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
00970 
00971   fits_close_file( thisFitsFile, &status );
00972   sprintf( errorString, "Error closing fits file named %s", theFile->name );
00973   M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
00974   return;
00975 }
00976 #endif
00977 
00978 void M3_File_readData_LevelS_pointing( M3_File *theFile, M3_Interval *readInterval,  M3_PointingEl *data )
00979 {
00980   M3_FormatStruct_LevelS formatStruct;
00981   int64_t readLength, offset, i;
00982   FILE *fid;
00983   fitsfile *thisFitsFile;
00984   int status = 0;
00985   char errorString[M3_CONTENT_LENGTH];
00986   char strBuffer[M3_CONTENT_LENGTH];
00987   int coordBytes, isBigEndian;
00988   int64_t bufferLength, numReads, j;
00989   double coordDblPtr[3];
00990   void *fileBuffer;
00991   float *fltPtr;
00992   double *dblPtr;
00993   M3_PointingEl *pointingPtr;
00994   long p, nside;
00995 
00996   static int64_t diskBufferSize = -1;
00997   char *tempPtr;
00998 
00999   if( diskBufferSize == -1 )
01000   {
01001     tempPtr = getenv("M3_DISK_BUFFER_SIZE");
01002     if( tempPtr )
01003       diskBufferSize = strtoll( tempPtr, NULL, 10);
01004     else
01005       diskBufferSize = M3_DISK_BUFFER_SIZE;
01006   }
01007 
01008 
01009 
01010   M3_File_parseFormatString_LevelS( theFile, &formatStruct );
01011 
01012   /* Use cfitsio to determine if the data is double or single precision */
01013   fits_open_file( &thisFitsFile, theFile->name, READONLY, &status );
01014   M3_ErrorCheck(-1, theFile->name, status == 0, M3_EFLAG_FOPEN_READ );
01015 
01016   fits_movabs_hdu( thisFitsFile, 2, NULL, &status );
01017   sprintf( errorString, "Could not go to second fits header in file %s", theFile->name );
01018   M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
01019 
01020   fits_read_key_str( thisFitsFile, "TFORM1", strBuffer, NULL, &status );
01021   sprintf( errorString, "Could not read TFORM1 flag from second HDU in file %s", theFile->name );
01022   M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
01023   if( strncmp( strBuffer, "1E", 2) == 0  || strncmp( strBuffer+1, "1E", 2) == 0 )
01024     coordBytes = 4;
01025     else if( strncmp( strBuffer, "1D", 2) == 0  || strncmp( strBuffer+1, "1D", 2) == 0 )
01026     coordBytes = 8;
01027   else
01028   {
01029     sprintf( errorString, "Could not interpret TFORM1 flag from second HDU in file %s", theFile->name );
01030     M3_ErrorCheck( -1, errorString, 0, M3_EFLAG_DEFAULT );
01031   }
01032 
01033   fits_close_file( thisFitsFile, &status);
01034   sprintf( errorString, "Error closing fits file named %s", theFile->name );
01035   M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
01036 
01037   fid = fopen( theFile->name, "r");
01038   M3_ErrorCheck( -1, theFile->name, fid, M3_EFLAG_FOPEN_READ );
01039   skipFitsHeaders( fid, 2);
01040   isBigEndian = testEndian();
01041 
01042   if( formatStruct.template )
01043   {
01044     readLength = readInterval->lastSample - readInterval->firstSample + 1;
01045     offset = sizeof(float)*(readInterval->firstSample - theFile->param.pointing.interval.firstSample );
01046     fseeko64( fid, offset, SEEK_CUR);
01047         
01048     fltPtr = ((float*)data) + readLength;
01049     fread(fltPtr, sizeof(float), readLength, fid);
01050     if( !isBigEndian )
01051       flipByteOrder( fltPtr, readLength, sizeof(float));
01052 
01053     for( i = 0; i < readLength; i++ )
01054     {
01055       data[i].pixel = 0;
01056       data[i].weight = fltPtr[i];
01057     }
01058   }
01059   else
01060   {
01061     fileBuffer = malloc(diskBufferSize);
01062     M3_ErrorCheck( -1, "M3_File_readData_LevelS_pointing()", (fileBuffer ? 1 : 0), M3_EFLAG_MALLOC_FSTRING );
01063 
01064     readLength = readInterval->lastSample - readInterval->firstSample + 1;
01065     bufferLength = diskBufferSize/(coordBytes*3);
01066     numReads = readLength/bufferLength + ( readLength%bufferLength ? 1 : 0 );
01067 
01068     offset = 3*coordBytes*(readInterval->firstSample - theFile->param.pointing.interval.firstSample );
01069     fseeko64( fid, offset, SEEK_CUR);
01070 
01071     fltPtr = (float *)fileBuffer;
01072     dblPtr = (double *)fileBuffer;
01073     pointingPtr = data;
01074 
01075     for( i = 0; i < numReads; i++ )
01076     {
01077       if( i == numReads - 1 && readLength%bufferLength )
01078         bufferLength = readLength%bufferLength;
01079       
01080       fread(fileBuffer, coordBytes, 3*bufferLength, fid );
01081       if( !isBigEndian )
01082         flipByteOrder( fileBuffer, 3*bufferLength, coordBytes );
01083       if( formatStruct.rotateDirection[0] != '\0' )
01084         if( coordBytes == 4 )
01085           for( j = 0; j < bufferLength; j++ )
01086           {
01087             coordDblPtr[0] = fltPtr[3*j];
01088             coordDblPtr[1] = fltPtr[3*j+1];
01089             coordDblPtr[2] = fltPtr[3*j+2];
01090             rotateCoords( formatStruct.rotateDirection, formatStruct.rotateEquinox, 1, coordDblPtr );
01091             fltPtr[3*j] = coordDblPtr[0];
01092             fltPtr[3*j+1] = coordDblPtr[1];
01093             fltPtr[3*j+2] = coordDblPtr[2];
01094           }
01095         else
01096           rotateCoords( formatStruct.rotateDirection, formatStruct.rotateEquinox, bufferLength, dblPtr );
01097 
01098       if( coordBytes  == 4 )
01099       {
01100         if( formatStruct.pixelScheme == 'r' )
01101         {
01102           if( formatStruct.pixelType == M3_CMB_I_PIXEL_TYPE || formatStruct.pixelType == M3_DEFAULT_PIXEL_TYPE )
01103             for( j = 0; j < bufferLength; j++ )
01104             {
01105               ang2pix_ring(formatStruct.nside, fltPtr[3*j], fltPtr[3*j+1], &p);
01106               pointingPtr[j].pixel = p;
01107               pointingPtr[j].weight = 1;
01108             }
01109           else if( formatStruct.pixelType == M3_CMB_Q_PIXEL_TYPE )
01110             for( j = 0; j < bufferLength; j++ )
01111             {
01112               ang2pix_ring(formatStruct.nside, fltPtr[3*j], fltPtr[3*j+1], &p );
01113               pointingPtr[j].pixel = p;
01114               pointingPtr[j].weight = cos(2*(fltPtr[3*j+2] + formatStruct.psiPol));
01115             }
01116           else if( formatStruct.pixelType == M3_CMB_U_PIXEL_TYPE )
01117             for( j = 0; j < bufferLength; j++ )
01118             {
01119               ang2pix_ring(formatStruct.nside, fltPtr[3*j], fltPtr[3*j+1], &p );
01120               pointingPtr[j].pixel = p;
01121               pointingPtr[j].weight = sin(2*(fltPtr[3*j+2] + formatStruct.psiPol));
01122             }
01123         }
01124         else
01125         {
01126           if( formatStruct.pixelType == M3_CMB_I_PIXEL_TYPE || formatStruct.pixelType == M3_DEFAULT_PIXEL_TYPE )
01127             for( j = 0; j < bufferLength; j++ )
01128             {
01129               ang2pix_nest(formatStruct.nside, fltPtr[3*j], fltPtr[3*j+1], &p);
01130               pointingPtr[j].pixel = p;
01131               pointingPtr[j].weight = 1;
01132             }
01133           else if( formatStruct.pixelType == M3_CMB_Q_PIXEL_TYPE )
01134             for( j = 0; j < bufferLength; j++ )
01135             {
01136               ang2pix_nest(formatStruct.nside, fltPtr[3*j], fltPtr[3*j+1], &p );
01137               pointingPtr[j].pixel = p;
01138               pointingPtr[j].weight = cos(2*(fltPtr[3*j+2] + formatStruct.psiPol));
01139             }
01140           else if( formatStruct.pixelType == M3_CMB_U_PIXEL_TYPE )
01141             for( j = 0; j < bufferLength; j++ )
01142             {
01143               ang2pix_nest(formatStruct.nside, fltPtr[3*j], fltPtr[3*j+1], &p );
01144               pointingPtr[j].pixel = p;
01145               pointingPtr[j].weight = sin(2*(fltPtr[3*j+2] + formatStruct.psiPol));
01146             }
01147         }
01148       }
01149       else 
01150       {
01151         if( formatStruct.pixelScheme == 'r' )
01152         {
01153           if( formatStruct.pixelType == M3_CMB_I_PIXEL_TYPE || formatStruct.pixelType == M3_DEFAULT_PIXEL_TYPE )
01154             for( j = 0; j < bufferLength; j++ )
01155             {
01156               ang2pix_ring(formatStruct.nside, dblPtr[3*j], dblPtr[3*j+1], &p);
01157               pointingPtr[j].pixel = p;
01158               pointingPtr[j].weight = 1;
01159             }
01160           else if( formatStruct.pixelType == M3_CMB_Q_PIXEL_TYPE )
01161             for( j = 0; j < bufferLength; j++ )
01162             {
01163               ang2pix_ring(formatStruct.nside, dblPtr[3*j], dblPtr[3*j+1], &p );
01164               pointingPtr[j].pixel = p;
01165               pointingPtr[j].weight = cos(2*(dblPtr[3*j+2] + formatStruct.psiPol));
01166             }
01167           else if( formatStruct.pixelType == M3_CMB_U_PIXEL_TYPE )
01168             for( j = 0; j < bufferLength; j++ )
01169             {
01170               ang2pix_ring(formatStruct.nside, dblPtr[3*j], dblPtr[3*j+1], &p );
01171               pointingPtr[j].pixel = p;
01172               pointingPtr[j].weight = sin(2*(dblPtr[3*j+2] + formatStruct.psiPol));
01173             }
01174           }
01175           else
01176           {
01177             if( formatStruct.pixelType == M3_CMB_I_PIXEL_TYPE || formatStruct.pixelType == M3_DEFAULT_PIXEL_TYPE )
01178               for( j = 0; j < bufferLength; j++ )
01179               {
01180                 ang2pix_nest(formatStruct.nside, dblPtr[3*j], dblPtr[3*j+1], &p);
01181                 pointingPtr[j].pixel = p;
01182                 pointingPtr[j].weight = 1;
01183               }
01184             else if( formatStruct.pixelType == M3_CMB_Q_PIXEL_TYPE )
01185               for( j = 0; j < bufferLength; j++ )
01186               {
01187                 ang2pix_nest(formatStruct.nside, dblPtr[3*j], dblPtr[3*j+1], &p );
01188                 pointingPtr[j].pixel = p;
01189                 pointingPtr[j].weight = cos(2*(dblPtr[3*j+2] + formatStruct.psiPol));
01190               }
01191             else if( formatStruct.pixelType == M3_CMB_U_PIXEL_TYPE )
01192               for( j = 0; j < bufferLength; j++ )
01193               {
01194                 ang2pix_nest(formatStruct.nside, dblPtr[3*j], dblPtr[3*j+1], &p );
01195                 pointingPtr[j].pixel = p;
01196                 pointingPtr[j].weight = sin(2*(dblPtr[3*j+2] + formatStruct.psiPol));
01197               }
01198           }
01199       }
01200         pointingPtr += bufferLength;
01201     }
01202     free( fileBuffer );
01203   }
01204   fclose(fid);
01205 }
01206 
01207 
01208 void M3_File_readData_LevelS_gcpointing( M3_File *theFile, M3_Interval *readInterval, double *data )
01209 {
01210   int64_t readLength;
01211   M3_FormatStruct_LevelS formatStruct;
01212   int64_t offset, i, j, k, l;
01213   double tempd;
01214   fitsfile *theFitsFile;
01215   int status = 0;
01216   char errorString[M3_CONTENT_LENGTH];
01217   char *tempPtr;
01218   int colnums[6] = {0, 1, 2, 3, 4, 5};
01219 
01220 
01221   M3_File_parseFormatString_LevelS( theFile, &formatStruct );
01222 
01223   readLength = readInterval->lastSample - readInterval->firstSample + 1;
01224 
01225   fits_open_file( &theFitsFile, theFile->name, READONLY, &status );
01226   M3_ErrorCheck(-1, theFile->name, status == 0, M3_EFLAG_FOPEN_READ );
01227   
01228   if( formatStruct.simmission2006 ) {
01229 
01230     fits_movabs_hdu( theFitsFile, 3, NULL, &status );
01231     sprintf( errorString, "Could not go to third fits HDU in file %s", theFile->name );
01232     M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
01233 
01234   } else {
01235     
01236     fits_movabs_hdu( theFitsFile, 2, NULL, &status );
01237     sprintf( errorString, "Could not go to second fits HDU in file %s", theFile->name );
01238     M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
01239     
01240   }
01241     
01242   status = read_fits_tableblock(theFitsFile, readInterval->firstSample, readInterval->lastSample, NULL, 6, FITS_BLOCK_NUMS, NULL, colnums, data);
01243     
01244   sprintf( errorString, "Error with block-reading file %s", theFile->name );
01245   M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
01246 
01247   if( formatStruct.spinAxis != 'z' ) {
01248     for( i = 0; i < readLength; i++ ) {
01249       offset = 6*i;
01250       tempd = data[offset];
01251       data[offset] = data[offset+4];
01252       data[offset+4] = tempd;
01253       tempd = data[offset+1];
01254       data[offset+1] = data[offset+5];
01255       data[offset+5] = tempd;
01256       data[offset+2] = M_PI - data[offset+2];
01257       data[offset+3] = data[offset+3] + M_PI;
01258     }
01259   }
01260     
01261   fits_close_file(theFitsFile, &status);
01262   
01263   return;
01264 }
01265 
01266 
01267 void M3_File_readData_LevelS_aux( M3_File *theFile, M3_planckAux *data )
01268 {
01269   void *fpBuffer;
01270   M3_FormatStruct_LevelS formatStruct;
01271   fitsfile *thisFitsFile;
01272   int status = 0, isBigEndian;
01273   char errorString[M3_CONTENT_LENGTH];
01274   char strBuffer[M3_CONTENT_LENGTH];
01275   double boresightSpinAxisAngle;  
01276   int64_t tableWidth, tableLength, i, j;
01277   FILE *fid;
01278   double *dblPtr;
01279 
01280 
01281   M3_File_parseFormatString_LevelS( theFile, &formatStruct );
01282 
01283   fits_open_file( &thisFitsFile, theFile->name, READONLY, &status );
01284   M3_ErrorCheck(-1, theFile->name, status == 0, M3_EFLAG_FOPEN_READ );
01285 
01286   if( formatStruct.header2007 )
01287   {
01288     fits_movabs_hdu( thisFitsFile, 1, NULL, &status );
01289     sprintf( errorString, "Could not go to first fits header in file %s", theFile->name );
01290     M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
01291 
01292     fits_read_key_str(thisFitsFile, "theta_b", strBuffer, NULL, &status);
01293     sprintf( errorString, "Error reading theta_b key from fits header of file %s", theFile->name);
01294     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
01295     boresightSpinAxisAngle = (M_PI/180.0)*atof(strBuffer);
01296 
01297     fits_movabs_hdu( thisFitsFile, 2, NULL, &status );
01298     sprintf( errorString, "Could not go to second fits header in file %s", theFile->name );
01299     M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
01300 
01301   }
01302   else
01303   {
01304     fits_movabs_hdu( thisFitsFile, 2, NULL, &status );
01305     sprintf( errorString, "Could not go to second fits header in file %s", theFile->name );
01306     M3_ErrorCheck( -1, errorString, status == 0, M3_EFLAG_DEFAULT );
01307 
01308     fits_read_key_str(thisFitsFile, "THETA_B", strBuffer, NULL, &status);
01309     sprintf( errorString, "Error reading THETA_B key from fits header of file %s", theFile->name);
01310     M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
01311     boresightSpinAxisAngle = (M_PI/180.0)*atof(strBuffer);
01312   }
01313   
01314   fits_read_key_str(thisFitsFile, "NAXIS1", strBuffer, NULL, &status);
01315   sprintf( errorString, "Error reading NAXIS1 key from second HDU of fits header of file %s", theFile->name);  
01316   M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
01317   tableWidth = strtoll(strBuffer, NULL, 10);
01318 
01319   fits_read_key_str(thisFitsFile, "NAXIS2", strBuffer, NULL, &status);
01320   sprintf( errorString, "Error reading NAXIS2 key from second HDU of fits header of file %s", theFile->name);
01321   M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
01322   tableLength = strtoll(strBuffer, NULL, 10);
01323 
01324   fits_close_file( thisFitsFile, &status);
01325   sprintf( errorString, "Error closing fits file named %s", theFile->name );
01326   M3_ErrorCheck(-1, errorString, status == 0, M3_EFLAG_DEFAULT );
01327 
01328   data->boresightSpinAxisAngle = boresightSpinAxisAngle;
01329   data->numDetector = tableLength;
01330   data->detectorInfo = (M3_planckDetector*)(((char*)data) + sizeof(M3_planckAux));
01331 
01332 
01333   fid = fopen( theFile->name, "r");
01334   M3_ErrorCheck( -1, theFile->name, fid, M3_EFLAG_FOPEN_READ );
01335   skipFitsHeaders( fid, 2);
01336   isBigEndian = testEndian();
01337 
01338   fpBuffer = malloc( tableWidth*tableLength);
01339   M3_ErrorCheck(-1, "M3_File_readData_LevelS_aux", (fpBuffer ? 1 : 0), M3_EFLAG_MALLOC_FSTRING);
01340   fread(fpBuffer, 1, tableWidth*tableLength, fid );
01341       
01342   for( i = 0; i < tableLength; i++ )
01343   {
01344     ((M3_planckAux*)data)->detectorInfo[i].detectorID = ((char*)data) + sizeof(M3_planckAux) + 
01345                                                         tableLength*sizeof(M3_planckDetector) + 
01346                                                         8*i;
01347     memcpy(((M3_planckAux*)data)->detectorInfo[i].detectorID, ((char*)fpBuffer) + i*tableWidth, 8);
01348     for( j = 0; j < 8; j++ )
01349       if( ((M3_planckAux*)data)->detectorInfo[i].detectorID[j] == ' ')
01350         break;
01351         
01352     ((M3_planckAux*)data)->detectorInfo[i].detectorID[j] = '\0';
01353         
01354     dblPtr = (double*)(((char*)fpBuffer) + i*tableWidth + 8);
01355     if(!isBigEndian)
01356       flipByteOrder( dblPtr, 4, sizeof(double));
01357     data->detectorInfo[i].offset[0] = (M_PI/180.0)*dblPtr[1];
01358     data->detectorInfo[i].offset[1] = (M_PI/180.0)*dblPtr[0];
01359     data->detectorInfo[i].offset[2] = (M_PI/180.0)*dblPtr[2];
01360     data->detectorInfo[i].psiPol = (M_PI/180.0)*dblPtr[3];
01361   }
01362   free(fpBuffer);
01363 
01364   fclose(fid);
01365 }
01366 
01367 
01368 
01369 void M3_File_getFPDBparam( M3_File *theFile, double *fknee, double *alpha, double *fmin, double *fsample, double *NET )
01370 {
01371   M3_FormatStruct_LevelS formatStruct;
01372   fitsfile *thisFitsFile;
01373   int status = 0;
01374   long nrows;
01375   int colnum;
01376   char **detids;
01377   int coltype;
01378   long colrepeat;
01379   long colwidth;
01380   long detrow;
01381 
01382   int i, j, k, foundDet = -1;
01383 
01384   char errorMessage[M3_CONTENT_LENGTH];
01385 
01386   M3_File_parseFormatString_LevelS( theFile, &formatStruct );
01387 
01388   fits_open_file( &thisFitsFile, theFile->name, READONLY, &status );
01389   M3_ErrorCheck(-1, theFile->name, status == 0, M3_EFLAG_FOPEN_READ );
01390 
01391   fits_movabs_hdu( thisFitsFile, 2, NULL, &status );
01392   sprintf( errorMessage, "Could not go to second HDU in file %s", theFile->name );
01393   M3_ErrorCheck( -1, errorMessage, status == 0, M3_EFLAG_DEFAULT );
01394 
01395   /* get the number of rows in the table */
01396 
01397   fits_get_num_rows( thisFitsFile, &nrows, &status);
01398   sprintf( errorMessage, "Could not retrieve number of rows in file %s", theFile->name );
01399   M3_ErrorCheck( -1, errorMessage, status == 0, M3_EFLAG_DEFAULT );
01400 
01401   /* determine detector column and type */
01402 
01403   fits_get_colnum( thisFitsFile, CASEINSEN, "DETECTOR", &colnum, &status);
01404   sprintf( errorMessage, "Could not find detector column in file %s", theFile->name );
01405   M3_ErrorCheck( -1, errorMessage, status == 0, M3_EFLAG_DEFAULT );
01406 
01407   fits_get_coltype( thisFitsFile, colnum, &coltype, &colrepeat, &colwidth, &status);
01408   sprintf( errorMessage, "Could not determine type of detector column in file %s", theFile->name );
01409   M3_ErrorCheck( -1, errorMessage, status == 0, M3_EFLAG_DEFAULT );
01410 
01411   /* allocate memory for detector column */
01412 
01413   detids = (char**)malloc(nrows * sizeof(char*));
01414   sprintf( errorMessage, "Could not allocate detector IDs for file %s", theFile->name );
01415   M3_ErrorCheck( -1, errorMessage, detids, M3_EFLAG_DEFAULT );
01416 
01417   for (i = 0; i < nrows; i++) {
01418     detids[i] = (char*)malloc((colwidth+2) * sizeof(char));
01419     sprintf( errorMessage, "Could not allocate detector ID for file %s, row %d", theFile->name, i );
01420     M3_ErrorCheck( -1, errorMessage, detids[i], M3_EFLAG_DEFAULT );
01421   }
01422   
01423   /* read detector IDs and search for the row we want */
01424 
01425   fits_read_col( thisFitsFile, TSTRING, colnum, 1, 1, nrows, NULL, detids, NULL, &status);
01426   sprintf( errorMessage, "Could not read detector IDs for file %s", theFile->name );
01427   M3_ErrorCheck( -1, errorMessage, detids, M3_EFLAG_DEFAULT );
01428 
01429   for (i = 0; i < nrows; i++) {
01430     if( strcmp(detids[i], formatStruct.detectorID) == 0 ) {
01431       foundDet = i;
01432       break;
01433     }
01434   }
01435   if (foundDet == -1) {
01436     sprintf( errorMessage, "Could not find detector ID %s in file %s", formatStruct.detectorID, theFile->name );
01437     M3_ErrorCheck( -1, errorMessage, detids, M3_EFLAG_DEFAULT );
01438   }
01439 
01440   /* free detector ID memory */
01441 
01442   for (i = 0; i < nrows; i++) {
01443     free(detids[i]);
01444   }
01445   free(detids);
01446 
01447   /* for each parameter we want, look up column number and read the parameter */
01448 
01449   fits_get_colnum( thisFitsFile, CASEINSEN, "F_KNEE", &colnum, &status);
01450   sprintf( errorMessage, "Could not find f_knee column in file %s", theFile->name );
01451   M3_ErrorCheck( -1, errorMessage, status == 0, M3_EFLAG_DEFAULT );
01452 
01453   fits_read_col( thisFitsFile, TDOUBLE, colnum, (foundDet+1), 1, 1, NULL, fknee, NULL, &status);
01454   sprintf( errorMessage, "Could not read f_knee for detector %s in file %s", formatStruct.detectorID, theFile->name );
01455   M3_ErrorCheck( -1, errorMessage, detids, M3_EFLAG_DEFAULT );
01456 
01457   fits_get_colnum( thisFitsFile, CASEINSEN, "ALPHA", &colnum, &status);
01458   sprintf( errorMessage, "Could not find alpha column in file %s", theFile->name );
01459   M3_ErrorCheck( -1, errorMessage, status == 0, M3_EFLAG_DEFAULT );
01460 
01461   fits_read_col( thisFitsFile, TDOUBLE, colnum, (foundDet+1), 1, 1, NULL, alpha, NULL, &status);
01462   sprintf( errorMessage, "Could not read alpha for detector %s in file %s", formatStruct.detectorID, theFile->name );
01463   M3_ErrorCheck( -1, errorMessage, detids, M3_EFLAG_DEFAULT );
01464 
01465   fits_get_colnum( thisFitsFile, CASEINSEN, "F_MIN", &colnum, &status);
01466   sprintf( errorMessage, "Could not find f_min column in file %s", theFile->name );
01467   M3_ErrorCheck( -1, errorMessage, status == 0, M3_EFLAG_DEFAULT );
01468 
01469   fits_read_col( thisFitsFile, TDOUBLE, colnum, (foundDet+1), 1, 1, NULL, fmin, NULL, &status);
01470   sprintf( errorMessage, "Could not read f_min for detector %s in file %s", formatStruct.detectorID, theFile->name );
01471   M3_ErrorCheck( -1, errorMessage, detids, M3_EFLAG_DEFAULT );
01472 
01473   fits_get_colnum( thisFitsFile, CASEINSEN, "F_SAMP", &colnum, &status);
01474   sprintf( errorMessage, "Could not find f_samp column in file %s", theFile->name );
01475   M3_ErrorCheck( -1, errorMessage, status == 0, M3_EFLAG_DEFAULT );
01476 
01477   fits_read_col( thisFitsFile, TDOUBLE, colnum, (foundDet+1), 1, 1, NULL, fsample, NULL, &status);
01478   sprintf( errorMessage, "Could not read f_samp for detector %s in file %s", formatStruct.detectorID, theFile->name );
01479   M3_ErrorCheck( -1, errorMessage, detids, M3_EFLAG_DEFAULT );
01480 
01481   fits_get_colnum( thisFitsFile, CASEINSEN, "NET_RJ", &colnum, &status);
01482   sprintf( errorMessage, "Could not find net_rj column in file %s", theFile->name );
01483   M3_ErrorCheck( -1, errorMessage, status == 0, M3_EFLAG_DEFAULT );
01484 
01485   fits_read_col( thisFitsFile, TDOUBLE, colnum, (foundDet+1), 1, 1, NULL, NET, NULL, &status);
01486   sprintf( errorMessage, "Could not read net_rj for detector %s in file %s", formatStruct.detectorID, theFile->name );
01487   M3_ErrorCheck( -1, errorMessage, detids, M3_EFLAG_DEFAULT );
01488 
01489   /* close the file */
01490 
01491   fits_close_file( thisFitsFile, &status);
01492   sprintf( errorMessage, "Error closing fits file named %s", theFile->name );
01493   M3_ErrorCheck(-1, errorMessage, status == 0, M3_EFLAG_DEFAULT );
01494 
01495   return;
01496 }
01497 
01498 
01499 void M3_CreateNoiseFilter( double fknee, double alpha, double fmin, double fsample, double NET, int64_t corr, double *itt_noise )
01500 {
01501   /* parameters */
01502   char errorMessage[M3_CONTENT_LENGTH];
01503   char errorString[M3_CONTENT_LENGTH];
01504   char strBuffer[M3_CONTENT_LENGTH];
01505   char strBuffer2[M3_CONTENT_LENGTH];
01506   char invnttfile[M3_CONTENT_LENGTH];
01507   char invntttext[M3_CONTENT_LENGTH];
01508   char psdfile[M3_CONTENT_LENGTH];
01509   int apo = 0;
01510   int apowidth = 0;
01511   double rttwo = sqrt(2.0);
01512 
01513   /* variables */
01514   int i;  
01515   int tfields;
01516   int npsd;
01517   int nfft;
01518   double *freq;
01519   double *psd;
01520   double *fft;
01521   double *invntt;
01522   
01523   double nyquist;
01524   double bandwidth;
01525   double halfband;
01526   double cur;
01527   fftw_plan plan;
01528 
01529   /* temp variables */
01530 
01531   double temp;
01532   double ktemp;
01533   double mtemp;
01534   char command[M3_CONTENT_LENGTH];
01535 
01536 
01537   if (corr == 0) {
01538     itt_noise[0] = 1.0 / (NET * NET * fsample);
01539     return;
01540   }
01541 
01542   nfft = 2;
01543   while (nfft < 2*corr) {
01544     nfft *= 2;
01545   }
01546   nfft *= M3_NOISE_GEN_CORRFACTOR;
01547   
01548   nfft = (nfft < M3_NOISE_GEN_MINIMUM) ? M3_NOISE_GEN_MINIMUM : nfft;
01549 
01550   /* generate the psd */
01551 
01552   npsd = 1 + (int)(nfft / 2);
01553   nyquist = (int)(fsample / 2);
01554   bandwidth = fsample / (double)(nfft);
01555   halfband = 0.5 * bandwidth;
01556   
01557   freq = (double*)calloc(npsd, sizeof(double));
01558   psd = (double*)calloc(npsd, sizeof(double));
01559   M3_ErrorCheck(-1, "M3_File_readData_LevelS_noise()", (freq && psd), M3_EFLAG_MALLOC_FSTRING );
01560 
01561   ktemp = pow(fknee, alpha);
01562   mtemp = pow(fmin, alpha);  
01563   freq[0] = 0.0;
01564   psd[0] = NET * sqrt( ktemp / mtemp );
01565   for (i = 1; i < npsd-1; i++) {
01566     cur = (double)i * bandwidth;
01567     freq[i] = cur;
01568     temp = pow(cur, alpha);
01569     psd[i] = rttwo * NET * sqrt((temp + ktemp) / (temp + mtemp));
01570   }
01571   freq[npsd-1] = bandwidth * (double)(npsd-1);
01572   temp = pow(freq[npsd-1], alpha);
01573   psd[npsd-1] = NET * sqrt((temp + ktemp) / (temp + mtemp));
01574   
01575   /* convert PSD to (N / |Y(f)|^2) and pre-normalize for FFTW */
01576 
01577   invntt = (double*)calloc(nfft, sizeof(double));
01578   fft = (double*)calloc(nfft, sizeof(double));
01579   M3_ErrorCheck(-1, "M3_File_readData_LevelS_noise()", (invntt && fft), M3_EFLAG_MALLOC_FSTRING );
01580   
01581   plan = fftw_plan_r2r_1d(nfft, fft, invntt, FFTW_HC2R, FFTW_ESTIMATE);
01582   
01583   temp = (double)(nfft) * (double)(nfft);
01584   for (i = 0; i < npsd; i++) {
01585     if ((i > 0) && (i < npsd-1)) {
01586       fft[i] = 1.0 / (temp * halfband * (psd[i] * psd[i]));
01587     } else {
01588       fft[i] = 1.0 / (temp * bandwidth * (psd[i] * psd[i]));
01589     }
01590   }
01591   
01592   /* compute inverse noise correlations.  */
01593   fftw_execute(plan);
01594   memcpy( itt_noise, invntt, (corr+1)*sizeof(double));
01595 
01596   fftw_destroy_plan(plan);
01597   fftw_cleanup();
01598   free(psd);
01599   free(invntt);
01600   free(fft);
01601   free(freq);
01602 
01603   return;
01604 }
01605 
01606 
01607 void M3_File_readData_LevelS_noise( M3_File *theFile,  double *itt_noise )
01608 {
01609   double fsample = 0.0;
01610   double fknee = 0.0;
01611   double fmin = 0.0;
01612   double NET = 0.0;
01613   double alpha = 0.0;
01614   int64_t corr = 0.0;
01615 
01616   M3_File_getFPDBparam( theFile, &fknee, &alpha, &fmin, &fsample, &NET );
01617   corr = theFile->param.noise.corLength;
01618   M3_CreateNoiseFilter( fknee, alpha, fmin, fsample, NET, corr, itt_noise );
01619 }
01620 
01621 
01622 
01623 

Generated on Mon Nov 24 10:05:12 2008 for M3 by  doxygen 1.5.3-20071008