M3.c

00001 /*******************************************************************************
00002 *   M3:  M3.c                                                                  *
00003 *                                                                              *
00004 *   Version 1.0 May 2004                                                       *
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 
00025 /* FIX ME: M3_RunConfigStruct_Read() does not check that all nessesary files are given, 
00026    in particular, it does not check that a map file is given in the case of a 
00027    MADmap run.  */
00028 
00029 
00030 #include <sys/types.h>
00031 #include <sys/stat.h>
00032 #include "M3.h"
00033 #include "M3_system.h"
00034 #include "M3_otfs.h"
00035 #include "M3_cache.h"
00036 #include <M3_memory.h>
00037 #include <M3_gcp.h>
00038 #include <M3_format.h>
00039 #include <M3_profile.h>
00040 #include <chealpix.h>
00041 
00042 #define minimum(a,b) (((a) < (b)) ? (a) : (b))
00043 #define maximum(a,b) (((a) > (b)) ? (a) : (b))
00044 
00045 
00046 
00047 #define M3_NAME_LENGTH 64
00048 #define M3_CONTENT_LENGTH 256
00049 #define M3_PLANCK_POINTING_EVENT_RATE 2.777777777777778e-04
00050 #define M3_GCP_STORE_JOIN_TIME 1e-7
00051 
00052 typedef struct
00053 {
00054   M3_TimeEl value;
00055   int boundryFlag;
00056 } M3_intervalSortStruct;
00057 
00058 int M3_TimeIntervalLL_qsortComp( const void *a, const void *b );
00059 
00060 int M3_TimeIntervalLL_qsortComp( const void *a, const void *b )
00061 {
00062   M3_intervalSortStruct *as, *bs;
00063   double diff;
00064 
00065 
00066   as = (M3_intervalSortStruct *)a;
00067   bs = (M3_intervalSortStruct *)b;
00068 
00069   diff = M3_TimeEl_Difference( as->value, bs->value );
00070   if( fabs(diff) <  M3_GCP_STORE_JOIN_TIME )
00071   {
00072     if( as->boundryFlag == 1 && bs->boundryFlag == -1 )
00073       return -1;
00074     else if( bs->boundryFlag == 1 && as->boundryFlag == -1)
00075       return 1;
00076     return 0;
00077   }
00078   if( diff < 0 )
00079     return -1;
00080   if( diff > 0 )
00081     return 1;
00082 }
00083 
00084 
00085 
00086 /* PUBLIC DATABASE INTERFACE FUNCTION DEFINITIONS */
00087 
00088 /* OBJECT:  M3_RunConfigStruct */
00089 
00090 void M3_RunConfigStruct_Read( M3_RunConfigStruct **runConfigOut, char *runConfigFileName, int runType )
00091 {
00092   char name[M3_NAME_LENGTH];
00093   xmlDocPtr xmlDoc = NULL;
00094   xmlNodePtr thisXMLnode = NULL;
00095   M3_PixelClassLL *thisPixelClass;
00096   M3_DataSetLL *thisDataSet;
00097   M3_RunConfigStruct *runConfig;
00098   M3_GCPointingGroupLL *thisGCPointingGroup;
00099 #ifdef M3_USE_PROFILE_FREAD
00100   char *tempPtr;
00101   static int envUseProfile = -1;
00102   if( envUseProfile == -1 )
00103   {
00104     tempPtr = getenv( "M3_USE_PROFILE_FREAD" );
00105     if( tempPtr )
00106       envUseProfile = 1;
00107     else 
00108       envUseProfile = 0;  
00109   }
00110   if( envUseProfile )
00111   {
00112     M3_ProfileInit( "M3_fread" );
00113     envUseProfile = 0;
00114   }
00115 #endif
00116 
00117   name[M3_NAME_LENGTH-1] = '\0';
00118 
00119 
00120   runConfig = (M3_RunConfigStruct *)calloc(1, sizeof(M3_RunConfigStruct));
00121   M3_ErrorCheck(-1, "M3_RunConfigStruct_Read", runConfig, M3_EFLAG_MALLOC_FSTRING);
00122   *runConfigOut = runConfig;
00123 
00124   /* Go to the root of XML file. */
00125   xmlDoc = xmlReadFile(runConfigFileName, NULL, 0);
00126   M3_ErrorCheck(-1, "XML read of config file failed", xmlDoc, M3_EFLAG_DEFAULT);
00127     
00128   thisXMLnode = xmlDocGetRootElement(xmlDoc);
00129   M3_ErrorCheck(-1, "Config file empty", thisXMLnode, M3_EFLAG_DEFAULT);
00130 
00131   M3_ErrorCheck(-1, "File not of type runConfig", 
00132                 strcmp( (char*)(thisXMLnode->name), "runConfig") == 0, M3_EFLAG_DEFAULT);
00133 
00134   /* Parse pixel class and GCPointing information first */
00135   M3_XML_decend( thisXMLnode, &thisXMLnode, M3_NAME_LENGTH, name );
00136   while(name[0])
00137   {
00138     if( strcmp(name, "pixelClass") == 0 )
00139     {
00140       thisPixelClass = (M3_PixelClassLL *)calloc(1, sizeof(M3_PixelClassLL));
00141       M3_XML_parsePixelClassNode( thisXMLnode, runType,thisPixelClass );
00142       M3_PixelClassLL_insertInOrder( thisPixelClass, &(runConfig->pixelClassList) );
00143     }
00144     else if( strcmp(name, "GCPointingGroup") == 0 )
00145     {
00146       if( runConfig->GCPointingGroupList )
00147       {
00148         for( thisGCPointingGroup = runConfig->GCPointingGroupList; thisGCPointingGroup = thisGCPointingGroup->next; thisGCPointingGroup->next );
00149         thisGCPointingGroup->next = (M3_GCPointingGroupLL *)calloc(1, sizeof(M3_GCPointingGroupLL));
00150         M3_ErrorCheck(-1, "M3_RunConfigStruct_Read", (thisGCPointingGroup->next ? 1 : 0 ), M3_EFLAG_MALLOC_FSTRING);
00151         thisGCPointingGroup = thisGCPointingGroup->next;
00152       }
00153       else
00154       {
00155         runConfig->GCPointingGroupList = (M3_GCPointingGroupLL *)calloc(1, sizeof(M3_GCPointingGroupLL));
00156         M3_ErrorCheck(-1, "M3_RunConfigStruct_Read", (runConfig->GCPointingGroupList ? 1 : 0 ), M3_EFLAG_MALLOC_FSTRING);
00157         thisGCPointingGroup = runConfig->GCPointingGroupList;
00158       }
00159       M3_XML_parseGCPointingGroupNode( thisXMLnode, runType, thisGCPointingGroup );
00160     }
00161     else if( strcmp(name, "dataSet") && strcmp(name, "powerSpectrum") && strcmp(name, "sparsePixelMatrixFile") )
00162       fprintf(stderr, "WARNING:  %s is not a valid tag in a runConfig, it will be ignored\n", name);
00163 
00164     M3_XML_follow(thisXMLnode, &thisXMLnode, M3_NAME_LENGTH, name );
00165   }
00166 
00167   /* Go back and parse the data sets and power spectrum */
00168 
00169   thisXMLnode = xmlDocGetRootElement(xmlDoc);
00170 
00171   M3_XML_decend(thisXMLnode, & thisXMLnode, M3_NAME_LENGTH, name );
00172   
00173   while( name[0] )
00174   {
00175     if( strcmp(name, "dataSet") == 0 )
00176     {
00177       if( runConfig->dataSetList )
00178       {
00179         for( thisDataSet = runConfig->dataSetList; thisDataSet->next; thisDataSet = thisDataSet->next );
00180         thisDataSet->next = (M3_DataSetLL *)calloc(1, sizeof(M3_DataSetLL));
00181         M3_ErrorCheck(-1, "M3_RunConfigStruct_Read", (thisDataSet->next), M3_EFLAG_MALLOC_FSTRING);
00182         thisDataSet = thisDataSet->next;
00183       }
00184       else
00185       {
00186         runConfig->dataSetList = (M3_DataSetLL *)calloc(1, sizeof(M3_DataSetLL));
00187         M3_ErrorCheck(-1, "M3_RunConfigStruct_Read", (runConfig->dataSetList), M3_EFLAG_MALLOC_FSTRING);
00188         thisDataSet = runConfig->dataSetList;
00189       }
00190       M3_XML_parseDataSetNode(thisXMLnode, runType, runConfig->pixelClassList, runConfig->GCPointingGroupList, thisDataSet );
00191       thisDataSet->pixelConvertNode = &(runConfig->pixelConvert);
00192       thisDataSet->runConfigNode = runConfig;
00193     }
00194     else if( strcmp(name, "powerSpectrum") == 0 )
00195     {
00196       M3_XML_parsePowerSpectrumNode( thisXMLnode, runType, &(runConfig->powerSpectrum) );
00197     }
00198     else if( strcmp(name, "sparsePixelMatrixFile") == 0 )
00199     {
00200       M3_XML_parseSparsePixelMatrixNode( thisXMLnode, runType, &(runConfig->sparsePixelMatrix) );
00201     }
00202     M3_XML_follow( thisXMLnode, &thisXMLnode, M3_NAME_LENGTH, name);
00203   }
00204 
00205   /* Free up the XML structure */
00206   xmlFreeDoc(xmlDoc);
00207   /* Fill in remaining elements in the run config structure */
00208   M3_RunConfigStruct_refine( runConfig, runType );
00209 
00210   return;
00211 }
00212 
00213 void M3_RunConfigStruct_ReadBin( M3_RunConfigStruct **runConfigOut, char *runConfigFileName, int runType )
00214 {
00215   FILE *fid;
00216   struct stat sb;
00217   M3_RunConfigStruct *runConfigP;
00218 #ifdef M3_USE_PROFILE_FREAD
00219   char *tempPtr;
00220   static int envUseProfile = -1;
00221   if( envUseProfile == -1 )
00222   {
00223     tempPtr = getenv( "M3_USE_PROFILE_FREAD" );
00224     if( tempPtr )
00225       envUseProfile = 1;
00226     else 
00227       envUseProfile = 0;  
00228   }
00229   if( envUseProfile )
00230   {
00231     M3_ProfileInit( "M3_fread" );
00232     envUseProfile = 0;
00233   }
00234 #endif
00235 
00236   fid = fopen(runConfigFileName, "r" );
00237 
00238   M3_ErrorCheck(-1, runConfigFileName, (fid?1:0), M3_EFLAG_FOPEN_READ );
00239 
00240   stat( runConfigFileName, &sb );
00241 
00242   M3_ErrorCheck(-1, "Binary run config file is empty", sb.st_size, M3_EFLAG_DEFAULT );
00243 
00244   runConfigP = (M3_RunConfigStruct *)malloc( sb.st_size );
00245 
00246   M3_ErrorCheck(-1, "M3_RunConfigStruct_ReadBin", (runConfigP?1:0), M3_EFLAG_MALLOC_FSTRING );
00247 
00248   fread( runConfigP, 1, sb.st_size, fid );
00249 
00250   fclose(fid);
00251 
00252   M3_RunConfigStruct_shiftPointers( runConfigP, 1 );
00253 
00254   M3_RunConfigStruct_duplicateP( runConfigP, runConfigOut, 0 );
00255 
00256   free( runConfigP );
00257 
00258   return;
00259 }
00260 
00261 void M3_RunConfigStruct_Write( M3_RunConfigStruct *runConfig, char *runConfigFileName  )
00262 {
00263   int i, j;
00264   struct stat64 sbuf;
00265   FILE *runConfigFile;
00266   M3_PixelClassLL *thisPixelClass;
00267   M3_FileLL *thisFile;
00268   M3_DataSetLL *thisDataSet;
00269   M3_ComponentLL *thisComponent;
00270   M3_SubcomponentLL *thisSubcomponent;
00271   M3_PointingClassLL *thisClass;
00272   M3_PointingSubclassLL *thisSubclass;
00273   M3_IntervalLL *thisInterval;
00274   M3_SpectrumClassLL *thisSpectrumClass;
00275   M3_GCPointingGroupLL *thisGCPointingGroup;
00276 
00277   runConfigFile = fopen( runConfigFileName, "w");
00278   M3_ErrorCheck( -1, runConfigFileName, runConfigFile, M3_EFLAG_FOPEN_WRITE );
00279 
00280   fprintf( runConfigFile, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
00281   fprintf( runConfigFile, "<runConfig>\n\n");
00282 
00283   for( thisPixelClass = runConfig->pixelClassList; thisPixelClass; thisPixelClass = thisPixelClass->next )
00284   {
00285     fprintf( runConfigFile, "<pixelClass>\n");
00286 
00287     fprintf( runConfigFile, "  <className>%s</className>\n", thisPixelClass->className );
00288 
00289     fprintf( runConfigFile, "  <numPixelInClass>%i</numPixelInClass>\n", thisPixelClass->numPixelInClass);
00290 
00291     fprintf( runConfigFile, "  <mapFile>\n");
00292     fprintf( runConfigFile, "    <name>%s</name>\n", thisPixelClass->mapFile->name);
00293     fprintf( runConfigFile, "    <format>%s</format>\n", thisPixelClass->mapFile->format);
00294     fprintf( runConfigFile, "  </mapFile>\n");
00295 
00296     switch( thisPixelClass->pixelType )
00297     {
00298       case M3_DEFAULT_PIXEL_TYPE:
00299         fprintf( runConfigFile, "  <pixelType>default</pixelType>\n");
00300         break;
00301       case M3_CMB_I_PIXEL_TYPE:
00302         fprintf( runConfigFile, "  <pixelType>I</pixelType>\n");
00303         break;
00304       case M3_CMB_Q_PIXEL_TYPE:
00305         fprintf( runConfigFile, "  <pixelType>Q</pixelType>\n");
00306         break;
00307       case M3_CMB_U_PIXEL_TYPE:
00308         fprintf( runConfigFile, "  <pixelType>U</pixelType>\n");
00309     }
00310 
00311     if( thisPixelClass->coordFile )
00312     {
00313       fprintf( runConfigFile, "  <coordFile>\n");
00314       fprintf( runConfigFile, "    <name>%s</name>\n", thisPixelClass->coordFile->name);
00315       fprintf( runConfigFile, "    <format>%s</format>\n", thisPixelClass->coordFile->format);
00316       fprintf( runConfigFile, "  </coordFile>\n");
00317     }
00318     
00319     if( thisPixelClass->windowFile )
00320     {
00321       fprintf( runConfigFile, "  <windowFile>\n");
00322       fprintf( runConfigFile, "    <name>%s</name>\n", thisPixelClass->windowFile->name);
00323       fprintf( runConfigFile, "    <format>%s</format>\n", thisPixelClass->windowFile->format);
00324       fprintf( runConfigFile, "  </windowFile>");
00325     }
00326     
00327     if( thisPixelClass->maskFileList )
00328     {
00329       fprintf( runConfigFile, "  <maskFiles>\n");
00330       for( thisFile = thisPixelClass->maskFileList; thisFile; thisFile = thisFile->next )
00331       {
00332         fprintf( runConfigFile, "    <file>\n");
00333         fprintf( runConfigFile, "      <name>%s</name>\n", thisFile->file.name);
00334         fprintf( runConfigFile, "      <format>%s</format>\n", thisFile->file.format);
00335         fprintf( runConfigFile, "    </file>\n");
00336       }
00337       fprintf( runConfigFile, "  </maskFiles>\n");
00338     }
00339 
00340     if( thisPixelClass->templateFileList )
00341     {
00342       fprintf( runConfigFile, "  <templateFiles>\n");
00343       for( thisFile = thisPixelClass->templateFileList; thisFile; thisFile = thisFile->next )
00344       {
00345         fprintf( runConfigFile, "    <file>\n");
00346         fprintf( runConfigFile, "      <name>%s</name>\n", thisFile->file.name);
00347         fprintf( runConfigFile, "      <format>%s</format>\n", thisFile->file.format);
00348         fprintf( runConfigFile, "    </file>\n");
00349       }
00350       fprintf( runConfigFile, "  </templateFiles>\n");
00351     }
00352     
00353     fprintf( runConfigFile, "</pixelClass>\n\n");
00354   }
00355 
00356   if( runConfig->sparsePixelMatrix != NULL )
00357   {
00358     fprintf( runConfigFile, "<sparsePixelMatrixFile>\n");
00359     
00360     fprintf( runConfigFile, "  <name>%s</name>\n", runConfig->sparsePixelMatrix->name);
00361     
00362     fprintf( runConfigFile, "  <format>%s</format>\n", runConfig->sparsePixelMatrix->format);
00363     
00364     fprintf( runConfigFile, "</sparsePixelMatrixFile>\n");
00365   }
00366 
00367   for( thisGCPointingGroup = runConfig->GCPointingGroupList; thisGCPointingGroup; thisGCPointingGroup = thisGCPointingGroup->next )
00368   {
00369     fprintf( runConfigFile, "<GCPointingGroup>\n");
00370     
00371     fprintf( runConfigFile, "  <name>%s</name>\n", thisGCPointingGroup->name);
00372 
00373     fprintf( runConfigFile, "  <GCPointingType>%s</GCPointingType>\n", thisGCPointingGroup->GCPointingType);
00374     
00375     if( thisGCPointingGroup->auxFile )
00376     {
00377       fprintf( runConfigFile, "  <auxDataFile>\n");
00378       
00379       fprintf( runConfigFile, "    <name>%s</name>\n", thisGCPointingGroup->auxFile->name);
00380       
00381       fprintf( runConfigFile, "    <format>%s</format>\n", thisGCPointingGroup->auxFile->format);
00382 
00383       fprintf( runConfigFile, "  </auxDataFile>\n");
00384     }
00385 
00386     if( thisGCPointingGroup->GCPointingFileList )
00387     {
00388       fprintf( runConfigFile, "  <GCPointingFiles>\n" );
00389    
00390       for( thisFile = thisGCPointingGroup->GCPointingFileList; thisFile; thisFile = thisFile->next )
00391       {
00392         fprintf( runConfigFile, "    <file>\n");
00393 
00394         fprintf( runConfigFile, "      <name>%s</name>\n", thisFile->file.name);
00395 
00396         fprintf( runConfigFile, "      <format>%s</format>\n", thisFile->file.format);
00397 
00398         fprintf( runConfigFile, "    </file>\n");
00399       }
00400 
00401       fprintf( runConfigFile, "  </GCPointingFiles>\n");
00402     }
00403     fprintf( runConfigFile, "</GCPointingGroup>\n" );
00404   }
00405 
00406   for( thisDataSet = runConfig->dataSetList; thisDataSet; thisDataSet = thisDataSet->next)
00407   {
00408     fprintf( runConfigFile, "<dataSet>\n");
00409 
00410     fprintf( runConfigFile, "  <name>%s</name>\n", thisDataSet->name );
00411     
00412     if( thisDataSet->firstTime.sec )
00413       fprintf( runConfigFile, "<firstTime_sec>%lli</firstTime_sec>\n", thisDataSet->firstTime.sec );
00414 
00415     if( thisDataSet->firstTime.nsec) 
00416       fprintf( runConfigFile, "<firstTime_nsec>%.16e</firstTime_nsec>\n", thisDataSet->firstTime.nsec );
00417 
00418     if( thisDataSet->sampleRate )
00419       fprintf( runConfigFile, "<sampleRate>%e</sampleRate>\n", thisDataSet->sampleRate );
00420 
00421     for( thisComponent = thisDataSet->componentList; thisComponent; thisComponent = thisComponent->next)
00422     {
00423       fprintf( runConfigFile, "  <component>\n");
00424 
00425       for( thisSubcomponent = thisComponent->subcomponentList; thisSubcomponent; thisSubcomponent = thisSubcomponent->next )
00426       {
00427         if( thisSubcomponent->simType ==  M3_NO_SIM_TYPE )
00428         {
00429           fprintf( runConfigFile, "    <subcomponent>\n");
00430         
00431           for( thisFile = thisSubcomponent->todFileList; thisFile; thisFile = thisFile->next )
00432           {
00433             fprintf( runConfigFile, "      <file>\n");
00434             fprintf( runConfigFile, "        <name>%s</name>\n", thisFile->file.name);
00435             fprintf( runConfigFile, "        <format>%s</format>\n", thisFile->file.format);
00436             if( thisFile->file.param.tod.calib != 1 )
00437               fprintf( runConfigFile, "        <calib>%e</calib>\n", thisFile->file.param.tod.calib );
00438             fprintf( runConfigFile, "      </file>\n");
00439           }
00440         
00441           fprintf( runConfigFile, "    </subcomponent>\n");
00442         }
00443         else if( thisSubcomponent->simType == M3_MAPSCAN_SIM_TYPE )
00444         {
00445           fprintf( runConfigFile, "    <subcomponentSim>\n");
00446           fprintf( runConfigFile, "      <mapScanSim>\n");
00447           fprintf( runConfigFile, "      </mapScanSim>\n");
00448           fprintf( runConfigFile, "    </subcomponentSim>\n");
00449         }
00450         else if( thisSubcomponent->simType == M3_OOFNOISE_SIM_TYPE )
00451         {
00452           fprintf( runConfigFile, "    <subcomponentSim>\n");
00453           fprintf( runConfigFile, "      <oofNoiseSim>\n");
00454           fprintf( runConfigFile, "      </oofNoiseSim>\n");
00455           fprintf( runConfigFile, "    </subcomponentSim>\n");
00456         }
00457 
00458       }
00459       if( thisComponent->todCalibFileList )
00460       {
00461         fprintf( runConfigFile, "    <tocFiles>\n");  
00462         for( thisFile = thisComponent->todCalibFileList; thisFile; thisFile = thisFile->next )
00463         {
00464           fprintf( runConfigFile, "      <file>\n");
00465           fprintf( runConfigFile, "        <name>%s</name>\n", thisFile->file.name);
00466           fprintf( runConfigFile, "        <format>%s</format>\n", thisFile->file.format);
00467           if( thisFile->file.param.toc.calib != 1 )
00468             fprintf( runConfigFile, "        <calib>%e</calib>\n", thisFile->file.param.toc.calib );
00469           if( thisFile->file.param.toc.action == M3_MULTIPLY_TOC_ACTION )
00470             fprintf( runConfigFile, "        <action>multiply</action>\n");
00471           else 
00472             fprintf( runConfigFile, "        <action>divide</action>\n");
00473           fprintf( runConfigFile, "      </file>\n");
00474         }
00475 
00476         fprintf( runConfigFile, "    </tocFiles>\n");
00477       }
00478 
00479       fprintf( runConfigFile, "  </component>\n");
00480     }
00481 
00482     fprintf( runConfigFile, "  <pointingFiles>\n");
00483 
00484     for( thisClass = thisDataSet->pointingClassList; thisClass; thisClass = thisClass->next )
00485     {
00486       fprintf( runConfigFile, "    <class>\n");
00487       fprintf( runConfigFile, "      <pixelClassName>%s</pixelClassName>\n", thisClass->pixelClassNode->className);
00488 
00489       for( thisSubclass = thisClass->subclassList; thisSubclass; thisSubclass = thisSubclass->next )
00490       {
00491         if( thisSubclass->pointingFileList )
00492         {
00493           fprintf( runConfigFile, "      <subclass>\n");
00494           for( thisFile = thisSubclass->pointingFileList; thisFile; thisFile = thisFile->next )
00495           {
00496             fprintf( runConfigFile, "        <file>\n");
00497             fprintf( runConfigFile, "          <name>%s</name>\n", thisFile->file.name);
00498             fprintf( runConfigFile, "          <format>%s</format>\n", thisFile->file.format);
00499             if( thisFile->file.param.pointing.calib != 1 )
00500               fprintf( runConfigFile, "          <calib>%e</calib>\n", thisFile->file.param.pointing.calib );
00501             fprintf( runConfigFile, "        </file>\n");
00502           }
00503 
00504           fprintf( runConfigFile, "      </subclass>\n");
00505         }
00506         else if( thisSubclass->GCPointingGroupNode )
00507         {
00508           fprintf( runConfigFile, "      <subclassGC>\n");
00509           fprintf( runConfigFile, "        <GCPointingGroupRef>%s</GCPointingGroupRef>\n", thisSubclass->GCPointingGroupNode->name);
00510           fprintf( runConfigFile, "        <auxComplement>%s</auxComplement>\n", thisSubclass->auxComplement);
00511           fprintf( runConfigFile, "      </subclassGC>\n");
00512         }
00513       }
00514 
00515       if( thisClass->pointingCalibFileList )
00516       {
00517         fprintf( runConfigFile, "      <tocFiles>\n");
00518         
00519         for( thisFile = thisClass->pointingCalibFileList; thisFile; thisFile = thisFile->next )
00520         {
00521           fprintf( runConfigFile, "        <file>\n");
00522           fprintf( runConfigFile, "          <name>%s</name>\n", thisFile->file.name);
00523           fprintf( runConfigFile, "          <format>%s</format>\n", thisFile->file.format);
00524           if( thisFile->file.param.toc.calib != 1 )
00525             fprintf( runConfigFile, "          <calib>%e</calib>\n", thisFile->file.param.toc.calib );
00526           if( thisFile->file.param.toc.action == M3_MULTIPLY_TOC_ACTION )
00527             fprintf( runConfigFile, "          <action>multiply</action>\n");
00528           else
00529             fprintf( runConfigFile, "          <action>divide</action>\n");
00530           fprintf( runConfigFile, "        </file>\n");
00531         }
00532 
00533         fprintf( runConfigFile, "      </tocFiles>\n");
00534       }
00535 
00536       fprintf( runConfigFile, "    </class>\n");
00537     }
00538     
00539     fprintf( runConfigFile, "  </pointingFiles>\n");
00540     
00541     fprintf( runConfigFile, "  <noiseFiles>\n");
00542 
00543     for( thisFile = thisDataSet->noiseFileList; thisFile; thisFile = thisFile->next )
00544     {
00545       fprintf( runConfigFile, "    <file>\n");
00546       fprintf( runConfigFile, "      <name>%s</name>\n", thisFile->file.name );
00547       fprintf( runConfigFile, "      <format>%s</format>\n", thisFile->file.format);
00548       if( thisFile->file.param.noise.calib != 1 )
00549         fprintf( runConfigFile, "      <calib>%e</calib>\n", thisFile->file.param.noise.calib );
00550       fprintf( runConfigFile, "      <corLength>%lli</corLength>\n", thisFile->file.param.noise.corLength );
00551       if( stat64( thisFile->file.name, &sbuf) != 0 )
00552       {
00553         fprintf( runConfigFile, "      <interval>\n");
00554         fprintf( runConfigFile, "        <firstSample>%lli</firstSample>\n", thisFile->file.param.noise.interval.firstSample );
00555         fprintf( runConfigFile, "        <lastSample>%lli</lastSample>\n", thisFile->file.param.noise.interval.lastSample );
00556         fprintf( runConfigFile, "      </interval>\n");
00557       }
00558       fprintf( runConfigFile, "    </file>\n");
00559     }    
00560 
00561     fprintf( runConfigFile, "  </noiseFiles>\n");
00562     
00563     fprintf( runConfigFile, "  <setIntervals>\n");
00564     
00565     for( thisInterval = thisDataSet->coveredIntervalList; thisInterval; thisInterval = thisInterval->next )
00566     {
00567       fprintf( runConfigFile, "    <interval>\n");
00568       fprintf( runConfigFile, "      <firstSample>%lli</firstSample>\n", thisInterval->interval.firstSample );
00569       fprintf( runConfigFile, "      <lastSample>%lli</lastSample>\n", thisInterval->interval.lastSample );
00570       fprintf( runConfigFile, "    </interval>\n");
00571     }
00572 
00573     fprintf( runConfigFile, "  </setIntervals>\n");
00574     
00575     j = 0;
00576     for( i = 0; i < M3_NUM_FILTER_TYPE; i++ )
00577       if( thisDataSet->filterFileList[i] )
00578         j = 1;
00579 
00580     if( j )
00581     {
00582       fprintf( runConfigFile, "  <filterFiles>\n");
00583       
00584       if( thisDataSet->filterFileList[M3_W_FILTER_TYPE] )
00585       {
00586         fprintf( runConfigFile, "    <wFilters>\n");
00587         
00588         for( thisFile = thisDataSet->filterFileList[M3_W_FILTER_TYPE]; thisFile; thisFile = thisFile->next )
00589         {
00590           fprintf( runConfigFile, "      <file>\n");
00591           fprintf( runConfigFile, "        <name>%s</name>\n", thisFile->file.name);
00592           fprintf( runConfigFile, "        <format>%s</format>\n", thisFile->file.format);
00593           fprintf( runConfigFile, "        <length>%lli</length>\n", thisFile->file.param.filter.length);
00594           fprintf( runConfigFile, "        <bandWidth>%lli</bandWidth>\n", thisFile->file.param.filter.bandWidth);
00595           fprintf( runConfigFile, "      </file>\n");
00596         }
00597         
00598         fprintf( runConfigFile, "    </wFilters>\n");
00599 
00600       }
00601 
00602       if( thisDataSet->filterFileList[M3_E_FILTER_TYPE] )
00603       {
00604 
00605         fprintf( runConfigFile, "    <eFilters>\n");
00606         
00607         for( thisFile = thisDataSet->filterFileList[M3_E_FILTER_TYPE]; thisFile; thisFile = thisFile->next )
00608         {
00609           fprintf( runConfigFile, "      <file>\n");
00610           fprintf( runConfigFile, "        <name>%s</name>\n", thisFile->file.name);
00611           fprintf( runConfigFile, "        <format>%s</format>\n", thisFile->file.format);
00612           fprintf( runConfigFile, "        <length>%lli</length>\n", thisFile->file.param.filter.length);
00613           fprintf( runConfigFile, "        <bandWidth>%lli</bandWidth>\n", thisFile->file.param.filter.bandWidth);
00614           fprintf( runConfigFile, "      </file>\n");
00615         }
00616         
00617         fprintf( runConfigFile, "    </eFilters>\n");
00618       }
00619       if( thisDataSet->filterFileList[M3_S_FILTER_TYPE] )
00620       {
00621         fprintf( runConfigFile, "    <sFilters>\n");
00622         
00623         for( thisFile = thisDataSet->filterFileList[M3_S_FILTER_TYPE]; thisFile; thisFile = thisFile->next )
00624         {
00625           fprintf( runConfigFile, "      <file>\n");
00626           fprintf( runConfigFile, "        <name>%s</name>\n", thisFile->file.name);
00627           fprintf( runConfigFile, "        <format>%s</format>\n", thisFile->file.format);
00628           fprintf( runConfigFile, "        <length>%lli</length>\n", thisFile->file.param.filter.length);
00629           fprintf( runConfigFile, "        <bandWidth>%lli</bandWidth>\n", thisFile->file.param.filter.bandWidth);
00630           fprintf( runConfigFile, "      </file>\n");
00631         }
00632         
00633         fprintf( runConfigFile, "    </sFilters>\n");
00634       }
00635 
00636       if( thisDataSet->filterFileList[M3_B_FILTER_TYPE] )
00637       {
00638 
00639         fprintf( runConfigFile, "    <bFilters>\n");
00640         
00641         for( thisFile = thisDataSet->filterFileList[M3_B_FILTER_TYPE]; thisFile; thisFile = thisFile->next )
00642         {
00643           fprintf( runConfigFile, "      <file>\n");
00644           fprintf( runConfigFile, "        <name>%s</name>\n", thisFile->file.name);
00645           fprintf( runConfigFile, "        <format>%s</format>\n", thisFile->file.format);
00646           fprintf( runConfigFile, "        <length>%lli</length>\n", thisFile->file.param.filter.length);
00647           fprintf( runConfigFile, "        <bandWidth>%lli</bandWidth>\n", thisFile->file.param.filter.bandWidth);
00648           fprintf( runConfigFile, "      </file>\n");
00649         }
00650         
00651         fprintf( runConfigFile, "    </bFilters>\n");
00652       }
00653 
00654       fprintf( runConfigFile, "  </filterFiles>\n");
00655     }
00656 
00657     fprintf( runConfigFile, "</dataSet>\n\n");
00658   }
00659 
00660   if( runConfig->powerSpectrum.spectrumClassList )
00661   {
00662     fprintf( runConfigFile, "<powerSpectrum>\n");
00663 
00664     for(thisSpectrumClass = runConfig->powerSpectrum.spectrumClassList; thisSpectrumClass; thisSpectrumClass = thisSpectrumClass->next)
00665     {
00666       fprintf( runConfigFile, "  <spectrumClass>\n");
00667       
00668       switch( thisSpectrumClass->spectrumType )
00669       {
00670         case M3_TT_SPECTRUM_TYPE:
00671           fprintf( runConfigFile, "    <spectrumType>TT</spectrumType>\n");
00672           break;
00673         case M3_EE_SPECTRUM_TYPE:
00674           fprintf( runConfigFile, "    <spectrumType>EE</spectrumType>\n");
00675           break;
00676         case M3_BB_SPECTRUM_TYPE:
00677           fprintf( runConfigFile, "    <spectrumType>BB</spectrumType>\n");
00678           break;
00679         case M3_TE_SPECTRUM_TYPE:
00680           fprintf( runConfigFile, "    <spectrumType>TE</spectrumType>\n");
00681           break;
00682         case M3_TB_SPECTRUM_TYPE:
00683           fprintf( runConfigFile, "    <spectrumType>TB</spectrumType>\n");
00684           break;
00685         case M3_EB_SPECTRUM_TYPE:
00686           fprintf( runConfigFile, "    <spectrumType>EB</spectrumType>\n");
00687           break;
00688       }
00689 
00690       fprintf( runConfigFile, "    <binFile>\n");
00691       fprintf( runConfigFile, "      <name>%s</name>\n", thisSpectrumClass->binFile->name );
00692       fprintf( runConfigFile, "      <format>%s</format>\n", thisSpectrumClass->binFile->format );
00693       fprintf( runConfigFile, "    </binFile>\n");
00694 
00695       fprintf( runConfigFile, "    <shapeFile>\n");
00696       fprintf( runConfigFile, "      <name>%s</name>\n", thisSpectrumClass->shapeFile->name );
00697       fprintf( runConfigFile, "      <format>%s</format>\n", thisSpectrumClass->shapeFile->format);
00698       fprintf( runConfigFile, "    </shapeFile>\n");
00699 
00700       fprintf( runConfigFile, "    <bpsFile>\n");
00701       fprintf( runConfigFile, "      <name>%s</name>\n", thisSpectrumClass->bpsFile->name);
00702       fprintf( runConfigFile, "      <format>%s</format>\n", thisSpectrumClass->bpsFile->format);
00703       fprintf( runConfigFile, "    </bpsFile>\n");
00704 
00705       fprintf( runConfigFile, "  </spectrumClass>\n");
00706     }
00707 
00708     fprintf( runConfigFile, "  <fisherMatrixFile>\n");
00709     fprintf( runConfigFile, "    <name>%s</name>\n", runConfig->powerSpectrum.fisherMatrix->name );
00710     fprintf( runConfigFile, "    <format>%s</format>\n", runConfig->powerSpectrum.fisherMatrix->format );
00711     fprintf( runConfigFile, "  </fisherMatrixFile>\n");
00712 
00713     fprintf( runConfigFile, "</powerSpectrum>\n\n");
00714   }
00715 
00716   fprintf( runConfigFile, "</runConfig>\n");
00717 
00718   fclose( runConfigFile);
00719 
00720   return;
00721 }
00722 
00723 
00724 void M3_RunConfigStruct_Destroy( M3_RunConfigStruct *runConfig )
00725 {
00726 #ifdef M3_USE_PROFILE_FREAD
00727   char *tempPtr;
00728   static int envUseProfile = -1;
00729   if( envUseProfile == -1 )
00730   {
00731     tempPtr = getenv( "M3_USE_PROFILE_FREAD" );
00732     if( tempPtr )
00733       envUseProfile = 1;
00734     else 
00735       envUseProfile = 0;  
00736   }
00737 #endif 
00738 
00739   if( runConfig )
00740   {
00741     M3_PixelClassLL_destroyList( runConfig->pixelClassList );
00742 
00743     M3_File_destroy( runConfig->sparsePixelMatrix );
00744 
00745     M3_GCPointingGroupLL_destroyList( runConfig->GCPointingGroupList );
00746 
00747     M3_DataSetLL_destroyList( runConfig->dataSetList );
00748 
00749     M3_SpectrumClassLL_destroyList( runConfig->powerSpectrum.spectrumClassList );
00750 
00751     M3_File_destroy( runConfig->powerSpectrum.fisherMatrix );
00752   }
00753 
00754   free(runConfig);
00755 
00756 #ifdef M3_USE_PROFILE_FREAD
00757   if( envUseProfile )
00758   {
00759     M3_ProfileFinalize( );
00760     envUseProfile = 0;
00761   }
00762 #endif
00763   
00764   return;
00765 }
00766 
00767 
00768 void M3_RunConfigStruct_Duplicate( M3_RunConfigStruct *inRunConfig, M3_RunConfigStruct **outRunConfig )
00769 {
00770   M3_RunConfigStruct_duplicateP( inRunConfig, outRunConfig, 0 );
00771   return;
00772 }
00773 
00774 
00775 int M3_RunConfigStruct_GetDataSetRoot( M3_RunConfigStruct *runConfig, M3_DataSetLL **dataSetRoot )
00776 {
00777   *dataSetRoot = runConfig->dataSetList;
00778   if( *dataSetRoot )
00779     return 1;
00780   return 0;
00781 }
00782 
00783 int M3_RunConfigStruct_GetPixelClassRoot( M3_RunConfigStruct *runConfig, M3_PixelClassLL **pixelClassRoot )
00784 {
00785   *pixelClassRoot = runConfig->pixelClassList;
00786   if(pixelClassRoot )
00787     return(1);
00788   return(0);
00789 }
00790 
00791 int M3_RunConfigStruct_GetPowerSpectrum( M3_RunConfigStruct *runConfig, M3_PowerSpectrumStruct **powerSpectrum )
00792 {
00793   *powerSpectrum = &(runConfig->powerSpectrum);
00794   return(1);
00795 }
00796 
00797 int M3_RunConfigStruct_GetSparseMatrixName(
00798   M3_RunConfigStruct *runConfig,
00799   char *name,
00800   long maxStringLength )
00801 {
00802   if( runConfig->sparsePixelMatrix == NULL )
00803     return 0;
00804 
00805   if( name )
00806   {
00807     name[maxStringLength-1] = '\0';
00808     strncpy( name, runConfig->sparsePixelMatrix->name, maxStringLength-1);
00809   }
00810   return 1;
00811 }
00812 
00813 
00814 int M3_RunConfigStruct_GetSparseMatrixNumNZ(
00815   M3_RunConfigStruct *runConfig,
00816   M3_SparsePixelMatrixData *sparsePixelMatrixData )
00817 {
00818   /* sparsePixelMatrixData->numColumn INPUT
00819      sparsePixelMatrixData->numNZ     OUTPUT
00820      sparsePixelMatrixData->column    INPUT/OUTPUT (allocate numColumn elements before calling)
00821                                                    (columnClass and columnPixel elements set by user,
00822                                                     numNZ elements set by function call )
00823      sparsePixelMatrixData->matrix    NULL
00824   */
00825   M3_SparsePixelMatrixEl *temp;
00826 
00827   if( runConfig->sparsePixelMatrix == NULL )
00828     return 0;
00829 
00830   temp = sparsePixelMatrixData->matrix;
00831   sparsePixelMatrixData->matrix = NULL;
00832 
00833   M3_File_ReadData( runConfig->sparsePixelMatrix, NULL, sparsePixelMatrixData );
00834 
00835   sparsePixelMatrixData->matrix = temp;
00836 
00837   return 1;
00838 }
00839 
00840 
00841 int M3_RunConfigStruct_GetSparseMatrix( 
00842   M3_RunConfigStruct *runConfig,
00843   M3_SparsePixelMatrixData *sparsePixelMatrixData )
00844 {
00845   /* sparsePixelMatrixData->numColumn INPUT
00846      sparsePixelMatrixData->numNZ     INPUT
00847      sparsePixelMatrixData->column    INPUT
00848      sparsePixelMatrixData->matrix    OUTPUT   (allocate total numNZ elements before calling)
00849   */
00850   
00851   M3_ErrorCheck( -1, "M3_RunConfigStruct_GetSparseMatrix():  matrix pointer in structure is null, but it must be allocated previous to calling M3_RunConfigStruct_GetSparseMatrix()", sparsePixelMatrixData->matrix != NULL, M3_EFLAG_DEFAULT);
00852 
00853   M3_File_ReadData( runConfig->sparsePixelMatrix, NULL, sparsePixelMatrixData );
00854 
00855   return 1;
00856 }
00857 
00858 int M3_RunConfigStruct_GetGCPointingGroupRoot( M3_RunConfigStruct *runConfig, M3_GCPointingGroupLL **GCPointingRoot )
00859 {
00860   *GCPointingRoot = runConfig->GCPointingGroupList;
00861   return( *GCPointingRoot ? 1 : 0 );
00862 }
00863 
00864 
00865 /* OBJECT:  M3_DataSetLL */
00866 
00867 
00868 int M3_DataSetLL_GetNextNodeInList( M3_DataSetLL **dataSetNode )
00869 {
00870   *dataSetNode = (*dataSetNode)->next;
00871   if( *dataSetNode )
00872     return(1);
00873   return(0);
00874 }
00875 
00876 void M3_DataSetLL_GetName( M3_DataSetLL *dataSetNode, char *name, long maxStringLength )
00877 {
00878   name[maxStringLength-1] = '\0';
00879   strncpy( name, dataSetNode->name, maxStringLength-1);
00880   return;
00881 }
00882 
00883 int M3_DataSetLL_GetCoveredIntervalRoot( M3_DataSetLL *dataSet, M3_IntervalLL **coveredIntervalRoot )
00884 {
00885   *coveredIntervalRoot = dataSet->coveredIntervalList;
00886   if( *coveredIntervalRoot )
00887     return(1);
00888   return(0);
00889 }
00890 
00891 
00892 void M3_DataSetLL_GetNumNZ( M3_DataSetLL *dataSetNode, int32_t *numNZ )
00893 {
00894   *numNZ = dataSetNode->numNZ;
00895   return;
00896 }
00897 
00898 
00899 int M3_DataSetLL_GetPointingClassRoot( M3_DataSetLL *dataSetNode, M3_PointingClassLL **pointingClassRoot )
00900 {
00901   *pointingClassRoot = dataSetNode->pointingClassList;
00902   if( *pointingClassRoot )
00903     return(1);
00904   return(0);
00905 }
00906 
00907 
00908 void M3_bufferIntervalStart( M3_Interval fullInterval, int64_t bufferByteLength, int64_t objectSize, int64_t *bufferLength, int64_t *numIteration )
00909 {
00910   int64_t numSample;
00911 
00912   M3_ErrorCheck( -1, "M3_bufferIntervalStart():  M3_DISK_BUFFER_SIZE is too small to fit a single object", bufferByteLength >= objectSize, M3_EFLAG_DEFAULT );
00913 
00914   numSample = fullInterval.lastSample - fullInterval.firstSample + 1;
00915   *bufferLength = bufferByteLength/objectSize;
00916   *numIteration = numSample/(*bufferLength) + ( numSample%(*bufferLength) ? 1 : 0 );
00917   return;
00918 }
00919 
00920 
00921 void M3_bufferIntervalStep( M3_Interval fullInterval, int64_t bufferLength, int64_t iteration, M3_Interval *bufferInterval )
00922 {
00923   int64_t numSample;
00924   int64_t numIteration;
00925 
00926   numSample = fullInterval.lastSample - fullInterval.firstSample + 1;
00927   numIteration = numSample/bufferLength + ( numSample%bufferLength ? 1 : 0 );
00928 
00929 
00930   bufferInterval->firstSample = fullInterval.firstSample + iteration*bufferLength;
00931 
00932   if( iteration == numIteration - 1 && numSample%bufferLength != 0 )
00933     bufferLength = numSample%bufferLength;
00934 
00935   bufferInterval->lastSample = bufferInterval->firstSample + bufferLength - 1;
00936   
00937   return;
00938 }
00939 
00940 void M3_DataSetLL_GetTOD( M3_DataSetLL *dataSetNode, M3_Interval readInterval, double *tod)
00941 {
00942   int64_t i, j, imax, readLength, bufferLength, numReads;
00943   double *todPtr, *buffer1, *buffer2, *buffer2ptr;
00944   M3_Interval thisInterval, bufferInterval;
00945   M3_FileLL *thisFile;
00946   M3_ComponentLL *thisComponent;
00947   M3_SubcomponentLL *thisSubcomponent;
00948   static int64_t diskBufferSize = -1;
00949   char *tempPtr;
00950 
00951   if( diskBufferSize == -1 )
00952   {
00953     tempPtr = getenv("M3_DISK_BUFFER_SIZE");
00954     if( tempPtr )
00955       diskBufferSize = strtoll( tempPtr, NULL, 10);
00956     else
00957       diskBufferSize = M3_DISK_BUFFER_SIZE;
00958   }
00959 
00960   readLength = readInterval.lastSample - readInterval.firstSample + 1;
00961 
00962   M3_bufferIntervalStart( readInterval, diskBufferSize, sizeof(double), &bufferLength, &numReads );
00963 
00964   buffer1 = (double *)malloc(sizeof(double)*bufferLength);
00965   buffer2 = (double *)malloc(sizeof(double)*bufferLength);
00966   M3_ErrorCheck(-1, "M3_DataSetLL_GetTOD", buffer1 && buffer2, M3_EFLAG_MALLOC_FSTRING);
00967 
00968   memset( tod, 0, sizeof(double)*readLength );
00969 
00970   /* Read in time ordered data */
00971   for( j = 0; j < numReads; j++ )
00972   {
00973     M3_bufferIntervalStep( readInterval, bufferLength, j, &bufferInterval );
00974 
00975     for( thisComponent = dataSetNode->componentList; thisComponent; thisComponent = thisComponent->next )
00976     {
00977       memset(buffer2, 0, sizeof(double)*bufferLength );
00978       for( thisSubcomponent = thisComponent->subcomponentList; thisSubcomponent; thisSubcomponent = thisSubcomponent->next )
00979       {
00980         if( thisSubcomponent->simType == M3_NO_SIM_TYPE )
00981         {
00982           for( thisFile = thisSubcomponent->todFileList; thisFile; thisFile = thisFile->next )
00983           {
00984             if( thisFile->file.param.tod.interval.firstSample <= bufferInterval.lastSample && 
00985                 thisFile->file.param.tod.interval.lastSample >= bufferInterval.firstSample )
00986             {
00987               thisInterval.firstSample = maximum( thisFile->file.param.tod.interval.firstSample, bufferInterval.firstSample );
00988               thisInterval.lastSample = minimum(thisFile->file.param.tod.interval.lastSample, bufferInterval.lastSample);
00989        
00990               M3_File_ReadData( &(thisFile->file), &thisInterval, buffer1 );
00991 
00992               buffer2ptr = buffer2 + thisInterval.firstSample - bufferInterval.firstSample;
00993               imax = thisInterval.lastSample - thisInterval.firstSample + 1;
00994 
00995               for( i = 0; i < imax; i++ )
00996                 buffer2ptr[i] += buffer1[i];
00997             }
00998           }
00999         }
01000         else if( thisSubcomponent->simType == M3_MAPSCAN_SIM_TYPE )
01001         {
01002           if( thisSubcomponent->mapScanSimPointingList )
01003           {
01004             M3_ErrorCheck(-1, "Using different pointing for analysis and simulation is not yet supported.  ", 0, M3_EFLAG_DEFAULT );
01005           }
01006           else
01007           {
01008             M3_DataSetLL_GetScanMapSimTOD( dataSetNode, bufferInterval, 0, buffer2 );
01009           }
01010         }
01011         else if( thisSubcomponent->simType == M3_OOFNOISE_SIM_TYPE )
01012         {
01013           if( thisSubcomponent->oofNoiseSimFileList )
01014           {
01015             M3_ErrorCheck( -1, "Using different noise filters for analysis and simulation is not yet supported.  ", 0, M3_EFLAG_DEFAULT );
01016           }
01017           else
01018           {
01019             M3_ErrorCheck( -1, "Simulating one over frequency noise is not yet supported.  ", 0, M3_EFLAG_DEFAULT );
01020           }
01021         }
01022       }
01023       for( thisFile = thisComponent->todCalibFileList; thisFile; thisFile = thisFile->next )
01024       {
01025         if( thisFile->file.param.toc.interval.firstSample <= bufferInterval.lastSample &&
01026             thisFile->file.param.toc.interval.lastSample >= bufferInterval.firstSample )
01027         {
01028           thisInterval.firstSample = maximum( thisFile->file.param.toc.interval.firstSample, bufferInterval.firstSample );
01029           thisInterval.lastSample = minimum( thisFile->file.param.toc.interval.lastSample, bufferInterval.lastSample );
01030 
01031           M3_File_ReadData( &(thisFile->file), &thisInterval, buffer1 );
01032       
01033           buffer2ptr = buffer2 + thisInterval.firstSample - bufferInterval.firstSample;
01034           imax = thisInterval.lastSample - thisInterval.firstSample + 1;
01035 
01036           if( thisFile->file.param.toc.action == M3_MULTIPLY_TOC_ACTION )
01037             for( i = 0; i < imax; i++ )
01038               buffer2ptr[i] *= buffer1[i];
01039           else
01040             for( i = 0; i < imax; i++ )
01041               buffer2ptr[i] /= buffer1[i];
01042         }
01043       }
01044       imax = bufferInterval.lastSample - bufferInterval.firstSample + 1;
01045       todPtr = tod + (bufferInterval.firstSample - readInterval.firstSample);
01046       for( i = 0; i < imax; i++ )
01047         todPtr[i] += buffer2[i];
01048     }
01049   }
01050 
01051   free(buffer2);
01052   free(buffer1);
01053 
01054   return;
01055 }
01056 
01057 
01058 void M3_DataSetLL_GetPointing( M3_DataSetLL *dataSetNode, M3_Interval readInterval, M3_PointingEl *pointing )
01059 {
01060   int isCompIQU;
01061   M3_GCPointingGroupLL *thisGCPointingGroup;
01062   char *sptr;
01063   double *dbuffer;
01064   int64_t bufferLength;
01065   int64_t readLength;
01066   int64_t numReads;
01067   int64_t i, j, k, l;
01068   double temp;
01069   M3_PointingClassLL *thisClass;
01070   M3_PointingEl *buffer;
01071   M3_Interval bufferInterval;
01072   static int64_t diskBufferSize = -1;
01073   char *tempPtr;
01074   long int p;
01075   int useGetPointingIQU = 0;
01076   long *pixelPtr;
01077   int iquPixelScheme;
01078 
01079   int nside[3];
01080   char pixelScheme[4] = {0};
01081 
01082   if( diskBufferSize == -1 )
01083   {
01084     tempPtr = getenv("M3_DISK_BUFFER_SIZE");
01085     if( tempPtr )
01086       diskBufferSize = strtoll( tempPtr, NULL, 10);
01087     else
01088       diskBufferSize = M3_DISK_BUFFER_SIZE;
01089   }
01090 
01091   /* If there is only one class we can just use M3_DataSetLL_getClassPointing() */
01092   if( dataSetNode->pointingClassList->next == NULL )
01093   {
01094     M3_DataSetLL_getClassPointing( dataSetNode, readInterval, 
01095                              dataSetNode->pointingClassList->pixelClassNode->className , pointing );
01096     /* Now do calibration if it exists */
01097     M3_DataSetLL_calibratePointing( dataSetNode, pointing, readInterval );
01098     return;
01099   }
01100 
01101   /* Otherwise read each class into a bufffer, and then rearrange the data for the output. */
01102   readLength = readInterval.lastSample - readInterval.firstSample + 1;
01103 
01104   /* Allocate the buffer. */
01105   buffer = (M3_PointingEl *)malloc(diskBufferSize);
01106   M3_ErrorCheck(-1, "M3_DataSetLL_GetPointing", buffer, M3_EFLAG_MALLOC_FSTRING);
01107 
01108 
01109   /* Check to see if the pointing is compressed IQU:   */
01110   /* There is compressed pointing.                     */
01111   /* There are three pointing classes.                 */
01112   /* These classes are types I, Q, and U in that order.*/
01113 
01114   isCompIQU = 1;
01115   for( thisClass = dataSetNode->pointingClassList, i = 0; isCompIQU && thisClass; thisClass = thisClass->next, i++)
01116   {
01117     if( i == 0 )
01118       thisGCPointingGroup = thisClass->subclassList->GCPointingGroupNode;
01119 
01120     if( thisClass->subclassList->next )
01121       isCompIQU = 0;
01122     else if( thisClass->subclassList->isFull )
01123       isCompIQU = 0;
01124     else if( i == 0 && thisClass->pixelClassNode->pixelType != M3_CMB_I_PIXEL_TYPE )
01125       isCompIQU = 0;
01126     else if( i == 1 && thisClass->pixelClassNode->pixelType != M3_CMB_Q_PIXEL_TYPE )
01127       isCompIQU = 0;
01128     else if( i == 2 && thisClass->pixelClassNode->pixelType != M3_CMB_U_PIXEL_TYPE )
01129       isCompIQU = 0;
01130     else if( i >= 3 )
01131       isCompIQU = 0;
01132     else if( i > 0 && thisGCPointingGroup != thisClass->subclassList->GCPointingGroupNode )
01133       isCompIQU = 0;
01134     if( isCompIQU )
01135     {
01136       /* FIX ME this should use the getParam function istead of reimplementing it.  */
01137       sptr = strstr( thisClass->subclassList->auxComplement, "nside=");
01138       if( sptr )
01139       {
01140         sptr += 6;
01141         nside[i] = atoi(sptr);
01142       }
01143       else
01144         isCompIQU = 0;
01145     }
01146     if( isCompIQU )
01147     {
01148       sptr = strstr( thisClass->subclassList->auxComplement, "pixelScheme=");
01149       if( sptr )
01150       {
01151         sptr += 12;
01152         if( strncmp( sptr, "ring", 4) == 0 )
01153           pixelScheme[i] = 'r';
01154         else
01155           pixelScheme[i] = 'n';
01156       }
01157       else
01158         pixelScheme[i] = 'r';
01159     }
01160   }
01161 
01162   /* If it is compressed IQU pointing see if the pixel 
01163      class nides match and are all the same pixelation 
01164      scheme (i.e. ring or nested) */
01165   if( isCompIQU )
01166   {
01167     if( ( strncmp( thisGCPointingGroup->GCPointingType, "simmission", 10 ) == 0  || 
01168           strncmp( thisGCPointingGroup->GCPointingType, "ebex", 4 ) == 0 ) && 
01169         ( strcmp(pixelScheme, "rrr") == 0 || strcmp(pixelScheme, "nnn") == 0 ) && 
01170         nside[0] == nside[1] && nside[1] == nside[2] ) 
01171     {
01172       useGetPointingIQU = 1;
01173       if( strcmp( pixelScheme, "rrr") == 0 )
01174         iquPixelScheme = 1;
01175       else
01176         iquPixelScheme = 0;
01177     }
01178   }
01179 
01180   /* If the pointing is compressed IQU use faster method to fill pointing matrix */
01181   if( isCompIQU )
01182   {
01183     dbuffer = (double *) buffer;
01184     M3_bufferIntervalStart( readInterval, diskBufferSize, sizeof(double)*3, &bufferLength, &numReads );
01185     pixelPtr = (long*)(dbuffer + 2*bufferLength);
01186 
01187     /* Do a series of buffered reads. */
01188     if( useGetPointingIQU )
01189     {
01190       for( l = 0; l < numReads; l++ )
01191       {
01192         M3_bufferIntervalStep( readInterval, bufferLength, l, &bufferInterval );
01193         M3_DataSetLL_getPointingIQU( dataSetNode, bufferInterval, nside[0], iquPixelScheme, pixelPtr, dbuffer );
01194         i = bufferInterval.firstSample - readInterval.firstSample;
01195         j = 0;
01196         k = bufferInterval.lastSample - readInterval.firstSample + 1;
01197         while( i < k )
01198         {
01199           pointing[3*i].pixel = pointing[3*i+1].pixel = pointing[3*i+2].pixel = pixelPtr[j];
01200           pointing[3*i].weight = 1;
01201           pointing[3*i+1].weight = dbuffer[2*j];
01202           pointing[3*i+2].weight = dbuffer[2*j+1];
01203           i++;
01204           j++;
01205         }
01206         /* Now do calibration if it exists */
01207         M3_DataSetLL_calibratePointing( dataSetNode, pointing + 3*(bufferInterval.firstSample - readInterval.firstSample ), bufferInterval );
01208       }
01209     }
01210     /* Take care of the cases where there is compressed pointing but it 
01211        is not simmission or ebex compressed pointing */
01212     else if( strcmp(pixelScheme, "rrr" ) == 0 && nside[0] == nside[1] && nside[1] == nside[2] )
01213     {
01214       for( l = 0; l < numReads; l++ )
01215       {
01216         M3_bufferIntervalStep( readInterval, bufferLength, l, &bufferInterval );
01217         M3_DataSetLL_GetEuler( dataSetNode, bufferInterval, dbuffer );
01218        
01219         i = bufferInterval.firstSample - readInterval.firstSample;
01220         j = 0;
01221         k = bufferInterval.lastSample - readInterval.firstSample + 1;
01222         while( i < k )
01223         {
01224           ang2pix_ring(nside[0], dbuffer[j*3], dbuffer[j*3+1], &p);
01225           pointing[3*i].pixel = pointing[3*i+1].pixel = pointing[3*i+2].pixel = p;
01226           pointing[3*i].weight = 1;
01227           pointing[3*i+1].weight = cos(2*dbuffer[j*3+2]);
01228           pointing[3*i+2].weight = sin(2*dbuffer[j*3+2]);
01229           i++;
01230           j++;
01231         }
01232         /* Now do calibration if it exists */
01233         M3_DataSetLL_calibratePointing( dataSetNode, pointing + 3*(bufferInterval.firstSample - readInterval.firstSample ), bufferInterval );
01234       }
01235     }
01236     else if( strcmp(pixelScheme, "nnn") == 0 && nside[0] == nside[1] && nside[1] == nside[2] )
01237     {
01238       for( l = 0; l < numReads; l++ )
01239       {
01240         M3_bufferIntervalStep( readInterval, bufferLength, l, &bufferInterval );
01241         M3_DataSetLL_GetEuler( dataSetNode, bufferInterval, dbuffer );
01242       
01243         i = bufferInterval.firstSample - readInterval.firstSample;
01244         j = 0;
01245         k = bufferInterval.lastSample - readInterval.firstSample + 1;
01246         while( i < k )
01247         {
01248           ang2pix_nest(nside[0], dbuffer[j*3], dbuffer[j*3+1], &p);
01249           pointing[3*i].pixel = pointing[3*i+1].pixel = pointing[3*i+2].pixel = p;
01250           pointing[3*i].weight = 1;
01251           pointing[3*i+1].weight = cos(2*dbuffer[j*3+2]);
01252           pointing[3*i+2].weight = sin(2*dbuffer[j*3+2]);
01253           i++;
01254           j++;
01255         }
01256         /* Now do calibration if it exists */
01257         M3_DataSetLL_calibratePointing( dataSetNode, pointing + 3*(bufferInterval.firstSample - readInterval.firstSample ), bufferInterval );
01258       }
01259     }
01260     /* Now do the case where the resolutions for I, Q, and U differ.  */
01261     else if( strcmp(pixelScheme, "rrr" ) == 0 )
01262     {
01263       for( l = 0; l < numReads; l++ )
01264       {
01265         M3_bufferIntervalStep( readInterval, bufferLength, l, &bufferInterval );
01266         M3_DataSetLL_GetEuler( dataSetNode, bufferInterval, dbuffer );
01267       
01268         i = bufferInterval.firstSample - readInterval.firstSample;
01269         j = 0;
01270         k = bufferInterval.lastSample - readInterval.firstSample + 1;
01271         while( i < k )
01272         {
01273           ang2pix_ring(nside[0], dbuffer[j*3], dbuffer[j*3+1], &p);
01274           pointing[3*i].pixel = p;
01275           pointing[3*i].weight = 1;
01276           ang2pix_ring(nside[1], dbuffer[j*3], dbuffer[j*3+1], &p);
01277           pointing[3*i+1].pixel = p;
01278           pointing[3*i+1].weight = cos(2*dbuffer[j*3+2]);
01279           ang2pix_ring(nside[2], dbuffer[j*3], dbuffer[j*3+1], &p);
01280           pointing[3*i+2].pixel = p;
01281           pointing[3*i+2].weight = sin(2*dbuffer[j*3+2]);
01282           i++;
01283           j++;
01284         }
01285         /* Now do calibration if it exists */
01286         M3_DataSetLL_calibratePointing( dataSetNode, pointing + 3*(bufferInterval.firstSample - readInterval.firstSample ), bufferInterval );
01287       }
01288     }
01289     else if( strcmp(pixelScheme,  "nnn" ) == 0 )
01290     {
01291       for( l = 0; l < numReads; l++ )
01292       {
01293         M3_bufferIntervalStep( readInterval, bufferLength, l, &bufferInterval );
01294         M3_DataSetLL_GetEuler( dataSetNode, bufferInterval, dbuffer );
01295       
01296         i = bufferInterval.firstSample - readInterval.firstSample;
01297         j = 0;
01298         k = bufferInterval.lastSample - readInterval.firstSample + 1;
01299         while( i < k )
01300         {
01301           ang2pix_nest(nside[0], dbuffer[j*3], dbuffer[j*3+1], &p);
01302           pointing[3*i].pixel = p;
01303           pointing[3*i].weight = 1;
01304           ang2pix_nest(nside[1], dbuffer[j*3], dbuffer[j*3+1], &p);
01305           pointing[3*i+1].pixel = p;
01306           pointing[3*i+1].weight = cos(2*dbuffer[j*3+2]);
01307           ang2pix_nest(nside[2], dbuffer[j*3], dbuffer[j*3+1], &p);
01308           pointing[3*i+2].pixel = p;
01309           pointing[3*i+2].weight = sin(2*dbuffer[j*3+2]);
01310           i++;
01311           j++;
01312         }
01313         /* Now do calibration if it exists */
01314         M3_DataSetLL_calibratePointing( dataSetNode, pointing + 3*(bufferInterval.firstSample - readInterval.firstSample ), bufferInterval );
01315       }
01316     }
01317     /* Finally take care of the case where the resolutions and the pixelation scheme differ between I, Q,and U */
01318     else
01319     {
01320       for( l = 0; l < numReads; l++ )
01321       {
01322         M3_bufferIntervalStep( readInterval, bufferLength, l, &bufferInterval );
01323         M3_DataSetLL_GetEuler( dataSetNode, bufferInterval, dbuffer );
01324       
01325         i = bufferInterval.firstSample - readInterval.firstSample;
01326         j = 0;
01327         k = bufferInterval.lastSample - readInterval.firstSample + 1;
01328         while( i < k )
01329         {
01330           if( pixelScheme[0] == 'r' )
01331           {
01332             ang2pix_ring(nside[0], dbuffer[j*3], dbuffer[j*3+1], &p);
01333             pointing[3*i].pixel = p;
01334           }
01335           else 
01336           {
01337             ang2pix_nest(nside[0], dbuffer[j*3], dbuffer[j*3+1], &p);
01338             pointing[3*i].pixel = p;
01339           }
01340           pointing[3*i].weight = 1;
01341           if( pixelScheme[1] == 'r' )
01342           {
01343             ang2pix_ring(nside[1], dbuffer[j*3], dbuffer[j*3+1], &p);
01344             pointing[3*i+1].pixel = p;
01345           }
01346           else
01347           {
01348             ang2pix_nest(nside[1], dbuffer[j*3], dbuffer[j*3+1], &p);
01349             pointing[3*i+1].pixel = p;
01350           }
01351           pointing[3*i+1].weight = cos(2*dbuffer[j*3+2]);
01352           if( pixelScheme[2] == 'r' )
01353           {
01354             ang2pix_ring(nside[2], dbuffer[j*3], dbuffer[j*3+1], &p);
01355             pointing[3*i+2].pixel = p;
01356           }
01357           else
01358           {
01359             pointing[3*i+2].pixel = p;
01360             ang2pix_nest(nside[2], dbuffer[j*3], dbuffer[j*3+1], &p);
01361           }
01362           pointing[3*i+2].weight = sin(2*dbuffer[j*3+2]);
01363           i++;
01364           j++;
01365         }
01366         /* Now do calibration if it exists */
01367         M3_DataSetLL_calibratePointing( dataSetNode, pointing + 3*(bufferInterval.firstSample - readInterval.firstSample ), bufferInterval );
01368       }
01369     }
01370   }
01371   else 
01372   {
01373     /* Without any obvious shortcuts get the class pointing
01374        for each class and assemble the pointing. */
01375     /* Find the largest number of non zeros in all of the classes. */
01376     i = 0;
01377     for( thisClass = dataSetNode->pointingClassList; thisClass; thisClass = thisClass->next )
01378       if( i < thisClass->numNZ )
01379         i = thisClass->numNZ;
01380 
01381     M3_bufferIntervalStart( readInterval, diskBufferSize, sizeof(M3_PointingEl)*i, &bufferLength, &numReads );
01382 
01383     /* Do a series of buffered reads. */
01384     for( l = 0; l < numReads; l++ )
01385     {
01386       M3_bufferIntervalStep( readInterval, bufferLength, l, &bufferInterval );
01387 
01388       /* Go through all of the classes. */
01389       for( thisClass = dataSetNode->pointingClassList; thisClass; thisClass = thisClass->next )
01390       {
01391 
01392         M3_DataSetLL_getClassPointing( dataSetNode, bufferInterval, 
01393                                        thisClass->pixelClassNode->className, buffer );
01394 
01395         /* Copy the buffer into the output vector */
01396         i = bufferInterval.firstSample - readInterval.firstSample;
01397         j = 0;
01398         k = bufferInterval.lastSample - readInterval.firstSample + 1;
01399         while( i < k )
01400         {
01401           memcpy( pointing + i*dataSetNode->numNZ + thisClass->columnOffset, 
01402                   buffer + j*thisClass->numNZ, thisClass->numNZ*sizeof(M3_PointingEl));
01403           i++;
01404           j++;
01405         }
01406       }
01407       /* Now do calibration if it exists */
01408       M3_DataSetLL_calibratePointing( dataSetNode, pointing + dataSetNode->numNZ*(bufferInterval.firstSample - readInterval.firstSample ), bufferInterval );
01409     }
01410   }
01411   
01412   free(buffer);
01413 
01414   return;
01415 }
01416 
01417 int M3_ConvertRotationStringForGCP( char *rotateDirection, char *rotateEquinox, int *gcpInCoord, int *gcpOutCoord, int *gcpEpoch )
01418 {
01419   if( rotateDirection[0] != '\0' ) {
01420     if( strcmp( rotateDirection, "radec2gal") == 0) {
01421       *gcpInCoord = GCP_COORD_EQU;
01422       *gcpOutCoord = GCP_COORD_GAL;
01423     } else if( strcmp( rotateDirection, "gal2radec") == 0) {
01424       *gcpInCoord = GCP_COORD_GAL;
01425       *gcpOutCoord = GCP_COORD_EQU;
01426     } else if( strcmp( rotateDirection, "radec2ecl") == 0) {
01427       *gcpInCoord = GCP_COORD_EQU;
01428       *gcpOutCoord = GCP_COORD_ECL;
01429     } else if( strcmp( rotateDirection, "ecl2radec") == 0) {
01430       *gcpInCoord = GCP_COORD_ECL;
01431       *gcpOutCoord = GCP_COORD_EQU;
01432     } else if( strcmp( rotateDirection, "ecl2gal") == 0) {
01433       *gcpInCoord = GCP_COORD_ECL;
01434       *gcpOutCoord = GCP_COORD_GAL;
01435     } else if( strcmp( rotateDirection, "gal2ecl") == 0) {
01436       *gcpInCoord = GCP_COORD_GAL;
01437       *gcpOutCoord = GCP_COORD_ECL;
01438     } else { 
01439       fprintf( stderr, "Wrong coordinate conversion option ... \n"); exit(1);
01440     }
01441     if( strcmp( rotateEquinox, "J1950") == 0) { 
01442       *gcpEpoch = GCP_EPOCH_B1950;
01443     } else if( strcmp( rotateEquinox, "J2000") == 0) {  
01444       *gcpEpoch = GCP_EPOCH_J2000;
01445     } else {
01446       printf("wrong equinox in euler ... \n"); exit(1);
01447     }
01448   } else {
01449     *gcpInCoord = GCP_COORD_EQU;
01450     *gcpOutCoord = GCP_COORD_EQU;
01451     *gcpEpoch = GCP_EPOCH_J2000;
01452   }
01453 }
01454 
01455 void M3_DataSetLL_GetEuler( M3_DataSetLL *dataSetNode, M3_Interval requestInterval,double *eulerAngles )
01456 {
01457   M3_TimeIntervalLL timeIntervalList;
01458   void *storeSpace = NULL;
01459   M3_GCPointingStoreLL *storeList = NULL;
01460   M3_planckAux *planckAux = NULL;
01461   M3_planckAuxComplement acStruct;
01462   M3_TimeEl requestFirstTime;
01463   double dataSetSampleRate;
01464   M3_GCPointingStoreLL *gcpointingStoreNode = NULL;
01465   M3_GCPointingGroupLL *gcpointingGroupNode = NULL;
01466   size_t storeSize;
01467   static int64_t diskBufferSize = -1;
01468   char *tempPtr;
01469   int detectorIndex;
01470   char eMessage[256];
01471   char *auxComplement;
01472   int64_t requestLength;
01473   int64_t i;
01474   static int envUseProfile = -1;
01475   int dataIsStored;
01476   int gcpInCoord;
01477   int gcpOutCoord;
01478   int gcpInEpoch;
01479   int gcpOutEpoch;
01480   int destroyCache;
01481   M3_TODcacheStruct *todCache;
01482 
01483   if( diskBufferSize == -1 )
01484   {
01485     tempPtr = getenv("M3_DISK_BUFFER_SIZE");
01486     if( tempPtr )
01487       diskBufferSize = strtoll( tempPtr, NULL, 10);
01488     else
01489       diskBufferSize = M3_DISK_BUFFER_SIZE;
01490   }
01491   if( envUseProfile == -1 )
01492   {
01493     tempPtr = getenv( "M3_USE_PROFILE_GCPOINTING");
01494     if(tempPtr )
01495       envUseProfile = 1;
01496     else
01497       envUseProfile = 0;
01498   }
01499 
01500   if( envUseProfile )
01501     M3_ProfileStart( 229, "M3_DataSetLL_GetEuler() all");
01502   
01503   auxComplement = M3_DataSetLL_GetGCPointingGroupNode( dataSetNode, &gcpointingGroupNode );
01504  
01505   M3_ErrorCheck(-1, "Requested Euler angles from data set without GCP group", auxComplement, M3_EFLAG_DEFAULT );
01506 
01507   M3_ErrorCheck( -1, "Requested Euler angles from GCP that is not simmission or HFI type",
01508                  strncmp( gcpointingGroupNode->GCPointingType, "simmission", 10 ) == 0 ||
01509                  strncmp( gcpointingGroupNode->GCPointingType, "HFI", 3) == 0 ||
01510                  strncmp( gcpointingGroupNode->GCPointingType, "ebex", 4) == 0, 
01511                  M3_EFLAG_DEFAULT );
01512 
01513   requestLength = requestInterval.lastSample - requestInterval.firstSample + 1;
01514   requestFirstTime = M3_TimeEl_AddSamples( dataSetNode->firstTime, requestInterval.firstSample, dataSetNode->sampleRate );
01515 
01516   timeIntervalList.interval.firstTime = M3_TimeEl_AddSamples( dataSetNode->firstTime, requestInterval.firstSample, dataSetNode->sampleRate );
01517   timeIntervalList.interval.lastTime = M3_TimeEl_AddSamples( dataSetNode->firstTime, requestInterval.lastSample, dataSetNode->sampleRate );
01518   timeIntervalList.next = NULL;
01519 
01520   dataIsStored = M3_GCPointingGroupLL_IsStored( gcpointingGroupNode, &timeIntervalList );
01521 
01522   todCache = &(dataSetNode->runConfigNode->todCache);
01523   destroyCache = 0;
01524   if( !dataIsStored )
01525   {
01526     destroyCache = 1;
01527     M3_TODcacheStruct_Destroy( todCache );
01528     M3_RunConfigStruct_GetTODcache( dataSetNode->runConfigNode, &todCache );
01529     M3_TODcacheStruct_SetCacheGCPdata( todCache, 1 );
01530     M3_TODcacheStruct_SetCacheScanMapData( todCache, 0 );
01531     M3_TODcacheStruct_AppendRequest( todCache, dataSetNode, requestInterval );
01532     M3_TODcacheStruct_Initialize( todCache, dataSetNode->runConfigNode, &storeSize );
01533   }
01534   
01535 
01536   if( strncmp( gcpointingGroupNode->GCPointingType, "simmission", 10) == 0 ||
01537       strncmp( gcpointingGroupNode->GCPointingType, "HFI", 3) == 0 )
01538   {
01539     planckAux = (M3_planckAux*)(gcpointingGroupNode->auxStore);
01540     M3_planckAuxComplement_Parse( &acStruct, auxComplement );
01541 
01542     /* Match the detector ID with the focal plane data base.  */
01543     detectorIndex = -1;
01544     for( i = 0; i < planckAux->numDetector; i++ )
01545     {
01546       if( strcmp( acStruct.detectorID, planckAux->detectorInfo[i].detectorID) == 0 )
01547       {
01548        detectorIndex = i;
01549          break;
01550       }
01551     }
01552     sprintf( eMessage, "No match in focal plane database to detector id %s", acStruct.detectorID );
01553     M3_ErrorCheck(-1, eMessage, detectorIndex != -1, M3_EFLAG_DEFAULT );
01554     
01555   }
01556 
01557   M3_ConvertRotationStringForGCP( acStruct.rotateDirection, acStruct.rotateEquinox, &gcpInCoord, &gcpOutCoord, &gcpInEpoch);
01558   gcpOutEpoch = gcpInEpoch;
01559 
01560   if( strncmp( gcpointingGroupNode->GCPointingType, "simmission", 10 ) == 0)
01561   {
01562     if( envUseProfile )
01563       M3_ProfileStart( 233, "M3_DataSetLL_GetEuler():  gcp_expand_xyz2euler" );
01564 
01565     M3_GCPointingStoreLL_expand_xyz2euler(gcpointingGroupNode->GCPointingStoreList, planckAux->boresightSpinAxisAngle, GCP_SPIN_Z, gcpInCoord, gcpInEpoch, *((gcp_time*)(&(dataSetNode->firstTime))), 1.0/3600.0, planckAux->detectorInfo[detectorIndex].offset, planckAux->detectorInfo[detectorIndex].psiPol, *((gcp_time*)(&requestFirstTime)), dataSetNode->sampleRate, requestLength, gcpOutCoord, gcpOutEpoch, eulerAngles);
01566     
01567     if( envUseProfile )
01568       M3_ProfileStop( 233 );
01569 
01570   }
01571   else if( strncmp( gcpointingGroupNode->GCPointingType, "ebex", 4) == 0 )
01572   {
01573     /* FIX ME ebex get euler not implemented.  */
01574     M3_ErrorCheck( -1, "I only pointing and euler angles are not implemented yet for ebex data in M3 this needs to be fixed soon!", 0, M3_EFLAG_DEFAULT );
01575   }
01576   else if( strncmp( gcpointingGroupNode->GCPointingType, "HFI", 3) == 0 )
01577   {
01578     if( envUseProfile )
01579       M3_ProfileStart( 234, "M3_DataSetLL_GetEuler:  gcp_expand_quat2euler" );
01580     /* FIX ME there should be a GCPointingStoreLL_expand_quat2euler() the below code assumes that the gcp store list contains only one node */
01581     gcpointingStoreNode = gcpointingGroupNode->GCPointingStoreList;
01582     gcp_expand_quat2euler(planckAux->boresightSpinAxisAngle, GCP_SPIN_Z, *((gcp_time*)(&(gcpointingStoreNode->firstTime))), gcpointingStoreNode->sampleRate, gcpointingStoreNode->numSample, gcpInCoord, gcpInEpoch, gcpointingStoreNode->data, *((gcp_time*)(&(dataSetNode->firstTime))), 1.0/3600.0, planckAux->detectorInfo[detectorIndex].offset, planckAux->detectorInfo[detectorIndex].psiPol, *((gcp_time*)(&requestFirstTime)), dataSetNode->sampleRate, requestLength, gcpOutCoord, gcpOutEpoch, eulerAngles);
01583 
01584     if( envUseProfile )
01585       M3_ProfileStop( 234 );
01586   }
01587 
01588   if( destroyCache )
01589     M3_TODcacheStruct_Destroy( todCache );
01590 
01591   if( envUseProfile )
01592     M3_ProfileStop( 229 );
01593   
01594   return;
01595 }
01596 
01597 void M3_DataSetLL_getPointingIQU( M3_DataSetLL *dataSetNode, M3_Interval requestInterval, int32_t nside, int pixelScheme, long *pixels, double *weights )
01598 {
01599   char *auxComplement;
01600   int auxNotStored;
01601   M3_TimeIntervalLL timeIntervalList;
01602   void *storeSpace = NULL;
01603   M3_GCPointingStoreLL *storeList = NULL;
01604   M3_planckAux *planckAux = NULL;
01605   M3_planckAuxComplement acStruct;
01606   M3_ebexAux *ebexAux = NULL;
01607   M3_ebexAuxComplement acStructEbex;
01608   M3_TimeEl requestFirstTime;
01609   double dataSetSampleRate;
01610   M3_GCPointingGroupLL *gcpointingGroupNode = NULL;
01611   M3_GCPointingStoreLL *storeNode;
01612   size_t storeSize;
01613   static int64_t diskBufferSize = -1;
01614   char *tempPtr;
01615   int detectorIndex;
01616   char eMessage[256];
01617   int64_t requestLength;
01618   int64_t i;
01619   static int envUseProfile = -1;
01620   int dataIsStored;
01621   int gcpInCoord;
01622   int gcpOutCoord;
01623   int gcpInEpoch;
01624   int gcpOutEpoch;
01625   int destroyCache;
01626   M3_TODcacheStruct *todCache;
01627 
01628   if( diskBufferSize == -1 )
01629   {
01630     tempPtr = getenv("M3_DISK_BUFFER_SIZE");
01631     if( tempPtr )
01632       diskBufferSize = strtoll( tempPtr, NULL, 10);
01633     else
01634       diskBufferSize = M3_DISK_BUFFER_SIZE;
01635   }
01636   if( envUseProfile == -1 )
01637   {
01638     tempPtr = getenv( "M3_USE_PROFILE_GCPOINTING");
01639     if(tempPtr )
01640       envUseProfile = 1;
01641     else
01642       envUseProfile = 0;
01643   }
01644 
01645   if( envUseProfile )
01646     M3_ProfileStart( 229, "M3_DataSetLL_GetPointingIQU() all");
01647   
01648   auxComplement = M3_DataSetLL_GetGCPointingGroupNode( dataSetNode, &gcpointingGroupNode );
01649   
01650   M3_ErrorCheck(-1, "Requested fast IQU from data set without GCP group", auxComplement, M3_EFLAG_DEFAULT );
01651 
01652   M3_ErrorCheck( -1, "Requested fast IQU from GCP that is not simmission or ebex type",
01653                  ( strncmp( gcpointingGroupNode->GCPointingType, "simmission", 10 ) == 0 || 
01654                    strncmp( gcpointingGroupNode->GCPointingType, "ebex", 4 ) == 0 ),
01655                    M3_EFLAG_DEFAULT );
01656 
01657   requestLength = requestInterval.lastSample - requestInterval.firstSample + 1;
01658   requestFirstTime = M3_TimeEl_AddSamples( dataSetNode->firstTime, requestInterval.firstSample, dataSetNode->sampleRate );
01659 
01660 
01661   timeIntervalList.interval.firstTime = M3_TimeEl_AddSamples( dataSetNode->firstTime, requestInterval.firstSample, dataSetNode->sampleRate );
01662   timeIntervalList.interval.lastTime = M3_TimeEl_AddSamples( dataSetNode->firstTime, requestInterval.lastSample, dataSetNode->sampleRate );
01663   timeIntervalList.next = NULL;  
01664   dataIsStored = M3_GCPointingGroupLL_IsStored( gcpointingGroupNode, &timeIntervalList );
01665 
01666   todCache = &(dataSetNode->runConfigNode->todCache);
01667   destroyCache = 0;
01668   if( !dataIsStored )
01669   {
01670     destroyCache = 1;
01671     M3_TODcacheStruct_Destroy( todCache );
01672     M3_RunConfigStruct_GetTODcache( dataSetNode->runConfigNode, &todCache );
01673     M3_TODcacheStruct_SetCacheGCPdata( todCache, 1 );
01674     M3_TODcacheStruct_SetCacheScanMapData( todCache, 0 );
01675     M3_TODcacheStruct_AppendRequest( todCache, dataSetNode, requestInterval );
01676     M3_TODcacheStruct_Initialize( todCache, dataSetNode->runConfigNode, &storeSize );
01677   }
01678 
01679   if( envUseProfile )
01680     M3_ProfileStart( 233, "M3_DataSetLL_GetPointingIQU():  M3_GCPointingStoreLL_expand_*2hpx" );
01681 
01682   if( strncmp( gcpointingGroupNode->GCPointingType, "simmission", 10 ) == 0)
01683   {
01684     planckAux = (M3_planckAux*)(gcpointingGroupNode->auxStore);
01685     M3_planckAuxComplement_Parse( &acStruct, auxComplement );
01686 
01687     /* Match the detector ID with the focal plane data base.  */
01688     detectorIndex = -1;
01689     for( i = 0; i < planckAux->numDetector; i++ )
01690     {
01691       if( strcmp( acStruct.detectorID, planckAux->detectorInfo[i].detectorID) == 0 )
01692       {
01693         detectorIndex = i;
01694         break;
01695       }
01696     }
01697     sprintf( eMessage, "No match in focal plane database to detector id %s", acStruct.detectorID );
01698     M3_ErrorCheck(-1, eMessage, detectorIndex != -1, M3_EFLAG_DEFAULT );
01699   
01700 
01701     M3_GCPointingStoreLL_expand_simmission2hpx( gcpointingGroupNode->GCPointingStoreList, planckAux, acStruct, dataSetNode->firstTime, 
01702                                                 M3_PLANCK_POINTING_EVENT_RATE, requestFirstTime, dataSetNode->sampleRate, detectorIndex, 
01703                                                 requestLength, weights, pixels );
01704   }
01705   else if( strncmp( gcpointingGroupNode->GCPointingType, "ebex", 4 ) == 0 )
01706   {
01707     ebexAux = (M3_ebexAux*)(gcpointingGroupNode->auxStore);
01708     M3_ebexAuxComplement_Parse( &acStructEbex, auxComplement );
01709     M3_GCPointingStoreLL_expand_ebex2hpx( gcpointingGroupNode->GCPointingStoreList, ebexAux, acStructEbex,
01710                                           requestFirstTime, dataSetNode->sampleRate, requestLength, weights, pixels );
01711   }
01712   if( envUseProfile )
01713     M3_ProfileStop( 233 );
01714 
01715   if( envUseProfile )
01716     M3_ProfileStop( 229 );
01717 
01718   if( destroyCache == 1 )
01719     M3_TODcacheStruct_Destroy( todCache );
01720   return;
01721 }
01722 
01723 int M3_DataSetLL_GetNoiseFileRoot( M3_DataSetLL *dataSetNode, M3_FileLL **noiseFileRoot )
01724 {
01725   *noiseFileRoot = dataSetNode->noiseFileList;
01726   if( *noiseFileRoot )
01727     return(1);
01728   return(0);
01729 }
01730 
01731 
01732 int M3_DataSetLL_GetNoiseCorLength( M3_DataSetLL *dataSetNode, int64_t sample, int64_t *corLength )
01733 {
01734   M3_FileLL *thisFile;
01735   M3_Interval stationaryInterval;
01736 
01737   stationaryInterval.firstSample = sample;
01738   stationaryInterval.lastSample = sample;
01739 
01740   M3_DataSetLL_GetNoiseFile( dataSetNode, stationaryInterval, &thisFile );
01741   M3_FileLL_GetNoiseCorLength( thisFile, corLength);
01742   return(0);
01743 }
01744 
01745 int M3_DataSetLL_GetNoise( M3_DataSetLL *dataSetNode, int64_t sample, double *noise )
01746 {
01747   M3_FileLL *thisFile;
01748   M3_Interval stationaryInterval;
01749 
01750   stationaryInterval.firstSample = sample;
01751   stationaryInterval.lastSample = sample;
01752 
01753   M3_DataSetLL_GetNoiseFile( dataSetNode, stationaryInterval, &thisFile );
01754   M3_FileLL_GetNoise( thisFile, noise );
01755   return(0);
01756 }
01757 
01758 int M3_DataSetLL_GetNoiseFile( M3_DataSetLL *dataSetNode, M3_Interval stationaryInterval, M3_FileLL **noiseFileNode)
01759 {
01760   M3_FileLL *thisFile;
01761 
01762   for( thisFile = dataSetNode->noiseFileList; thisFile; thisFile = thisFile->next )
01763   {
01764     if( thisFile->file.param.noise.interval.firstSample <= stationaryInterval.firstSample &&
01765         thisFile->file.param.noise.interval.lastSample >= stationaryInterval.lastSample )
01766     {
01767       *noiseFileNode = thisFile;
01768       return(1);
01769     }
01770     if( ( stationaryInterval.firstSample < thisFile->file.param.noise.interval.firstSample && 
01771           stationaryInterval.lastSample >= thisFile->file.param.noise.interval.firstSample   ) ||
01772         ( stationaryInterval.lastSample > thisFile->file.param.noise.interval.lastSample   && 
01773           stationaryInterval.firstSample <= thisFile->file.param.noise.interval.lastSample   )   )
01774     {
01775       M3_ErrorCheck(-1, "M3_GetSetNoiseFile(): Requested a noise file for an interval that was not stationary", 
01776                      0, M3_EFLAG_DEFAULT );
01777     }
01778   }
01779 
01780   *noiseFileNode = NULL;
01781   return(0);
01782 }
01783 
01784 
01785 int M3_DataSetLL_GetFilterFileRoot( M3_DataSetLL *dataSetNode, int32_t filterType, M3_FileLL **filterFile )
01786 {
01787   M3_ErrorCheck( -1, "M3_DataSetLL_GetFilterFileRoot:  Asked for out of range filter type", filterType < M3_NUM_FILTER_TYPE, M3_EFLAG_DEFAULT);
01788   *filterFile = dataSetNode->filterFileList[filterType];
01789   if( *filterFile )
01790     return(1);
01791   return(0);
01792 }
01793 
01794 
01795 
01796 int M3_DataSetLL_GetFilterFile( M3_DataSetLL *dataSetNode, M3_Interval stationaryInterval, int32_t filterType, M3_FileLL **filterFileNode)
01797 {
01798   M3_FileLL *thisFile;
01799 
01800   M3_ErrorCheck( -1, "M3_DataSetLL_GetFilterFile:  Asked for out of range filter type", filterType < M3_NUM_FILTER_TYPE, M3_EFLAG_DEFAULT);
01801 
01802   for( thisFile = dataSetNode->filterFileList[filterType]; thisFile; thisFile = thisFile->next )
01803   {
01804     if( thisFile->file.param.filter.interval.firstSample <= stationaryInterval.firstSample &&
01805         thisFile->file.param.filter.interval.lastSample >= stationaryInterval.lastSample )
01806     {
01807       *filterFileNode = thisFile;
01808       return(1);
01809     }
01810     if( ( stationaryInterval.firstSample < thisFile->file.param.filter.interval.firstSample && 
01811           stationaryInterval.lastSample >= thisFile->file.param.filter.interval.firstSample   ) ||
01812         ( stationaryInterval.lastSample > thisFile->file.param.filter.interval.lastSample   && 
01813           stationaryInterval.firstSample <= thisFile->file.param.filter.interval.lastSample   )   )
01814     {
01815       M3_ErrorCheck(-1, "M3_GetSetFilterFile(): Requested a filter file for an interval that was not stationary", 
01816                      0, M3_EFLAG_DEFAULT );
01817     }
01818   }
01819 
01820   *filterFileNode = NULL;
01821   return(0);
01822 }
01823 
01824 void M3_DataSetLL_SampleIntervalToTimeInterval( M3_DataSetLL *dataSetNode, M3_Interval sampleInterval, M3_TimeInterval *timeInterval )
01825 {
01826   timeInterval->firstTime = M3_TimeEl_AddSamples( dataSetNode->firstTime, sampleInterval.firstSample, dataSetNode->sampleRate );
01827   timeInterval->lastTime = M3_TimeEl_AddSamples( dataSetNode->firstTime, sampleInterval.lastSample, dataSetNode->sampleRate );
01828 
01829   return;
01830 }
01831 
01832 void M3_DataSetLL_SampleIntervalToTimeIntervalExt( M3_DataSetLL *dataSetNode, M3_Interval sampleInterval, M3_TimeInterval *timeInterval )
01833 {
01834   timeInterval->firstTime = M3_TimeEl_AddSamples( dataSetNode->firstTime, sampleInterval.firstSample, dataSetNode->sampleRate );
01835   timeInterval->lastTime = M3_TimeEl_AddSamples( dataSetNode->firstTime, sampleInterval.lastSample+1, dataSetNode->sampleRate );
01836   M3_TimeEl_subtractNano( &(timeInterval->lastTime) );
01837 
01838   return;
01839 }
01840 
01841 
01842 char *M3_DataSetLL_GetGCPointingGroupNode( M3_DataSetLL *dataSetNode, M3_GCPointingGroupLL **GCPointingGroupNode )
01843 {
01844   M3_PointingClassLL *thisPointingClass;
01845   M3_PointingSubclassLL *thisPointingSubclass;
01846   char *outputAuxComplement = NULL;
01847   *GCPointingGroupNode = NULL;
01848   
01849 
01850   for( thisPointingClass = dataSetNode->pointingClassList;
01851        thisPointingClass;
01852        thisPointingClass = thisPointingClass->next )
01853   {
01854     for( thisPointingSubclass = thisPointingClass->subclassList;
01855          thisPointingSubclass;
01856          thisPointingSubclass = thisPointingSubclass->next )
01857     {
01858       if( thisPointingSubclass->GCPointingGroupNode )
01859       {
01860         M3_ErrorCheck( -1, "M3_DataSetLL_GetGCPointingGroupNode() called but there are multiple pointing groups within the dataset.", *GCPointingGroupNode == NULL || *GCPointingGroupNode == thisPointingSubclass->GCPointingGroupNode, M3_EFLAG_DEFAULT );
01861         *GCPointingGroupNode = thisPointingSubclass->GCPointingGroupNode;
01862         outputAuxComplement = thisPointingSubclass->auxComplement;
01863       }
01864     }
01865   }
01866   return( outputAuxComplement );
01867 }
01868 
01869 /* OBJECT:  M3_PixelClassLL */
01870 
01871 
01872 int M3_PixelClassLL_GetNextNodeInList( M3_PixelClassLL **pixelClassNode )
01873 {
01874   *pixelClassNode = (*pixelClassNode)->next;
01875   if( *pixelClassNode )
01876     return(1);
01877   return(0);
01878 }
01879 
01880 
01881 void M3_PixelClassLL_GetClassIndex( M3_PixelClassLL *pixelClassNode, int32_t *index )
01882 {
01883   *index = pixelClassNode->classIndex;
01884   return;
01885 }
01886 
01887 void M3_PixelClassLL_GetClassName( M3_PixelClassLL *pixelClassNode, char *className, long maxStringLength )
01888 {
01889   className[maxStringLength-1] = '\0';
01890   strncpy(className, pixelClassNode->className, maxStringLength-1);
01891   return;
01892 }
01893 
01894 void M3_PixelClassLL_GetPixelType( M3_PixelClassLL *pixelClassNode, int32_t *pixelType )
01895 {
01896   *pixelType = pixelClassNode->pixelType;
01897   return;
01898 }
01899 
01900 void M3_PixelClassLL_GetNumPixelInClass( M3_PixelClassLL *pixelClassNode, int32_t *numPixelInClass )
01901 {
01902   *numPixelInClass = pixelClassNode->numPixelInClass;
01903   return;
01904 }
01905 
01906 void M3_PixelClassLL_GetNumPixelInMap( M3_PixelClassLL *pixelClassNode, int32_t *numPixelInMap )
01907 {
01908   if( pixelClassNode->mapFile )
01909   {
01910     *numPixelInMap = pixelClassNode->mapFile->param.map.numPixel;
01911   }
01912   else
01913   {
01914     *numPixelInMap = 0;
01915   }
01916   return;
01917 }
01918 
01919 
01920 int M3_PixelClassLL_GetMapName( M3_PixelClassLL *pixelClassNode, char *mapName, long maxStringLength )
01921 {
01922   if( pixelClassNode->mapFile && pixelClassNode->mapFile->name )
01923   {
01924     mapName[maxStringLength-1] = '\0';
01925     strncpy( mapName, pixelClassNode->mapFile->name, maxStringLength - 1 );
01926     return 1;
01927   }
01928   else
01929     return 0;
01930 }
01931 
01932 
01933 void M3_PixelClassLL_GetFullMap( M3_PixelClassLL *pixelClassNode, M3_MapEl *map )
01934 {
01935   M3_File_ReadData( pixelClassNode->mapFile, &(pixelClassNode->mapFile->param.map.numPixel), map );
01936   return;
01937 }
01938 
01939 
01940 void M3_PixelClassLL_GetIndexedMap( M3_PixelClassLL *pixelClassNode, int32_t numPixel, M3_MapEl *map )
01941 {
01942   M3_File_ReadData( pixelClassNode->mapFile, &numPixel, map );
01943   return;
01944 }
01945 
01946 void M3_PixelClassLL_GetIndexedCoord( M3_PixelClassLL *pixelClassNode, int32_t numPixel, M3_CoordEl *coord )
01947 {
01948   M3_File_ReadData( pixelClassNode->coordFile, &numPixel, coord);  
01949   return;
01950 }
01951 
01952 
01953 void M3_PixelClassLL_GetWindow( M3_PixelClassLL *pixelClassNode, int32_t lmax, double *window )
01954 {
01955   M3_File_ReadData( pixelClassNode->windowFile, &lmax, window );
01956   return;
01957 }
01958 
01959 
01960 void M3_PixelClassLL_GetIndexedMask( M3_PixelClassLL *pixelClassNode, int32_t numPixel, M3_MapEl *mask )
01961 {
01962   int32_t i;
01963   M3_FileLL *thisMask;
01964   M3_MapEl *buffer;
01965 
01966 
01967   /* FIX ME SHOULD USE M3_DISK_BUFFER_SIZE */
01968 
01969   buffer = (M3_MapEl *)malloc( numPixel*sizeof(M3_MapEl));
01970   M3_ErrorCheck(-1, "M3_ReadClassMask", buffer, M3_EFLAG_MALLOC_FSTRING);
01971 
01972   for( i = 0; i < numPixel; i++ )
01973   {
01974     mask[i].value = 1.0;
01975     buffer[i].pixel = mask[i].pixel;
01976   }
01977 
01978   for( thisMask = pixelClassNode->maskFileList; thisMask; thisMask = thisMask->next )
01979   {
01980     M3_File_ReadData( &(thisMask->file), &numPixel, buffer );
01981     for( i = 0; i < numPixel; i++ )
01982       mask[i].value *= buffer[i].value;
01983   }
01984 
01985   free(buffer);
01986   return;
01987 }
01988 
01989 
01990 int M3_PixelClassLL_GetTemplateFileRoot( M3_PixelClassLL *pixelClassNode, M3_FileLL **templateFileRoot )
01991 {
01992   *templateFileRoot = pixelClassNode->templateFileList;
01993   if( *templateFileRoot )
01994     return(1);
01995   return(0);
01996 }
01997 
01998 
01999 /* OBJECT:  M3_PointingClassLL */
02000 
02001 
02002 int M3_PointingClassLL_GetNextNodeInList( M3_PointingClassLL **pointingClassNode )
02003 {
02004   *pointingClassNode = (*pointingClassNode)->next;
02005   if( *pointingClassNode )
02006     return(1);
02007   return(0);
02008 }
02009 
02010 
02011 void M3_PointingClassLL_GetNumNZ( M3_PointingClassLL *pointingClassNode, int32_t *numNZ )
02012 {
02013   *numNZ = pointingClassNode->numNZ;
02014   return;
02015 }
02016 
02017 void M3_PointingClassLL_GetPixelClassNode( M3_PointingClassLL *pointingClassNode, M3_PixelClassLL **pixelClassNode )
02018 {
02019   *pixelClassNode = pointingClassNode->pixelClassNode;
02020   return;
02021 }
02022 
02023 
02024 /* OBJECT:  M3_PowerSpectrumStruct */
02025 
02026 void M3_PowerSpectrumStruct_GetNumBin( M3_PowerSpectrumStruct *powerSpectrum, int32_t *numBin )
02027 {
02028   *numBin = powerSpectrum->numBin;
02029   return;
02030 }
02031 
02032 int M3_PowerSpectrumStruct_GetSpectrumClassRoot( M3_PowerSpectrumStruct *powerSpectrum, M3_SpectrumClassLL **spectrumClassRoot )
02033 {
02034   *spectrumClassRoot = powerSpectrum->spectrumClassList;
02035   if( *spectrumClassRoot )
02036     return(1);
02037   return(0);
02038 }
02039 
02040 
02041 void M3_PowerSpectrumStruct_GetFisherMatrix( M3_PowerSpectrumStruct *powerSpectrum, double *fisherMatrix )
02042 {
02043   M3_File_ReadData( powerSpectrum->fisherMatrix, NULL, fisherMatrix );
02044   return;
02045 }
02046 
02047 
02048 /* OBJECT:  M3_SpectrumClassLL */
02049 
02050 int M3_SpectrumClassLL_GetNextNodeInList( M3_SpectrumClassLL **spectrumClassNode )
02051 {
02052   *spectrumClassNode = (*spectrumClassNode)->next;
02053   if( *spectrumClassNode )
02054     return(1);
02055   return(0);
02056 }
02057 
02058 
02059 void M3_SpectrumClassLL_GetSpectrumType( M3_SpectrumClassLL *spectrumClassNode, int32_t *spectrumType )
02060 {
02061   *spectrumType = spectrumClassNode->spectrumType;
02062   return;
02063 }
02064 
02065 
02066 void M3_SpectrumClassLL_GetMultipoleMax( M3_SpectrumClassLL *spectrumClassNode, int32_t *lmax )
02067 {
02068   *lmax = spectrumClassNode->lmax;
02069   return;
02070 }
02071 
02072 
02073 void M3_SpectrumClassLL_GetNumBin( M3_SpectrumClassLL *spectrumClassNode, int32_t *numBin )
02074 {
02075   *numBin = spectrumClassNode->numBin;
02076   return;
02077 }
02078 
02079 
02080 void M3_SpectrumClassLL_GetShape( M3_SpectrumClassLL *spectrumClassNode, double * shape)
02081 {
02082   int32_t lmax;
02083 
02084   M3_File_ReadData( spectrumClassNode->shapeFile, &(spectrumClassNode->lmax), shape);
02085   return;
02086 }
02087 
02088 
02089 void M3_SpectrumClassLL_GetBin( M3_SpectrumClassLL *spectrumClassNode, M3_BinEl *bin)
02090 {
02091   M3_File_ReadData( spectrumClassNode->binFile, &(spectrumClassNode->numBin), bin );
02092   return;
02093 }
02094 
02095 
02096 void M3_SpectrumClassLL_GetBPS( M3_SpectrumClassLL *spectrumClassNode, M3_BPSel *bps)
02097 {
02098   M3_File_ReadData( spectrumClassNode->bpsFile, &(spectrumClassNode->numBin), bps);
02099   return;
02100 }
02101 
02102 
02103 /* OBJECT:  M3_IntervalLL */
02104 
02105 int M3_IntervalLL_GetNextNodeInList( M3_IntervalLL **intervalNode )
02106 {
02107   *intervalNode = (*intervalNode)->next;
02108   if( *intervalNode )
02109     return(1);
02110   return(0);
02111 }
02112 
02113 void M3_IntervalLL_GetInterval( M3_IntervalLL *intervalNode, M3_Interval *interval )
02114 {
02115   *interval = intervalNode->interval;
02116   return;
02117 }
02118 
02119 
02120 /* OBJECT:  M3_TimeIntervalLL */
02121 int M3_TimeIntervalLL_GetNextNodeInList( M3_TimeIntervalLL **timeIntervalNode )
02122 {
02123   *timeIntervalNode = (*timeIntervalNode)->next;
02124   return( *timeIntervalNode ? 1 : 0 );
02125 }
02126 
02127 void M3_TimeIntervalLL_GetInterval( M3_TimeIntervalLL *timeIntervalNode, M3_TimeInterval *timeInterval )
02128 {
02129   *timeInterval = timeIntervalNode->interval;
02130   return;
02131 }
02132 
02133 
02134 void M3_TimeIntervalLL_InsertInterval( M3_TimeIntervalLL **timeIntervalList, M3_TimeInterval timeInterval )
02135 {
02136   M3_TimeIntervalLL *timeIntervalPtr;
02137   M3_TimeIntervalLL insertList = {0};
02138 
02139   insertList.interval = timeInterval;
02140 
02141   timeIntervalPtr = M3_TimeIntervalLL_Union( *timeIntervalList, &insertList );
02142   M3_TimeIntervalLL_DestroyList(*timeIntervalList);
02143   *timeIntervalList = timeIntervalPtr;
02144   
02145 }
02146 
02147 M3_TimeIntervalLL *M3_TimeIntervalLL_Union( M3_TimeIntervalLL *aList, M3_TimeIntervalLL *bList )
02148 {
02149   int counter = 0;
02150   M3_TimeIntervalLL *aPtr = aList;
02151   M3_TimeIntervalLL *bPtr = bList;
02152   M3_TimeIntervalLL *cPtr = NULL;
02153   M3_TimeIntervalLL *cList = NULL;
02154   int numAB, i;
02155   M3_intervalSortStruct *abArray;
02156   
02157 
02158   for( aPtr = aList, numAB = 0; aPtr; aPtr = aPtr->next, numAB++ );
02159   for( bPtr = bList; bPtr; bPtr = bPtr->next, numAB++ );
02160 
02161   numAB *= 2;
02162 
02163   abArray = malloc(numAB*sizeof(M3_intervalSortStruct));
02164   M3_ErrorCheck(-1, "M3_TimeIntervalLL_Union()", (abArray?1:0), M3_EFLAG_MALLOC_FSTRING );
02165   for( aPtr = aList, i = 0; aPtr; aPtr = aPtr->next, i++ )
02166   {
02167     abArray[2*i].value = aPtr->interval.firstTime;
02168     abArray[2*i].boundryFlag = 1;
02169     abArray[2*i+1].value = aPtr->interval.lastTime;
02170     abArray[2*i+1].boundryFlag = -1;
02171   }
02172   for( bPtr = bList; bPtr; bPtr = bPtr->next, i++ )
02173   {
02174     abArray[2*i].value = bPtr->interval.firstTime;
02175     abArray[2*i].boundryFlag = 1;
02176     abArray[2*i+1].value = bPtr->interval.lastTime;
02177     abArray[2*i+1].boundryFlag = -1;
02178   }  
02179 
02180   qsort( abArray, numAB, sizeof(M3_intervalSortStruct), &M3_TimeIntervalLL_qsortComp);
02181   
02182   counter = 0;
02183   for( i = 0; i < numAB; i++ )
02184   {
02185     if( counter == 0 && abArray[i].boundryFlag == 1 )
02186     {
02187       if( cPtr )
02188       {
02189         cPtr->next = calloc(1, sizeof(M3_TimeIntervalLL));
02190         cPtr = cPtr->next;
02191       }
02192       else
02193       {
02194         cList = cPtr = calloc(1, sizeof(M3_TimeIntervalLL));
02195       }
02196       cPtr->interval.firstTime = abArray[i].value;
02197     }
02198 
02199     if( counter == 1 && abArray[i].boundryFlag == -1 )
02200     {
02201       cPtr->interval.lastTime = abArray[i].value;
02202     }
02203     counter += abArray[i].boundryFlag;
02204   }
02205   free(abArray);
02206 
02207   return cList;
02208 }
02209 
02210 void M3_TimeIntervalLL_DestroyList( M3_TimeIntervalLL *timeIntervalList )
02211 {
02212   M3_TimeIntervalLL *timeIntervalPtr;
02213 
02214   while( timeIntervalList )
02215   {
02216     timeIntervalPtr = timeIntervalList->next;
02217     free( timeIntervalList );
02218     timeIntervalList = timeIntervalPtr;
02219   }
02220   return;
02221 }
02222 
02223 
02224 
02225 /* OBJECT:  M3_FileLL */
02226 
02227 int M3_FileLL_GetNextNodeInList( M3_FileLL **fileNode )
02228 {
02229   *fileNode = (*fileNode)->next;
02230   if( *fileNode )
02231     return(1);
02232   return(0);
02233 }
02234 
02235 
02236 void M3_FileLL_GetIndexedTemplate( M3_FileLL *templateNode, int32_t numPixel, M3_MapEl *template)
02237 {
02238   M3_File_ReadData( &(templateNode->file), &numPixel, template);
02239   return;
02240 }
02241 
02242 
02243 
02244 void M3_FileLL_GetNoiseInterval( M3_FileLL *noiseFileNode, M3_Interval *noiseInterval )
02245 {
02246   *noiseInterval = noiseFileNode->file.param.noise.interval;
02247   return;
02248 }
02249 
02250 
02251 void M3_FileLL_GetNoiseCorLength( M3_FileLL *noiseFileNode, int64_t *corLength )
02252 {
02253   *corLength = noiseFileNode->file.param.noise.corLength;
02254   return;
02255 }
02256 
02257 
02258 void M3_FileLL_GetNoise( M3_FileLL *noiseFileNode, double *noise )
02259 {
02260   M3_File_ReadData( &(noiseFileNode->file), NULL, noise );
02261   return;
02262 }
02263 
02264 
02265 void M3_FileLL_GetFilterInterval( M3_FileLL *filterFileNode, M3_Interval *interval )
02266 {
02267   *interval = filterFileNode->file.param.filter.interval;
02268   return;
02269 }
02270 
02271 
02272 void M3_FileLL_GetFilterLength( M3_FileLL *filterFileNode, int64_t *length )
02273 {
02274   *length = filterFileNode->file.param.filter.length;
02275   return;
02276 }
02277 
02278 
02279 void M3_FileLL_GetFilterBandWidth( M3_FileLL *filterFileNode, int64_t *bandWidth )
02280 {
02281   *bandWidth = filterFileNode->file.param.filter.bandWidth;
02282   return;
02283 }
02284 
02285 
02286 void M3_FileLL_GetFilter( M3_FileLL *filterFileNode, M3_FilterEl *filter )
02287 {
02288   M3_File_ReadData( &(filterFileNode->file), NULL, filter ); 
02289   return;
02290 }
02291 
02292 
02293 
02294 
02295 
02296 /*******************************
02297 * PRIVATE FUNCTION DEFINITIONS *
02298 *******************************/
02299 
02300 
02301 void M3_File_destroy( M3_File *thisFile )
02302 {
02303   if( thisFile )
02304   {
02305     if( thisFile->name )
02306       free(thisFile->name);
02307     if( thisFile->format )
02308       free(thisFile->format);
02309     free(thisFile);
02310   }
02311   return;
02312 }
02313 
02314 void M3_PixelClassLL_destroyList( M3_PixelClassLL *pixelClassList )
02315 {
02316   M3_PixelClassLL *thisPixelClass;
02317   M3_PixelClassLL *nextPixelClass;
02318 
02319   thisPixelClass = pixelClassList;
02320   while( thisPixelClass )
02321   {
02322     free( thisPixelClass->className);
02323 
02324     M3_File_destroy( thisPixelClass->mapFile );
02325     M3_File_destroy( thisPixelClass->coordFile );
02326     M3_File_destroy( thisPixelClass->windowFile );
02327 
02328     M3_FileLL_destroyList( thisPixelClass->maskFileList );
02329     M3_FileLL_destroyList( thisPixelClass->templateFileList );
02330 
02331     nextPixelClass = thisPixelClass->next;
02332     free( thisPixelClass );
02333     thisPixelClass = nextPixelClass;
02334   }
02335   return;
02336 }
02337 
02338 
02339 int M3_GCPointingGroupLL_GetNextNodeInList( M3_GCPointingGroupLL **GCPointingGroupNode )
02340 {
02341   *GCPointingGroupNode = (*GCPointingGroupNode)->next;
02342   return( (*GCPointingGroupNode) ? 1 : 0);
02343 }
02344 
02345 
02346 void M3_GCPointingGroupLL_destroyList( M3_GCPointingGroupLL *GCPointingGroupList )
02347 {
02348   M3_GCPointingGroupLL *thisGCPointingGroup;
02349   M3_GCPointingGroupLL *nextGCPointingGroup;
02350 
02351 
02352   thisGCPointingGroup = GCPointingGroupList;
02353   while( thisGCPointingGroup )
02354   {
02355     if( thisGCPointingGroup->name )
02356       free( thisGCPointingGroup->name );
02357     if( thisGCPointingGroup->GCPointingType)
02358       free( thisGCPointingGroup->GCPointingType );
02359     M3_File_destroy( thisGCPointingGroup->auxFile );
02360     M3_FileLL_destroyList( thisGCPointingGroup->GCPointingFileList );
02361 
02362     nextGCPointingGroup = thisGCPointingGroup->next;
02363     free(thisGCPointingGroup);
02364     thisGCPointingGroup = nextGCPointingGroup;
02365   }
02366   return;
02367 }
02368 
02369 
02370 void M3_DataSetLL_destroyList( M3_DataSetLL *dataSetList )
02371 {
02372   int i;
02373   M3_DataSetLL *thisDataSet, *nextDataSet;
02374   M3_ComponentLL *thisComponent, *nextComponent;
02375   M3_SubcomponentLL *thisSubcomponent, *nextSubcomponent;
02376   M3_PointingClassLL *thisPointingClass, *nextPointingClass;
02377   M3_PointingSubclassLL *thisSubclass, *nextSubclass;
02378 
02379   thisDataSet = dataSetList;
02380   while( thisDataSet )
02381   {
02382     if( thisDataSet->name )
02383       free(thisDataSet->name );
02384 
02385     M3_IntervalLL_destroyList( thisDataSet->coveredIntervalList );
02386 
02387     thisComponent = thisDataSet->componentList;
02388     while( thisComponent )
02389     {
02390       thisSubcomponent = thisComponent->subcomponentList;
02391       while( thisSubcomponent )
02392       {
02393         M3_FileLL_destroyList( thisSubcomponent->todFileList );
02394         
02395         nextSubcomponent = thisSubcomponent->next;
02396         free(thisSubcomponent);
02397         thisSubcomponent = nextSubcomponent;
02398       }
02399 
02400       M3_FileLL_destroyList( thisComponent->todCalibFileList );
02401 
02402       nextComponent = thisComponent->next;
02403       free(thisComponent);
02404       thisComponent = nextComponent;
02405     }
02406     
02407     M3_FileLL_destroyList( thisDataSet->noiseFileList );
02408 
02409     for( i = 0; i < M3_NUM_FILTER_TYPE; i++ )
02410       M3_FileLL_destroyList( thisDataSet->filterFileList[i] );
02411 
02412     thisPointingClass = thisDataSet->pointingClassList;
02413     while( thisPointingClass )
02414     {
02415       thisSubclass = thisPointingClass->subclassList;
02416       while( thisSubclass )
02417       {
02418         M3_FileLL_destroyList( thisSubclass->pointingFileList );
02419         if( thisSubclass->auxComplement )
02420           free(thisSubclass->auxComplement);        
02421         nextSubclass = thisSubclass->next;
02422         free(thisSubclass);
02423         thisSubclass = nextSubclass;
02424       }
02425       
02426       M3_FileLL_destroyList( thisPointingClass->pointingCalibFileList );
02427       nextPointingClass = thisPointingClass->next;
02428       free(thisPointingClass);
02429       thisPointingClass = nextPointingClass;
02430     }
02431    
02432 
02433     nextDataSet = thisDataSet->next;
02434     free(thisDataSet);
02435     thisDataSet = nextDataSet;
02436   }
02437 
02438   return;
02439 }
02440 
02441 void M3_SpectrumClassLL_destroyList( M3_SpectrumClassLL *spectrumClassList )
02442 {
02443   M3_SpectrumClassLL *thisSpectrumClass, *nextSpectrumClass;
02444 
02445   thisSpectrumClass = spectrumClassList;
02446   while( thisSpectrumClass )
02447   {
02448     M3_File_destroy( thisSpectrumClass->shapeFile );
02449     M3_File_destroy( thisSpectrumClass->binFile );
02450     M3_File_destroy( thisSpectrumClass->bpsFile );
02451 
02452     nextSpectrumClass = thisSpectrumClass->next;
02453     free(thisSpectrumClass);
02454     thisSpectrumClass = nextSpectrumClass;
02455   }
02456   
02457   return;
02458 }
02459 
02460 
02461 void M3_IntervalLL_destroyList( M3_IntervalLL *list)
02462 {
02463   M3_IntervalLL *a;
02464 
02465   while( list )
02466   {
02467     a = list->next;
02468     free(list);
02469     list = a;
02470   }
02471   
02472   return;
02473 }
02474 
02475 
02476 void M3_FileLL_destroyList( M3_FileLL *thisList )
02477 {
02478   M3_FileLL *thisFile, *nextFile;
02479   
02480   thisFile = thisList;
02481 
02482   while( thisFile )
02483   {
02484     if( thisFile->file.name )
02485       free(thisFile->file.name);
02486     if( thisFile->file.format )
02487       free(thisFile->file.format);
02488     nextFile = thisFile->next;
02489     free(thisFile);
02490     thisFile = nextFile;
02491   }
02492   
02493   return;
02494 }
02495 
02496 
02497 void M3_DataSetLL_getClassPointing( M3_DataSetLL *dataSetNode, M3_Interval readInterval, char *className, M3_PointingEl *pointing )
02498 {
02499   M3_PointingClassLL *thisClass;
02500   M3_FileLL *thisFile;
02501   M3_Interval thisInterval;
02502   M3_Interval bufferInterval;
02503   M3_PointingSubclassLL *thisSubclass;
02504   M3_PointingEl *buffer = NULL;
02505   int64_t bufferLength, readLength;
02506   int64_t numReads;
02507   int64_t i, j, k, l, m, maxNumNZ;
02508   double *dbuffer = NULL;
02509   static int64_t diskBufferSize = -1;
02510   char *tempPtr;
02511 
02512   if( diskBufferSize == -1 )
02513   {
02514     tempPtr = getenv("M3_DISK_BUFFER_SIZE");
02515     if( tempPtr )
02516       diskBufferSize = strtoll( tempPtr, NULL, 10);
02517     else
02518       diskBufferSize = M3_DISK_BUFFER_SIZE;
02519   }
02520 
02521   for( thisClass = dataSetNode->pointingClassList; thisClass; thisClass = thisClass->next )
02522     if( strcmp(thisClass->pixelClassNode->className, className) == 0 )
02523       break;
02524 
02525   M3_ErrorCheck( -1, "M3_DataSetLL_getClassPointing(): Could not find class with the specified name", 
02526                  thisClass, M3_EFLAG_DEFAULT );
02527 
02528   /* If there is only one subclass then just read in the files. */  
02529   if( thisClass->subclassList->next == NULL )
02530   {
02531     if( thisClass->subclassList->isFull )
02532     {
02533       for( thisFile = thisClass->subclassList->pointingFileList; thisFile; thisFile = thisFile->next )
02534       {
02535         if( readInterval.firstSample <= thisFile->file.param.pointing.interval.lastSample && 
02536             readInterval.lastSample >= thisFile->file.param.pointing.interval.firstSample )
02537         {
02538           thisInterval.firstSample = maximum(readInterval.firstSample, thisFile->file.param.pointing.interval.firstSample);
02539           thisInterval.lastSample = minimum(readInterval.lastSample, thisFile->file.param.pointing.interval.lastSample);
02540           M3_File_ReadData( &(thisFile->file), &thisInterval, pointing + (thisInterval.firstSample - readInterval.firstSample)*thisClass->numNZ);
02541         }
02542       }
02543     }
02544     else 
02545     {
02546       M3_GCPointingGroupLL_ExpandPointing(thisClass->subclassList->GCPointingGroupNode, 
02547                                           thisClass->subclassList->auxComplement,
02548                                           dataSetNode->firstTime, 
02549                                           dataSetNode->sampleRate, 
02550                                           readInterval, 
02551                                           pointing );
02552                                      
02553     }
02554   }
02555 
02556   /* Otherwise do a buffered read.  */
02557   else
02558   {
02559     readLength = readInterval.lastSample - readInterval.firstSample + 1;
02560 
02561     /* Find the largest number of non-zeros */
02562     maxNumNZ = 0;
02563     for( thisSubclass = thisClass->subclassList; thisSubclass; thisSubclass = thisSubclass->next )
02564       if( maxNumNZ < thisSubclass->numNZ )
02565         maxNumNZ = thisSubclass->numNZ;
02566 
02567     /* Allocate some memory */
02568     M3_bufferIntervalStart( readInterval, diskBufferSize, sizeof(M3_PointingEl)*maxNumNZ, &bufferLength, &numReads );
02569     buffer = (M3_PointingEl *)malloc(sizeof(M3_PointingEl)*bufferLength*maxNumNZ);
02570     M3_ErrorCheck( -1, "M3_DataSetLL_getClassPointing", buffer, M3_EFLAG_MALLOC_FSTRING);
02571 
02572     for( l = 0; l < numReads; l++ )
02573     {
02574       M3_bufferIntervalStep( readInterval, bufferLength, l, &bufferInterval );
02575 
02576       /* Go through the subclasses */
02577       for( thisSubclass = thisClass->subclassList; thisSubclass; thisSubclass = thisSubclass->next )
02578       {
02579         if( thisSubclass->isFull )
02580         {
02581           for( thisFile = thisSubclass->pointingFileList;
02582                thisFile && thisFile->file.param.pointing.interval.firstSample <= readInterval.lastSample;
02583                thisFile = thisFile->next)
02584           {
02585 
02586             if( bufferInterval.firstSample <= thisFile->file.param.pointing.interval.lastSample && 
02587                 bufferInterval.lastSample >= thisFile->file.param.pointing.interval.firstSample )
02588             {
02589               /* Figure out the interval that is needed from the file.  */
02590               thisInterval.firstSample = maximum(bufferInterval.firstSample, thisFile->file.param.pointing.interval.firstSample);
02591               thisInterval.lastSample = minimum(bufferInterval.lastSample, thisFile->file.param.pointing.interval.lastSample);
02592 
02593               M3_File_ReadData( &(thisFile->file), &thisInterval, buffer );
02594               i = thisInterval.firstSample - readInterval.firstSample;
02595               j = 0;
02596               k = thisInterval.lastSample - readInterval.firstSample + 1;
02597               while( i < k )
02598               {
02599                 memcpy( pointing + i*thisClass->numNZ + thisSubclass->columnOffset, 
02600                         buffer + j*thisSubclass->numNZ, thisSubclass->numNZ*sizeof(M3_PointingEl));
02601                 i++;
02602                 j++;
02603               }
02604             }
02605           }
02606         }
02607         else
02608         {
02609           M3_GCPointingGroupLL_ExpandPointing(thisClass->subclassList->GCPointingGroupNode, 
02610                                               thisClass->subclassList->auxComplement,
02611                                               dataSetNode->firstTime, 
02612                                               dataSetNode->sampleRate, 
02613                                               bufferInterval,
02614                                               buffer );
02615           i = bufferInterval.firstSample - readInterval.firstSample;
02616           j = 0;
02617           k = bufferInterval.lastSample - readInterval.firstSample + 1;
02618           while( i < k )
02619           {
02620             memcpy( pointing + i*thisClass->numNZ + thisSubclass->columnOffset, 
02621                     buffer + j*thisSubclass->numNZ, thisSubclass->numNZ*sizeof(M3_PointingEl));
02622             i++;
02623             j++;
02624           }
02625         }
02626       }
02627     }
02628     free( buffer );
02629   }
02630   
02631   return;
02632 }
02633 
02634 
02635 
02636 void M3_DataSetLL_calibratePointing( M3_DataSetLL *dataSetNode, M3_PointingEl *pointing, M3_Interval pointingInterval )
02637 {
02638   int calibExists;
02639   M3_PointingClassLL *thisClass;
02640   int64_t numReads, bufferLength, i, j, k, l, m;
02641   M3_Interval thisInterval, bufferInterval;
02642   double *dbuffer;
02643   M3_FileLL *thisFile;
02644 
02645 
02646   static int64_t diskBufferSize = -1;
02647   char *tempPtr;
02648 
02649   if( diskBufferSize == -1 )
02650   {
02651     tempPtr = getenv("M3_DISK_BUFFER_SIZE");
02652     if( tempPtr )
02653       diskBufferSize = strtoll( tempPtr, NULL, 10);
02654     else
02655       diskBufferSize = M3_DISK_BUFFER_SIZE;
02656   }
02657 
02658 
02659 
02660   /* Figure out if there is any calibration to be applied */
02661   calibExists = 0;
02662   for( thisClass = dataSetNode->pointingClassList; thisClass && calibExists == 0; thisClass = thisClass->next )
02663     for( thisFile = thisClass->pointingCalibFileList; thisFile && calibExists == 0; thisFile = thisFile->next )
02664       if( thisFile->file.param.toc.interval.firstSample <= pointingInterval.lastSample && 
02665           thisFile->file.param.toc.interval.lastSample >= pointingInterval.firstSample )
02666         calibExists = 1;
02667 
02668   if( calibExists == 0 )
02669     return;
02670 
02671   /* Do a series of buffered reads */
02672   dbuffer = (double *)malloc(diskBufferSize);
02673   M3_ErrorCheck(-1, "M3_DataSetLL_getClassPointing", dbuffer, M3_EFLAG_MALLOC_FSTRING);  
02674 
02675   M3_bufferIntervalStart( pointingInterval, diskBufferSize, sizeof(double), &bufferLength, &numReads );
02676 
02677   for( l = 0; l < numReads; l++ )
02678   {
02679     M3_bufferIntervalStep( pointingInterval, bufferLength, l, &bufferInterval );
02680 
02681     for( thisClass = dataSetNode->pointingClassList; thisClass; thisClass = thisClass->next )
02682     {
02683       for( thisFile = thisClass->pointingCalibFileList; thisFile; thisFile = thisFile->next )
02684       {
02685         if( bufferInterval.firstSample <= thisFile->file.param.toc.interval.lastSample &&
02686             bufferInterval.lastSample >= thisFile->file.param.toc.interval.firstSample )
02687         {
02688           thisInterval.firstSample = maximum(bufferInterval.firstSample, thisFile->file.param.toc.interval.firstSample );
02689           thisInterval.lastSample = minimum(bufferInterval.lastSample, thisFile->file.param.toc.interval.lastSample);
02690     
02691           M3_File_ReadData( &(thisFile->file), &thisInterval, dbuffer );
02692 
02693           i = thisInterval.firstSample - pointingInterval.firstSample;
02694           j = 0;
02695           k = thisInterval.lastSample - pointingInterval.firstSample + 1;
02696           if( thisFile->file.param.toc.action == M3_MULTIPLY_TOC_ACTION )
02697           {
02698             while( i < k )
02699             {
02700               for( m = 0; m < thisClass->numNZ; m++ )
02701               {
02702                 pointing[i*dataSetNode->numNZ + thisClass->columnOffset + m].weight *= dbuffer[j];
02703                 if( dbuffer[j] == 0 )
02704                   pointing[i*dataSetNode->numNZ + thisClass->columnOffset + m].pixel = -1;
02705               }
02706               i++;
02707               j++;
02708             }
02709           }
02710           else
02711           {
02712             while( i < k )
02713             {
02714               for( m = 0; m < thisClass->numNZ; m++ )
02715                 pointing[i*dataSetNode->numNZ + thisClass->columnOffset + m].weight /= dbuffer[j];
02716               i++;
02717               j++;
02718             }
02719           }
02720         }
02721       }
02722     }
02723   }
02724 
02725   free(dbuffer);
02726   
02727   return;
02728 }
02729 
02730 #ifdef UNDEFINED 
02731 
02732 void M3_PointingClassLL_maskPointing( M3_PointingClassLL *pointingClass, M3_Interval pointingInterval, M3_PointingEl *pointing )
02733 {
02734   int32_t numPixelInPointing, j, k, numMaskedPixel;
02735   int64_t i, numEl;
02736   M3_BitArray bitArray;
02737   M3_MapEl *mask;
02738   int32_t *maskedPixelList;
02739   void *space;
02740 
02741   numEl = (pointingInterval.lastSample - pointingInterval.firstSample + 1)*pointingClass->numNZ;
02742 
02743   /* First figure out which pixels in the class have been hit.  */
02744   i = pointingClass->pixelClassNode->numPixelInClass;
02745   i = (i/8) + ( i % 8 ? 1 : 0 );
02746 
02747   space = (unsigned char *)calloc( i, 1 );
02748   M3_ErrorCheck(-1, "M3_PointingClassLL_maskPointing()", (space), M3_EFLAG_MALLOC_FSTRING );
02749 
02750   M3_BitArray_Init( &bitArray, pointingClass->pixelClassNode->numPixelInClass, space );
02751 
02752   for( i = 0; i < numEl; i++ )
02753     if( pointing[i].pixel >= 0 )
02754       M3_BitArray_SetBit( bitArray, pointing[i].pixel, 1 );
02755 
02756   numPixelInPointing = 0;
02757   for( j = 0; j < pointingClass->pixelClassNode->numPixelInClass; j++ )
02758     numPixelInPointing += M3_getBit( bitArray, j );
02759   
02760   /* Now create a mask corresponding to the hit pixels */
02761   mask = (M3_MapEl *)calloc( numPixelInPointing, sizeof( M3_MapEl ) );
02762   M3_ErrorCheck( -1, "M3_PointingClassLL_maskPointing()", (mask), M3_EFLAG_MALLOC_FSTRING );
02763 
02764   k = 0;
02765   for( j = 0; j < pointingClass->pixelClassNode->numPixelInClass; j++ )
02766     if( M3_getBit( bitArray, j ) )
02767     {
02768       mask[k].pixel = j; 
02769       k++;
02770     }
02771 
02772   free( space );
02773 
02774   /* Get the values for the mask.  */
02775   M3_PixelClassLL_GetIndexedMask( pointingClass->pixelClassNode, numPixelInPointing, mask );
02776 
02777   /* Make a list of the masked out pixels */
02778   numMaskedPixel = 0;  
02779   for( j = 0; j < numPixelInPointing; j++ )
02780     if( mask[j].value == 0 ) 
02781       numMaskedPixel++;
02782 
02783   maskedPixelList = ( int32_t * )malloc(numMaskedPixel*sizeof(int32_t));
02784 
02785   k = 0;
02786   for( j = 0; j < numPixelInPointing; j++ )
02787     if( mask[j].value == 0 )
02788     {
02789       maskedPixelList[k] = mask[k].pixel;
02790       k++;
02791     }
02792 
02793   free( mask );
02794 
02795   /* Now go through the pointing data and mask out bad pixels.  */
02796   for( i = 0; i < numEl; i++ )
02797     if( M3_binarySearch( numMaskedPixel, maskedPixelList, pointing[i].pixel ) >= 0 )
02798       pointing[i].pixel = -1;    
02799 
02800   free( maskedPixelList );
02801 }
02802 
02803 #endif 
02804 
02805 
02806 void M3_XML_parsePixelClassNode( xmlNodePtr pixelClassXMLnode, int runType, M3_PixelClassLL *thisPixelClass )
02807 {
02808   const int32_t initCookie = -2147483647;
02809   char name[M3_NAME_LENGTH];
02810   char content[M3_CONTENT_LENGTH];
02811   xmlNodePtr thisXMLnode = NULL;
02812   xmlNodePtr childXMLnode = NULL;
02813   M3_FileLL *thisFileNode;
02814 
02815   name[M3_NAME_LENGTH-1] = '\0';
02816   content[M3_CONTENT_LENGTH-1] = '\0';
02817 
02818   memset(thisPixelClass, 0, sizeof(M3_PixelClassLL));
02819   thisPixelClass->pixelType = initCookie;
02820   thisPixelClass->numPixelInClass = initCookie;
02821 
02822   M3_XML_decend( pixelClassXMLnode, &thisXMLnode, M3_NAME_LENGTH, name );
02823   M3_XML_getContent( thisXMLnode, M3_CONTENT_LENGTH, content );
02824 
02825   while( name[0] )
02826   {
02827 
02828     if(strcmp(name, "className") == 0 )
02829     {
02830       if( thisPixelClass->className == NULL )
02831       {
02832         thisPixelClass->className = (char *)malloc(4*(strlen(content)/4+1));
02833         M3_ErrorCheck(-1, "M3_XML_parsePixelClassNode", (thisPixelClass->className), M3_EFLAG_MALLOC_FSTRING);
02834         strcpy(thisPixelClass->className, content);
02835       }
02836       else
02837         fprintf(stderr, "WARNING M3_XML_parsePixelClassNode():  Pixel class name given mutiple times, only first occurance will be heeded.\n");
02838     }
02839     else if( strcmp(name, "pixelType") == 0 )
02840     {
02841       if( thisPixelClass->pixelType == initCookie )
02842       {
02843         if(content[0] == 'I' || content[0] == 'i' )
02844           thisPixelClass->pixelType = M3_CMB_I_PIXEL_TYPE;
02845         else if( content[0] == 'Q' || content[0] == 'q' )
02846           thisPixelClass->pixelType = M3_CMB_Q_PIXEL_TYPE;
02847         else if( content[0] == 'U' || content[0] == 'u')
02848           thisPixelClass->pixelType = M3_CMB_U_PIXEL_TYPE;
02849         else
02850           thisPixelClass->pixelType = M3_DEFAULT_PIXEL_TYPE;
02851       }
02852       else
02853         fprintf(stderr, "WARNING M3_XML_parsePixelClassNode():  Pixel type given multiple times, only first occurance will be heeded.\n");
02854     }
02855     else if( strcmp(name, "numPixelInClass") == 0 )
02856     {
02857       if( thisPixelClass->numPixelInClass == initCookie )
02858         thisPixelClass->numPixelInClass = atoi(content);
02859       else
02860         fprintf(stderr, "WARNING M3_XML_parsePixelClassNode():  Number of pixels in class given multiple times, only first occurance will be heeded.\n");
02861     }
02862     else if( strcmp(name, "mapFile") == 0 )
02863     {
02864       if( thisPixelClass->mapFile == NULL )
02865       {
02866         thisPixelClass->mapFile = (M3_File *)calloc(1,sizeof(M3_File));
02867         M3_ErrorCheck(-1, "M3_XML_parsePixelClassNode", (thisPixelClass->mapFile), M3_EFLAG_MALLOC_FSTRING);
02868         if( runType == M3_MADNES_RUN_TYPE || runType == M3_MADMAP_RUN_TYPE || runType == M3_SPRINGTIDE_RUN_TYPE )
02869           M3_XML_parseFileNode(thisXMLnode, M3_MAP_FILE_TYPE, 0, thisPixelClass->mapFile );
02870         else
02871           M3_XML_parseFileNode(thisXMLnode, M3_MAP_FILE_TYPE, 1, thisPixelClass->mapFile );
02872       }
02873       else
02874         fprintf(stderr, "WARNING M3_XML_parsePixelClassNode():  Map file given multiple times, only first occurance will be heeded.\n");
02875     }
02876     else if( strcmp(name, "coordFile") == 0 )
02877     {
02878       if( thisPixelClass->coordFile == NULL )
02879       {
02880         thisPixelClass->coordFile = (M3_File *)calloc(1, sizeof(M3_File));
02881         M3_ErrorCheck(-1, "M3_XML_parsePixelClassNode", (thisPixelClass->coordFile), M3_EFLAG_MALLOC_FSTRING);
02882         M3_XML_parseFileNode( thisXMLnode, M3_COORD_FILE_TYPE, 1, thisPixelClass->coordFile );
02883       }
02884       else
02885         fprintf(stderr, "WARNING M3_XML_parsePixelClassNode():  Coordinate file given multiple times, only first occurance will be heeded.\n");
02886     }
02887     else if( strcmp(name, "windowFile") == 0 )
02888     {
02889       if( thisPixelClass->windowFile == NULL )
02890       {
02891         thisPixelClass->windowFile = (M3_File *)calloc(1, sizeof(M3_File));
02892         M3_ErrorCheck(-1, "M3_XML_parsePixelClassNode", (thisPixelClass->windowFile), M3_EFLAG_MALLOC_FSTRING);
02893         M3_XML_parseFileNode( thisXMLnode, M3_SPECTRUM_FILE_TYPE, 1, thisPixelClass->windowFile );
02894       }
02895       else
02896         fprintf(stderr, "WARNING M3_XML_parsePixelClassNode():  Window file given multiple times, only first occurance will be heeded.\n");
02897     }
02898     else if( strcmp(name, "maskFiles") == 0 )
02899     {
02900       M3_XML_decend( thisXMLnode, &childXMLnode, M3_NAME_LENGTH, name );
02901       
02902       while( name[0] )
02903       {
02904         if( strcmp(name, "file") == 0 )
02905         {
02906           thisFileNode = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
02907           M3_ErrorCheck(-1, "M3_XML_parsePixelClassNode", (thisFileNode), M3_EFLAG_MALLOC_FSTRING);
02908           M3_XML_parseFileNode(childXMLnode, M3_MASK_FILE_TYPE, 1, &(thisFileNode->file) );
02909           M3_FileLL_insertInOrder( thisFileNode, &(thisPixelClass->maskFileList) );
02910         }
02911         else
02912           fprintf( stderr, "WARNING:  %s is not a valid tag within a mask file list, it will be ignored.\n", name);
02913         M3_XML_follow( childXMLnode, &childXMLnode, M3_NAME_LENGTH, name );
02914       }
02915     }
02916     else if( strcmp( name, "templateFiles") == 0 )
02917     {
02918       M3_XML_decend( thisXMLnode, &childXMLnode, M3_NAME_LENGTH, name );
02919 
02920       while( name[0] )
02921       {
02922         if( strcmp(name, "file") == 0 )
02923         {
02924           thisFileNode = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
02925           M3_ErrorCheck(-1, "M3_XML_parsePixelClassNode", (thisFileNode), M3_EFLAG_MALLOC_FSTRING);
02926           M3_XML_parseFileNode( childXMLnode, M3_MASK_FILE_TYPE, 1, &(thisFileNode->file) );
02927           M3_FileLL_insertInOrder( thisFileNode, &(thisPixelClass->templateFileList) );
02928         }
02929         else
02930           fprintf( stderr, "WARNING:  %s is not a valid tag within a template file list, it will be ignored.\n", name);
02931         M3_XML_follow( childXMLnode, &childXMLnode, M3_NAME_LENGTH, name );
02932       }
02933     }
02934     else
02935       fprintf(stderr, "WARNING:  %s is not a valid tag within a pixelClass, it will be ignored.\n", name);
02936 
02937     M3_XML_follow( thisXMLnode, &thisXMLnode, M3_NAME_LENGTH, name );
02938     M3_XML_getContent( thisXMLnode, M3_CONTENT_LENGTH, content );
02939   }
02940   if( thisPixelClass->pixelType == initCookie )
02941     thisPixelClass->pixelType = M3_CMB_I_PIXEL_TYPE;
02942   M3_ErrorCheck( -1 , "Number of pixels in class not given.", thisPixelClass->numPixelInClass != initCookie, M3_EFLAG_DEFAULT);
02943   
02944   return;
02945 }
02946 
02947 void M3_XML_parseSparsePixelMatrixNode( xmlNodePtr sparseMatrixNode, int runType, M3_File **m3file )
02948 {
02949   int i;
02950 
02951   *m3file = (M3_File *)calloc(1, sizeof(M3_File));
02952   M3_ErrorCheck(-1, "M3_XML_parseSparsePixelMatrixNode", (*m3file), M3_EFLAG_MALLOC_FSTRING);
02953   /* For noise estimation runs this is an output file */
02954   if( runType == M3_MADNES_RUN_TYPE )
02955   {
02956     M3_XML_parseFileNode( sparseMatrixNode, M3_SPARSE_FILE_TYPE, 0, *m3file);
02957   }
02958   /* For other types of runs this is an iput file, and should exist on disk */
02959   else
02960   {
02961     M3_XML_parseFileNode( sparseMatrixNode, M3_SPARSE_FILE_TYPE, 1, *m3file);
02962   }
02963 
02964   return;
02965 }
02966 
02967 
02968 void M3_XML_parseFileNode( xmlNodePtr fileXMLnode, int fileType, int isInputFile, M3_File *m3file )
02969 {
02970   const int32_t initCookie = -2147483647;
02971   char name[M3_NAME_LENGTH];
02972   char content[M3_CONTENT_LENGTH];
02973   int test;
02974   xmlNodePtr childXMLnode;
02975   xmlNodePtr intervalValXMLnode;
02976   M3_Interval theInterval;
02977   M3_AnyHeader header;
02978 
02979   /*Initialize output*/
02980   m3file->name = NULL;
02981   m3file->format = NULL;
02982   m3file->fileType = fileType;
02983 
02984   switch( fileType )
02985   {
02986     case M3_TOD_FILE_TYPE:
02987       m3file->param.tod.interval.firstSample = initCookie;
02988       m3file->param.tod.interval.lastSample = initCookie;
02989       m3file->param.tod.calib = initCookie;
02990       break;
02991     case M3_TOC_FILE_TYPE:
02992       m3file->param.toc.interval.firstSample = initCookie;
02993       m3file->param.toc.interval.lastSample = initCookie;
02994       m3file->param.toc.calib = initCookie;
02995       m3file->param.toc.action = initCookie;
02996       break;
02997     case M3_POINTING_FILE_TYPE:
02998       m3file->param.pointing.interval.firstSample = initCookie;
02999       m3file->param.pointing.interval.lastSample = initCookie;
03000       m3file->param.pointing.calib = initCookie;
03001       break;
03002     case M3_NOISE_FILE_TYPE:
03003       m3file->param.noise.interval.firstSample = initCookie;
03004       m3file->param.noise.interval.lastSample = initCookie;
03005       m3file->param.noise.corLength = initCookie;
03006       m3file->param.noise.calib = initCookie;
03007       break;
03008     case M3_FILTER_FILE_TYPE:
03009       m3file->param.filter.interval.firstSample = initCookie;
03010       m3file->param.filter.interval.lastSample = initCookie;
03011       m3file->param.filter.length = initCookie;
03012       m3file->param.filter.bandWidth = initCookie;
03013       break;
03014     case M3_MAP_FILE_TYPE:
03015       m3file->param.map.numPixel = initCookie;
03016       m3file->param.map.offset = 0;
03017       break;
03018     case M3_MASK_FILE_TYPE:
03019       m3file->param.mask.offset = 0;
03020       break;
03021     case M3_SPARSE_FILE_TYPE:
03022       m3file->param.sparse.numColumn = initCookie;
03023       m3file->param.sparse.numNZ = initCookie;
03024       break;
03025     case M3_GCPOINTING_FILE_TYPE:
03026       m3file->param.gcpointing.firstTime.sec = initCookie;
03027       m3file->param.gcpointing.firstTime.nsec = initCookie;
03028       m3file->param.gcpointing.numSample = initCookie;
03029       m3file->param.gcpointing.sampleRate = initCookie;
03030       m3file->param.gcpointing.numDataPerSample = initCookie;
03031       break;
03032     case M3_AUX_FILE_TYPE:
03033       m3file->param.aux.size = initCookie;
03034       break;
03035   }
03036 
03037 
03038   M3_XML_decend( fileXMLnode, &childXMLnode, M3_NAME_LENGTH, name );
03039   M3_XML_getContent( childXMLnode, M3_CONTENT_LENGTH, content  );
03040 
03041   while(name[0])
03042   {
03043  
03044     if( strcmp(name, "name") == 0 )
03045     {
03046       if(m3file->name == NULL ) 
03047       {
03048         m3file->name = (char*)calloc(4*(strlen(content)/4 + 1), sizeof(char));
03049         M3_ErrorCheck(-1, "M3_XML_parseFileNode", (m3file->name), M3_EFLAG_MALLOC_FSTRING);
03050         strcpy(m3file->name, content);
03051       }
03052       else
03053         fprintf(stderr, "WARNING M3_XML_parseFileNode():  Multiple file names given, only first heeded\n");
03054     }
03055     else if( strcmp(name, "format") == 0 )
03056     {
03057       if(m3file->format == NULL )
03058       {
03059         m3file->format = (char*)malloc(4*(strlen(content)/4 + 1));
03060         M3_ErrorCheck(-1, "M3_XML_parseFileNode", (m3file->format), M3_EFLAG_MALLOC_FSTRING);
03061         strcpy(m3file->format, content);
03062       }
03063       else
03064         fprintf(stderr, "WARNING M3_XML_parseFileNode():  Multiple file formats given, only first heeded\n");
03065     }
03066     else switch( fileType )
03067     {
03068       case M3_TOD_FILE_TYPE:
03069         if( strcmp(name, "calib") == 0 )
03070         {
03071           if( m3file->param.tod.calib == initCookie )
03072             m3file->param.tod.calib = atof(content);
03073           else
03074             fprintf(stderr, "WARNING M3_XML_parseFileNode():  Multiple file calibrations given, only first heeded\n");
03075         }
03076         else
03077           fprintf(stderr, "WARNING M3_XML_parseFileNode(): Tag %s does not make sense for a TOD file, it will be ignored.\n", name);
03078         break;
03079       case M3_TOC_FILE_TYPE:
03080         if( strcmp(name, "calib") == 0 )
03081         {
03082           if( m3file->param.toc.calib == initCookie )
03083             m3file->param.toc.calib = atof(content);
03084           else
03085             fprintf(stderr, "WARNING M3_XML_parseFileNode():  Multiple file calibrations are given, only first heeded\n");
03086         }
03087         else if( strcmp(name, "action") == 0 )
03088         {
03089           if( m3file->param.toc.action == initCookie )
03090           {
03091             if( strcmp(content, "multiply") == 0 || 
03092                 strcmp(content, "MULTIPLY") == 0 || 
03093                 strcmp(content, "m") == 0 || 
03094                 strcmp(content, "M") == 0 )
03095             {
03096               m3file->param.toc.action = M3_MULTIPLY_TOC_ACTION;
03097             }
03098             else if( strcmp( content, "divide") == 0 || 
03099                      strcmp( content, "DIVIDE") == 0 ||
03100                      strcmp( content, "d") == 0 ||
03101                      strcmp( content, "D") == 0 )
03102             {
03103               m3file->param.toc.action = M3_DIVIDE_TOC_ACTION;
03104             }
03105             else
03106               fprintf(stderr, "WARNING M3_XML_parseFileNode():  Could not interperate action ignoring tag\n");
03107           }
03108           else
03109             fprintf(stderr, "WARNING M3_XML_parseFileNode():  Multiple file actions are given, only first heeded\n");
03110         }
03111         else
03112           fprintf(stderr, "WARNING M3_XML_parseFileNode():  Tag %s does not make sense for a TOC file, it will be ignored.\n", name);
03113         break;
03114       case M3_POINTING_FILE_TYPE:
03115         if( strcmp(name, "calib") == 0 )
03116         {
03117           if( m3file->param.pointing.calib == initCookie )
03118             m3file->param.pointing.calib = atof(content);
03119           else
03120             fprintf(stderr, "WARNING M3_XML_parseFileNode():  Multiple file calibrations are given, only first heeded\n");
03121         }
03122         else
03123           fprintf(stderr, "WARNING M3_XML_parseFileNode():  Tag %s does not make sense for a pointing file, it will be ignored.\n", name);
03124         break;
03125       case M3_NOISE_FILE_TYPE:
03126         if( strcmp(name, "calib") == 0 )
03127         {
03128           if( m3file->param.noise.calib == initCookie ) 
03129             m3file->param.noise.calib = atof(content);
03130           else
03131             fprintf(stderr, "WARNING M3_XML_parseFileNode():  Multiple file calibrations are given, only first heeded\n");
03132         }
03133         else if( strcmp(name, "corLength") == 0 )
03134         {
03135           if(m3file->param.noise.corLength == initCookie )
03136             m3file->param.noise.corLength = strtoll(content, NULL, 10);
03137           else
03138             fprintf(stderr, "WARNING M3_XML_parseFileNode():  Multiple file correlation lengths are given, only first heeded\n");
03139         }
03140         else if( strcmp(name, "interval") == 0 )
03141         {
03142           if( isInputFile )
03143           {
03144             fprintf(stderr, "WARNING M3_parasXMLfileNode():  Interval given in runConfig for a noise file, but it is an input file for this run.\n");
03145             fprintf(stderr, "                                Interval in runConfig will be ignored, only file header will be used.\n");
03146           }
03147           else if( m3file->param.noise.interval.firstSample == initCookie && m3file->param.noise.interval.lastSample == initCookie )
03148             M3_XML_parseIntervalNode( childXMLnode, &(m3file->param.noise.interval) );
03149           else
03150             fprintf(stderr, "WARNING M3_XML_parseFileNode():  Multiple file intervals are given, only first heeded.\n");
03151         }
03152         else
03153           fprintf(stderr, "WARNING M3_parseXMLfileDesciption():  Tag %s does not make sense for a noise file, it will be ignored.\n", name);
03154         break;
03155       case M3_FILTER_FILE_TYPE:
03156         if( strcmp(name, "length") == 0 )
03157         {
03158           if( m3file->param.filter.length == initCookie )
03159             m3file->param.filter.length = strtoll(content, NULL, 10);
03160           else
03161             fprintf(stderr, "WARNING M3_XML_parseFileNode():  Multiple filter lengths are given, only first heeded.\n");
03162         }
03163         else if( strcmp(name, "bandWidth") == 0 )
03164         {
03165           if( m3file->param.filter.bandWidth == initCookie ) 
03166             m3file->param.filter.bandWidth = strtoll(content, NULL, 10);
03167           else
03168             fprintf(stderr, "WARNING M3_XML_parseFileNode():  Multiple band widths are given, only first heeded.\n");
03169         }
03170         else
03171           fprintf(stderr, "WARNING M3_parseXMLfileDesciption():  Tag %s does not make sense for a filter file, it will be ignored.\n", name);
03172         break;
03173       case M3_MAP_FILE_TYPE:
03174         fprintf( stderr, "WARNING M3_XML_parseFileNode():  Tag %s does not make sense for a map file, it will be ignored.\n", name);
03175         break;
03176       case M3_COORD_FILE_TYPE:
03177         fprintf( stderr, "WARNING M3_XML_parseFileNode():  Tag %s does not make sense for a coordinate file, it will be ignored.\n", name);
03178         break;
03179       case M3_SPECTRUM_FILE_TYPE:
03180         fprintf( stderr, "WARNING M3_XML_parseFileNode():  Tag %s does not make sense for a spectrum file, it will be ignored.\n", name);          
03181         break;
03182       case M3_BIN_FILE_TYPE:
03183         fprintf( stderr, "WARNING M3_XML_parseFileNode():  Tag %s does not make sense for a bin file, it will be ignored.\n", name);
03184         break;
03185       case M3_BPS_FILE_TYPE:
03186         fprintf( stderr, "WARNING M3_XML_parseFileNode():  Tag %s does not make sense for a binned power spectrum file, it will be ignored.\n", name);
03187         break;
03188       case M3_FISHER_FILE_TYPE:
03189         fprintf( stderr, "WARNING M3_XML_parseFileNode():  Tag %s does not make sense for a Fisher matrix file, it will be ignored.\n", name);
03190         break;
03191       case M3_SPARSE_FILE_TYPE:
03192         fprintf( stderr, "WARNING M3_XML_parseFileNode():  Tag %s does not make sense for a sparse file, it will be ignored.\n", name);
03193         break;
03194       case M3_GCPOINTING_FILE_TYPE:
03195         fprintf( stderr, "WARNING M3_XML_parseFileNode():  Tag %s does not make sense for a gcpointing file, it will be ignored.\n", name);
03196         break;
03197       case M3_AUX_FILE_TYPE:
03198         fprintf( stderr, "WARNING M3_XML_parseFileNode():  Tag %s does not make sense for a auxiliary file, it will be ignored.\n", name);
03199         break; 
03200     }
03201 
03202     M3_XML_follow( childXMLnode, &childXMLnode, M3_NAME_LENGTH, name );
03203     M3_XML_getContent( childXMLnode, M3_CONTENT_LENGTH, content );
03204 
03205   }
03206 
03207 
03208   /* Read in header data */  
03209   if( isInputFile )
03210   {
03211     M3_ErrorCheck(-1, "M3_XML_parseFileNode():  No format was given", (m3file->format), M3_EFLAG_DEFAULT );
03212 
03213     M3_File_ReadHeader( m3file, &header );
03214 
03215     /* use the header data to fill in the structure */
03216     switch( fileType )
03217     {
03218       case M3_TOD_FILE_TYPE:
03219         m3file->param.tod.interval.firstSample = header.tod.firstSample;
03220         m3file->param.tod.interval.lastSample = header.tod.lastSample;
03221         break;
03222       case M3_TOC_FILE_TYPE:
03223         m3file->param.toc.interval.firstSample = header.toc.firstSample;
03224         m3file->param.toc.interval.lastSample = header.toc.lastSample;  
03225         break;
03226       case M3_POINTING_FILE_TYPE:
03227         m3file->param.pointing.interval.firstSample = header.pointing.firstSample;
03228         m3file->param.pointing.interval.lastSample = header.pointing.lastSample;
03229         break;
03230       case M3_NOISE_FILE_TYPE:
03231         m3file->param.noise.interval.firstSample = header.noise.firstSample;
03232         m3file->param.noise.interval.lastSample = header.noise.lastSample;
03233         if( m3file->param.noise.corLength == initCookie )
03234           m3file->param.noise.corLength = header.noise.corLength;
03235         else
03236           M3_ErrorCheck(-1, "M3_XML_parseFileNode():  Correlation length in run config is greater than in file header.", 
03237                         m3file->param.noise.corLength <= header.noise.corLength, M3_EFLAG_DEFAULT );
03238         break;
03239       case M3_FILTER_FILE_TYPE:
03240         m3file->param.filter.interval.firstSample = header.filter.firstSample;
03241         m3file->param.filter.interval.lastSample = header.filter.lastSample;
03242         m3file->param.filter.length = header.filter.length;
03243         m3file->param.filter.bandWidth = header.filter.bandWidth;
03244         break;
03245       case M3_MAP_FILE_TYPE:
03246         m3file->param.map.numPixel = header.map.numPixelInMap;
03247         break;
03248       case M3_SPARSE_FILE_TYPE:
03249         m3file->param.sparse.numColumn = header.sparse.numColumn;
03250         m3file->param.sparse.numNZ = header.sparse.numNZ;
03251         break;
03252       case M3_GCPOINTING_FILE_TYPE:
03253         m3file->param.gcpointing.firstTime.sec = header.gcpointing.firstTime_sec;
03254         m3file->param.gcpointing.firstTime.nsec = header.gcpointing.firstTime_nsec;
03255         m3file->param.gcpointing.numSample = header.gcpointing.numSample;
03256         m3file->param.gcpointing.sampleRate = header.gcpointing.sampleRate;
03257         m3file->param.gcpointing.numDataPerSample = header.gcpointing.numDataPerSample;
03258         break;
03259       case M3_AUX_FILE_TYPE:
03260         m3file->param.aux.size = header.aux.size;
03261 /*
03262       case M3_MASK_FILE_TYPE:
03263       case M3_COORD_FILE_TYPE:
03264       case M3_SPECTRUM_FILE_TYPE:
03265       case M3_BIN_FILE_TYPE:
03266       case M3_BPS_FILE_TYPE:
03267       case M3_FISHER_FILE_TYPE:
03268 */
03269     }
03270 
03271   }
03272 
03273   /* Replace all of the initCookies with default values and check that required elements have been asigned */
03274   switch( fileType )
03275   {
03276     case M3_TOD_FILE_TYPE:
03277       M3_ErrorCheck(-1, "No interval found for tod file.", m3file->param.tod.interval.firstSample != initCookie, M3_EFLAG_DEFAULT );
03278       M3_ErrorCheck(-1, "No interval found for tod file.", m3file->param.tod.interval.lastSample != initCookie, M3_EFLAG_DEFAULT );
03279       if( m3file->param.tod.calib == initCookie )
03280         m3file->param.tod.calib = 1;
03281       break;
03282     case M3_TOC_FILE_TYPE:
03283       M3_ErrorCheck(-1, "No interval found for toc file.", m3file->param.toc.interval.firstSample != initCookie, M3_EFLAG_DEFAULT );
03284       M3_ErrorCheck(-1, "No interval found for toc file.", m3file->param.toc.interval.lastSample != initCookie, M3_EFLAG_DEFAULT );
03285       if( m3file->param.toc.calib == initCookie )
03286         m3file->param.toc.calib = 1;
03287       if( m3file->param.toc.action == initCookie )
03288         m3file->param.toc.action = M3_MULTIPLY_TOC_ACTION;
03289       break;
03290     case M3_POINTING_FILE_TYPE:
03291       M3_ErrorCheck(-1, "No interval found for pointing file.", m3file->param.pointing.interval.firstSample != initCookie, M3_EFLAG_DEFAULT );
03292       M3_ErrorCheck(-1, "No interval found for pointing file.", m3file->param.pointing.interval.lastSample != initCookie, M3_EFLAG_DEFAULT );
03293       if( m3file->param.pointing.calib == initCookie )
03294         m3file->param.pointing.calib = 1.0;
03295       break;
03296     case M3_NOISE_FILE_TYPE:
03297       M3_ErrorCheck(-1, "No interval found for noise file.", m3file->param.noise.interval.firstSample != initCookie, M3_EFLAG_DEFAULT );
03298       M3_ErrorCheck(-1, "No interval found for noise file.", m3file->param.noise.interval.lastSample != initCookie, M3_EFLAG_DEFAULT );
03299       M3_ErrorCheck(-1, "No correlation length given for noise file.", m3file->param.noise.corLength != initCookie, M3_EFLAG_DEFAULT );
03300       if( m3file->param.noise.calib == initCookie)
03301         m3file->param.noise.calib = 1.0;
03302       break;
03303     case M3_FILTER_FILE_TYPE:
03304       M3_ErrorCheck(-1, "No interval found for filter file.", m3file->param.filter.interval.firstSample != initCookie, M3_EFLAG_DEFAULT );
03305       M3_ErrorCheck(-1, "No interval found for filter file.", m3file->param.filter.interval.lastSample != initCookie, M3_EFLAG_DEFAULT );
03306       M3_ErrorCheck(-1, "No length found for filter file.", m3file->param.filter.length != initCookie, M3_EFLAG_DEFAULT );
03307       M3_ErrorCheck(-1, "No band width found for filter file.", m3file->param.filter.bandWidth != initCookie,M3_EFLAG_DEFAULT );
03308       break;
03309     case M3_MAP_FILE_TYPE:
03310       if( m3file->param.map.numPixel == initCookie )
03311         m3file->param.map.numPixel = 0;
03312       break;
03313     case M3_SPARSE_FILE_TYPE:
03314       if( m3file->param.sparse.numColumn == initCookie )
03315         m3file->param.sparse.numColumn = 0;
03316       if( m3file->param.sparse.numNZ == initCookie )
03317         m3file->param.sparse.numNZ = 0;
03318       break;
03319     case M3_GCPOINTING_FILE_TYPE:
03320       M3_ErrorCheck(-1, "No first time found for gcpointing file.", m3file->param.gcpointing.firstTime.sec != initCookie, M3_EFLAG_DEFAULT );
03321       M3_ErrorCheck(-1, "No first time found for gcpointing file.", m3file->param.gcpointing.firstTime.nsec != initCookie, M3_EFLAG_DEFAULT );
03322       M3_ErrorCheck(-1, "No number of sample found for gcpointing file.", m3file->param.gcpointing.numSample != initCookie, M3_EFLAG_DEFAULT );
03323       M3_ErrorCheck(-1, "No sample rate found for gcpointing file.", m3file->param.gcpointing.sampleRate != initCookie, M3_EFLAG_DEFAULT );
03324       M3_ErrorCheck(-1, "No number of data per sample found for gcpointing file.", m3file->param.gcpointing.sampleRate != initCookie, M3_EFLAG_DEFAULT );
03325       break;
03326     case M3_AUX_FILE_TYPE:
03327       M3_ErrorCheck(-1, "No size found for aux file.", m3file->param.aux.size != initCookie, M3_EFLAG_DEFAULT );
03328       break;
03329 
03330 /*
03331     case M3_MASK_FILE_TYPE:
03332     case M3_COORD_FILE_TYPE:
03333     case M3_SPECTRUM_FILE_TYPE:
03334     case M3_BIN_FILE_TYPE:
03335     case M3_BPS_FILE_TYPE:
03336     case M3_FISHER_FILE_TYPE:
03337 */
03338   }
03339 
03340   return;
03341 }
03342 
03343 
03344 void M3_XML_parseIntervalNode( xmlNodePtr intervalXMLnode, M3_Interval *interval )
03345 {
03346   char name[M3_NAME_LENGTH];
03347   char content[M3_CONTENT_LENGTH];  
03348   const int32_t initCookie = -2147483647;
03349   xmlNodePtr intervalValXMLnode = NULL;
03350   
03351   interval->firstSample = initCookie;
03352   interval->lastSample = initCookie;
03353 
03354 
03355   M3_XML_decend( intervalXMLnode, &intervalValXMLnode, M3_NAME_LENGTH, name );
03356   M3_XML_getContent( intervalValXMLnode, M3_CONTENT_LENGTH, content );
03357 
03358   while( name[0] )
03359   {
03360     if( strcmp( name, "firstSample") == 0 )
03361     {
03362       if( interval->firstSample == initCookie )
03363         interval->firstSample = strtoll(content, NULL, 10);
03364       else
03365         fprintf(stderr, "WARNING M3_XML_parseIntervalNode(): firstSample given multiple times, only first occurance will be heeded.\n");
03366     }
03367     else if( strcmp(name, "lastSample") == 0 )
03368     {
03369       if( interval->lastSample == initCookie )
03370         interval->lastSample = strtoll(content, NULL, 10);
03371       else
03372         fprintf(stderr, "WARNING M3_XML_parseIntervalNode(): lastSample given mutiple times, only first occurance will be heeded.\n");
03373     }
03374 
03375     M3_XML_follow( intervalValXMLnode, &intervalValXMLnode, M3_NAME_LENGTH, name );
03376     M3_XML_getContent( intervalValXMLnode, M3_CONTENT_LENGTH, content );
03377   }
03378   
03379   return;
03380 }
03381 
03382 
03383 void M3_XML_parseDataSetNode( xmlNodePtr dataSetXMLnode, int32_t runType, M3_PixelClassLL *pixelClassList, M3_GCPointingGroupLL *GCPointingGroupList, M3_DataSetLL *outDataSet )
03384 {
03385   char name[M3_NAME_LENGTH];
03386   char content[M3_CONTENT_LENGTH];
03387   int temp;
03388   xmlNodePtr thisXMLnode = NULL;
03389   xmlNodePtr childXMLnode = NULL;
03390   xmlNodePtr grandchildXMLnode = NULL;
03391   xmlNodePtr greatgrandchildXMLnode = NULL;
03392   M3_FileLL *thisFileNode;
03393   M3_IntervalLL *thisInterval;
03394   M3_ComponentLL *thisComponent;
03395   M3_SubcomponentLL *thisSubcomponent;
03396   M3_PointingClassLL *thisPointingClass;
03397   M3_PixelClassLL *thisPixelClass;
03398   M3_PointingSubclassLL *thisSubclass;
03399   M3_GCPointingGroupLL *thisGCPointingGroup;
03400 
03401   name[M3_NAME_LENGTH - 1] = '\0';
03402   content[M3_CONTENT_LENGTH-1] = '\0';
03403 
03404   /* initalize the output to zero */
03405   memset(outDataSet, 0, sizeof(M3_DataSetLL));
03406 
03407   /* Loop over the next level down in the XML data structure */
03408   M3_XML_decend(dataSetXMLnode, &thisXMLnode, M3_NAME_LENGTH, name );
03409 
03410   while( name[0] )
03411   {
03412     if( strcmp( name, "name" ) == 0 )
03413     {
03414       M3_XML_getContent( thisXMLnode, M3_CONTENT_LENGTH, content );
03415       if( outDataSet->name == NULL )
03416       {
03417         outDataSet->name = (char*)calloc(4*(strlen(content)/4 + 1), sizeof(char));
03418         M3_ErrorCheck(-1, "M3_XML_parseDataSetNode", (outDataSet->name), M3_EFLAG_MALLOC_FSTRING );
03419         strcpy(outDataSet->name, content );
03420       }
03421       else
03422         fprintf(stderr, "WARNING M3_XML_parseDataSetNode() Multiple data set names given, only first heeded.\n");
03423     }
03424     else if( strcmp( name, "firstTime_sec") == 0 )
03425     {
03426       M3_XML_getContent( thisXMLnode, M3_CONTENT_LENGTH, content );
03427       if( outDataSet->firstTime.sec == 0 )
03428       {
03429         outDataSet->firstTime.sec = strtoll(content, NULL, 10);
03430       }
03431       else
03432         fprintf(stderr, "WARNING M3_XML_parseDataSetNode():  Multiple first time seconds given, only first heeded.\n");
03433     }
03434     else if( strcmp( name, "firstTime_nsec") == 0 )
03435     {
03436       M3_XML_getContent( thisXMLnode, M3_CONTENT_LENGTH, content );
03437       if( outDataSet->firstTime.nsec == 0 )
03438       {
03439         outDataSet->firstTime.nsec = atof(content);
03440       }
03441       else
03442         fprintf(stderr, "WARNING M3_XML_parseDataSetNode():  Multiple first time nanoseconds given, only first heeded.\n");
03443     }
03444     else if( strcmp( name, "sampleRate") == 0 )
03445     {
03446       M3_XML_getContent( thisXMLnode, M3_CONTENT_LENGTH, content );
03447       if( outDataSet->sampleRate == 0 )
03448       {
03449         outDataSet->sampleRate = atof(content );
03450       }
03451       else
03452         fprintf(stderr, "WARNING M3_XML_parseDataSetNode():  Multiple sample rates given, only first heeded.\n");
03453     }
03454 
03455     /* Check to see if this node is a set interval list */
03456     else if( strcmp(name, "setIntervals") == 0 )
03457     {
03458       M3_XML_decend( thisXMLnode, &childXMLnode, M3_NAME_LENGTH, name );
03459 
03460       while( name[0] )
03461       {
03462         if(strcmp( name, "interval") == 0 )
03463         {
03464           /* Allocate memory for the interval */
03465           thisInterval = (M3_IntervalLL *)calloc(1, sizeof(M3_IntervalLL));
03466           M3_ErrorCheck(-1, "M3_XML_parseDataSetNode()", (thisInterval), M3_EFLAG_MALLOC_FSTRING );
03467 
03468           /* Read the interval in from the XML */
03469           M3_XML_parseIntervalNode( childXMLnode, &(thisInterval->interval));
03470 
03471           /* Insert the interval into the list in order */
03472           M3_IntervalLL_insertInOrder( thisInterval, &(outDataSet->coveredIntervalList));
03473         }
03474         else
03475           fprintf(stderr, "WARNING M3_parseXMLdataSet():  Tag %s does not make sense within a setIntervals list, it will be ignored.\n", name);
03476       
03477 
03478         M3_XML_follow( childXMLnode, &childXMLnode, M3_NAME_LENGTH, name );
03479       }
03480     }
03481 
03482     /* Check to see if this node is a component list */
03483     else if( strcmp(name, "component" ) == 0 )
03484     {
03485       if( outDataSet->componentList == NULL )
03486       {
03487         outDataSet->componentList = (M3_ComponentLL *)calloc(1, sizeof(M3_ComponentLL));
03488         M3_ErrorCheck(-1, "M3_XML_parseDataSetNode()", (outDataSet->componentList), M3_EFLAG_MALLOC_FSTRING );
03489         thisComponent = outDataSet->componentList;
03490       }
03491       else
03492       {
03493         for( thisComponent = outDataSet->componentList; thisComponent->next; thisComponent = thisComponent->next );
03494         thisComponent->next = (M3_ComponentLL *)calloc(1, sizeof(M3_ComponentLL));
03495         M3_ErrorCheck(-1, "M3_XML_parseDataSetNode()", (thisComponent->next), M3_EFLAG_MALLOC_FSTRING);
03496         thisComponent = thisComponent->next;
03497       }
03498  
03499       M3_XML_decend( thisXMLnode, &childXMLnode, M3_NAME_LENGTH, name );
03500       
03501       while( name[0] )
03502       {
03503         if( strcmp( name, "subcomponent") == 0 || strcmp( name, "subcomponentSim" ) == 0 )
03504         {
03505           if( thisComponent->subcomponentList == NULL )
03506           {
03507             thisComponent->subcomponentList =(M3_SubcomponentLL *)calloc(1, sizeof(M3_SubcomponentLL));
03508             M3_ErrorCheck(-1, "M3_XML_parseDataSetNode()", (thisComponent->subcomponentList), M3_EFLAG_MALLOC_FSTRING);
03509             thisSubcomponent = thisComponent->subcomponentList;
03510           }
03511           else
03512           {
03513             for( thisSubcomponent = thisComponent->subcomponentList; thisSubcomponent->next; thisSubcomponent = thisSubcomponent->next);
03514             thisSubcomponent->next = (M3_SubcomponentLL *)calloc(1, sizeof(M3_SubcomponentLL));
03515             M3_ErrorCheck(-1, "M3_XML_parseDataSetNode()", (thisSubcomponent->next), M3_EFLAG_MALLOC_FSTRING);
03516             thisSubcomponent = thisSubcomponent->next;
03517           }
03518         }
03519 
03520         if( strcmp( name, "subcomponent" ) == 0 )
03521         {
03522           thisSubcomponent->simType = M3_NO_SIM_TYPE;
03523           M3_XML_decend( childXMLnode, &grandchildXMLnode, M3_NAME_LENGTH, name);
03524 
03525           while( name[0] )
03526           {
03527             if(strcmp(name, "file") == 0 )
03528             {
03529               thisFileNode = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
03530               M3_ErrorCheck(-1, "M3_XML_parseDataSetNode", (thisFileNode), M3_EFLAG_MALLOC_FSTRING);
03531               M3_XML_parseFileNode( grandchildXMLnode, M3_TOD_FILE_TYPE, 1, &(thisFileNode->file));
03532               M3_FileLL_insertInOrder(thisFileNode, &(thisSubcomponent->todFileList));
03533             }
03534             else
03535               fprintf(stderr, "WARNING:  %s is not a valid tag within a subcomponent, it will be ignored.\n", name);
03536 
03537             M3_XML_follow( grandchildXMLnode, &grandchildXMLnode, M3_NAME_LENGTH, name );
03538           }
03539         }
03540         else if( strcmp(name, "tocFiles") == 0 ) 
03541         {
03542           M3_XML_decend( childXMLnode, &grandchildXMLnode, M3_NAME_LENGTH, name );
03543 
03544           while( name[0] )
03545           {
03546             if( strcmp(name, "file") == 0 )
03547             {
03548               thisFileNode = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
03549               M3_ErrorCheck(-1, "M3_XML_parseDataSetNode", (thisFileNode), M3_EFLAG_MALLOC_FSTRING);
03550               M3_XML_parseFileNode( grandchildXMLnode, M3_TOC_FILE_TYPE, 1,  &(thisFileNode->file) );
03551               M3_FileLL_insertInOrder( thisFileNode, &(thisComponent->todCalibFileList));
03552             }
03553             else
03554               fprintf(stderr, "WARNING:  %s is not a valid tag within a tocFiles list, it will be ignored.\n", name);
03555             M3_XML_follow( grandchildXMLnode, &grandchildXMLnode, M3_NAME_LENGTH, name );
03556           }
03557         }
03558         else if( strcmp( name, "subcomponentSim" ) == 0 )
03559         {
03560           M3_XML_decend( childXMLnode, &grandchildXMLnode, M3_NAME_LENGTH, name );
03561 
03562           while( name[0] )
03563           {
03564             if( strcmp(name, "mapScanSim") == 0 )
03565             {
03566               thisSubcomponent->simType = M3_MAPSCAN_SIM_TYPE;
03567 
03568               M3_XML_decend(grandchildXMLnode, &greatgrandchildXMLnode, M3_NAME_LENGTH, name );
03569               if( greatgrandchildXMLnode )
03570               {
03571                 M3_ErrorCheck( -1, "Using different pointing for analysis and simuliation is not yet implemented. ", 0, M3_EFLAG_DEFAULT );
03572               }
03573             }
03574             else if( strcmp( name, "oofNoiseSim" ) == 0  )
03575             {
03576               M3_ErrorCheck( -1, "oofNoiseSim type is not yet implemented. ", 0, M3_EFLAG_DEFAULT );
03577               thisSubcomponent->simType = M3_OOFNOISE_SIM_TYPE;
03578               M3_XML_decend(grandchildXMLnode, &greatgrandchildXMLnode, M3_NAME_LENGTH, name );
03579               if( greatgrandchildXMLnode )
03580               {
03581                 M3_ErrorCheck( -1, "Using different noise filters for analysis and simuliation is not yet implemented. ", 0, M3_EFLAG_DEFAULT );
03582               }
03583             }
03584             else
03585               fprintf(stderr, "WARNING:  %s is not a valid tag within a subcomponentSim, it will be ignored.\n", name);
03586             M3_XML_follow( grandchildXMLnode, &grandchildXMLnode, M3_NAME_LENGTH, name );
03587           }
03588         }
03589         else
03590           fprintf(stderr, "WARNING:  %s is not a valid tag within a component list, it will be ignored\n", name);
03591         M3_XML_follow( childXMLnode, &childXMLnode, M3_NAME_LENGTH, name );
03592       }
03593     }
03594     else if( strcmp(name, "noiseFiles" ) == 0 )
03595     {
03596       M3_XML_decend( thisXMLnode, &childXMLnode, M3_NAME_LENGTH, name );
03597       
03598       while( name[0] )
03599       {
03600         if( strcmp(name, "file") == 0 )
03601         {
03602           thisFileNode = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
03603           M3_ErrorCheck(-1, "M3_XML_parseDataSetNode", (thisFileNode), M3_EFLAG_MALLOC_FSTRING);
03604           if( runType == M3_MADNES_RUN_TYPE )
03605             M3_XML_parseFileNode(childXMLnode, M3_NOISE_FILE_TYPE, 0, &(thisFileNode->file) );
03606           else
03607             M3_XML_parseFileNode(childXMLnode, M3_NOISE_FILE_TYPE, 1, &(thisFileNode->file) );
03608           M3_FileLL_insertInOrder(thisFileNode, &(outDataSet->noiseFileList));
03609         }
03610         else
03611           fprintf(stderr, "WARNING:  %s is not a valid tag within a noiseFiles list, it will be ignored\n", name);
03612 
03613         M3_XML_follow( childXMLnode, &childXMLnode, M3_NAME_LENGTH, name );
03614 
03615       }
03616     }
03617     else if( strcmp(name, "pointingFiles" ) == 0 )
03618     {
03619       M3_XML_decend( thisXMLnode, &childXMLnode, M3_NAME_LENGTH, name );
03620       while( name[0] )
03621       {
03622         if( strcmp(name, "class" ) == 0 )
03623         {
03624           if( outDataSet->pointingClassList == NULL )
03625           {
03626             outDataSet->pointingClassList = (M3_PointingClassLL *)calloc(1, sizeof(M3_PointingClassLL));
03627             M3_ErrorCheck(-1, "M3_XML_parseDataSetNode", (outDataSet->pointingClassList), M3_EFLAG_MALLOC_FSTRING );
03628             thisPointingClass = outDataSet->pointingClassList;
03629           }
03630           else
03631           {
03632             for( thisPointingClass = outDataSet->pointingClassList; thisPointingClass->next; thisPointingClass = thisPointingClass->next );
03633             thisPointingClass->next = (M3_PointingClassLL *)calloc(1, sizeof(M3_PointingClassLL));
03634             M3_ErrorCheck(-1, "M3_XML_parseDataSetNode", (thisPointingClass->next), M3_EFLAG_MALLOC_FSTRING );
03635             thisPointingClass = thisPointingClass->next;
03636           }
03637 
03638           M3_XML_decend( childXMLnode, &grandchildXMLnode, M3_NAME_LENGTH, name );
03639           M3_XML_getContent( grandchildXMLnode, M3_CONTENT_LENGTH, content );
03640 
03641           while( name[0] )
03642           {
03643             if( strcmp(name, "pixelClassName" ) == 0 )
03644             {
03645               for( thisPixelClass = pixelClassList; thisPixelClass && strcmp( thisPixelClass->className, content ); thisPixelClass = thisPixelClass->next );
03646               M3_ErrorCheck(-1, "Pixel class name given for pointing file does not match any of the pixel classes in run config", 
03647                              thisPixelClass, M3_EFLAG_DEFAULT);
03648               thisPointingClass->pixelClassNode = thisPixelClass; 
03649             }
03650             else if( strcmp(name, "subclass") == 0 )
03651             {
03652               if( thisPointingClass->subclassList == NULL )
03653               {
03654                 thisPointingClass->subclassList = (M3_PointingSubclassLL *)calloc(1, sizeof(M3_PointingSubclassLL));
03655                 thisSubclass = thisPointingClass->subclassList;
03656               }
03657               else
03658               {
03659                 for( thisSubclass = thisPointingClass->subclassList; thisSubclass->next; thisSubclass = thisSubclass->next );
03660                 thisSubclass->next = (M3_PointingSubclassLL *)calloc(1, sizeof(M3_PointingSubclassLL));
03661                 thisSubclass = thisSubclass->next;
03662               }
03663               thisSubclass->isFull = 1;
03664               M3_XML_decend( grandchildXMLnode, &greatgrandchildXMLnode, M3_NAME_LENGTH, name );
03665               while( name[0] )
03666               {
03667                 if( strcmp(name, "file" ) == 0 )
03668                 {
03669                   thisFileNode = (M3_FileLL *)calloc(1, sizeof(M3_FileLL) );
03670                   M3_ErrorCheck(-1, "M3_parseXMLdatatSetNode", (thisFileNode), M3_EFLAG_MALLOC_FSTRING );
03671                   M3_XML_parseFileNode( greatgrandchildXMLnode, M3_POINTING_FILE_TYPE, 1, &(thisFileNode->file));
03672                   M3_FileLL_insertInOrder( thisFileNode, &(thisSubclass->pointingFileList));
03673                 }
03674                 else
03675                   fprintf(stderr, "WARNING:  %s is not a valid tag within a subclass, it will be ignored.\n", name);
03676                 M3_XML_follow( greatgrandchildXMLnode, &greatgrandchildXMLnode, M3_NAME_LENGTH, name );
03677               }
03678             }
03679             else if( strcmp(name, "subclassGC") == 0 )
03680             {
03681               if( thisPointingClass->subclassList == NULL )
03682               {
03683                 thisPointingClass->subclassList = (M3_PointingSubclassLL *)calloc(1, sizeof(M3_PointingSubclassLL));
03684                 thisSubclass = thisPointingClass->subclassList;
03685               }
03686               else
03687               {
03688                 for( thisSubclass = thisPointingClass->subclassList; thisSubclass->next; thisSubclass=thisSubclass->next );
03689                 thisSubclass->next = (M3_PointingSubclassLL *)calloc(1, sizeof(M3_PointingSubclassLL));
03690                 thisSubclass = thisSubclass->next;
03691               }
03692               thisSubclass->isFull = 0;
03693 
03694               M3_XML_decend( grandchildXMLnode, &greatgrandchildXMLnode, M3_NAME_LENGTH, name );
03695               M3_XML_getContent(greatgrandchildXMLnode, M3_CONTENT_LENGTH, content );
03696               while( name[0] )
03697               {
03698                 if( strcmp( name, "GCPointingGroupRef") == 0 )
03699                 {
03700                   for( thisGCPointingGroup = GCPointingGroupList; thisGCPointingGroup; thisGCPointingGroup = thisGCPointingGroup->next )
03701                   {
03702                     if( strcmp(thisGCPointingGroup->name, content) == 0 )
03703                     {
03704                       thisSubclass->GCPointingGroupNode = thisGCPointingGroup;
03705                       break;
03706                     }
03707                   }
03708                 }
03709                 else if( strcmp( name, "auxComplement") == 0 )
03710                 {
03711                   thisSubclass->auxComplement = malloc(4*(strlen(content)/4+1));
03712                   M3_ErrorCheck(-1, "M3_XML_parseDataSetNode", (thisSubclass->auxComplement ? 1 : 0), M3_EFLAG_MALLOC_FSTRING);
03713                   strcpy(thisSubclass->auxComplement, content);
03714                 }
03715                 else
03716                   fprintf( stderr, "WARNING:  %s is not a valid tag within a subclassGC, it will be ignored.\n", name);
03717                 M3_XML_follow(greatgrandchildXMLnode, &greatgrandchildXMLnode, M3_NAME_LENGTH, name );
03718                 M3_XML_getContent( greatgrandchildXMLnode, M3_CONTENT_LENGTH, content);
03719               }
03720             }
03721             else if( strcmp(name, "tocFiles") == 0 )
03722             {
03723               M3_XML_decend( grandchildXMLnode, &greatgrandchildXMLnode, M3_NAME_LENGTH, name );
03724               while( name[0] )
03725               {
03726                 if( strcmp(name, "file") == 0 )
03727                 {
03728                   thisFileNode = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
03729                   M3_ErrorCheck( -1, "M3_XML_parseDataSetNode", (thisFileNode), M3_EFLAG_MALLOC_FSTRING );
03730                   M3_XML_parseFileNode( greatgrandchildXMLnode, M3_TOC_FILE_TYPE, 1, &(thisFileNode->file) );
03731                   M3_FileLL_insertInOrder( thisFileNode, &(thisPointingClass->pointingCalibFileList));
03732                 }
03733                 else
03734                   fprintf(stderr, "WARNING:  %s is not a valid tag within a tocFiles list, it will be ignored.\n", name);
03735                 M3_XML_follow( greatgrandchildXMLnode, &greatgrandchildXMLnode, M3_NAME_LENGTH, name );
03736               }
03737             }
03738             else
03739               fprintf(stderr, "WARNING:  %s is not a valid tag within a class, it will be ignored.\n", name);
03740             M3_XML_follow( grandchildXMLnode, &grandchildXMLnode, M3_NAME_LENGTH, name);
03741             M3_XML_getContent( grandchildXMLnode, M3_CONTENT_LENGTH, content );
03742           }
03743         }
03744         else
03745           fprintf(stderr, "WARNING:  %s is not a valid tag within a pointingFiles list, it will be ignored.\n", name);
03746 
03747         M3_XML_follow( childXMLnode, &childXMLnode, M3_NAME_LENGTH, name);
03748       }
03749     }
03750     else if( strcmp(name, "filterFiles" ) == 0 )
03751     {
03752       M3_XML_decend( thisXMLnode, &childXMLnode, M3_NAME_LENGTH, name );
03753       while( name[0] )
03754       {
03755         /* put in while loop */
03756         temp = -1;
03757         if( strcmp( name, "wFilters" ) == 0 )
03758           temp = M3_W_FILTER_TYPE;
03759         else if( strcmp( name, "eFilters") == 0 )
03760           temp = M3_E_FILTER_TYPE;
03761         else if( strcmp( name, "sFilters") == 0 )
03762           temp = M3_S_FILTER_TYPE;
03763         else if( strcmp(name, "bFilters") == 0 )
03764           temp = M3_B_FILTER_TYPE;
03765         if( temp != -1 )
03766         {
03767           M3_XML_decend( childXMLnode, &grandchildXMLnode, M3_NAME_LENGTH, name );
03768           while( name[0] )
03769           {
03770             if( strcmp(name, "file") == 0 )
03771             {
03772               thisFileNode = (M3_FileLL *)calloc(1, sizeof( M3_FileLL ));
03773               M3_ErrorCheck(-1, "M3_XML_parseDataSetNode", (thisFileNode), M3_EFLAG_MALLOC_FSTRING);
03774               M3_XML_parseFileNode( grandchildXMLnode, M3_FILTER_FILE_TYPE, 1, &(thisFileNode->file) );
03775               M3_FileLL_insertInOrder( thisFileNode, &(outDataSet->filterFileList[temp]));
03776             }
03777             else
03778               fprintf(stderr, "WARNING:  %s is not a valid tag within a filter list, it will be ignored.\n", name);
03779             M3_XML_follow( grandchildXMLnode, &grandchildXMLnode, M3_NAME_LENGTH, name );
03780           }
03781         }
03782         else
03783           fprintf(stderr, "WARNING:  %s is not a valid tag within a filterFiles list, it will be ignored.\n", name);
03784         M3_XML_follow( childXMLnode, &childXMLnode, M3_NAME_LENGTH, name ); 
03785       }
03786     }
03787     else
03788       fprintf(stderr, "WARNING:  %s is not a valid tag within a dataSet, it will be ignored.\n", name);
03789 
03790     M3_XML_follow( thisXMLnode, &thisXMLnode, M3_NAME_LENGTH, name );
03791     M3_XML_getContent( thisXMLnode, M3_CONTENT_LENGTH, content );
03792   }
03793   
03794   return;
03795 }
03796 
03797 void M3_XML_parseGCPointingGroupNode( xmlNodePtr GCPointingGroupXMLnode, int runType, M3_GCPointingGroupLL *outPointingGroup )
03798 {
03799   char name[M3_NAME_LENGTH];
03800   char content[M3_CONTENT_LENGTH];
03801   xmlNodePtr thisXMLnode = NULL;
03802   xmlNodePtr childXMLnode = NULL;
03803   M3_FileLL *thisFileNode;
03804   
03805   name[M3_NAME_LENGTH -1] = '\0';
03806   content[M3_CONTENT_LENGTH-1] = '\0';
03807 
03808   memset(outPointingGroup, 0, sizeof(M3_GCPointingGroupLL));
03809 
03810   M3_XML_decend( GCPointingGroupXMLnode, &thisXMLnode, M3_NAME_LENGTH, name );
03811   M3_XML_getContent( thisXMLnode, M3_CONTENT_LENGTH, content );
03812 
03813   while( name[0] )
03814   {
03815     if( strcmp( name, "name") == 0 )
03816     {
03817       if( outPointingGroup->name == NULL )
03818       {
03819         outPointingGroup->name = (char *)malloc(4*(strlen(content)/4+1));
03820         M3_ErrorCheck( -1, "M3_XML_parseGCPointingGroupNode", (outPointingGroup->name ? 1 : 0), M3_EFLAG_MALLOC_FSTRING);
03821         strcpy( outPointingGroup->name, content);
03822       }
03823       else
03824         fprintf(stderr, "WARNING:  M3_XML_parseGCPointingGroupNode():  GCPointingGroup name given multiple times, only first occurance will be heeded.\n");
03825     }
03826     else if( strcmp( name, "GCPointingType") == 0 )
03827     {
03828       if( outPointingGroup->GCPointingType == NULL )
03829       {
03830         outPointingGroup->GCPointingType = (char *)malloc(4*(strlen(content)/4+1));
03831         M3_ErrorCheck( -1, "M3_XML_parseGCPointingGroupNode", (outPointingGroup->GCPointingType ? 1 : 0), M3_EFLAG_MALLOC_FSTRING);
03832         strcpy( outPointingGroup->GCPointingType, content);
03833       }
03834       else
03835         fprintf(stderr, "WARNING:  M3_XML_parseGCPointingGroupNode():  GCPointingGroup type given multiple times, only first occurance will be heeded.\n");
03836     }
03837     else if( strcmp( name, "auxDataFile" ) == 0 )
03838     {
03839       if( outPointingGroup->auxFile == NULL )
03840       {
03841         outPointingGroup->auxFile = (M3_File*)calloc(1, sizeof(M3_File));
03842         M3_ErrorCheck(-1, "M3_XML_parseGCPointingGroupNode", (outPointingGroup->auxFile ? 1 : 0 ), M3_EFLAG_MALLOC_FSTRING);
03843         M3_XML_parseFileNode( thisXMLnode, M3_AUX_FILE_TYPE, 1, outPointingGroup->auxFile);
03844       }
03845       else
03846         fprintf(stderr, "WARNING:  M3_XML_parseGCPointingGroupNode():  GCPointingGroup auxiliary file given mulitple times, only first occurance will be heeded.\n" );
03847     }
03848     else if( strcmp( name, "GCPointingFiles") == 0 )
03849     {
03850       M3_XML_decend( thisXMLnode, &childXMLnode, M3_NAME_LENGTH, name );
03851 
03852       while( name[0] )
03853       {
03854         if( strcmp(name, "file" ) == 0 )
03855         {
03856           thisFileNode = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
03857           M3_ErrorCheck(-1, "M3_XML_parseGCPointingGroupNode()", (thisFileNode ? 1 : 0 ), M3_EFLAG_MALLOC_FSTRING );
03858           M3_XML_parseFileNode( childXMLnode, M3_GCPOINTING_FILE_TYPE, 1, &(thisFileNode->file ));
03859           M3_FileLL_insertInOrder( thisFileNode, &(outPointingGroup->GCPointingFileList) );
03860         }
03861         else
03862           fprintf(stderr, "WARNING:  %s is not a valid tag within a GCPointing file list, it will be ignored.\n", name );
03863         M3_XML_follow( childXMLnode, &childXMLnode, M3_NAME_LENGTH, name );
03864       }
03865     }
03866     else
03867       fprintf(stderr, "WARNING:  %s is not a valid tag within a GCPointing group, it will be ignored\n", name );
03868     M3_XML_follow( thisXMLnode, &thisXMLnode, M3_NAME_LENGTH, name );
03869     M3_XML_getContent( thisXMLnode, M3_CONTENT_LENGTH, content );
03870   }
03871 
03872   return;
03873 }
03874 
03875 
03876 
03877 void M3_IntervalLL_insertInOrder( M3_IntervalLL *intervalNode,  M3_IntervalLL **intervalList )
03878 {
03879   M3_IntervalLL *thisInterval;
03880   M3_IntervalLL *lastInterval;
03881 
03882   if( *intervalList == NULL )
03883   {
03884     *intervalList = intervalNode;
03885   }
03886   else if( intervalNode->interval.firstSample < (*intervalList)->interval.firstSample )
03887   {
03888     intervalNode->next = *intervalList;
03889     *intervalList = intervalNode;
03890   }
03891   else
03892   {
03893     thisInterval = *intervalList;
03894     while( thisInterval && intervalNode->interval.firstSample >= thisInterval->interval.firstSample )
03895     {
03896       lastInterval = thisInterval;
03897       thisInterval = thisInterval->next;
03898     }
03899   
03900     lastInterval->next = intervalNode;
03901     intervalNode->next = thisInterval;
03902   }
03903   
03904   return;
03905 }
03906 
03907 
03908 void M3_FileLL_duplicateList( M3_FileLL *inFileList, M3_FileLL **outFileList )
03909 {
03910   M3_FileLL *thisFile;
03911   M3_FileLL *copyFile;
03912 
03913   copyFile = NULL;
03914   for( thisFile = inFileList; thisFile; thisFile = thisFile->next )
03915   {
03916     if( !copyFile )
03917     {
03918       *outFileList = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
03919       M3_ErrorCheck(-1, "M3_FileLL_duplicateList", (*outFileList), M3_EFLAG_MALLOC_FSTRING);
03920       copyFile = *outFileList;
03921     }
03922     else
03923     {
03924       copyFile->next = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
03925       M3_ErrorCheck(-1, "M3_FileLL_duplicateList", (copyFile->next), M3_EFLAG_MALLOC_FSTRING);
03926       copyFile = copyFile->next;
03927     }
03928     
03929     copyFile->file.name = calloc( 4*(strlen(thisFile->file.name)/4+1), sizeof(char));
03930     M3_ErrorCheck(-1, "M3_FileLL_duplicateList", (copyFile->file.name), M3_EFLAG_MALLOC_FSTRING);
03931     strcpy( copyFile->file.name, thisFile->file.name);
03932 
03933     copyFile->file.format = calloc( 4*(strlen(thisFile->file.format)/4+1), sizeof(char));
03934     M3_ErrorCheck(-1, "M3_FileLL_duplicateList", (copyFile->file.format), M3_EFLAG_MALLOC_FSTRING);
03935     strcpy( copyFile->file.format, thisFile->file.format );
03936 
03937     copyFile->file.fileType = thisFile->file.fileType;
03938 
03939     copyFile->file.param = thisFile->file.param;
03940   }
03941 
03942   return;
03943 }
03944 
03945 
03946 void M3_FileLL_insertInOrder( M3_FileLL *fileNode, M3_FileLL **fileList )
03947 {
03948   M3_FileLL *thisFile;
03949   M3_FileLL *lastFile;
03950   M3_Interval inInterval, thisInterval;
03951   M3_TimeEl inTime, thisTime;
03952 
03953   if( *fileList == NULL )
03954   {
03955     *fileList = fileNode;
03956     return;
03957   }
03958 
03959   if( fileNode->file.fileType != M3_GCPOINTING_FILE_TYPE )
03960   {
03961     M3_File_getInterval( &(fileNode->file), &inInterval);
03962 
03963     thisFile = *fileList;
03964     M3_File_getInterval( &(thisFile->file), &thisInterval );
03965 
03966     if( inInterval.firstSample < thisInterval.firstSample )
03967     { 
03968       fileNode->next = *fileList;
03969       *fileList = fileNode;
03970       return;
03971     }
03972 
03973     while( thisFile && inInterval.firstSample >= thisInterval.firstSample )
03974     {
03975       lastFile = thisFile;
03976       thisFile = thisFile->next;
03977       if( thisFile )
03978         M3_File_getInterval( &(thisFile->file), &thisInterval);
03979     }
03980  
03981     lastFile->next = fileNode;
03982     fileNode->next = thisFile;
03983   }
03984   else
03985   {
03986     inTime = fileNode->file.param.gcpointing.firstTime;
03987     
03988     thisFile = *fileList;
03989     thisTime = thisFile->file.param.gcpointing.firstTime;
03990     
03991     if( M3_TimeEl_Compare(inTime, thisTime ) < 0 )
03992     {
03993       fileNode->next = *fileList;
03994       *fileList = fileNode;
03995       return;
03996     }
03997 
03998     while( thisFile && M3_TimeEl_Compare(inTime, thisTime ) >= 0 )
03999     {
04000       lastFile = thisFile;
04001       thisFile = thisFile->next;
04002       if( thisFile )
04003         thisTime = thisFile->file.param.gcpointing.firstTime;
04004     }
04005     lastFile->next = fileNode;
04006     fileNode->next = thisFile;
04007   }
04008 
04009   return;
04010 }
04011 
04012 void M3_XML_decend( xmlNodePtr thisXMLnode, xmlNodePtr *childXMLnode, int nameLength, char *name )
04013 {
04014   *childXMLnode = thisXMLnode->children;
04015         
04016   while( *childXMLnode && (*childXMLnode)->type != XML_ELEMENT_NODE )
04017     *childXMLnode = (*childXMLnode)->next;
04018   if( *childXMLnode )
04019     strncpy( name, (char *)((*childXMLnode)->name), nameLength-1);
04020   else
04021     name[0] = '\0';
04022   
04023   return;
04024 }
04025 
04026 
04027 void M3_XML_follow( xmlNodePtr theXMLnode, xmlNodePtr *nextXMLnode, int nameLength, char *name )
04028 {
04029   *nextXMLnode = theXMLnode->next;
04030   while( *nextXMLnode && (*nextXMLnode)->type != XML_ELEMENT_NODE )
04031     *nextXMLnode = (*nextXMLnode)->next;
04032   if( *nextXMLnode )
04033     strncpy( name, (char*)((*nextXMLnode)->name), nameLength-1);
04034   else
04035     name[0] = '\0';
04036   
04037   return;
04038 }
04039 
04040 
04041 void M3_XML_getContent( xmlNodePtr thisXMLnode, int contentLength, char *content )
04042 {
04043   if( thisXMLnode && thisXMLnode->children && thisXMLnode->children->content)
04044     strncpy(content, (char*)(thisXMLnode->children->content), contentLength - 1);
04045   else
04046     content[0] = '\0';
04047   
04048   return;
04049 }
04050 
04051 
04052 void M3_PixelClassLL_insertInOrder( M3_PixelClassLL *thisPixelClass, M3_PixelClassLL **pixelClassList )
04053 {
04054   M3_PixelClassLL *aPixelClass;
04055 
04056 
04057   /* If the list is empty, start the list and return */
04058   if( *pixelClassList == NULL )
04059   {
04060     *pixelClassList = thisPixelClass;
04061     return;
04062   }
04063 
04064   /* Initalize aPixelClass to NULL */
04065   aPixelClass = NULL;
04066 
04067   /* Check to see if the first element in the list is an intensity pixel class */
04068   /* If it is, then advance aPixelClass so that it points at the last I pixel class in the list */
04069   if( (*pixelClassList)->pixelType == M3_CMB_I_PIXEL_TYPE )
04070     for( aPixelClass = (*pixelClassList); aPixelClass->next && aPixelClass->next->pixelType == M3_CMB_I_PIXEL_TYPE; aPixelClass = aPixelClass->next);
04071 
04072   /* If the pixel class to be added is an I pixel type, then it belongs here in the list */
04073   if( thisPixelClass->pixelType == M3_CMB_I_PIXEL_TYPE )
04074   {
04075     /* If we have advanced aPixelClass, then put the new class at this point in the list */
04076     if( aPixelClass )
04077     {
04078       thisPixelClass->next = aPixelClass->next;
04079       aPixelClass->next = thisPixelClass;
04080     }
04081     /* Otherwise, begin the list with the new pixel class */
04082     else
04083     {
04084       thisPixelClass->next = (*pixelClassList);
04085       (*pixelClassList) = thisPixelClass;
04086     }
04087   }
04088   else
04089   {
04090     /* If the class to add is not an I type, we have to advance to the last Q pixel class in the list */
04091     if( aPixelClass == NULL )
04092     {
04093       if( (*pixelClassList)->pixelType == M3_CMB_Q_PIXEL_TYPE )
04094         for( aPixelClass = (*pixelClassList); aPixelClass->next && aPixelClass->next->pixelType == M3_CMB_Q_PIXEL_TYPE; aPixelClass = aPixelClass->next);
04095     }
04096     else
04097       for( ; aPixelClass->next && aPixelClass->next->pixelType == M3_CMB_Q_PIXEL_TYPE; aPixelClass = aPixelClass->next );
04098 
04099     /* If the pixel class to add is of type Q then add it here in the list.  */    
04100     if( thisPixelClass->pixelType == M3_CMB_Q_PIXEL_TYPE )
04101     {
04102       if( aPixelClass )
04103       {
04104         thisPixelClass->next = aPixelClass->next;
04105         aPixelClass->next = thisPixelClass;
04106       }
04107       else
04108       {
04109         thisPixelClass->next = (*pixelClassList);
04110         (*pixelClassList) = thisPixelClass;
04111       }
04112     }
04113     /* Otherwise advance to the last U pixel type */
04114     else
04115     {
04116       if( aPixelClass == NULL )
04117       {
04118         if( (*pixelClassList)->pixelType == M3_CMB_U_PIXEL_TYPE )
04119           for( aPixelClass = (*pixelClassList); aPixelClass->next && aPixelClass->next->pixelType == M3_CMB_U_PIXEL_TYPE; aPixelClass = aPixelClass->next);
04120       }
04121       else
04122         for( ; aPixelClass->next && aPixelClass->next->pixelType == M3_CMB_U_PIXEL_TYPE; aPixelClass = aPixelClass->next );
04123       
04124       /* If the pixel class to add is a U pixel type then add it here */
04125       if( thisPixelClass->pixelType == M3_CMB_U_PIXEL_TYPE )
04126       {
04127         if( aPixelClass )
04128         {
04129           thisPixelClass->next = aPixelClass->next;
04130           aPixelClass->next = thisPixelClass;
04131         }
04132         else
04133         {
04134           thisPixelClass->next = (*pixelClassList);
04135           (*pixelClassList) = thisPixelClass;
04136         }
04137       }
04138       /* Otherwise advance to the end of the list and add the pixel class there */
04139       else
04140       {
04141         if( aPixelClass == NULL )
04142           for( aPixelClass = (*pixelClassList); aPixelClass->next; aPixelClass = aPixelClass->next );
04143         else
04144           for( ; aPixelClass->next; aPixelClass = aPixelClass->next );
04145         thisPixelClass->next = aPixelClass->next;
04146         aPixelClass->next = thisPixelClass;
04147       }
04148     }
04149   }
04150   
04151   return;
04152 }
04153 
04154 
04155 void M3_XML_parsePowerSpectrumNode( xmlNodePtr spectrumXMLnode, int runType, M3_PowerSpectrumStruct *outPowerSpectrum )
04156 {
04157   char content[M3_CONTENT_LENGTH];  
04158   char name[M3_NAME_LENGTH];
04159   M3_SpectrumClassLL *thisSpectrumClass;
04160   xmlNodePtr childXMLnode;
04161   xmlNodePtr grandchildXMLnode;
04162 
04163 
04164   M3_XML_decend( spectrumXMLnode, &childXMLnode, M3_NAME_LENGTH, name );
04165   while( name[0] )
04166   {
04167     if( strcmp( name, "spectrumClass") == 0 )
04168     {
04169       if( outPowerSpectrum->spectrumClassList == NULL )
04170       {
04171         outPowerSpectrum->spectrumClassList = (M3_SpectrumClassLL *)calloc(1, sizeof(M3_SpectrumClassLL) );
04172         M3_ErrorCheck(-1, "M3_XML_parsePowerSpectrumNode", (outPowerSpectrum->spectrumClassList), M3_EFLAG_MALLOC_FSTRING );
04173         thisSpectrumClass = outPowerSpectrum->spectrumClassList;
04174       }
04175       else
04176       {
04177         for( thisSpectrumClass = outPowerSpectrum->spectrumClassList; thisSpectrumClass->next; thisSpectrumClass = thisSpectrumClass->next );
04178         thisSpectrumClass->next = (M3_SpectrumClassLL *)calloc(1, sizeof(M3_SpectrumClassLL) );
04179         M3_ErrorCheck(-1, "M3_XML_parsePowerSpectrumNode", (thisSpectrumClass->next), M3_EFLAG_MALLOC_FSTRING );
04180         thisSpectrumClass = thisSpectrumClass->next;
04181       }
04182 
04183       M3_XML_decend(childXMLnode, &grandchildXMLnode, M3_NAME_LENGTH, name );
04184       
04185       while( name[0] )
04186       {
04187         if( strcmp(name, "spectrumType") == 0 )
04188         {
04189           M3_XML_getContent( grandchildXMLnode, M3_CONTENT_LENGTH, content );
04190 
04191           /* What about ET, BT or BE, should these also be accepted?  */ 
04192           if( strcmp( content, "TT") == 0 || strcmp( content, "tt") == 0 )
04193             thisSpectrumClass->spectrumType = M3_TT_SPECTRUM_TYPE;
04194           else if( strcmp( content, "EE") == 0 || strcmp( content, "ee") == 0 )
04195             thisSpectrumClass->spectrumType = M3_EE_SPECTRUM_TYPE;
04196           else if( strcmp( content, "BB") == 0 || strcmp( content, "bb") == 0 )
04197             thisSpectrumClass->spectrumType = M3_BB_SPECTRUM_TYPE;
04198           else if( strcmp( content, "TE") == 0 || strcmp( content, "te") == 0 )
04199             thisSpectrumClass->spectrumType = M3_TE_SPECTRUM_TYPE;
04200           else if( strcmp( content, "TB") == 0 || strcmp( content, "tb") == 0 )
04201             thisSpectrumClass->spectrumType = M3_TB_SPECTRUM_TYPE;
04202           else if( strcmp( content, "EB") == 0 || strcmp( content, "eb") == 0 )
04203             thisSpectrumClass->spectrumType = M3_EB_SPECTRUM_TYPE;
04204           else
04205             fprintf( stderr, "WARNING:  %s is not a valid spectrumType, default type will be asigned.\n", content);
04206         }
04207         else if( strcmp(name, "binFile") == 0 )
04208         {
04209           if( thisSpectrumClass->binFile == NULL )
04210           {
04211             thisSpectrumClass->binFile = (M3_File *)calloc(1, sizeof(M3_File));
04212             M3_ErrorCheck(-1, "M3_XML_parsePowerSpectrumNode", (thisSpectrumClass->binFile), M3_EFLAG_MALLOC_FSTRING);
04213             M3_XML_parseFileNode( grandchildXMLnode, M3_BIN_FILE_TYPE, 1, thisSpectrumClass->binFile );
04214           }
04215           else
04216             fprintf(stderr, "WARNING:  Two bin files are given for a single spectrum class, only the first will be heeded\n");
04217         }
04218         else if( strcmp(name, "shapeFile") == 0 )
04219         {
04220           if( thisSpectrumClass->shapeFile == NULL )
04221           {
04222             thisSpectrumClass->shapeFile = (M3_File *)calloc(1, sizeof(M3_File));
04223             M3_ErrorCheck(-1, "M3_XML_parsePowerSpectrumNode", (thisSpectrumClass->shapeFile), M3_EFLAG_MALLOC_FSTRING);
04224             M3_XML_parseFileNode( grandchildXMLnode, M3_SPECTRUM_FILE_TYPE, 1, thisSpectrumClass->shapeFile  );
04225           }
04226           else
04227             fprintf( stderr, "WARNING:  Two shape files are given for a single spectrum class, only the first will be heeded\n");
04228         }
04229         else if( strcmp(name, "bpsFile") == 0 )
04230         {
04231           if( thisSpectrumClass->bpsFile == NULL )
04232           {
04233             thisSpectrumClass->bpsFile = (M3_File *)calloc(1, sizeof(M3_File));
04234             M3_ErrorCheck(-1, "M3_XML_parsePowerSpectrumNode", (thisSpectrumClass->bpsFile), M3_EFLAG_MALLOC_FSTRING);
04235             M3_XML_parseFileNode( grandchildXMLnode, M3_BPS_FILE_TYPE, 0, thisSpectrumClass->bpsFile );
04236           }
04237           else
04238             fprintf( stderr, "WARNING:  Two binned power spectrum files were given for a single spectrum class, only the first will be heeded\n");
04239         }
04240         else
04241           fprintf(stderr, "WARNING:  %s is not a valid tag within a spectrumClass, it will be ignored.\n", name);
04242 
04243         M3_XML_follow(grandchildXMLnode, &grandchildXMLnode, M3_NAME_LENGTH, name );
04244       }
04245     }
04246     else if( strcmp(name, "fisherMatrixFile") == 0 )
04247     {
04248       if( outPowerSpectrum->fisherMatrix == NULL )
04249       {
04250         outPowerSpectrum->fisherMatrix = (M3_File *)calloc(1, sizeof(M3_File) );
04251         M3_ErrorCheck(-1, "M3_XML_parsePowerSpectrumNode", (outPowerSpectrum->fisherMatrix), M3_EFLAG_MALLOC_FSTRING);
04252         M3_XML_parseFileNode( childXMLnode, M3_FISHER_FILE_TYPE, 0, outPowerSpectrum->fisherMatrix );
04253       }
04254       else
04255         fprintf( stderr, "WARNING:  Two fisher matrix files are given, only the first will be heeded\n");
04256     }
04257     else
04258       fprintf(stderr, "WARNING:  %s is not a valid tag within a powerSpectrum, it will be ignored", name);
04259 
04260     M3_XML_follow( childXMLnode, &childXMLnode, M3_NAME_LENGTH, name );
04261   }
04262 
04263   return;
04264 }
04265 
04266 
04267 void M3_RunConfigStruct_refine( M3_RunConfigStruct *runConfig, int runType )
04268 {
04269   int64_t i, j;
04270   int32_t k;
04271   char buffer[512];
04272   M3_FileLL *thisFile;
04273   M3_IntervalLL *aList, *bList, *cList;
04274   M3_DataSetLL *thisDataSet;
04275   M3_PointingClassLL *thisClass;
04276   M3_PointingSubclassLL *thisSubclass;
04277   M3_PointingHeader pointingHeader;
04278   M3_ComponentLL *thisComponent;
04279   M3_SubcomponentLL *thisSubcomponent;
04280   M3_SpectrumClassLL *thisSpectrumClass;
04281   M3_SpectrumHeader spectrumHeader;
04282   M3_BinHeader binHeader;
04283   M3_BPSheader bpsHeader;
04284   M3_PixelClassLL *thisPixelClass;
04285   M3_TimeEl thisLastTime, nextFirstTime;
04286   int32_t thisNumNZ;
04287   M3_GCPointingGroupLL *thisGCPointingGroup;
04288 
04289   /* fill in the class indices */
04290   j = 0;
04291   for( i = 0, thisPixelClass = runConfig->pixelClassList; thisPixelClass; thisPixelClass = thisPixelClass->next, i++ )
04292   {
04293     thisPixelClass->classIndex = i;
04294     thisPixelClass->globalPixelOffset = j;
04295     M3_PixelClassLL_GetNumPixelInClass(thisPixelClass, &k);
04296     j += k;
04297   }
04298 
04299 
04300   for(thisDataSet = runConfig->dataSetList; thisDataSet; thisDataSet = thisDataSet->next )
04301   {
04302     /* Fill in the numPixelInClass, numNZ and offset values. */
04303     thisDataSet->numNZ = 0;
04304     thisDataSet->pointingClassList->columnOffset = 0;
04305     thisDataSet->runConfigNode = runConfig;
04306     for(thisClass = thisDataSet->pointingClassList; thisClass; thisClass = thisClass->next) 
04307     {
04308       thisClass->numNZ = 0;
04309       thisClass->subclassList->columnOffset = thisClass->columnOffset;
04310       for(thisSubclass = thisClass->subclassList; thisSubclass; thisSubclass = thisSubclass->next)
04311       {
04312         if( thisSubclass->GCPointingGroupNode )
04313         {
04314           M3_GCPointingType_GetNumNZ( thisSubclass->GCPointingGroupNode->GCPointingType, thisSubclass->auxComplement, &thisNumNZ );
04315           thisSubclass->numNZ = thisNumNZ;
04316           thisClass->numNZ += thisNumNZ;
04317           thisDataSet->numNZ += thisNumNZ;
04318         }
04319         else if( thisSubclass->pointingFileList )
04320         {
04321           M3_File_ReadHeader( &(thisSubclass->pointingFileList->file), &pointingHeader);
04322           thisSubclass->numNZ = pointingHeader.numNZ;
04323           thisClass->numNZ += pointingHeader.numNZ;
04324           thisDataSet->numNZ += pointingHeader.numNZ;
04325         }
04326 
04327         if(thisSubclass->next)
04328           thisSubclass->next->columnOffset = thisSubclass->columnOffset + thisSubclass->numNZ;
04329       }
04330       if( !(thisClass->pixelClassNode->numPixelInClass ) )
04331         thisClass->pixelClassNode->numPixelInClass = pointingHeader.numPixelInClass;
04332       if(thisClass->next)
04333         thisClass->next->columnOffset = thisClass->columnOffset + thisClass->numNZ;
04334     }
04335 
04336     /* Check that file list intervals do not overlap */
04337     if( thisDataSet->noiseFileList )
04338       for( thisFile = thisDataSet->noiseFileList; thisFile->next; thisFile = thisFile->next )
04339       {
04340         M3_ErrorCheck(-1, "Noise files overlap",  
04341                       thisFile->file.param.noise.interval.lastSample < thisFile->next->file.param.noise.interval.firstSample, M3_EFLAG_DEFAULT );
04342       }
04343     for( thisClass = thisDataSet->pointingClassList; thisClass; thisClass = thisClass->next )
04344       for( thisSubclass = thisClass->subclassList; thisSubclass; thisSubclass = thisSubclass->next )
04345         if( thisSubclass->pointingFileList )
04346         {
04347           for( thisFile = thisSubclass->pointingFileList; thisFile->next; thisFile = thisFile->next )
04348           {
04349             M3_ErrorCheck(-1, "Pointing files overlap",
04350                           thisFile->file.param.pointing.interval.lastSample < thisFile->next->file.param.pointing.interval.firstSample, M3_EFLAG_DEFAULT);
04351           }
04352         }
04353 
04354 
04355     for( thisGCPointingGroup = runConfig->GCPointingGroupList; thisGCPointingGroup; thisGCPointingGroup = thisGCPointingGroup->next )
04356       for( thisFile = thisGCPointingGroup->GCPointingFileList; thisFile->next; thisFile = thisFile->next )
04357       {
04358         thisLastTime = M3_TimeEl_AddSamples( thisFile->file.param.gcpointing.firstTime, thisFile->file.param.gcpointing.numSample-1, thisFile->file.param.gcpointing.sampleRate);
04359         nextFirstTime = thisFile->next->file.param.gcpointing.firstTime;
04360         M3_ErrorCheck(-1, "GCPointingFiles overlap", M3_TimeEl_Compare( thisLastTime, nextFirstTime) <= 0, M3_EFLAG_DEFAULT ); 
04361       }
04362     
04363 
04364     for( i = 0; i < M3_NUM_FILTER_TYPE; i++ )
04365       for( thisFile = thisDataSet->filterFileList[i]; thisFile && thisFile->next; thisFile = thisFile->next )
04366       {
04367         M3_ErrorCheck(-1, "Filter files overlap", 
04368                       thisFile->file.param.filter.interval.lastSample < thisFile->next->file.param.filter.interval.firstSample, M3_EFLAG_DEFAULT);
04369       }
04370 
04371     /* Correct covered interval list */
04372     aList = thisDataSet->coveredIntervalList;
04373     for( thisComponent = thisDataSet->componentList; thisComponent; thisComponent = thisComponent->next )
04374     {
04375       for( thisSubcomponent = thisComponent->subcomponentList; thisSubcomponent; thisSubcomponent = thisSubcomponent->next)
04376       {
04377         if( thisSubcomponent->simType == M3_NO_SIM_TYPE )
04378         {
04379 
04380           bList = M3_fileListToIntervalList( thisSubcomponent->todFileList );
04381          
04382           if( aList)
04383           {
04384             cList = M3_intersectIntervalLists( aList, bList );
04385             M3_IntervalLL_destroyList( aList );
04386             M3_IntervalLL_destroyList( bList );
04387             aList = cList;
04388           }
04389           else
04390             aList = bList;
04391         }
04392         else if( thisSubcomponent->simType == M3_MAPSCAN_SIM_TYPE )
04393         {
04394           M3_ErrorCheck( -1, "Using different pointing for simulation and analysis is not yet implemented.", thisSubcomponent->mapScanSimPointingList == 0, M3_EFLAG_DEFAULT );
04395         }
04396         else if( thisSubcomponent->simType == M3_OOFNOISE_SIM_TYPE )
04397         {
04398           M3_ErrorCheck( -1, "Using different noise for simulation and analysis is not yet implemented.", thisSubcomponent->oofNoiseSimFileList == 0, M3_EFLAG_DEFAULT );
04399         }
04400       }
04401     }
04402     for( thisClass = thisDataSet->pointingClassList; thisClass; thisClass = thisClass->next )
04403       for( thisSubclass = thisClass->subclassList; thisSubclass; thisSubclass = thisSubclass->next )
04404       {
04405         if( thisSubclass->pointingFileList )
04406         {
04407           bList = M3_fileListToIntervalList( thisSubclass->pointingFileList);
04408         }
04409         else if( thisSubclass->GCPointingGroupNode )
04410         {
04411           bList = M3_gcpFileListToIntervalList(thisSubclass->GCPointingGroupNode->GCPointingFileList, thisDataSet->firstTime, thisDataSet->sampleRate );
04412         }
04413         else
04414           bList = NULL;
04415         cList = M3_intersectIntervalLists( aList, bList );
04416         M3_IntervalLL_destroyList( aList );
04417         M3_IntervalLL_destroyList( bList );
04418         aList = cList;
04419       }
04420 
04421     if( runType != M3_SPRINGTIDE_RUN_TYPE ) 
04422     {
04423       bList = M3_fileListToIntervalList( thisDataSet->noiseFileList);
04424       thisDataSet->coveredIntervalList = M3_intersectIntervalLists( aList, bList );
04425       M3_IntervalLL_destroyList( aList );
04426       M3_IntervalLL_destroyList( bList );
04427     }
04428     else
04429       thisDataSet->coveredIntervalList = aList;
04430 
04431     /* Check that pointing file headers are consistant with runConfig structure */
04432     for( thisClass = thisDataSet->pointingClassList; thisClass; thisClass = thisClass->next )
04433       for( thisSubclass = thisClass->subclassList; thisSubclass; thisSubclass = thisSubclass->next )
04434       {
04435         for( thisFile = thisSubclass->pointingFileList; thisFile; thisFile = thisFile->next )
04436         {
04437           M3_File_ReadHeader( &(thisFile->file), &pointingHeader );
04438           sprintf(buffer, "Header of file named %s does not make sense %i %i", thisFile->file.name, pointingHeader.numNZ, pointingHeader.numPixelInClass);
04439           M3_ErrorCheck(-1, buffer, pointingHeader.numNZ == thisSubclass->numNZ, M3_EFLAG_DEFAULT );
04440           M3_ErrorCheck(-1, buffer, pointingHeader.numPixelInClass == thisClass->pixelClassNode->numPixelInClass, M3_EFLAG_DEFAULT );
04441         }
04442       }
04443   } 
04444   
04445   /* Fill in lmax and numBin arguements */
04446   runConfig->powerSpectrum.numBin = 0;
04447   for( thisSpectrumClass = runConfig->powerSpectrum.spectrumClassList; thisSpectrumClass; thisSpectrumClass = thisSpectrumClass->next )
04448   {
04449     M3_File_ReadHeader( thisSpectrumClass->shapeFile, &spectrumHeader );
04450     thisSpectrumClass->lmax = spectrumHeader.lmax;
04451     M3_File_ReadHeader( thisSpectrumClass->binFile, &binHeader );
04452     thisSpectrumClass->numBin = binHeader.numBin;
04453     runConfig->powerSpectrum.numBin += thisSpectrumClass->numBin;
04454   }
04455 
04456   runConfig->todCache.useGCPcache = 0;
04457   runConfig->todCache.useScanMapCache = 0;
04458   if( runConfig->GCPointingGroupList != NULL )
04459     runConfig->todCache.useGCPcache = 1;
04460 
04461   for( thisDataSet = runConfig->dataSetList; thisDataSet; thisDataSet = thisDataSet->next )
04462     for( thisComponent = thisDataSet->componentList; thisComponent; thisComponent = thisComponent->next )
04463       for( thisSubcomponent = thisComponent->subcomponentList; thisSubcomponent; thisSubcomponent = thisSubcomponent->next )
04464         if( thisSubcomponent->simType == M3_MAPSCAN_SIM_TYPE )
04465           runConfig->todCache.useScanMapCache = 1;
04466   return;
04467 }
04468   
04469 
04470 
04471 M3_IntervalLL *M3_fileListToIntervalList( M3_FileLL *fileList )
04472 {
04473   int isNoise;
04474   M3_Interval thisInterval;
04475   M3_IntervalLL *aList;
04476   M3_IntervalLL *aNode;
04477   M3_FileLL *thisFile;
04478 
04479   if( fileList == NULL ) 
04480     return( NULL );
04481 
04482   aList = NULL;
04483   aNode = NULL;
04484   
04485   if( fileList->file.fileType == M3_NOISE_FILE_TYPE )
04486     isNoise = 1;
04487   else
04488     isNoise = 0;
04489 
04490   if( !fileList )
04491     return(NULL);
04492 
04493   aList = (M3_IntervalLL*)calloc(1, sizeof(M3_IntervalLL));
04494   M3_ErrorCheck(-1, "M3_fileListToIntervalList", aList, M3_EFLAG_MALLOC_FSTRING);
04495   aNode = aList;
04496 
04497   M3_File_getInterval( &(fileList->file), &thisInterval );
04498   aNode->interval = thisInterval;
04499 
04500   thisFile = fileList->next;
04501   if( thisFile )
04502     M3_File_getInterval( &(thisFile->file), &thisInterval);
04503   while( thisFile )
04504   {
04505     if( isNoise || aNode->interval.lastSample != thisInterval.firstSample - 1 )
04506     {
04507       aNode->next = (M3_IntervalLL*)calloc(1, sizeof(M3_IntervalLL));
04508       M3_ErrorCheck(-1, "M3_fileListToIntervalList", (aNode->next ? 1 : 0), M3_EFLAG_MALLOC_FSTRING);
04509       aNode = aNode->next;
04510       
04511       aNode->interval = thisInterval;
04512       thisFile = thisFile->next;
04513       if( thisFile )
04514         M3_File_getInterval( &(thisFile->file), &thisInterval);
04515     }
04516     else
04517     {
04518       while( thisFile && aNode->interval.lastSample == thisInterval.firstSample - 1)
04519       {
04520         aNode->interval.lastSample = thisInterval.lastSample;
04521         thisFile = thisFile->next;
04522         if(thisFile )
04523           M3_File_getInterval( &(thisFile->file), &thisInterval);
04524       }
04525     }
04526   }
04527 
04528   return(aList);
04529 }
04530 
04531 int64_t M3_myRound( double a )
04532 {
04533   return( (int64_t)(a+.5)); 
04534 }
04535 
04536 void M3_File_gcpGetInterval( M3_FileLL *thisFile, M3_TimeEl dataSetFirstTime, double dataSetSampleRate, M3_Interval *thisInterval )
04537 {
04538   M3_TimeEl lastTime;
04539 
04540   if( thisFile)
04541   {
04542     lastTime = M3_TimeEl_AddSamples( thisFile->file.param.gcpointing.firstTime, thisFile->file.param.gcpointing.numSample, thisFile->file.param.gcpointing.sampleRate );
04543     thisInterval->firstSample = (int64_t)M3_myRound(M3_TimeEl_Difference( thisFile->file.param.gcpointing.firstTime, dataSetFirstTime )*dataSetSampleRate);
04544     thisInterval->lastSample = (int64_t)M3_myRound(M3_TimeEl_Difference( lastTime, dataSetFirstTime )*dataSetSampleRate)-1;    
04545   }
04546   else
04547   {
04548     thisInterval->firstSample = 0;
04549     thisInterval->lastSample = 0;
04550   }
04551   
04552   return;
04553 }
04554 
04555 M3_IntervalLL *M3_gcpFileListToIntervalList( M3_FileLL *gcpFileList, M3_TimeEl dataSetFirstTime, double dataSetSampleRate )
04556 {
04557   M3_IntervalLL *aList;
04558   M3_IntervalLL *aNode;
04559   M3_Interval thisInterval;
04560   M3_FileLL *thisFile;
04561 
04562   if( gcpFileList == NULL )
04563     return(NULL);
04564 
04565   thisFile = gcpFileList;
04566 
04567   aList = (M3_IntervalLL*)calloc(1, sizeof(M3_IntervalLL));
04568   M3_ErrorCheck(-1, "M3_gcpFileListToIntervalList", (aList ? 1 : 0), M3_EFLAG_MALLOC_FSTRING);
04569   aNode = aList;
04570 
04571   M3_File_gcpGetInterval( thisFile, dataSetFirstTime, dataSetSampleRate, &thisInterval );
04572   thisInterval.firstSample -= 2;
04573   if( thisFile->next == NULL )
04574     thisInterval.lastSample += 2;
04575   aNode->interval = thisInterval;
04576 
04577   thisFile = thisFile->next;
04578   if( thisFile == NULL )
04579     return(aList);
04580 
04581   M3_File_gcpGetInterval( thisFile, dataSetFirstTime, dataSetSampleRate, &thisInterval);
04582   if( thisFile->next == NULL )
04583     thisInterval.lastSample += 2;
04584   while( thisFile )
04585   {
04586     if( aNode->interval.lastSample != thisInterval.firstSample - 1 )
04587     {
04588       aNode->next = (M3_IntervalLL*)calloc(1, sizeof(M3_IntervalLL));
04589       M3_ErrorCheck(-1, "M3_gcpFileListToIntervalList", (aNode->next ? 1 : 0), M3_EFLAG_MALLOC_FSTRING );
04590       aNode = aNode->next;
04591 
04592       aNode->interval = thisInterval;
04593       thisFile = thisFile->next;
04594       if( thisFile )
04595       {
04596         M3_File_gcpGetInterval( thisFile, dataSetFirstTime, dataSetSampleRate, &thisInterval);
04597         if( thisFile->next == NULL )
04598           thisInterval.lastSample += 2;
04599       }
04600     }
04601     else
04602     {
04603       while( thisFile && aNode->interval.lastSample == thisInterval.firstSample - 1)
04604       {
04605         aNode->interval.lastSample = thisInterval.lastSample;
04606         thisFile = thisFile->next;
04607         if( thisFile )
04608         {
04609           M3_File_gcpGetInterval( thisFile, dataSetFirstTime, dataSetSampleRate, &thisInterval);
04610           if( thisFile->next == NULL )
04611             thisInterval.lastSample += 2;
04612         }
04613       }
04614     }
04615   }
04616   
04617   return(aList);
04618 }
04619 
04620 
04621 M3_IntervalLL *M3_intersectIntervalLists( M3_IntervalLL *aList, M3_IntervalLL *bList )
04622 {
04623   int64_t aFirstSample, bFirstSample;
04624   M3_IntervalLL *intersectList = NULL;
04625   M3_IntervalLL *intersectNode = NULL;
04626   M3_IntervalLL *aNode = NULL;
04627   M3_IntervalLL *bNode = NULL;
04628 
04629   if( aList == NULL || bList == NULL )
04630     return( NULL );
04631 
04632   intersectList = NULL;
04633   intersectNode = NULL;
04634 
04635   aNode = aList;
04636   bNode = bList;
04637   aFirstSample = aNode->interval.firstSample;
04638   bFirstSample = bNode->interval.firstSample;
04639 
04640   while( aNode && bNode )
04641   {
04642     /* Skip through list until overlapping intervals are found */
04643     while( ( aNode && bNode ) && 
04644            ( aNode->interval.lastSample < bFirstSample ||
04645              bNode->interval.lastSample < aFirstSample ) )
04646     {
04647       if( aNode->interval.lastSample < bFirstSample )
04648       {
04649         aNode = aNode->next;
04650         if( aNode )
04651           aFirstSample = aNode->interval.firstSample;
04652       }
04653       else if( bNode->interval.lastSample < aFirstSample )
04654       {
04655         bNode = bNode->next;
04656         if( bNode )
04657           bFirstSample = bNode->interval.firstSample;
04658       }
04659     }
04660 
04661     /* If we have not gotten to the end of the list */
04662     if( aNode && bNode )
04663     {
04664       /* Add a new node to the output list */
04665       if( intersectList == NULL )
04666       {
04667         intersectList = (M3_IntervalLL *)calloc(1, sizeof(M3_IntervalLL));
04668         M3_ErrorCheck(-1, "M3_intersectIntervalLists", intersectList, M3_EFLAG_MALLOC_FSTRING);
04669         intersectNode = intersectList;
04670       }
04671       else
04672       {
04673         intersectNode->next = (M3_IntervalLL *)calloc(1, sizeof(M3_IntervalLL));
04674         M3_ErrorCheck(-1, "M3_intersectIntervalLists", intersectNode->next, M3_EFLAG_MALLOC_FSTRING);
04675         intersectNode = intersectNode->next;
04676       }
04677     
04678       /* Give the new node values */
04679       intersectNode->interval.firstSample = maximum(aFirstSample, bFirstSample);
04680       intersectNode->interval.lastSample = minimum(aNode->interval.lastSample, bNode->interval.lastSample);
04681 
04682       /* If both nodes end at the same place move forward in both lists */
04683       if( aNode->interval.lastSample == bNode->interval.lastSample )
04684       {
04685         aNode = aNode->next;
04686         bNode = bNode->next;
04687         if( aNode && bNode )
04688         {
04689           aFirstSample = aNode->interval.firstSample;
04690           bFirstSample = bNode->interval.firstSample;
04691         }
04692       }
04693       /* If the a node ends first then move along the a list */
04694       else if( aNode->interval.lastSample < bNode->interval.lastSample )
04695       {
04696         bFirstSample = aNode->interval.lastSample + 1;
04697         aNode = aNode->next;
04698         if( aNode )
04699           aFirstSample = aNode->interval.firstSample;
04700       }
04701       /* If the b node ends first then move along the b list */
04702       else
04703       {
04704         aFirstSample = bNode->interval.lastSample + 1;
04705         bNode = bNode->next;
04706         if( bNode )
04707           bFirstSample = bNode->interval.firstSample;
04708       }
04709     }
04710   }
04711 
04712   return(intersectList);
04713 }
04714 
04715 
04716 void M3_File_getInterval( M3_File *thisFile, M3_Interval *theInterval )
04717 {
04718   if( thisFile == NULL )
04719   {
04720     theInterval->firstSample = 0;
04721     theInterval->lastSample = 0;
04722     return;
04723   }
04724   switch( thisFile->fileType )
04725   {
04726     case M3_TOD_FILE_TYPE:
04727       theInterval->firstSample = thisFile->param.tod.interval.firstSample;
04728       theInterval->lastSample = thisFile->param.tod.interval.lastSample;
04729       break;
04730     case M3_TOC_FILE_TYPE:
04731       theInterval->firstSample = thisFile->param.toc.interval.firstSample;
04732       theInterval->lastSample = thisFile->param.toc.interval.lastSample;
04733       break;
04734     case M3_POINTING_FILE_TYPE:
04735       theInterval->firstSample = thisFile->param.pointing.interval.firstSample;
04736       theInterval->lastSample = thisFile->param.pointing.interval.lastSample;
04737       break;
04738     case M3_NOISE_FILE_TYPE:
04739       theInterval->firstSample = thisFile->param.noise.interval.firstSample;
04740       theInterval->lastSample = thisFile->param.noise.interval.lastSample;
04741       break;
04742     case M3_FILTER_FILE_TYPE:
04743       theInterval->firstSample = thisFile->param.filter.interval.firstSample;
04744       theInterval->lastSample = thisFile->param.filter.interval.lastSample;
04745       break;
04746     default:
04747       theInterval->firstSample = 0;
04748       theInterval->lastSample = 0;
04749       break;
04750   }
04751   
04752   return;
04753 }
04754 
04755 
04756 int M3_File_getStringSizes( M3_File theFile )
04757 {
04758   int i;
04759 
04760   i = 8*(strlen(theFile.name)/8 + 1);
04761   i += 8*(strlen(theFile.format)/8 + 1);
04762   
04763   return(i);
04764 }
04765 
04766 
04767 size_t M3_RunConfigStruct_duplicateP( M3_RunConfigStruct *inRunConfig, M3_RunConfigStruct **outRunConfig, int outputIsPacked )
04768 {
04769   int k, errVal;
04770   M3_DataSetLL *inDataSet, *outDataSet;
04771   M3_IntervalLL *inInterval, *outInterval;
04772   M3_ComponentLL *inComponent, *outComponent;
04773   M3_SubcomponentLL *inSubcomponent, *outSubcomponent;
04774   M3_FileLL *inFile, *outFile;
04775   M3_PointingClassLL *inPointingClass, *outPointingClass;
04776   M3_PointingSubclassLL *inPointingSubclass, *outPointingSubclass;
04777   M3_PixelClassLL *inPixelClass, *outPixelClass;
04778   M3_SpectrumClassLL *inSpectrumClass, *outSpectrumClass;
04779   M3_GCPointingGroupLL *inGCPointingGroup, *outGCPointingGroup;
04780   M3_GCPointingStoreLL *inGCPointingStore, *outGCPointingStore;
04781   size_t dataSize;
04782   M3_MemoryStruct memStruct;
04783 
04784   M3_MemoryStruct_Init(&memStruct);
04785 
04786   if( outputIsPacked )
04787   {
04788     M3_MemoryStruct_Expand( &memStruct, sizeof(M3_RunConfigStruct) );
04789 
04790     /* Go through entire inRunConfig and figure out how much space is used. */
04791     for( inDataSet = inRunConfig->dataSetList; inDataSet; inDataSet = inDataSet->next )
04792     {
04793       M3_MemoryStruct_Expand( &memStruct, sizeof( M3_DataSetLL) );
04794       M3_MemoryStruct_Expand( &memStruct, (size_t)(strlen(inDataSet->name)+1) );
04795      
04796       for( inInterval = inDataSet->coveredIntervalList; inInterval; inInterval = inInterval->next )
04797         M3_MemoryStruct_Expand( &memStruct, sizeof(M3_IntervalLL) );
04798 
04799       for( inComponent = inDataSet->componentList; inComponent; inComponent = inComponent->next )
04800       {
04801         M3_MemoryStruct_Expand( &memStruct, sizeof(M3_ComponentLL) );
04802 
04803         for( inSubcomponent = inComponent->subcomponentList; inSubcomponent; inSubcomponent = inSubcomponent->next )
04804         {
04805           M3_MemoryStruct_Expand( &memStruct, sizeof(M3_SubcomponentLL) );
04806 
04807           for( inFile = inSubcomponent->todFileList; inFile; inFile = inFile->next )
04808           {
04809             M3_MemoryStruct_Expand( &memStruct, sizeof( M3_FileLL ) );
04810             M3_MemoryStruct_Expand( &memStruct, M3_File_getStringSizes(inFile->file));
04811           }
04812         }
04813 
04814         for( inFile = inComponent->todCalibFileList; inFile; inFile = inFile->next )
04815         {
04816           M3_MemoryStruct_Expand( &memStruct, sizeof( M3_FileLL ) );
04817           M3_MemoryStruct_Expand( &memStruct, M3_File_getStringSizes(inFile->file) );
04818         }
04819       }
04820 
04821       for( inFile = inDataSet->noiseFileList; inFile; inFile = inFile->next )
04822       {
04823         M3_MemoryStruct_Expand( &memStruct, sizeof( M3_FileLL ) );
04824         M3_MemoryStruct_Expand( &memStruct, M3_File_getStringSizes(inFile->file) );
04825       }
04826 
04827       for( k = 0; k < M3_NUM_FILTER_TYPE; k++ )
04828         for(inFile = inDataSet->filterFileList[k]; inFile; inFile = inFile->next )
04829         {
04830           M3_MemoryStruct_Expand( &memStruct, sizeof( M3_FileLL ) );
04831           M3_MemoryStruct_Expand( &memStruct, M3_File_getStringSizes(inFile->file) );
04832         }
04833 
04834       for( inPointingClass = inDataSet->pointingClassList; inPointingClass; inPointingClass = inPointingClass->next )
04835       {
04836         M3_MemoryStruct_Expand( &memStruct, sizeof( M3_PointingClassLL ));
04837       
04838         for( inPointingSubclass = inPointingClass->subclassList; inPointingSubclass; inPointingSubclass = inPointingSubclass->next )
04839         {
04840           M3_MemoryStruct_Expand( &memStruct, sizeof( M3_PointingSubclassLL ));
04841 
04842           if( inPointingSubclass->auxComplement )
04843             M3_MemoryStruct_Expand( &memStruct, strlen(inPointingSubclass->auxComplement) + 1 );
04844 
04845           for( inFile = inPointingSubclass->pointingFileList; inFile; inFile = inFile->next )
04846           {
04847             M3_MemoryStruct_Expand( &memStruct, sizeof( M3_FileLL ) );
04848             M3_MemoryStruct_Expand( &memStruct, M3_File_getStringSizes(inFile->file));
04849           }
04850         }
04851 
04852         for( inFile = inPointingClass->pointingCalibFileList; inFile; inFile = inFile->next )
04853         {
04854           M3_MemoryStruct_Expand( &memStruct, sizeof( M3_FileLL ) );
04855           M3_MemoryStruct_Expand( &memStruct, M3_File_getStringSizes(inFile->file));
04856         }
04857       }
04858 
04859     }
04860 
04861     for( inPixelClass = inRunConfig->pixelClassList; inPixelClass; inPixelClass = inPixelClass->next )
04862     {
04863       M3_MemoryStruct_Expand( &memStruct, sizeof(M3_PixelClassLL) );
04864     
04865       if( inPixelClass->className )
04866         M3_MemoryStruct_Expand( &memStruct, strlen(inPixelClass->className) + 1);
04867      
04868       if( inPixelClass->mapFile )
04869       {
04870         M3_MemoryStruct_Expand( &memStruct, sizeof(M3_File) );
04871         M3_MemoryStruct_Expand( &memStruct, M3_File_getStringSizes(*(inPixelClass->mapFile)) );
04872       }
04873       if( inPixelClass->coordFile )
04874       {
04875         M3_MemoryStruct_Expand( &memStruct, sizeof(M3_File) );
04876         M3_MemoryStruct_Expand( &memStruct, M3_File_getStringSizes(*(inPixelClass->coordFile)) );
04877       }
04878       if( inPixelClass->windowFile )
04879       {
04880         M3_MemoryStruct_Expand( &memStruct, sizeof(M3_File) );
04881         M3_MemoryStruct_Expand( &memStruct, M3_File_getStringSizes(*(inPixelClass->windowFile)) );
04882       }
04883 
04884       for( inFile = inPixelClass->maskFileList; inFile; inFile = inFile->next )
04885       {
04886         M3_MemoryStruct_Expand( &memStruct, sizeof(M3_FileLL) );
04887         M3_MemoryStruct_Expand( &memStruct, M3_File_getStringSizes( inFile->file ) );
04888       }
04889 
04890       for( inFile = inPixelClass->templateFileList; inFile; inFile = inFile->next )
04891       {
04892         M3_MemoryStruct_Expand( &memStruct, sizeof(M3_FileLL) );
04893         M3_MemoryStruct_Expand( &memStruct, M3_File_getStringSizes( inFile->file ) );
04894       }
04895     }
04896     
04897     for( inGCPointingGroup = inRunConfig->GCPointingGroupList; inGCPointingGroup; inGCPointingGroup = inGCPointingGroup->next )
04898     {
04899       M3_MemoryStruct_Expand( &memStruct, sizeof(M3_GCPointingGroupLL) );
04900       M3_MemoryStruct_Expand( &memStruct, strlen(inGCPointingGroup->name)+ 1);
04901       M3_MemoryStruct_Expand( &memStruct, strlen(inGCPointingGroup->GCPointingType) + 1);
04902       if( inGCPointingGroup->auxFile )
04903       {
04904         M3_MemoryStruct_Expand( &memStruct, sizeof(M3_File) );
04905         M3_MemoryStruct_Expand( &memStruct, M3_File_getStringSizes(*(inGCPointingGroup->auxFile)) );
04906       }
04907       for( inFile = inGCPointingGroup->GCPointingFileList; inFile; inFile = inFile->next )
04908       {
04909         M3_MemoryStruct_Expand( &memStruct, sizeof(M3_FileLL) );
04910         M3_MemoryStruct_Expand( &memStruct, M3_File_getStringSizes(inFile->file) );
04911       }
04912       for( inGCPointingStore = inGCPointingGroup->GCPointingStoreList; inGCPointingStore; inGCPointingStore = inGCPointingStore->next )
04913       {
04914         M3_MemoryStruct_Expand( &memStruct, sizeof( M3_GCPointingStoreLL ) );
04915         M3_MemoryStruct_Expand( &memStruct, inGCPointingStore->numSample*inGCPointingStore->numDataPerSample*sizeof(double) );
04916       }
04917     }
04918 
04919 
04920     if( inRunConfig->sparsePixelMatrix != NULL )
04921     {
04922       M3_MemoryStruct_Expand( &memStruct, sizeof(M3_File) );
04923       M3_MemoryStruct_Expand( &memStruct, M3_File_getStringSizes(*(inRunConfig->sparsePixelMatrix)) );
04924     }
04925 
04926     for( inSpectrumClass = inRunConfig->powerSpectrum.spectrumClassList; inSpectrumClass; inSpectrumClass = inSpectrumClass->next )
04927     {
04928       M3_MemoryStruct_Expand( &memStruct, sizeof( M3_SpectrumClassLL) );
04929 
04930       if( inSpectrumClass->shapeFile )
04931       {
04932         M3_MemoryStruct_Expand( &memStruct, sizeof( M3_File ) );
04933         M3_MemoryStruct_Expand( &memStruct, M3_File_getStringSizes(*(inSpectrumClass->shapeFile)) );
04934       }
04935 
04936       if( inSpectrumClass->binFile )
04937       {
04938         M3_MemoryStruct_Expand( &memStruct, sizeof( M3_File ) );
04939         M3_MemoryStruct_Expand( &memStruct, M3_File_getStringSizes(*(inSpectrumClass->binFile)) );
04940       }
04941     
04942       if( inSpectrumClass->bpsFile )
04943       {
04944         M3_MemoryStruct_Expand( &memStruct, sizeof( M3_File ) );
04945         M3_MemoryStruct_Expand( &memStruct, M3_File_getStringSizes(*(inSpectrumClass->bpsFile)) );
04946       }
04947     }
04948 
04949     if( inRunConfig->powerSpectrum.fisherMatrix )
04950     {
04951       M3_MemoryStruct_Expand( &memStruct, sizeof( M3_File ) );
04952       M3_MemoryStruct_Expand( &memStruct, M3_File_getStringSizes(*(inRunConfig->powerSpectrum.fisherMatrix)) );
04953     }
04954     
04955     /* Allocate memory for entire run config. */
04956     errVal = M3_MemoryStruct_Create( &memStruct );
04957     M3_ErrorCheck( -1, "M3_packRunConfig", errVal, M3_EFLAG_MALLOC_FSTRING );
04958     *outRunConfig = (M3_RunConfigStruct*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_RunConfigStruct));
04959   }
04960   else
04961   {
04962     *outRunConfig = (M3_RunConfigStruct *)calloc( 1, sizeof(M3_RunConfigStruct));
04963     M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (*outRunConfig), 1);
04964   }
04965 
04966 
04967   /* Go through entire packed runConfig and assign pointers. */
04968   (*outRunConfig)->todCache.useGCPcache = inRunConfig->todCache.useGCPcache;
04969   (*outRunConfig)->todCache.useScanMapCache = inRunConfig->todCache.useScanMapCache;
04970   /* dataSet section A */
04971   if( inRunConfig->dataSetList )
04972   {
04973     inDataSet = inRunConfig->dataSetList;
04974     if( outputIsPacked )
04975     {
04976       outDataSet = (*outRunConfig)->dataSetList = (M3_DataSetLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_DataSetLL) );
04977     }
04978     else
04979     {
04980       outDataSet = (*outRunConfig)->dataSetList = (M3_DataSetLL *)calloc(1,sizeof(M3_DataSetLL));
04981       M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outDataSet),M3_EFLAG_MALLOC_FSTRING);
04982     }
04983     
04984     while( inDataSet )
04985     {
04986       if( outputIsPacked )
04987       {
04988         outDataSet->name = (char *)M3_MemoryStruct_Malloc(&memStruct, strlen(inDataSet->name) + 1);
04989       }
04990       else
04991       {
04992         outDataSet->name = (char*)calloc( 4*(strlen(inDataSet->name)/4 + 1), sizeof(char) );
04993         M3_ErrorCheck( -1, "M3_RunConfigStruct_Duplicate", (outDataSet->name), M3_EFLAG_MALLOC_FSTRING );
04994       }
04995       strcpy( outDataSet->name, inDataSet->name );
04996 
04997       outDataSet->firstTime = inDataSet->firstTime;
04998       outDataSet->sampleRate = inDataSet->sampleRate;
04999       outDataSet->numNZ = inDataSet->numNZ;
05000       outDataSet->pixelConvertNode = &((*outRunConfig)->pixelConvert);
05001       outDataSet->runConfigNode = *outRunConfig;
05002      
05003       /* coveredInterval section A */      
05004       if( inDataSet->coveredIntervalList )
05005       {
05006         inInterval = inDataSet->coveredIntervalList;
05007         if( outputIsPacked )
05008         {
05009           outInterval = outDataSet->coveredIntervalList = (M3_IntervalLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_IntervalLL) );
05010         }
05011         else
05012         {
05013           outInterval = outDataSet->coveredIntervalList = (M3_IntervalLL *)calloc(1, sizeof(M3_IntervalLL));
05014           M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", outInterval, M3_EFLAG_MALLOC_FSTRING);
05015         }
05016 
05017         while( inInterval )
05018         {
05019           outInterval->interval = inInterval->interval;
05020           
05021           /* coveredInterval section B */
05022           inInterval = inInterval->next;
05023           if( inInterval )
05024           {
05025             if( outputIsPacked )
05026             {
05027               outInterval->next = (M3_IntervalLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_IntervalLL) );
05028             }
05029             else
05030             {
05031               outInterval->next = (M3_IntervalLL *)calloc(1, sizeof(M3_IntervalLL));
05032               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outInterval->next), M3_EFLAG_MALLOC_FSTRING);
05033             }
05034             outInterval = outInterval->next;
05035           }
05036         }
05037       }
05038 
05039       /* component section A */
05040       if( inDataSet->componentList )
05041       {
05042         inComponent = inDataSet->componentList;
05043         if( outputIsPacked )
05044         {
05045           outComponent = outDataSet->componentList = (M3_ComponentLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_ComponentLL));
05046         }
05047         else
05048         {
05049           outComponent = outDataSet->componentList = (M3_ComponentLL *)calloc(1, sizeof(M3_ComponentLL));
05050           M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outComponent), M3_EFLAG_MALLOC_FSTRING );
05051         }
05052         
05053         while( inComponent )
05054         {
05055           /* subcomponent section A */
05056           if( inComponent->subcomponentList )
05057           {
05058             inSubcomponent = inComponent->subcomponentList;
05059             if( outputIsPacked)
05060             {
05061               outSubcomponent = outComponent->subcomponentList = (M3_SubcomponentLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_SubcomponentLL) );
05062             }
05063             else
05064             {
05065               outSubcomponent = outComponent->subcomponentList = (M3_SubcomponentLL *)calloc(1, sizeof(M3_SubcomponentLL));
05066               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outSubcomponent), M3_EFLAG_MALLOC_FSTRING);
05067             }
05068 
05069             while( inSubcomponent )
05070             {
05071               outSubcomponent->simType = inSubcomponent->simType;
05072               /* todFile section  A */
05073               if( inSubcomponent->todFileList )
05074               {
05075                 inFile = inSubcomponent->todFileList;
05076                 if( outputIsPacked )
05077                 {
05078                   outFile = outSubcomponent->todFileList = (M3_FileLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_FileLL) );
05079                 }
05080                 else
05081                 {
05082                   outFile = outSubcomponent->todFileList = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
05083                   M3_ErrorCheck(-1, "M3_DuplicateRunConfig", outFile, M3_EFLAG_MALLOC_FSTRING);
05084                 }
05085 
05086                 while( inFile )
05087                 {
05088                   outFile->file.fileType = inFile->file.fileType;
05089                   outFile->file.param = inFile->file.param;
05090 
05091                   if( inFile->file.name )
05092                   {
05093                     if( outputIsPacked )
05094                     {
05095                       outFile->file.name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inFile->file.name) + 1 );
05096                     }
05097                     else
05098                     {
05099                       outFile->file.name = (char*)calloc(4*(strlen(inFile->file.name)/4 + 1), sizeof(char));
05100                       M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->file.name), M3_EFLAG_MALLOC_FSTRING);
05101                     }
05102   
05103                     strcpy(outFile->file.name, inFile->file.name);
05104                   }
05105 
05106                   if( inFile->file.format )
05107                   {
05108                     if( outputIsPacked )
05109                     {
05110                       outFile->file.format = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inFile->file.format) + 1);
05111                     }
05112                     else
05113                     {
05114                       outFile->file.format = (char*)calloc(4*(strlen(inFile->file.format)/4 + 1), sizeof(char));
05115                       M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->file.format), M3_EFLAG_MALLOC_FSTRING);
05116                     }
05117 
05118                     strcpy(outFile->file.format, inFile->file.format);
05119                   }
05120                     
05121                   /* todFile section B */
05122                   inFile = inFile->next;
05123                   if( inFile )
05124                   {
05125                     if( outputIsPacked )
05126                     {
05127                       outFile->next = (M3_FileLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_FileLL) );
05128                     }
05129                     else
05130                     {
05131                       outFile->next = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
05132                       M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->next), M3_EFLAG_MALLOC_FSTRING);
05133                     }
05134 
05135                     outFile = outFile->next;
05136                   }                   
05137                 }
05138 
05139               }
05140               
05141 
05142               /* subcomponent section B */
05143               inSubcomponent = inSubcomponent->next;
05144               if( inSubcomponent )
05145               {
05146                 if( outputIsPacked )
05147                 {
05148                   outSubcomponent->next = (M3_SubcomponentLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_SubcomponentLL) );
05149                 }
05150                 else
05151                 {
05152                   outSubcomponent->next = (M3_SubcomponentLL *)calloc(1, sizeof(M3_SubcomponentLL));
05153                   M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outSubcomponent->next), M3_EFLAG_MALLOC_FSTRING);
05154                 }
05155                 outSubcomponent = outSubcomponent->next;
05156               }
05157             }
05158           }
05159           
05160           /* todCalibFile section A */
05161           if( inComponent->todCalibFileList )
05162           {
05163             inFile = inComponent->todCalibFileList;
05164             if( outputIsPacked )
05165             {
05166               outFile = outComponent->todCalibFileList = (M3_FileLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_FileLL));
05167             }
05168             else
05169             {
05170               outFile = outComponent->todCalibFileList = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
05171               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", outFile, M3_EFLAG_MALLOC_FSTRING);
05172             }
05173 
05174 
05175             while( inFile )
05176             {
05177               outFile->file.fileType = inFile->file.fileType;
05178               outFile->file.param = inFile->file.param;
05179 
05180               if( inFile->file.name )
05181               {
05182                 if( outputIsPacked )
05183                 {
05184                   outFile->file.name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inFile->file.name)+ 1);
05185                 }
05186                 else
05187                 {
05188                   outFile->file.name = (char*)calloc(4*(strlen(inFile->file.name)/4 + 1), sizeof(char));
05189                   M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->file.name), M3_EFLAG_MALLOC_FSTRING);
05190                 }
05191 
05192                 strcpy( outFile->file.name, inFile->file.name);
05193               }
05194               
05195               if( inFile->file.format )
05196               {
05197                 if( outputIsPacked )
05198                 {
05199                   outFile->file.format = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inFile->file.format) + 1);
05200                 }
05201                 else
05202                 {
05203                   outFile->file.format = (char*)calloc(4*(strlen(inFile->file.format)/4 + 1), sizeof(char));
05204                   M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->file.format), M3_EFLAG_MALLOC_FSTRING);
05205                 }
05206               
05207                 strcpy(outFile->file.format, inFile->file.format);
05208               }
05209               
05210               /* todCalibFile section B */
05211               inFile = inFile->next;
05212               if( inFile )
05213               {
05214                 if( outputIsPacked )
05215                 {
05216                   outFile->next = (M3_FileLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_FileLL));
05217                 }
05218                 else
05219                 {
05220                   outFile->next = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
05221                   M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->next), M3_EFLAG_MALLOC_FSTRING);
05222                 }
05223                 outFile = outFile->next;
05224               }
05225             }
05226           }
05227 
05228           /* component section B */
05229           inComponent = inComponent->next;
05230           if( inComponent )
05231           {
05232             if( outputIsPacked )
05233             {
05234               outComponent->next = (M3_ComponentLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_ComponentLL));
05235             }
05236             else
05237             {
05238               outComponent->next = (M3_ComponentLL *)calloc(1, sizeof(M3_ComponentLL));
05239               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outComponent->next), M3_EFLAG_MALLOC_FSTRING);
05240             }
05241             outComponent = outComponent->next;
05242           }
05243         }
05244       }
05245 
05246       /* noiseFile section A */
05247       if( inDataSet->noiseFileList )
05248       {
05249         inFile = inDataSet->noiseFileList;
05250         if( outputIsPacked )
05251         {
05252           outFile = outDataSet->noiseFileList = (M3_FileLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_FileLL));
05253         }
05254         else
05255         {
05256           outFile = outDataSet->noiseFileList = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
05257           M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", outFile, M3_EFLAG_MALLOC_FSTRING );
05258         }
05259 
05260 
05261         while( inFile )
05262         {
05263           outFile->file.fileType = inFile->file.fileType;
05264           outFile->file.param = inFile->file.param;
05265 
05266           if( inFile->file.name )
05267           {
05268             if( outputIsPacked )
05269             {
05270               outFile->file.name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inFile->file.name) + 1 );
05271             }
05272             else 
05273             {
05274               outFile->file.name = (char*)calloc( 4*(strlen(inFile->file.name)/4 + 1), sizeof(char));
05275               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->file.name), M3_EFLAG_MALLOC_FSTRING );
05276             }
05277 
05278             strcpy( outFile->file.name, inFile->file.name);
05279           }
05280           
05281           if( inFile->file.format )
05282           {
05283             if( outputIsPacked)
05284             {
05285               outFile->file.format = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inFile->file.format) + 1);
05286             }
05287             else
05288             {
05289               outFile->file.format = (char*)calloc(4*(strlen(inFile->file.format)/4 + 1), sizeof(char));
05290               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->file.format), M3_EFLAG_MALLOC_FSTRING);
05291             }
05292 
05293             strcpy(outFile->file.format, inFile->file.format);
05294           }
05295 
05296           /* noiseFile section B */
05297           inFile = inFile->next;
05298           if( inFile )
05299           {
05300             if( outputIsPacked )
05301             {
05302               outFile->next = (M3_FileLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_FileLL) );
05303             }
05304             else
05305             {
05306               outFile->next = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
05307               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->next), M3_EFLAG_MALLOC_FSTRING);
05308             }
05309  
05310             outFile = outFile->next;
05311           }
05312         }
05313       }
05314 
05315       for( k = 0; k < M3_NUM_FILTER_TYPE; k++ )
05316       {
05317         /* filterFile section A */
05318         if( inDataSet->filterFileList[k] )
05319         {
05320           inFile = inDataSet->filterFileList[k];
05321           if( outputIsPacked )
05322           {
05323             outFile = outDataSet->filterFileList[k] = (M3_FileLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_FileLL));
05324           }
05325           else
05326           {
05327             outFile = outDataSet->filterFileList[k] = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
05328             M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile), M3_EFLAG_MALLOC_FSTRING);
05329           }
05330 
05331           while( inFile )
05332           {
05333             outFile->file.fileType = inFile->file.fileType;
05334             outFile->file.param = inFile->file.param;
05335 
05336             if(inFile->file.name )
05337             {
05338               if( outputIsPacked )
05339               {
05340                 outFile->file.name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inFile->file.name) + 1);
05341               }
05342               else
05343               {
05344                 outFile->file.name = (char*)calloc(4*(strlen(inFile->file.name)/4 + 1), sizeof(char));
05345                 M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->file.name), M3_EFLAG_MALLOC_FSTRING);
05346               }
05347 
05348               strcpy( outFile->file.name, inFile->file.name);
05349             }
05350 
05351             if( inFile->file.format )
05352             {
05353               if( outputIsPacked )
05354               {
05355                 outFile->file.format = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inFile->file.format) + 1);
05356               }
05357               else
05358               {
05359                 outFile->file.format = (char*)calloc(4*(strlen(inFile->file.format)/4 + 1), sizeof(char));
05360                 M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->file.format), M3_EFLAG_MALLOC_FSTRING);
05361               }
05362 
05363               strcpy(outFile->file.format, inFile->file.format);
05364             }
05365 
05366             /* filterFile section B */
05367             inFile = inFile->next;
05368             if( inFile )
05369             {
05370               if( outputIsPacked )
05371               {
05372                 outFile->next = (M3_FileLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_FileLL));
05373               }
05374               else
05375               {
05376                 outFile->next = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
05377                 M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->next), M3_EFLAG_MALLOC_FSTRING );
05378               }
05379 
05380               outFile = outFile->next;
05381             }
05382           }
05383         }
05384       }
05385 
05386       if( inDataSet->pointingClassList )
05387       {
05388         inPointingClass = inDataSet->pointingClassList;
05389         if( outputIsPacked )
05390         {
05391           outPointingClass = outDataSet->pointingClassList = (M3_PointingClassLL*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_PointingClassLL));
05392         }
05393         else
05394         {
05395           outPointingClass = outDataSet->pointingClassList = (M3_PointingClassLL*)calloc(1, sizeof(M3_PointingClassLL));
05396           M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outPointingClass), M3_EFLAG_MALLOC_FSTRING );
05397         }
05398 
05399         while( inPointingClass )
05400         {
05401           outPointingClass->numNZ = inPointingClass->numNZ;
05402           outPointingClass->columnOffset = inPointingClass->columnOffset;
05403           
05404 
05405           if( inPointingClass->subclassList )
05406           {
05407             inPointingSubclass = inPointingClass->subclassList;
05408             if( outputIsPacked )
05409             {
05410               outPointingSubclass = outPointingClass->subclassList = (M3_PointingSubclassLL*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_PointingSubclassLL));
05411             }
05412             else
05413             {
05414               outPointingSubclass = outPointingClass->subclassList = (M3_PointingSubclassLL*)calloc(1, sizeof(M3_PointingSubclassLL));
05415               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outPointingSubclass), M3_EFLAG_MALLOC_FSTRING );
05416             }
05417 
05418             while( inPointingSubclass )
05419             {
05420               outPointingSubclass->numNZ = inPointingSubclass->numNZ;
05421               outPointingSubclass->columnOffset = inPointingSubclass->columnOffset;
05422               outPointingSubclass->isFull = inPointingSubclass->isFull;
05423               if( inPointingSubclass->auxComplement )
05424               {
05425                 if( outputIsPacked )
05426                 {
05427                   outPointingSubclass->auxComplement = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inPointingSubclass->auxComplement) + 1);
05428                 }
05429                 else
05430                 {
05431                   outPointingSubclass->auxComplement = (char*)malloc(4*(strlen(inPointingSubclass->auxComplement)/4+1));
05432                   M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", ((outPointingSubclass->auxComplement)?1:0), M3_EFLAG_MALLOC_FSTRING);
05433                 }
05434                 strcpy( outPointingSubclass->auxComplement, inPointingSubclass->auxComplement );
05435               }              
05436               if( inPointingSubclass->pointingFileList )
05437               {
05438                 inFile = inPointingSubclass->pointingFileList;
05439                 if( outputIsPacked )
05440                 {
05441                   outFile = outPointingSubclass->pointingFileList = (M3_FileLL*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_FileLL));
05442                 }
05443                 else
05444                 {
05445                   outFile = outPointingSubclass->pointingFileList = (M3_FileLL*)calloc(1, sizeof(M3_FileLL));
05446                   M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile), M3_EFLAG_MALLOC_FSTRING );
05447                 }
05448 
05449                 while( inFile )
05450                 {
05451                   outFile->file.fileType = inFile->file.fileType;
05452                   outFile->file.param = inFile->file.param;
05453 
05454                   if( inFile->file.name )
05455                   {
05456                     if( outputIsPacked )
05457                     {
05458                       outFile->file.name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inFile->file.name) + 1);
05459                     }
05460                     else
05461                     {
05462                       outFile->file.name = (char*)calloc(4*(strlen(inFile->file.name)/4 + 1), sizeof(char));
05463                       M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->file.name), M3_EFLAG_MALLOC_FSTRING);
05464                     }
05465 
05466                     strcpy( outFile->file.name, inFile->file.name);
05467                   }
05468 
05469                   if( inFile->file.format )
05470                   {
05471                     if( outputIsPacked )
05472                     {
05473                       outFile->file.format = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inFile->file.format) + 1);
05474                     }
05475                     else
05476                     {
05477                       outFile->file.format = (char*)calloc(4*(strlen(inFile->file.format)/4 + 1), sizeof(char));
05478                       M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->file.format), M3_EFLAG_MALLOC_FSTRING);
05479                     }
05480 
05481                     strcpy(outFile->file.format, inFile->file.format);
05482                   }
05483 
05484                   inFile = inFile->next;
05485                   if( inFile )
05486                   {
05487                     if( outputIsPacked )
05488                     {
05489                       outFile->next = (M3_FileLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_FileLL));
05490                     }
05491                     else
05492                     {
05493                       outFile->next = (M3_FileLL *)calloc(1, sizeof(M3_FileLL) );
05494                       M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->next), M3_EFLAG_MALLOC_FSTRING);
05495                     }
05496                     outFile = outFile->next;
05497                   } 
05498                 }
05499               }                            
05500 
05501 
05502               inPointingSubclass = inPointingSubclass->next;
05503               if( inPointingSubclass )
05504               {
05505                 if( outputIsPacked )
05506                 {
05507                   outPointingSubclass->next = (M3_PointingSubclassLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_PointingSubclassLL));
05508                 }
05509                 else
05510                 {
05511                   outPointingSubclass->next = (M3_PointingSubclassLL *)calloc(1, sizeof(M3_PointingSubclassLL));
05512                   M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outPointingSubclass->next), M3_EFLAG_MALLOC_FSTRING);
05513                 }
05514                 outPointingSubclass = outPointingSubclass->next;
05515               }
05516             }
05517           }
05518 
05519           if( inPointingClass->pointingCalibFileList )
05520           {
05521             inFile = inPointingClass->pointingCalibFileList;
05522             if( outputIsPacked )
05523             {
05524               outFile = outPointingClass->pointingCalibFileList = (M3_FileLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_FileLL));
05525             }
05526             else
05527             {
05528               outFile = outPointingClass->pointingCalibFileList = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
05529               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", outFile, M3_EFLAG_MALLOC_FSTRING);
05530             }
05531 
05532             while( inFile )
05533             {
05534               outFile->file.fileType = inFile->file.fileType;
05535               outFile->file.param = inFile->file.param;
05536 
05537               if( inFile->file.name )
05538               {
05539                 if( outputIsPacked )
05540                 {
05541                   outFile->file.name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inFile->file.name) + 1);
05542                 }
05543                 else
05544                 {
05545                   outFile->file.name = (char*)calloc(4*(strlen(inFile->file.name)/4 + 1), sizeof(char));
05546                   M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->file.name), M3_EFLAG_MALLOC_FSTRING);
05547                 }
05548 
05549                 strcpy( outFile->file.name, inFile->file.name);
05550               }
05551 
05552               if( inFile->file.format )
05553               {
05554                 if( outputIsPacked )
05555                 {
05556                   outFile->file.format = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inFile->file.format) + 1);
05557                 }
05558                 else
05559                 {
05560                   outFile->file.format = (char*)calloc(4*(strlen(inFile->file.format)/4 + 1), sizeof(char));
05561                   M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->file.format), M3_EFLAG_MALLOC_FSTRING);
05562                 }
05563 
05564                 strcpy(outFile->file.format, inFile->file.format);
05565               }
05566 
05567               inFile = inFile->next;
05568               if( inFile )
05569               {
05570                 if( outputIsPacked )
05571                 {
05572                   outFile->next = (M3_FileLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_FileLL) );
05573                 }
05574                 else
05575                 {
05576                   outFile->next = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
05577                   M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->next), M3_EFLAG_MALLOC_FSTRING);
05578                 }
05579                 outFile = outFile->next;
05580               } 
05581             }             
05582           }
05583 
05584 
05585           inPointingClass = inPointingClass->next;
05586           if( inPointingClass )
05587           {
05588             if( outputIsPacked )
05589             {
05590               outPointingClass->next = (M3_PointingClassLL*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_PointingClassLL) );
05591             }
05592             else
05593             {
05594               outPointingClass->next = (M3_PointingClassLL*)calloc(1, sizeof(M3_PointingClassLL));
05595               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outPointingClass->next), M3_EFLAG_MALLOC_FSTRING);
05596             }
05597             outPointingClass = outPointingClass->next;
05598           }
05599         }
05600       }
05601 
05602       /* dataSet section B */
05603       inDataSet = inDataSet->next;
05604       if( inDataSet )
05605       {
05606         if( outputIsPacked )
05607         {
05608           outDataSet->next = (M3_DataSetLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_DataSetLL) );
05609         }
05610         else
05611         {
05612           outDataSet->next = (M3_DataSetLL *)calloc(1, sizeof(M3_DataSetLL));
05613           M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outDataSet->next), M3_EFLAG_MALLOC_FSTRING);
05614         }
05615         outDataSet = outDataSet->next;
05616       }
05617     }
05618   }
05619 
05620   if( inRunConfig->pixelClassList )
05621   {
05622     inPixelClass = inRunConfig->pixelClassList;
05623     if( outputIsPacked )
05624     {
05625       outPixelClass = (*outRunConfig)->pixelClassList = (M3_PixelClassLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_PixelClassLL));
05626     }
05627     else
05628     {
05629       outPixelClass = (*outRunConfig)->pixelClassList = (M3_PixelClassLL *)calloc(1, sizeof(M3_PixelClassLL));
05630       M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", outPixelClass, M3_EFLAG_MALLOC_FSTRING);
05631     }
05632 
05633     while( inPixelClass )
05634     {
05635       outPixelClass->classIndex = inPixelClass->classIndex;
05636       outPixelClass->pixelType = inPixelClass->pixelType;
05637       outPixelClass->numPixelInClass = inPixelClass->numPixelInClass;
05638       outPixelClass->globalPixelOffset = inPixelClass->globalPixelOffset;
05639 
05640       if( outputIsPacked)
05641       {
05642         outPixelClass->className = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inPixelClass->className) + 1);
05643       }
05644       else
05645       {
05646         outPixelClass->className = (char*)calloc(4*(strlen(inPixelClass->className)/4 + 1), sizeof(char));
05647         M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outPixelClass->className), M3_EFLAG_MALLOC_FSTRING);
05648       }
05649       strcpy(outPixelClass->className, inPixelClass->className);
05650 
05651       if( inPixelClass->mapFile )
05652       {
05653         if( outputIsPacked )
05654         {
05655           outPixelClass->mapFile = (M3_File*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_File));
05656         }
05657         else
05658         {
05659           outPixelClass->mapFile = (M3_File *)calloc(1, sizeof(M3_File));
05660           M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outPixelClass->mapFile), M3_EFLAG_MALLOC_FSTRING);
05661         }
05662 
05663         outPixelClass->mapFile->fileType = inPixelClass->mapFile->fileType;
05664         outPixelClass->mapFile->param = inPixelClass->mapFile->param;
05665 
05666         if( inPixelClass->mapFile->name )
05667         {
05668           if( outputIsPacked )
05669           {
05670             outPixelClass->mapFile->name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inPixelClass->mapFile->name) + 1);
05671           }
05672           else
05673           {
05674             outPixelClass->mapFile->name = (char*)calloc(4*(strlen(inPixelClass->mapFile->name)/4+1), sizeof(char));
05675             M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outPixelClass->mapFile->name), M3_EFLAG_MALLOC_FSTRING);
05676           }
05677 
05678           strcpy(outPixelClass->mapFile->name, inPixelClass->mapFile->name);
05679         }
05680 
05681         if( inPixelClass->mapFile->format )
05682         {
05683 
05684           if( outputIsPacked )
05685           {
05686             outPixelClass->mapFile->format = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inPixelClass->mapFile->format) + 1);
05687           }
05688           else
05689           {
05690             outPixelClass->mapFile->format = (char*)calloc(4*(strlen(inPixelClass->mapFile->format)/4 + 1), sizeof(char));
05691             M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outPixelClass->mapFile->format), M3_EFLAG_MALLOC_FSTRING );
05692           }
05693 
05694           strcpy(outPixelClass->mapFile->format, inPixelClass->mapFile->format);
05695         }
05696       }
05697 
05698       if( inPixelClass->coordFile )
05699       {
05700         if( outputIsPacked )
05701         {
05702           outPixelClass->coordFile = (M3_File*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_File));
05703         }
05704         else
05705         {
05706           outPixelClass->coordFile = (M3_File*)calloc(1, sizeof(M3_File));
05707           M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outPixelClass->coordFile), M3_EFLAG_MALLOC_FSTRING);
05708         }
05709         
05710         outPixelClass->coordFile->fileType = inPixelClass->coordFile->fileType;
05711         outPixelClass->coordFile->param = inPixelClass->coordFile->param;
05712 
05713         if( inPixelClass->coordFile->name )
05714         {
05715 
05716           if( outputIsPacked )
05717           {
05718             outPixelClass->coordFile->name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inPixelClass->coordFile->name) + 1);
05719           }
05720           else
05721           {
05722             outPixelClass->coordFile->name = (char*)calloc(4*(strlen(inPixelClass->coordFile->name)/4 + 1), sizeof(char));
05723             M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outPixelClass->coordFile->name), M3_EFLAG_MALLOC_FSTRING);
05724           }
05725 
05726           strcpy( outPixelClass->coordFile->name, inPixelClass->coordFile->name);
05727         }
05728 
05729         if( inPixelClass->coordFile->format )
05730         {
05731           if( outputIsPacked )
05732           {
05733             outPixelClass->coordFile->format = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inPixelClass->coordFile->format) + 1);
05734           }
05735           else
05736           {
05737             outPixelClass->coordFile->format = (char*)calloc(4*(strlen(inPixelClass->coordFile->format)/4 + 1), sizeof(char));
05738             M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outPixelClass->coordFile->format), M3_EFLAG_MALLOC_FSTRING);
05739           }
05740 
05741           strcpy( outPixelClass->coordFile->format, inPixelClass->coordFile->format);
05742         }
05743       }
05744 
05745       if( inPixelClass->windowFile )
05746       {
05747         if( outputIsPacked )
05748         {
05749           outPixelClass->windowFile = (M3_File*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_File) );
05750         }
05751         else
05752         {
05753           outPixelClass->windowFile = (M3_File*)calloc(1, sizeof(M3_File));
05754           M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outPixelClass->windowFile), M3_EFLAG_MALLOC_FSTRING);
05755         }
05756 
05757         outPixelClass->windowFile->fileType = inPixelClass->windowFile->fileType;
05758         outPixelClass->windowFile->param = inPixelClass->windowFile->param;
05759 
05760         if( inPixelClass->windowFile->name )
05761         {
05762           if( outputIsPacked )
05763           {
05764             outPixelClass->windowFile->name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inPixelClass->windowFile->name) + 1);
05765           }
05766           else 
05767           {
05768             outPixelClass->windowFile->name = (char*)calloc(4*(strlen(inPixelClass->windowFile->name)/4 + 1), sizeof(char));
05769            M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outPixelClass->windowFile->name), M3_EFLAG_MALLOC_FSTRING);
05770           }
05771  
05772           strcpy( outPixelClass->windowFile->name, inPixelClass->windowFile->name);
05773         }
05774 
05775         if( inPixelClass->windowFile->format )
05776         {
05777           if( outputIsPacked )
05778           {
05779             outPixelClass->windowFile->format = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inPixelClass->windowFile->format) + 1);
05780           }
05781           else
05782           {
05783             outPixelClass->windowFile->format = (char*)calloc(4*(strlen(inPixelClass->windowFile->format)/4 + 1), sizeof(char));
05784             M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outPixelClass->windowFile->format), M3_EFLAG_MALLOC_FSTRING);
05785           }
05786           strcpy( outPixelClass->windowFile->format, inPixelClass->windowFile->format);
05787         }
05788       }
05789 
05790       if( inPixelClass->maskFileList )
05791       {
05792         inFile = inPixelClass->maskFileList;
05793         if( outputIsPacked )
05794         {
05795           outFile = outPixelClass->maskFileList = (M3_FileLL*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_FileLL));
05796         }
05797         else
05798         {
05799           outFile = outPixelClass->maskFileList = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
05800           M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", outFile, M3_EFLAG_MALLOC_FSTRING);
05801         }
05802 
05803         while( inFile )
05804         {
05805           outFile->file.fileType = inFile->file.fileType;
05806           outFile->file.param = inFile->file.param;
05807 
05808           if( inFile->file.name )
05809           {
05810             if( outputIsPacked )
05811             {
05812               outFile->file.name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inFile->file.name) + 1);
05813             }
05814             else
05815             {
05816               outFile->file.name = (char*)calloc(4*(strlen(inFile->file.name)/4 + 1), sizeof(char));
05817               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->file.name), M3_EFLAG_MALLOC_FSTRING);
05818             }
05819 
05820             strcpy( outFile->file.name, inFile->file.name);
05821           }
05822 
05823           if( inFile->file.format )
05824           {
05825             if( outputIsPacked )
05826             {
05827               outFile->file.format = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inFile->file.format) + 1);
05828             }
05829             else
05830             {
05831               outFile->file.format = (char*)calloc(4*(strlen(inFile->file.format)/4 + 1), sizeof(char));
05832               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->file.format), M3_EFLAG_MALLOC_FSTRING);
05833             }
05834            
05835             strcpy(outFile->file.format, inFile->file.format);
05836           }
05837 
05838           inFile = inFile->next;
05839           if( inFile )
05840           {
05841             if( outputIsPacked )
05842             {
05843               outFile->next = (M3_FileLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_FileLL));
05844             }
05845             else 
05846             {
05847               outFile->next = (M3_FileLL *)calloc(1, sizeof(M3_FileLL) );
05848               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->next), M3_EFLAG_MALLOC_FSTRING);
05849             }
05850             outFile = outFile->next;
05851           } 
05852         }
05853       }
05854 
05855       if( inPixelClass->templateFileList )
05856       {
05857         inFile = inPixelClass->templateFileList;
05858         if( outputIsPacked )
05859         {
05860           outFile = outPixelClass->templateFileList = (M3_FileLL*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_FileLL) );
05861         }
05862         else
05863         {
05864           outFile = outPixelClass->templateFileList = (M3_FileLL*)calloc(1, sizeof(M3_FileLL));
05865           M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile), M3_EFLAG_MALLOC_FSTRING);
05866         }
05867         
05868         while( inFile )
05869         {
05870           outFile->file.fileType = inFile->file.fileType;
05871           outFile->file.param = inFile->file.param;
05872 
05873           if( inFile->file.name )
05874           {
05875             if( outputIsPacked )
05876             {
05877               outFile->file.name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inFile->file.name) + 1);
05878             }
05879             else
05880             {
05881               outFile->file.name = (char*)calloc(4*(strlen(inFile->file.name)/4 + 1), sizeof(char));
05882               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->file.name), M3_EFLAG_MALLOC_FSTRING);
05883             }
05884 
05885             strcpy( outFile->file.name, inFile->file.name);
05886           }
05887 
05888           if( inFile->file.format )
05889           {
05890             if( outputIsPacked )
05891             {
05892               outFile->file.format = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inFile->file.format) + 1);
05893             }
05894             else
05895             {
05896               outFile->file.format = (char*)calloc(4*(strlen(inFile->file.format)/4 + 1), sizeof(char));
05897               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->file.format), M3_EFLAG_MALLOC_FSTRING);
05898             }
05899 
05900             strcpy(outFile->file.format, inFile->file.format);
05901           }
05902 
05903           inFile = inFile->next;
05904           if( inFile )
05905           {
05906             if( outputIsPacked )
05907             {
05908               outFile->next = (M3_FileLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_FileLL) );
05909             }
05910             else
05911             {
05912               outFile->next = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
05913               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->next), M3_EFLAG_MALLOC_FSTRING);
05914             }
05915             outFile = outFile->next;          
05916           }
05917         }
05918       }
05919 
05920 
05921       inPixelClass = inPixelClass->next;
05922       if( inPixelClass )
05923       {
05924         if( outputIsPacked )
05925         {
05926           outPixelClass->next = (M3_PixelClassLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_PixelClassLL));
05927         }
05928         else
05929         {
05930           outPixelClass->next = (M3_PixelClassLL *)calloc(1, sizeof(M3_PixelClassLL));
05931           M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outPixelClass->next), M3_EFLAG_MALLOC_FSTRING);
05932         }
05933         outPixelClass = outPixelClass->next;
05934       }
05935     }
05936   }
05937 
05938   if( inRunConfig->sparsePixelMatrix )
05939   {
05940     if( outputIsPacked )
05941     {
05942       (*outRunConfig)->sparsePixelMatrix = (M3_File *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_File));
05943     }
05944     else
05945     {
05946       (*outRunConfig)->sparsePixelMatrix = (M3_File *)calloc(1, sizeof(M3_File));
05947       M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", ((*outRunConfig)->sparsePixelMatrix), M3_EFLAG_MALLOC_FSTRING);
05948     }
05949     
05950     (*outRunConfig)->sparsePixelMatrix->fileType = inRunConfig->sparsePixelMatrix->fileType;
05951     (*outRunConfig)->sparsePixelMatrix->param = inRunConfig->sparsePixelMatrix->param;
05952     if( inRunConfig->sparsePixelMatrix->name )
05953     {
05954       if( outputIsPacked )
05955       {
05956         (*outRunConfig)->sparsePixelMatrix->name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inRunConfig->sparsePixelMatrix->name)+1); 
05957       }
05958       else
05959       {
05960         (*outRunConfig)->sparsePixelMatrix->name = (char*)calloc(1,4*(strlen(inRunConfig->sparsePixelMatrix->name)/4+1));
05961         M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", ((*outRunConfig)->sparsePixelMatrix->name), M3_EFLAG_MALLOC_FSTRING);
05962       }
05963       strcpy( (*outRunConfig)->sparsePixelMatrix->name, inRunConfig->sparsePixelMatrix->name);
05964     }
05965     if( inRunConfig->sparsePixelMatrix->format )
05966     {
05967       if( outputIsPacked )
05968       {
05969         (*outRunConfig)->sparsePixelMatrix->format = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inRunConfig->sparsePixelMatrix->format)+1); 
05970       }
05971       else
05972       {
05973         (*outRunConfig)->sparsePixelMatrix->format = (char*)calloc(1,4*(strlen(inRunConfig->sparsePixelMatrix->format)/4+1));
05974         M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", ((*outRunConfig)->sparsePixelMatrix->format), M3_EFLAG_MALLOC_FSTRING);
05975       }
05976       strcpy( (*outRunConfig)->sparsePixelMatrix->format, inRunConfig->sparsePixelMatrix->format);
05977     }
05978 
05979   }
05980 
05981   if( inRunConfig->GCPointingGroupList )
05982   {
05983     inGCPointingGroup = inRunConfig->GCPointingGroupList;
05984     if( outputIsPacked )
05985     {
05986       outGCPointingGroup = (*outRunConfig)->GCPointingGroupList =(M3_GCPointingGroupLL*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_GCPointingGroupLL) );
05987     }
05988     else
05989     {
05990       outGCPointingGroup = (*outRunConfig)->GCPointingGroupList = (M3_GCPointingGroupLL*)calloc(1, sizeof(M3_GCPointingGroupLL));
05991       M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outGCPointingGroup ? 1:0), M3_EFLAG_MALLOC_FSTRING);
05992     }
05993 
05994     while( inGCPointingGroup )
05995     {
05996       if( inGCPointingGroup->name )
05997       {
05998         if( outputIsPacked )
05999         {
06000           outGCPointingGroup->name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inGCPointingGroup->name) + 1);
06001         }
06002         else
06003         {
06004           outGCPointingGroup->name = (char*)calloc(4*(strlen(inGCPointingGroup->name)/4 + 1), sizeof(char));
06005           M3_ErrorCheck(-1, "M3_RunConfigStructDuplicate", ((outGCPointingGroup->name) ? 1: 0), M3_EFLAG_MALLOC_FSTRING);
06006         }
06007         strcpy( outGCPointingGroup->name, inGCPointingGroup->name );
06008       }
06009 
06010       if( inGCPointingGroup->GCPointingType )
06011       {
06012         if( outputIsPacked )
06013         {
06014           outGCPointingGroup->GCPointingType = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inGCPointingGroup->GCPointingType) + 1);
06015         }
06016         else
06017         {
06018           outGCPointingGroup->GCPointingType = (char*)calloc(4*(strlen(inGCPointingGroup->GCPointingType)/4+1), sizeof(char));
06019           M3_ErrorCheck(-1, "M3_RunConfigStructDuplicate", ((outGCPointingGroup->GCPointingType) ? 1 : 0), M3_EFLAG_MALLOC_FSTRING);
06020         }
06021         strcpy( outGCPointingGroup->GCPointingType, inGCPointingGroup->GCPointingType);
06022       }
06023 
06024       if( inGCPointingGroup->auxFile )
06025       {
06026         if( outputIsPacked )
06027         {
06028           outGCPointingGroup->auxFile = (M3_File*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_File));
06029         }
06030         else
06031         {
06032           outGCPointingGroup->auxFile = (M3_File*)calloc(1, sizeof(M3_File));
06033           M3_ErrorCheck(-1, "M3_RunConfigStructDuplicate", ((outGCPointingGroup->auxFile) ? 1 : 0), M3_EFLAG_MALLOC_FSTRING);
06034         }
06035         
06036         outGCPointingGroup->auxFile->fileType = inGCPointingGroup->auxFile->fileType;
06037         outGCPointingGroup->auxFile->param = inGCPointingGroup->auxFile->param;
06038         
06039         if( inGCPointingGroup->auxFile->name )
06040         {
06041           if( outputIsPacked )
06042           {
06043             outGCPointingGroup->auxFile->name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inGCPointingGroup->auxFile->name) + 1);
06044           }
06045           else
06046           {
06047             outGCPointingGroup->auxFile->name = (char*)calloc(4*(strlen(inGCPointingGroup->auxFile->name)/4 + 1), sizeof(char));
06048             M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", ((outGCPointingGroup->auxFile->name) ? 1 : 0 ), M3_EFLAG_MALLOC_FSTRING);
06049           }
06050           strcpy( outGCPointingGroup->auxFile->name, inGCPointingGroup->auxFile->name );
06051         }
06052         if( inGCPointingGroup->auxFile->format )
06053         {
06054           if( outputIsPacked )
06055           {
06056             outGCPointingGroup->auxFile->format = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inGCPointingGroup->auxFile->format) + 1);
06057           }
06058           else
06059           {
06060             outGCPointingGroup->auxFile->format = (char*)calloc(4*(strlen(inGCPointingGroup->auxFile->format)/4 + 1), sizeof(char));
06061             M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", ((outGCPointingGroup->auxFile->format) ? 1 : 0 ), M3_EFLAG_MALLOC_FSTRING );
06062           }
06063           strcpy( outGCPointingGroup->auxFile->format, inGCPointingGroup->auxFile->format );
06064         }
06065       }
06066 
06067       if( inGCPointingGroup->GCPointingFileList )
06068       {
06069         inFile = inGCPointingGroup->GCPointingFileList;
06070         if( outputIsPacked )
06071         {
06072           outFile = outGCPointingGroup->GCPointingFileList = (M3_FileLL*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_FileLL));
06073         }
06074         else
06075         {
06076           outFile = outGCPointingGroup->GCPointingFileList = (M3_FileLL*)calloc(1, sizeof(M3_FileLL));
06077           M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile ? 1 : 0 ), M3_EFLAG_MALLOC_FSTRING);
06078         }
06079 
06080         while( inFile )
06081         {
06082           outFile->file.fileType = inFile->file.fileType;
06083           outFile->file.param = inFile->file.param;
06084 
06085           if( inFile->file.name )
06086           {
06087             if( outputIsPacked )
06088             {
06089               outFile->file.name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inFile->file.name) + 1);
06090             }
06091             else
06092             {
06093               outFile->file.name = (char*)calloc(4*(strlen(inFile->file.name)/4 + 1), sizeof(char));
06094               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->file.name), M3_EFLAG_MALLOC_FSTRING);
06095             }
06096 
06097             strcpy( outFile->file.name, inFile->file.name);
06098           }
06099 
06100           if( inFile->file.format )
06101           {
06102             if( outputIsPacked )
06103             {
06104               outFile->file.format = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inFile->file.format) + 1);
06105             }
06106             else
06107             {
06108               outFile->file.format = (char*)calloc(4*(strlen(inFile->file.format)/4 + 1), sizeof(char));
06109               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->file.format), M3_EFLAG_MALLOC_FSTRING);
06110             }
06111 
06112             strcpy(outFile->file.format, inFile->file.format);
06113           }
06114 
06115           inFile = inFile->next;
06116           if( inFile )
06117           {
06118             if( outputIsPacked )
06119             {
06120               outFile->next = (M3_FileLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_FileLL) );
06121             }
06122             else
06123             {
06124               outFile->next = (M3_FileLL *)calloc(1, sizeof(M3_FileLL));
06125               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outFile->next), M3_EFLAG_MALLOC_FSTRING);
06126             }
06127             outFile = outFile->next;
06128           }
06129         }
06130       }    
06131 
06132       if( inGCPointingGroup->GCPointingStoreList )      
06133       {
06134         inGCPointingStore = inGCPointingGroup->GCPointingStoreList;
06135         if( outputIsPacked )
06136         {
06137           outGCPointingStore = outGCPointingGroup->GCPointingStoreList = (M3_GCPointingStoreLL*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_GCPointingStoreLL));
06138         }
06139         else
06140         {
06141           outGCPointingStore = outGCPointingGroup->GCPointingStoreList = (M3_GCPointingStoreLL*)calloc(1, sizeof(M3_GCPointingStoreLL));
06142           M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outGCPointingStore ? 1 : 0 ), M3_EFLAG_MALLOC_FSTRING );
06143         }
06144         
06145         while( inGCPointingStore )
06146         {
06147           outGCPointingStore->firstTime = inGCPointingStore->firstTime;
06148           outGCPointingStore->numSample = inGCPointingStore->numSample;
06149           outGCPointingStore->sampleRate = inGCPointingStore->sampleRate;
06150           outGCPointingStore->numDataPerSample = inGCPointingStore->numDataPerSample;
06151           if( inGCPointingStore->numSample )
06152           {
06153             dataSize = outGCPointingStore->numSample*outGCPointingStore->numDataPerSample*sizeof(double);
06154             if( outputIsPacked )
06155             {
06156               outGCPointingStore->data = (double*)M3_MemoryStruct_Malloc(&memStruct, dataSize);
06157             }
06158             else
06159             {
06160               outGCPointingStore->data = (double*)malloc(dataSize);
06161               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", ((outGCPointingStore->data) ? 1 : 0 ), M3_EFLAG_MALLOC_FSTRING );
06162             }
06163             memcpy(outGCPointingStore->data, inGCPointingStore->data, dataSize);
06164           }
06165 
06166           inGCPointingStore = inGCPointingStore->next;
06167           if( inGCPointingStore )
06168           {
06169             if( outputIsPacked )
06170             {
06171               outGCPointingStore->next = (M3_GCPointingStoreLL*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_GCPointingStoreLL));
06172             }
06173             else
06174             {
06175               outGCPointingStore->next = (M3_GCPointingStoreLL*)calloc(1, sizeof(M3_GCPointingStoreLL));
06176               M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", ((outGCPointingStore->next) ? 1 : 0 ), M3_EFLAG_MALLOC_FSTRING);
06177             }
06178             outGCPointingStore = outGCPointingStore->next;
06179           }
06180         }
06181       }
06182 
06183       inGCPointingGroup = inGCPointingGroup->next;
06184       if( inGCPointingGroup )
06185       {
06186         if( outputIsPacked )
06187         {
06188           outGCPointingGroup->next = (M3_GCPointingGroupLL*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_GCPointingGroupLL));
06189         }
06190         else 
06191         {
06192           outGCPointingGroup->next = (M3_GCPointingGroupLL*)calloc(1, sizeof(M3_GCPointingGroupLL));
06193           M3_ErrorCheck(-1,"M3_RunConfig_Duplicate", ((outGCPointingGroup->next) ? 1 : 0), M3_EFLAG_MALLOC_FSTRING ); 
06194         }
06195       }
06196     }
06197   }
06198 
06199   if( inRunConfig->powerSpectrum.spectrumClassList )
06200   {
06201     inSpectrumClass = inRunConfig->powerSpectrum.spectrumClassList;
06202     if( outputIsPacked )
06203     {
06204       outSpectrumClass = (*outRunConfig)->powerSpectrum.spectrumClassList = (M3_SpectrumClassLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_SpectrumClassLL));
06205     }
06206     else
06207     {
06208       outSpectrumClass = (*outRunConfig)->powerSpectrum.spectrumClassList = (M3_SpectrumClassLL *)calloc(1, sizeof(M3_SpectrumClassLL));
06209       M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outSpectrumClass), M3_EFLAG_MALLOC_FSTRING);
06210     }
06211 
06212     while( inSpectrumClass )
06213     {
06214       outSpectrumClass->spectrumType = inSpectrumClass->spectrumType;
06215       outSpectrumClass->lmax = inSpectrumClass->lmax;
06216       outSpectrumClass->numBin = inSpectrumClass->numBin;
06217 
06218       if( inSpectrumClass->shapeFile )
06219       {
06220         if( outputIsPacked ) 
06221         {
06222           outSpectrumClass->shapeFile = (M3_File*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_File));
06223         }
06224         else
06225         {
06226           outSpectrumClass->shapeFile = (M3_File*)calloc(1, sizeof(M3_File));
06227           M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outSpectrumClass->shapeFile), M3_EFLAG_MALLOC_FSTRING);
06228         }
06229 
06230         outSpectrumClass->shapeFile->fileType = inSpectrumClass->shapeFile->fileType;
06231         outSpectrumClass->shapeFile->param = inSpectrumClass->shapeFile->param;
06232 
06233         if( inSpectrumClass->shapeFile->name )
06234         {
06235           if( outputIsPacked )
06236           {
06237             outSpectrumClass->shapeFile->name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inSpectrumClass->shapeFile->name) + 1);
06238           }
06239           else
06240           {
06241             outSpectrumClass->shapeFile->name = (char*)calloc(4*(strlen(inSpectrumClass->shapeFile->name)/4 + 1), sizeof(char));
06242             M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outSpectrumClass->shapeFile->name), M3_EFLAG_MALLOC_FSTRING);
06243           }
06244 
06245           strcpy( outSpectrumClass->shapeFile->name, inSpectrumClass->shapeFile->name);
06246         }
06247         
06248         if( inSpectrumClass->shapeFile->format )
06249         {
06250           if( outputIsPacked ) 
06251           {
06252             outSpectrumClass->shapeFile->format = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inSpectrumClass->shapeFile->format) + 1);
06253           }
06254           else 
06255           {
06256             outSpectrumClass->shapeFile->format = (char*)calloc(4*(strlen(inSpectrumClass->shapeFile->format)/4 + 1), sizeof(char));
06257             M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outSpectrumClass->shapeFile->format), M3_EFLAG_MALLOC_FSTRING);
06258           }
06259 
06260           strcpy( outSpectrumClass->shapeFile->format, inSpectrumClass->shapeFile->format);
06261         }
06262       }
06263 
06264       if( inSpectrumClass->binFile )
06265       {
06266         if( outputIsPacked )
06267         {
06268           outSpectrumClass->binFile = (M3_File*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_File));
06269         }
06270         else
06271         {
06272           outSpectrumClass->binFile = (M3_File *)calloc(1, sizeof(M3_File));
06273           M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outSpectrumClass->binFile), M3_EFLAG_MALLOC_FSTRING);
06274         }
06275         
06276         outSpectrumClass->binFile->fileType = inSpectrumClass->binFile->fileType;
06277         outSpectrumClass->binFile->param = inSpectrumClass->binFile->param;
06278 
06279         if( inSpectrumClass->binFile->name )
06280         {
06281           if( outputIsPacked )
06282           {
06283             outSpectrumClass->binFile->name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inSpectrumClass->binFile->name) + 1);
06284           }
06285           else
06286           {
06287             outSpectrumClass->binFile->name = (char*)calloc(4*(strlen(inSpectrumClass->binFile->name)/4 + 1), sizeof(char));
06288             M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outSpectrumClass->binFile->name), M3_EFLAG_MALLOC_FSTRING);
06289           }
06290 
06291           strcpy( outSpectrumClass->binFile->name, inSpectrumClass->binFile->name);
06292         }
06293 
06294         if( inSpectrumClass->binFile->format )
06295         {
06296           if( outputIsPacked )
06297           {
06298             outSpectrumClass->binFile->format = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inSpectrumClass->binFile->format) + 1);
06299           }
06300           else
06301           {
06302             outSpectrumClass->binFile->format = (char*)calloc(4*(strlen(inSpectrumClass->binFile->format)/4 + 1), sizeof(char));
06303             M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outSpectrumClass->binFile->format), M3_EFLAG_MALLOC_FSTRING);
06304           }
06305 
06306           strcpy( outSpectrumClass->binFile->format, inSpectrumClass->binFile->format);
06307         }
06308       }
06309 
06310       if( inSpectrumClass->bpsFile )
06311       {
06312         if( outputIsPacked ) 
06313         {
06314           outSpectrumClass->bpsFile = (M3_File*)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_File));
06315         }
06316         else
06317         {
06318           outSpectrumClass->bpsFile = (M3_File*)calloc(1, sizeof(M3_File));
06319           M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outSpectrumClass->bpsFile), M3_EFLAG_MALLOC_FSTRING);
06320         }
06321 
06322         outSpectrumClass->bpsFile->fileType = inSpectrumClass->bpsFile->fileType;
06323         outSpectrumClass->bpsFile->param = inSpectrumClass->bpsFile->param;
06324 
06325         if( inSpectrumClass->bpsFile->name )
06326         {
06327           if( outputIsPacked )
06328           {
06329             outSpectrumClass->bpsFile->name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inSpectrumClass->bpsFile->name) + 1);
06330           }
06331           else
06332           {
06333             outSpectrumClass->bpsFile->name = (char*)calloc(4*(strlen(inSpectrumClass->bpsFile->name)/4 + 1),sizeof(char));
06334             M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outSpectrumClass->bpsFile->name), M3_EFLAG_MALLOC_FSTRING);
06335           }
06336 
06337           strcpy( outSpectrumClass->bpsFile->name, inSpectrumClass->bpsFile->name);
06338         }
06339         
06340         if( inSpectrumClass->bpsFile->format )
06341         {
06342           if( outputIsPacked )
06343           {
06344             outSpectrumClass->bpsFile->format = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inSpectrumClass->bpsFile->format) + 1);
06345           }
06346           else
06347           {
06348             outSpectrumClass->bpsFile->format = (char*)calloc(4*(strlen(inSpectrumClass->bpsFile->format)/4 + 1), sizeof(char));
06349             M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outSpectrumClass->bpsFile->format), M3_EFLAG_MALLOC_FSTRING);
06350           }
06351           strcpy( outSpectrumClass->bpsFile->format, inSpectrumClass->bpsFile->format);
06352         }
06353       }
06354 
06355       inSpectrumClass = inSpectrumClass->next;
06356       if( inSpectrumClass )
06357       {
06358         if( outputIsPacked )
06359         {
06360           outSpectrumClass->next = (M3_SpectrumClassLL *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_SpectrumClassLL));
06361         }
06362         else
06363         {
06364           outSpectrumClass->next = (M3_SpectrumClassLL *)calloc(1, sizeof(M3_SpectrumClassLL));
06365           M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", (outSpectrumClass->next), M3_EFLAG_MALLOC_FSTRING);
06366         }
06367         outSpectrumClass = outSpectrumClass->next;
06368       }
06369     }
06370   }
06371 
06372   if( inRunConfig->powerSpectrum.fisherMatrix )
06373   {
06374     if( outputIsPacked )
06375     {
06376       (*outRunConfig)->powerSpectrum.fisherMatrix = (M3_File *)M3_MemoryStruct_Malloc(&memStruct, sizeof(M3_File));
06377     }
06378     else
06379     {
06380       (*outRunConfig)->powerSpectrum.fisherMatrix = (M3_File *)calloc(1, sizeof(M3_File) );
06381       M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", ((*outRunConfig)->powerSpectrum.fisherMatrix), M3_EFLAG_MALLOC_FSTRING);
06382     }
06383 
06384     (*outRunConfig)->powerSpectrum.fisherMatrix->fileType = inRunConfig->powerSpectrum.fisherMatrix->fileType;
06385     (*outRunConfig)->powerSpectrum.fisherMatrix->param = inRunConfig->powerSpectrum.fisherMatrix->param;
06386 
06387     if( inRunConfig->powerSpectrum.fisherMatrix->name )
06388     {
06389       if( outputIsPacked )
06390       {
06391         (*outRunConfig)->powerSpectrum.fisherMatrix->name = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inRunConfig->powerSpectrum.fisherMatrix->name) + 1);
06392       }
06393       else
06394       {
06395         (*outRunConfig)->powerSpectrum.fisherMatrix->name = (char*)calloc(4*(strlen(inRunConfig->powerSpectrum.fisherMatrix->name)/4 + 1), sizeof(char));
06396         M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", ((*outRunConfig)->powerSpectrum.fisherMatrix->name), M3_EFLAG_MALLOC_FSTRING);
06397       }
06398 
06399       strcpy((*outRunConfig)->powerSpectrum.fisherMatrix->name, inRunConfig->powerSpectrum.fisherMatrix->name);
06400     }
06401    
06402     if( inRunConfig->powerSpectrum.fisherMatrix->format )
06403     {
06404       if( outputIsPacked )
06405       {
06406         (*outRunConfig)->powerSpectrum.fisherMatrix->format = (char*)M3_MemoryStruct_Malloc(&memStruct, strlen(inRunConfig->powerSpectrum.fisherMatrix->format) + 1);
06407       }
06408       else
06409       {
06410         (*outRunConfig)->powerSpectrum.fisherMatrix->format = (char*)calloc(4*(strlen(inRunConfig->powerSpectrum.fisherMatrix->format)/4 + 1), sizeof(char));
06411         M3_ErrorCheck(-1, "M3_RunConfigStruct_Duplicate", ((*outRunConfig)->powerSpectrum.fisherMatrix->format), M3_EFLAG_MALLOC_FSTRING);
06412       }
06413 
06414       strcpy((*outRunConfig)->powerSpectrum.fisherMatrix->format, inRunConfig->powerSpectrum.fisherMatrix->format);
06415     }
06416   }
06417   /* Asign the pixel class nodes */
06418   for( inDataSet = inRunConfig->dataSetList,
06419        outDataSet = (*outRunConfig)->dataSetList;
06420        inDataSet && outDataSet;
06421        inDataSet = inDataSet->next,
06422        outDataSet = outDataSet->next)
06423   {
06424 
06425     for( inPointingClass = inDataSet->pointingClassList,
06426          outPointingClass = outDataSet->pointingClassList;
06427          inPointingClass && outPointingClass;
06428          inPointingClass = inPointingClass->next,
06429          outPointingClass = outPointingClass->next)
06430     {
06431       for( inPixelClass = inRunConfig->pixelClassList, 
06432            outPixelClass = (*outRunConfig)->pixelClassList;
06433            inPixelClass && outPixelClass;
06434            inPixelClass = inPixelClass->next,
06435            outPixelClass = outPixelClass->next)
06436 
06437       {
06438         if( inPointingClass->pixelClassNode == inPixelClass )
06439         {
06440           outPointingClass->pixelClassNode = outPixelClass;
06441           break;
06442         }
06443       }
06444     }
06445   }
06446 
06447   /* assign the GCPointingGroup nodes. */
06448   for( inDataSet = inRunConfig->dataSetList,
06449        outDataSet = (*outRunConfig)->dataSetList;
06450        inDataSet && outDataSet;
06451        inDataSet = inDataSet->next,
06452        outDataSet = outDataSet->next)
06453   {
06454 
06455     for( inPointingClass = inDataSet->pointingClassList,
06456          outPointingClass = outDataSet->pointingClassList;
06457          inPointingClass && outPointingClass;
06458          inPointingClass = inPointingClass->next,
06459          outPointingClass = outPointingClass->next)
06460     {
06461       for( inPointingSubclass = inPointingClass->subclassList,
06462            outPointingSubclass = outPointingClass->subclassList; 
06463            inPointingSubclass && outPointingSubclass; 
06464            inPointingSubclass = inPointingSubclass->next, 
06465            outPointingSubclass = outPointingSubclass->next)
06466       {
06467         for( inGCPointingGroup = inRunConfig->GCPointingGroupList,
06468              outGCPointingGroup = (*outRunConfig)->GCPointingGroupList;
06469              inGCPointingGroup && outGCPointingGroup;
06470              inGCPointingGroup = inGCPointingGroup->next,
06471              outGCPointingGroup = outGCPointingGroup->next )
06472         {
06473           if( inPointingSubclass->GCPointingGroupNode == inGCPointingGroup )
06474           { 
06475            outPointingSubclass->GCPointingGroupNode = outGCPointingGroup;
06476            break;
06477           }
06478         }
06479       }
06480     }
06481   }
06482 
06483   return(M3_MemoryStruct_Size(&memStruct));
06484 }
06485 
06486 
06487 
06488 void M3_RunConfigStruct_shiftPointers( M3_RunConfigStruct *runConfig, int shiftDirection)
06489 {
06490   void *tempPtr;
06491   size_t offset;
06492   int64_t k;
06493   M3_DataSetLL *thisDataSet;
06494   M3_IntervalLL *thisInterval;
06495   M3_ComponentLL *thisComponent;
06496   M3_SubcomponentLL *thisSubcomponent;
06497   M3_FileLL *thisFile;
06498   M3_PointingClassLL *thisPointingClass;
06499   M3_PointingSubclassLL *thisPointingSubclass;
06500   M3_PixelClassLL *thisPixelClass;
06501   M3_SpectrumClassLL *thisSpectrumClass;
06502   M3_GCPointingGroupLL *thisGCPointingGroup;
06503   M3_GCPointingStoreLL *thisGCPointingStore;
06504 
06505   offset = (size_t)(runConfig);  
06506 
06507   if( shiftDirection < 0 )
06508   {
06509     /* Shift from absolute to relative adresses */
06510 
06511     /* Go over the data sets */ 
06512     if( runConfig->dataSetList )
06513     {
06514       thisDataSet = runConfig->dataSetList;
06515       runConfig->dataSetList = (M3_DataSetLL*)(((char*)(runConfig->dataSetList)) - offset);
06516 
06517       while( thisDataSet )
06518       {
06519         if( thisDataSet->runConfigNode )
06520           thisDataSet->runConfigNode = (M3_RunConfigStruct *)(((char*)(thisDataSet->runConfigNode)) - offset );
06521         if( thisDataSet->pixelConvertNode )
06522           thisDataSet->pixelConvertNode = (M3_PixelConvertStruct *)(((char*)(thisDataSet->pixelConvertNode)) - offset );
06523         if( thisDataSet->name )
06524           thisDataSet->name -= offset;
06525         /* Go over the covered intervals */
06526         if( thisDataSet->coveredIntervalList )
06527         {
06528           thisInterval = thisDataSet->coveredIntervalList;
06529           thisDataSet->coveredIntervalList = (M3_IntervalLL*)(((char*)(thisDataSet->coveredIntervalList)) - offset );
06530 
06531           while( thisInterval )
06532           {
06533             tempPtr = thisInterval->next;
06534             if( thisInterval->next )
06535               thisInterval->next = (M3_IntervalLL*)(((char*)(thisInterval->next)) - offset );
06536             thisInterval = (M3_IntervalLL*)tempPtr;
06537           }
06538         }
06539 
06540         if( thisDataSet->componentList )
06541         {
06542           thisComponent = thisDataSet->componentList;
06543           thisDataSet->componentList = (M3_ComponentLL *)(((char*)(thisDataSet->componentList)) - offset );
06544 
06545           while( thisComponent )
06546           {
06547             if( thisComponent->subcomponentList )
06548             {
06549               thisSubcomponent = thisComponent->subcomponentList;
06550               thisComponent->subcomponentList = (M3_SubcomponentLL *)(((char*)(thisComponent->subcomponentList)) - offset );
06551             
06552               while( thisSubcomponent )
06553               {
06554                 if( thisSubcomponent->todFileList )
06555                 {
06556                   thisFile = thisSubcomponent->todFileList;
06557                   thisSubcomponent->todFileList = (M3_FileLL*)(((char*)(thisSubcomponent->todFileList)) - offset);
06558  
06559                   while( thisFile )
06560                   {
06561                     if( thisFile->file.name )
06562                       thisFile->file.name -= offset;
06563                    
06564                     if( thisFile->file.format )
06565                       thisFile->file.format -= offset;
06566 
06567                     tempPtr = thisFile->next;
06568                     if( thisFile->next )
06569                       thisFile->next = (M3_FileLL *)(((char*)(thisFile->next)) - offset);
06570                     thisFile = (M3_FileLL *)tempPtr;
06571                   }
06572                 }
06573 
06574                 tempPtr = thisSubcomponent->next;
06575                 if( thisSubcomponent->next )
06576                   thisSubcomponent->next = (M3_SubcomponentLL *)(((char*)(thisSubcomponent->next)) - offset );
06577                 thisSubcomponent = (M3_SubcomponentLL *)tempPtr;
06578               }
06579             }
06580 
06581             if( thisComponent->todCalibFileList )
06582             {
06583               thisFile = thisComponent->todCalibFileList;
06584               thisComponent->todCalibFileList = (M3_FileLL *)(((char*)(thisComponent->todCalibFileList)) - offset );
06585             
06586               while( thisFile )
06587               {
06588                 if( thisFile->file.name )
06589                  thisFile->file.name -= offset;
06590                    
06591                 if( thisFile->file.format )
06592                   thisFile->file.format -= offset;
06593 
06594                 tempPtr = thisFile->next;
06595                 if( thisFile->next )
06596                   thisFile->next = (M3_FileLL *)(((char*)(thisFile->next)) - offset);
06597                 thisFile = (M3_FileLL *)tempPtr;
06598               }
06599             }
06600 
06601             tempPtr = thisComponent->next;
06602             if( thisComponent->next )
06603               thisComponent->next = (M3_ComponentLL *)(((char*)(thisComponent->next)) - offset  );
06604             thisComponent = tempPtr;
06605           }
06606         }
06607 
06608         if( thisDataSet->noiseFileList )
06609         {
06610           thisFile = thisDataSet->noiseFileList;
06611           thisDataSet->noiseFileList = (M3_FileLL*)(((char*)(thisDataSet->noiseFileList)) - offset );
06612 
06613           while( thisFile )
06614           {
06615             if( thisFile->file.name )
06616               thisFile->file.name -= offset;
06617                   
06618             if( thisFile->file.format )
06619               thisFile->file.format -= offset;
06620 
06621             tempPtr = thisFile->next;
06622             if( thisFile->next )
06623               thisFile->next = (M3_FileLL *)(((char*)(thisFile->next)) - offset);
06624             thisFile = (M3_FileLL *)tempPtr;
06625           }
06626         }
06627 
06628 
06629         for( k = 0; k < M3_NUM_FILTER_TYPE; k++ )
06630         {
06631           if( thisDataSet->filterFileList[k] )
06632           {
06633             thisFile = thisDataSet->filterFileList[k];
06634             thisDataSet->filterFileList[k] = (M3_FileLL *)(((char*)(thisDataSet->filterFileList[k])) - offset );
06635                   
06636             while( thisFile )
06637             {
06638               if( thisFile->file.name )
06639                 thisFile->file.name -= offset;
06640                     
06641               if( thisFile->file.format )
06642                 thisFile->file.format -= offset;
06643 
06644               tempPtr = thisFile->next;
06645               if( thisFile->next )
06646                 thisFile->next = (M3_FileLL *)(((char*)(thisFile->next)) - offset);
06647               thisFile = (M3_FileLL *)tempPtr;
06648             }
06649           }
06650         }
06651 
06652         if( thisDataSet->pointingClassList )
06653         {
06654           thisPointingClass = thisDataSet->pointingClassList;
06655           thisDataSet->pointingClassList = (M3_PointingClassLL *)(((char*)(thisDataSet->pointingClassList)) - offset );
06656       
06657           while( thisPointingClass )
06658           {
06659             if( thisPointingClass->pixelClassNode )
06660               thisPointingClass->pixelClassNode = (M3_PixelClassLL *)(((char*)(thisPointingClass->pixelClassNode)) - offset );
06661         
06662             if( thisPointingClass->subclassList )
06663             {
06664               thisPointingSubclass = thisPointingClass->subclassList;
06665               thisPointingClass->subclassList = (M3_PointingSubclassLL *)(((char*)(thisPointingClass->subclassList)) - offset );
06666             
06667               while( thisPointingSubclass )
06668               {
06669 
06670                 if( thisPointingSubclass->pointingFileList )
06671                 {
06672                   thisFile = thisPointingSubclass->pointingFileList;
06673                   thisPointingSubclass->pointingFileList = (M3_FileLL *)(((char*)(thisPointingSubclass->pointingFileList)) - offset );
06674          
06675                   while( thisFile )
06676                   {
06677                     if( thisFile->file.name )
06678                       thisFile->file.name -= offset;
06679                   
06680                     if( thisFile->file.format )
06681                       thisFile->file.format -= offset;
06682 
06683                     tempPtr = thisFile->next;
06684                     if( thisFile->next )
06685                       thisFile->next = (M3_FileLL *)(((char*)(thisFile->next)) - offset);
06686                     thisFile = (M3_FileLL *)tempPtr;
06687                   }
06688                 }
06689                 if( thisPointingSubclass->GCPointingGroupNode )
06690                   thisPointingSubclass->GCPointingGroupNode = (M3_GCPointingGroupLL*)((char*)(thisPointingSubclass->GCPointingGroupNode) - offset);
06691 
06692                 if( thisPointingSubclass->auxComplement )
06693                   thisPointingSubclass->auxComplement -= offset;
06694 
06695                 tempPtr = thisPointingSubclass->next;
06696                 if( thisPointingSubclass->next )
06697                   thisPointingSubclass->next = (M3_PointingSubclassLL*)(((char*)(thisPointingSubclass->next)) - offset );
06698                 thisPointingSubclass = (M3_PointingSubclassLL*)tempPtr;
06699               }
06700             }
06701 
06702             if( thisPointingClass->pointingCalibFileList )
06703             {
06704               thisFile = thisPointingClass->pointingCalibFileList;
06705               thisPointingClass->pointingCalibFileList = (M3_FileLL *)(((char*)(thisPointingClass->pointingCalibFileList)) - offset );
06706               
06707               while( thisFile )
06708               {
06709                 if( thisFile->file.name )
06710                   thisFile->file.name -= offset;
06711                   
06712                 if( thisFile->file.format )
06713                   thisFile->file.format -= offset;
06714 
06715                 tempPtr = thisFile->next;
06716                 if( thisFile->next )
06717                   thisFile->next = (M3_FileLL *)(((char*)(thisFile->next)) - offset);
06718                 thisFile = tempPtr;
06719               }
06720             }
06721 
06722             tempPtr = thisPointingClass->next;
06723             if( thisPointingClass->next )
06724               thisPointingClass->next = (M3_PointingClassLL *)(((char*)(thisPointingClass->next)) - offset );
06725             thisPointingClass = tempPtr;
06726           }
06727         }
06728       
06729         tempPtr = thisDataSet->next;
06730         if( thisDataSet->next )
06731           thisDataSet->next = (M3_DataSetLL *)(((char*)(thisDataSet->next)) - offset );
06732         thisDataSet = (M3_DataSetLL *)tempPtr;
06733       }
06734     }
06735 
06736 
06737     if( runConfig->pixelClassList )
06738     {
06739       thisPixelClass = runConfig->pixelClassList;
06740       runConfig->pixelClassList = (M3_PixelClassLL*)(((char*)(runConfig->pixelClassList)) - offset);
06741 
06742       while( thisPixelClass )
06743       {
06744         if( thisPixelClass->className )
06745           thisPixelClass->className = thisPixelClass->className - offset;
06746 
06747         if( thisPixelClass->mapFile )
06748         {
06749           if( thisPixelClass->mapFile->name )
06750             thisPixelClass->mapFile->name = thisPixelClass->mapFile->name - offset;
06751 
06752           if( thisPixelClass->mapFile->format )
06753             thisPixelClass->mapFile->format = thisPixelClass->mapFile->format - offset;
06754 
06755           thisPixelClass->mapFile = (M3_File *)(((char*)(thisPixelClass->mapFile)) - offset );
06756         }
06757 
06758         if( thisPixelClass->coordFile )
06759         {
06760           if( thisPixelClass->coordFile->name )
06761             thisPixelClass->coordFile->name = thisPixelClass->coordFile->name - offset;
06762 
06763           if( thisPixelClass->coordFile->format )
06764             thisPixelClass->coordFile->format = thisPixelClass->coordFile->format - offset;
06765 
06766           thisPixelClass->coordFile = (M3_File *)(((char*)(thisPixelClass->coordFile)) - offset );
06767         }
06768 
06769         if( thisPixelClass->windowFile )
06770         {
06771           if( thisPixelClass->windowFile->name )
06772             thisPixelClass->windowFile->name = thisPixelClass->windowFile->name - offset;
06773 
06774           if( thisPixelClass->windowFile->format )
06775             thisPixelClass->windowFile->format = thisPixelClass->windowFile->format - offset;
06776 
06777           thisPixelClass->windowFile = (M3_File *)(((char*)(thisPixelClass->windowFile)) - offset );
06778         }
06779 
06780         if( thisPixelClass->maskFileList )
06781         {
06782           thisFile = thisPixelClass->maskFileList;
06783           thisPixelClass->maskFileList = (M3_FileLL *)(((char*)(thisPixelClass->maskFileList)) - offset );
06784 
06785           while( thisFile )
06786           {
06787             if( thisFile->file.name )
06788               thisFile->file.name -= offset;
06789                   
06790             if( thisFile->file.format )
06791               thisFile->file.format -= offset;
06792 
06793             tempPtr = thisFile->next;
06794             if( thisFile->next )
06795               thisFile->next = (M3_FileLL *)(((char*)(thisFile->next)) - offset);
06796             thisFile = (M3_FileLL *)tempPtr;
06797           }
06798         }
06799 
06800         if( thisPixelClass->templateFileList )
06801         {
06802           thisFile = thisPixelClass->templateFileList;
06803           thisPixelClass->templateFileList = (M3_FileLL *)(((char*)(thisPixelClass->templateFileList)) - offset );
06804 
06805           while( thisFile )
06806           {
06807             if( thisFile->file.name )
06808               thisFile->file.name -= offset;
06809                   
06810             if( thisFile->file.format )
06811               thisFile->file.format -= offset;
06812 
06813             tempPtr = thisFile->next;
06814             if( thisFile->next )
06815               thisFile->next = (M3_FileLL *)(((char*)(thisFile->next)) - offset);
06816             thisFile = (M3_FileLL *)tempPtr;
06817           }
06818         }
06819 
06820         tempPtr = thisPixelClass->next;
06821         if( thisPixelClass->next )
06822           thisPixelClass->next = (M3_PixelClassLL*)(((char*)(thisPixelClass->next)) - offset);
06823         thisPixelClass = (M3_PixelClassLL *)tempPtr;
06824       }
06825     }
06826 
06827     if( runConfig->GCPointingGroupList )
06828     {
06829       thisGCPointingGroup = runConfig->GCPointingGroupList;
06830       runConfig->GCPointingGroupList = (M3_GCPointingGroupLL*)(((char*)(runConfig->GCPointingGroupList)) - offset );
06831       while( thisGCPointingGroup )
06832       {
06833         if( thisGCPointingGroup->name )
06834           thisGCPointingGroup->name -= offset;
06835         if( thisGCPointingGroup->GCPointingType )
06836           thisGCPointingGroup->GCPointingType -= offset;
06837         if( thisGCPointingGroup->auxFile )
06838         {
06839           if( thisGCPointingGroup->auxFile->name )
06840             thisGCPointingGroup->auxFile->name -= offset;
06841           if( thisGCPointingGroup->auxFile->format )
06842             thisGCPointingGroup->auxFile->format -= offset;
06843           thisGCPointingGroup->auxFile = (M3_File *)(((char*)(thisGCPointingGroup->auxFile)) - offset);
06844         }
06845 
06846         if( thisGCPointingGroup->GCPointingFileList )
06847         {
06848           thisFile = thisGCPointingGroup->GCPointingFileList;
06849           thisGCPointingGroup->GCPointingFileList = (M3_FileLL*)(((char*)(thisGCPointingGroup->GCPointingFileList)) - offset);
06850           while(thisFile)
06851           {
06852             if( thisFile->file.name )
06853               thisFile->file.name -= offset;
06854             if( thisFile->file.format )
06855               thisFile->file.format -= offset;
06856             tempPtr = thisFile->next;
06857             if( thisFile->next )
06858               thisFile->next = (M3_FileLL*)(((char*)(thisFile->next)) - offset);
06859             thisFile = (M3_FileLL *)tempPtr;
06860           }
06861         }
06862         if( thisGCPointingGroup->GCPointingStoreList )
06863         {
06864           thisGCPointingStore = thisGCPointingGroup->GCPointingStoreList;
06865           thisGCPointingGroup->GCPointingStoreList = (M3_GCPointingStoreLL*)(((char*)(thisGCPointingGroup->GCPointingStoreList)) - offset );
06866           while( thisGCPointingStore )
06867           {
06868             if( thisGCPointingStore->data )
06869               thisGCPointingStore->data = (double*)(((char*)(thisGCPointingStore->data)) - offset );
06870             tempPtr = thisGCPointingStore->next;
06871             if( thisGCPointingStore->next )
06872               thisGCPointingStore->next = (M3_GCPointingStoreLL*)(((char*)(thisGCPointingStore->next)) - offset );
06873             thisGCPointingStore = (M3_GCPointingStoreLL*)tempPtr;
06874           }
06875         }
06876 
06877         tempPtr = thisGCPointingGroup->next;
06878         if( thisGCPointingGroup->next )
06879           thisGCPointingGroup->next = (M3_GCPointingGroupLL*)(((char*)(thisGCPointingGroup->next)) - offset );
06880         thisGCPointingGroup = (M3_GCPointingGroupLL *)tempPtr;
06881       }
06882     }
06883 
06884     if( runConfig->powerSpectrum.spectrumClassList )
06885     {
06886       thisSpectrumClass = runConfig->powerSpectrum.spectrumClassList;
06887       runConfig->powerSpectrum.spectrumClassList = (M3_SpectrumClassLL*)(((char*)(runConfig->powerSpectrum.spectrumClassList)) - offset);
06888 
06889       while( thisSpectrumClass )
06890       {
06891         if( thisSpectrumClass->shapeFile )
06892         {
06893           if( thisSpectrumClass->shapeFile->name )
06894             thisSpectrumClass->shapeFile->name -= offset;
06895 
06896           if( thisSpectrumClass->shapeFile->format )
06897             thisSpectrumClass->shapeFile->format -= offset;
06898 
06899           thisSpectrumClass->shapeFile = (M3_File *)(((char*)(thisSpectrumClass->shapeFile)) - offset );
06900         }
06901 
06902         if( thisSpectrumClass->binFile )
06903         {
06904           if( thisSpectrumClass->binFile->name )
06905             thisSpectrumClass->binFile->name -= offset;
06906 
06907           if( thisSpectrumClass->binFile->format )
06908             thisSpectrumClass->binFile->format -= offset;
06909  
06910           thisSpectrumClass->binFile = (M3_File *)(((char*)(thisSpectrumClass->binFile)) - offset );
06911         }
06912 
06913         if( thisSpectrumClass->bpsFile )
06914         {
06915           if( thisSpectrumClass->bpsFile->name )
06916             thisSpectrumClass->bpsFile->name -= offset;
06917 
06918           if( thisSpectrumClass->bpsFile->format )
06919             thisSpectrumClass->bpsFile->format -= offset;
06920 
06921           thisSpectrumClass->bpsFile = (M3_File *)(((char*)(thisSpectrumClass->bpsFile)) - offset );
06922         }
06923 
06924         tempPtr = thisSpectrumClass->next;
06925         if( thisSpectrumClass->next )
06926           thisSpectrumClass->next = (M3_SpectrumClassLL *)(((char*)(thisSpectrumClass->next)) - offset );
06927         thisSpectrumClass = (M3_SpectrumClassLL *)tempPtr;
06928       }
06929     }
06930 
06931     if( runConfig->powerSpectrum.fisherMatrix )
06932     {
06933       if( runConfig->powerSpectrum.fisherMatrix->name )
06934         runConfig->powerSpectrum.fisherMatrix->name -= offset;
06935       
06936       if( runConfig->powerSpectrum.fisherMatrix->format )
06937         runConfig->powerSpectrum.fisherMatrix->format -= offset;
06938 
06939       runConfig->powerSpectrum.fisherMatrix = (M3_File *)(((char*)(runConfig->powerSpectrum.fisherMatrix)) - offset );
06940     }
06941 
06942     if( runConfig->sparsePixelMatrix )
06943     {
06944       if( runConfig->sparsePixelMatrix->name )
06945         runConfig->sparsePixelMatrix->name -= offset;
06946       if( runConfig->sparsePixelMatrix->format )
06947         runConfig->sparsePixelMatrix->format -= offset;
06948 
06949       runConfig->sparsePixelMatrix = (M3_File *)(((char*)(runConfig->sparsePixelMatrix)) - offset);
06950     }
06951 
06952   }
06953   else
06954   {
06955     /* Shift from relative adresses to absolute adresses */
06956     if( runConfig->dataSetList )
06957       runConfig->dataSetList = (M3_DataSetLL *)(((char*)(runConfig->dataSetList)) + offset );
06958 
06959     for( thisDataSet = runConfig->dataSetList; thisDataSet; thisDataSet = thisDataSet->next )
06960     {
06961       thisDataSet->runConfigNode = (M3_RunConfigStruct*)(((char*)(thisDataSet->runConfigNode)) + offset);
06962       if( thisDataSet->pixelConvertNode )
06963         thisDataSet->pixelConvertNode = (M3_PixelConvertStruct*)(((char*)(thisDataSet->pixelConvertNode)) + offset);
06964       if( thisDataSet->name )
06965         thisDataSet->name += offset;
06966       if( thisDataSet->coveredIntervalList )
06967         thisDataSet->coveredIntervalList = (M3_IntervalLL*)(((char*)(thisDataSet->coveredIntervalList)) + offset );
06968 
06969       for( thisInterval = thisDataSet->coveredIntervalList; thisInterval; thisInterval = thisInterval->next )
06970         if( thisInterval->next )
06971           thisInterval->next = (M3_IntervalLL*)(((char*)(thisInterval->next)) + offset );
06972 
06973       if( thisDataSet->componentList )
06974         thisDataSet->componentList = (M3_ComponentLL *)(((char*)(thisDataSet->componentList)) + offset );
06975 
06976       for( thisComponent = thisDataSet->componentList; thisComponent; thisComponent = thisComponent->next )
06977       {
06978         if( thisComponent->subcomponentList )
06979           thisComponent->subcomponentList = (M3_SubcomponentLL *)(((char*)(thisComponent->subcomponentList)) + offset );
06980             
06981         for( thisSubcomponent = thisComponent->subcomponentList; thisSubcomponent; thisSubcomponent = thisSubcomponent->next )
06982         {
06983           if( thisSubcomponent->todFileList )
06984             thisSubcomponent->todFileList = (M3_FileLL*)(((char*)(thisSubcomponent->todFileList)) + offset);
06985                 
06986           for( thisFile = thisSubcomponent->todFileList; thisFile; thisFile = thisFile->next )
06987           {
06988             if( thisFile->file.name )
06989               thisFile->file.name += offset;
06990                   
06991             if( thisFile->file.format )
06992               thisFile->file.format += offset;
06993 
06994             if( thisFile->next )
06995               thisFile->next = (M3_FileLL *)(((char*)(thisFile->next)) + offset);
06996           }
06997           if( thisSubcomponent->next )
06998             thisSubcomponent->next = (M3_SubcomponentLL *)(((char*)(thisSubcomponent->next)) + offset );
06999         }  
07000 
07001         if( thisComponent->todCalibFileList )
07002           thisComponent->todCalibFileList = (M3_FileLL *)(((char*)(thisComponent->todCalibFileList)) + offset );
07003  
07004         for( thisFile = thisComponent->todCalibFileList; thisFile; thisFile = thisFile->next )
07005         {
07006           if( thisFile->file.name )
07007             thisFile->file.name += offset;
07008                   
07009           if( thisFile->file.format )
07010             thisFile->file.format += offset;
07011 
07012           if( thisFile->next )
07013             thisFile->next = (M3_FileLL *)(((char*)(thisFile->next)) + offset);
07014         }
07015 
07016         if( thisComponent->next )
07017           thisComponent->next = (M3_ComponentLL *)(((char*)(thisComponent->next)) + offset  );
07018       }
07019 
07020       if( thisDataSet->noiseFileList )
07021         thisDataSet->noiseFileList = (M3_FileLL*)(((char*)(thisDataSet->noiseFileList)) + offset );
07022 
07023       for( thisFile = thisDataSet->noiseFileList; thisFile; thisFile = thisFile->next )
07024       {
07025         if( thisFile->file.name )
07026           thisFile->file.name += offset;
07027                   
07028         if( thisFile->file.format )
07029           thisFile->file.format += offset;
07030 
07031         if( thisFile->next )
07032           thisFile->next = (M3_FileLL *)(((char*)(thisFile->next)) + offset);
07033       }
07034 
07035       for( k = 0; k < M3_NUM_FILTER_TYPE; k++ )
07036       {
07037         if( thisDataSet->filterFileList[k] )
07038           thisDataSet->filterFileList[k] = (M3_FileLL *)(((char*)(thisDataSet->filterFileList[k])) + offset );
07039         
07040         for( thisFile = thisDataSet->filterFileList[k]; thisFile; thisFile = thisFile->next )
07041         {
07042           if( thisFile->file.name )
07043             thisFile->file.name += offset;
07044                   
07045           if( thisFile->file.format )
07046             thisFile->file.format += offset;
07047 
07048           if( thisFile->next )
07049             thisFile->next = (M3_FileLL *)(((char*)(thisFile->next)) + offset);
07050         }
07051       }
07052 
07053       if( thisDataSet->pointingClassList )
07054         thisDataSet->pointingClassList =(M3_PointingClassLL *)(((char*)(thisDataSet->pointingClassList)) + offset );
07055       
07056       for( thisPointingClass = thisDataSet->pointingClassList; thisPointingClass; thisPointingClass = thisPointingClass->next )
07057       {
07058         if( thisPointingClass->pixelClassNode )
07059           thisPointingClass->pixelClassNode = (M3_PixelClassLL *)(((char*)(thisPointingClass->pixelClassNode)) + offset );
07060         
07061         if( thisPointingClass->subclassList )
07062           thisPointingClass->subclassList = (M3_PointingSubclassLL *)(((char*)(thisPointingClass->subclassList)) + offset );
07063 
07064         for( thisPointingSubclass = thisPointingClass->subclassList; thisPointingSubclass; thisPointingSubclass = thisPointingSubclass->next )
07065         {
07066           if( thisPointingSubclass->pointingFileList )
07067             thisPointingSubclass->pointingFileList = (M3_FileLL *)(((char*)(thisPointingSubclass->pointingFileList)) + offset );
07068           
07069           for( thisFile = thisPointingSubclass->pointingFileList; thisFile; thisFile = thisFile->next )
07070           {
07071             if( thisFile->file.name )
07072               thisFile->file.name += offset;
07073                   
07074             if( thisFile->file.format )
07075               thisFile->file.format += offset;
07076 
07077             if( thisFile->next )
07078               thisFile->next = (M3_FileLL *)(((char*)(thisFile->next)) + offset);
07079           }
07080 
07081           if( thisPointingSubclass->GCPointingGroupNode )
07082             thisPointingSubclass->GCPointingGroupNode = (M3_GCPointingGroupLL*)(((char*)(thisPointingSubclass->GCPointingGroupNode)) + offset );
07083           
07084           if( thisPointingSubclass->auxComplement )
07085             thisPointingSubclass->auxComplement += offset;        
07086 
07087           if( thisPointingSubclass->next )
07088             thisPointingSubclass->next = (M3_PointingSubclassLL*)(((char*)(thisPointingSubclass->next)) + offset );
07089         }
07090 
07091         if( thisPointingClass->pointingCalibFileList )
07092           thisPointingClass->pointingCalibFileList = (M3_FileLL *)(((char*)(thisPointingClass->pointingCalibFileList)) + offset );
07093 
07094         for( thisFile = thisPointingClass->pointingCalibFileList; thisFile; thisFile = thisFile->next )
07095         {
07096           if( thisFile->file.name )
07097             thisFile->file.name += offset;
07098                   
07099           if( thisFile->file.format )
07100             thisFile->file.format += offset;
07101 
07102           if( thisFile->next )
07103             thisFile->next = (M3_FileLL *)(((char*)(thisFile->next)) + offset);
07104         }
07105 
07106         if( thisPointingClass->next )
07107           thisPointingClass->next = (M3_PointingClassLL *)(((char*)(thisPointingClass->next)) + offset );
07108       }
07109 
07110       if( thisDataSet->next )
07111         thisDataSet->next = (M3_DataSetLL *)(((char*)(thisDataSet->next)) + offset );
07112     }
07113 
07114 
07115     if( runConfig->pixelClassList )
07116       runConfig->pixelClassList = (M3_PixelClassLL*)(((char *)(runConfig->pixelClassList)) + offset);
07117 
07118     for( thisPixelClass = runConfig->pixelClassList; thisPixelClass; thisPixelClass = thisPixelClass->next )
07119     {
07120       if( thisPixelClass->className )
07121         thisPixelClass->className = thisPixelClass->className + offset;
07122 
07123       if( thisPixelClass->mapFile )
07124       {
07125         thisPixelClass->mapFile = (M3_File *)(((char*)(thisPixelClass->mapFile)) + offset );
07126 
07127         if( thisPixelClass->mapFile->name )
07128           thisPixelClass->mapFile->name += offset;
07129 
07130         if( thisPixelClass->mapFile->format )
07131           thisPixelClass->mapFile->format += offset;
07132       }
07133 
07134       if( thisPixelClass->coordFile )
07135       {
07136         thisPixelClass->coordFile = (M3_File *)(((char*)(thisPixelClass->coordFile)) + offset );
07137 
07138         if( thisPixelClass->coordFile->name )
07139           thisPixelClass->coordFile->name += offset;
07140 
07141         if( thisPixelClass->coordFile->format )
07142           thisPixelClass->coordFile->format += offset;
07143       }
07144 
07145       if( thisPixelClass->windowFile )
07146       {
07147         thisPixelClass->windowFile = (M3_File *)(((char*)(thisPixelClass->windowFile)) + offset );
07148 
07149         if( thisPixelClass->windowFile->name )
07150           thisPixelClass->windowFile->name += offset;
07151 
07152         if( thisPixelClass->windowFile->format )
07153           thisPixelClass->windowFile->format += offset;
07154       }
07155       
07156       if( thisPixelClass->maskFileList )
07157         thisPixelClass->maskFileList = (M3_FileLL *)(((char*)(thisPixelClass->maskFileList)) + offset );
07158 
07159       for( thisFile = thisPixelClass->maskFileList; thisFile; thisFile = thisFile->next )
07160       {
07161         if( thisFile->file.name )
07162           thisFile->file.name += offset;
07163                   
07164         if( thisFile->file.format )
07165           thisFile->file.format += offset;
07166 
07167         if( thisFile->next )
07168           thisFile->next = (M3_FileLL *)(((char*)(thisFile->next)) + offset);
07169       }
07170 
07171       if( thisPixelClass->templateFileList )
07172         thisPixelClass->templateFileList = (M3_FileLL *)(((char*)(thisPixelClass->templateFileList)) + offset );
07173 
07174       for( thisFile = thisPixelClass->templateFileList; thisFile; thisFile = thisFile->next )
07175       {
07176         if( thisFile->file.name )
07177           thisFile->file.name += offset;
07178                   
07179         if( thisFile->file.format )
07180           thisFile->file.format += offset;
07181 
07182         if( thisFile->next )
07183           thisFile->next = (M3_FileLL *)(((char*)(thisFile->next)) + offset);
07184       }
07185 
07186       if( thisPixelClass->next )
07187         thisPixelClass->next = (M3_PixelClassLL*)(((char*)(thisPixelClass->next)) + offset);
07188     }
07189 
07190     if( runConfig->GCPointingGroupList )
07191       runConfig->GCPointingGroupList = (M3_GCPointingGroupLL*)(((char*)(runConfig->GCPointingGroupList)) + offset);
07192 
07193     for( thisGCPointingGroup = runConfig->GCPointingGroupList; thisGCPointingGroup; thisGCPointingGroup = thisGCPointingGroup->next )
07194     {
07195       if( thisGCPointingGroup->name )
07196         thisGCPointingGroup->name += offset;
07197       if( thisGCPointingGroup->GCPointingType )
07198         thisGCPointingGroup->GCPointingType += offset;
07199       if( thisGCPointingGroup->auxFile )
07200       {
07201         thisGCPointingGroup->auxFile = (M3_File*)(((char*)(thisGCPointingGroup->auxFile)) + offset );
07202         if( thisGCPointingGroup->auxFile->name )
07203           thisGCPointingGroup->auxFile->name += offset;
07204         if( thisGCPointingGroup->auxFile->format )
07205           thisGCPointingGroup->auxFile->format += offset;
07206       }
07207       if( thisGCPointingGroup->GCPointingFileList )
07208         thisGCPointingGroup->GCPointingFileList = (M3_FileLL *)(((char*)(thisGCPointingGroup->GCPointingFileList)) + offset );
07209       for( thisFile = thisGCPointingGroup->GCPointingFileList; thisFile; thisFile = thisFile->next )
07210       {
07211         if( thisFile->file.name )
07212           thisFile->file.name += offset;
07213         if( thisFile->file.format )
07214           thisFile->file.format += offset;
07215         if( thisFile->next)
07216           thisFile->next = (M3_FileLL*)(((char*)(thisFile->next))+offset);
07217       }
07218       if( thisGCPointingGroup->GCPointingStoreList )
07219         thisGCPointingGroup->GCPointingStoreList = (M3_GCPointingStoreLL*)(((char*)(thisGCPointingGroup->GCPointingStoreList))+offset);
07220       for( thisGCPointingStore = thisGCPointingGroup->GCPointingStoreList; thisGCPointingStore; thisGCPointingStore = thisGCPointingStore->next )
07221       {
07222         if(thisGCPointingStore->data )
07223           thisGCPointingStore->data = (double*)(((char*)(thisGCPointingStore->data)) + offset );
07224         if(thisGCPointingStore->next )
07225           thisGCPointingStore->next = (M3_GCPointingStoreLL*)(((char*)(thisGCPointingStore->next))+offset);
07226       }
07227       if( thisGCPointingGroup->next )
07228         thisGCPointingGroup->next = (M3_GCPointingGroupLL*)(((char*)(thisGCPointingGroup->next))+offset);
07229     }
07230 
07231 
07232     if( runConfig->powerSpectrum.spectrumClassList )
07233       runConfig->powerSpectrum.spectrumClassList = (M3_SpectrumClassLL*)(((char*)(runConfig->powerSpectrum.spectrumClassList)) + offset);
07234 
07235     for( thisSpectrumClass = runConfig->powerSpectrum.spectrumClassList; thisSpectrumClass; thisSpectrumClass = thisSpectrumClass->next )
07236     {
07237       if( thisSpectrumClass->shapeFile )
07238       {
07239         thisSpectrumClass->shapeFile = (M3_File *)(((char*)(thisSpectrumClass->shapeFile)) + offset );
07240 
07241         if( thisSpectrumClass->shapeFile->name )
07242           thisSpectrumClass->shapeFile->name += offset;
07243 
07244         if( thisSpectrumClass->shapeFile->format )
07245           thisSpectrumClass->shapeFile->format += offset;
07246       }
07247 
07248       if( thisSpectrumClass->binFile )
07249       {
07250         thisSpectrumClass->binFile = (M3_File *)(((char*)(thisSpectrumClass->binFile)) + offset );
07251 
07252         if( thisSpectrumClass->binFile->name )
07253           thisSpectrumClass->binFile->name += offset;
07254 
07255         if( thisSpectrumClass->binFile->format )
07256           thisSpectrumClass->binFile->format += offset;
07257       }
07258 
07259       if( thisSpectrumClass->bpsFile )
07260       {
07261         thisSpectrumClass->bpsFile = (M3_File *)(((char*)(thisSpectrumClass->bpsFile)) + offset );
07262 
07263         if( thisSpectrumClass->bpsFile->name )
07264           thisSpectrumClass->bpsFile->name += offset;
07265 
07266         if( thisSpectrumClass->bpsFile->format )
07267           thisSpectrumClass->bpsFile->format += offset;
07268       }
07269 
07270       if( thisSpectrumClass->next )
07271         thisSpectrumClass->next = (M3_SpectrumClassLL *)(((char*)(thisSpectrumClass->next)) + offset );
07272     }
07273 
07274     if( runConfig->powerSpectrum.fisherMatrix )
07275     {
07276       runConfig->powerSpectrum.fisherMatrix = (M3_File *)(((char*)(runConfig->powerSpectrum.fisherMatrix)) + offset );
07277 
07278       if( runConfig->powerSpectrum.fisherMatrix->name )
07279         runConfig->powerSpectrum.fisherMatrix->name += offset;
07280       
07281       if( runConfig->powerSpectrum.fisherMatrix->format )
07282         runConfig->powerSpectrum.fisherMatrix->format += offset;
07283     }
07284 
07285     if( runConfig->sparsePixelMatrix )
07286     {
07287       runConfig->sparsePixelMatrix = (M3_File *)(((char*)(runConfig->sparsePixelMatrix)) + offset );
07288 
07289       runConfig->sparsePixelMatrix->name += offset;
07290       runConfig->sparsePixelMatrix->format += offset;
07291     }
07292 
07293   }
07294   
07295   return;
07296 }
07297 
07298 
07299 
07300 #undef M3_NAME_LENGTH
07301 #undef M3_CONTENT_LENGTH

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