rl_Multilayer_rdb.cc

00001 // File:   rl_Multilayer_rdb.cc
00002 // Author: Terry Gaetz
00003 
00004 // --8<--8<--8<--8<--
00005 //
00006 // Copyright (C) 2006 Smithsonian Astrophysical Observatory
00007 //
00008 // This file is part of rl_ray
00009 //
00010 // rl_ray is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU General Public License
00012 // as published by the Free Software Foundation; either version 2
00013 // of the License, or (at your option) any later version.
00014 //
00015 // rl_ray is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU General Public License
00021 // along with this program; if not, write to the 
00022 //       Free Software Foundation, Inc. 
00023 //       51 Franklin Street, Fifth Floor
00024 //       Boston, MA  02110-1301, USA
00025 //
00026 // -->8-->8-->8-->8--
00027 
00028 #include <rl_Multilayer_rdb.h>              // rl_Multilayer_rdb
00029 
00030 #include <rl_raylib/rl_Traits.h>
00031 #include <rl_DielectricPOD_rdb.h>           // rl_DielectricPOD_rdb
00032 #include <tracefct/exiterrvals.h>
00033 #include <tracefctxx/TraceFct.h>
00034 
00035 #include <cctype>                           // toupper
00036 
00037 
00038 #include <mst_rdb/mst_rdb.h>
00039 #include <suplib/str.h>
00040 
00041 //=========================================================================
00042 // statics
00043 
00044 static TokListToken      /* note:  must be in lexical order */
00045 srough_type[] =
00046 {
00047   { "DW_CSAO",    rl_Traits::ERoughDebyeWaller_CSAO    },
00048   { "DW_RSAO",    rl_Traits::ERoughDebyeWaller_RSAO    },
00049   { "DW_SPILLER", rl_Traits::ERoughDebyeWaller_Spiller },
00050   { "MDW",        rl_Traits::ERoughModifiedDebyeWaller },
00051   { "NC",         rl_Traits::ERoughNevotCroce          },
00052   { "NONE",       rl_Traits::ERoughNone                }
00053 };
00054 TokList srough_types = GenTokList( srough_type );
00055 
00056 //=========================================================================
00057 // dtor, ctors
00058 
00059 rl_Multilayer_rdb::
00060 ~rl_Multilayer_rdb()
00061 {}
00062 
00063 //-------------------------------------------------------------------------
00064 // Routine to set up surface data
00065 
00066 rl_Multilayer_rdb::
00067 rl_Multilayer_rdb( char const             rdb_filename[], 
00068                    rl_Traits::EInterpMode interp_mode 
00069                  )
00070   : rl_Multilayer(0,0)
00071 {
00072   init_from_rdb( rdb_filename, interp_mode );
00073 }
00074 
00075 //-------------------------------------------------------------------------
00076 // function to read in data from multilayer rdb table
00077 
00078 void rl_Multilayer_rdb::
00079 init_from_rdb( char const             *rdb_filename_in, 
00080                rl_Traits::EInterpMode interp_mode 
00081              )
00082 {
00083   TraceFct tf("rl_Multilayer_rdb::init");
00084 
00085   own_data_ = rl_Traits::True;
00086 
00087   FILE             *in;
00088   rdbHeader        *hdr;
00089   DataColumnMap_st *map;
00090 
00091   long int          nrow;
00092   int               num_fields = 0;
00093 
00094   typedef struct LayerRecord
00095   {
00096     char*  material;
00097     double thickness;
00098     double bulkdensity;
00099     char*  roughness_type;
00100     double srough;
00101     char*  optconst_rdb;
00102   } LayerRecord;
00103   LayerRecord layer_record;
00104 
00105   RDBFieldStInfo fields[6];
00106 #if 0
00107   {
00108     RDBentry( material,       RDB_String, LayerRecord ),
00109     RDBentry( thickness,      RDB_Num,    LayerRecord ),
00110     RDBentry( bulkdensity,    RDB_Num,    LayerRecord ),
00111     RDBentry( optconst_rdb,   RDB_String, LayerRecord ),
00112     RDBentry( roughness_type, RDB_String, LayerRecord ),
00113     RDBentry( srough,         RDB_Num,    LayerRecord )
00114   };
00115 #endif
00116 
00117   #define SET_FIELD(colname,var,vartype,idx)             \
00118   do{                                                    \
00119       fields[idx].name = #colname;                       \
00120       fields[idx].type = vartype;                        \
00121       fields[idx].offset = offsetof( LayerRecord, var ); \
00122       idx++;                                             \
00123   }while(0)
00124 
00125   #define CHECK_FIELD(colname) \
00126   if (! rdb_is_column( hdr, #colname ) ) \
00127   {                        \
00128     tf.die( "no \"" #colname "\"column in reflectance rdb file" ); \
00129   }
00130 
00131   int error;
00132   char *rdb_filename =
00133     str_interp( rdb_filename_in, 1, NULL, NULL, &error );
00134   if ( error )
00135     tf.die( "error interpolating filename: %s", rdb_filename_in );
00136 
00137   if ( !(in=fopen( rdb_filename, "r" )) )
00138     tf.exit( ExitERR_fopen, "unable to open input `%s'", rdb_filename );
00139 
00140   if (! (hdr = rdb_rd_hdr( in )) )
00141     tf.die( "rdb file `%s' contains no rdb headers!", rdb_filename );
00142 
00143   CHECK_FIELD( material );
00144   SET_FIELD( material, material, RDB_String, num_fields );
00145 
00146   CHECK_FIELD( thickness );
00147   SET_FIELD( thickness, thickness, RDB_Num, num_fields );
00148 
00149   CHECK_FIELD( bulkdensity );
00150   SET_FIELD( bulkdensity, bulkdensity, RDB_Num, num_fields );
00151 
00152   CHECK_FIELD( optconst_rdb );
00153   SET_FIELD( optconst_rdb, optconst_rdb, RDB_String, num_fields );
00154 
00155   int have_roughness = 0;
00156   if ( rdb_is_column( hdr, "roughness_type" ) )
00157   {
00158     have_roughness = 1;
00159 
00160     CHECK_FIELD( srough );
00161     SET_FIELD( roughness_type, roughness_type, RDB_String, num_fields );
00162     SET_FIELD( srough,         srough,         RDB_Num,    num_fields );
00163   }
00164 
00165   map = rdb_map_cols_stst( hdr, num_fields, fields );
00166 
00167   /*
00168    * count number of rows (excluding header & comments) in rdb file
00169    */
00170   nrow = rdb_count(in, hdr);
00171   if ( nrow < 0 )
00172     tf.die( "multilayer rdb file '%s' is not rewindable" );
00173   else if ( nrow == 0 )
00174     tf.die(
00175       "multilayer rdb file '%s' must have at least one row", rdb_filename );
00176 
00177   num_layers_ = nrow;
00178 
00179   layer_ = new rl_DielectricLayer[num_layers_];
00180   if (! layer_ )
00181   {
00182     tf.exit(ExitERR_alloc, "unable to allocate rl_DielectricLayer array" );
00183   }
00184 
00185   int n;
00186   for ( n = 0 ; n < num_layers_ ; ++n )
00187   {
00188     rdb_col_read_st(in, hdr, map, &layer_record);
00189     if (! (layer_record.bulkdensity >= 0.0) )
00190     {
00191       tf.die( "layer %d:  must have bulk density >= 0.0" );
00192     }
00193     rl_DielectricPOD_rdb diel( layer_record.optconst_rdb );
00194 
00195     double srough = 0.0;
00196     rl_Traits::ERoughType rtype = rl_Traits::ERoughNone;
00197 
00198     if ( have_roughness )
00199     {
00200       char* str = layer_record.roughness_type;
00201       while ( *str )
00202       {
00203         *str = toupper(*str);
00204         ++str;
00205       }
00206       int roughtype = tokmatch( layer_record.roughness_type, &srough_types );
00207 
00208       if ( roughtype >= 0 )
00209       {
00210         rtype = (rl_Traits::ERoughType)roughtype;
00211       }
00212       else
00213       {
00214         tf.die( "invalid \"roughness\" type %s", layer_record.roughness_type );
00215       }
00216       srough = layer_record.srough;
00217     }
00218 
00219     rl_Traits::Bool substrate = rl_Traits::Bool((n == num_layers_-1) ? 1 : 0);
00220 
00221     layer_[n].init( diel.const_data_ptr(),
00222                     diel.num_elts(),
00223                     layer_record.thickness,
00224                     srough,
00225                     rtype,
00226                     interp_mode,
00227                     layer_record.bulkdensity,
00228                     layer_record.material,
00229                     substrate );
00230 
00231     delete layer_record.material;
00232     delete layer_record.roughness_type;
00233     delete layer_record.optconst_rdb;
00234   }
00235   // clean up
00236 
00237   free( rdb_filename );
00238   rdb_free_map(map);       // free up data column map
00239   rdb_free_hdr(hdr);       // free up rdbHeader dynamic allocation
00240   fclose(in);
00241 }
00242 #undef SET_FIELD
00243 #undef CHECK_FIELD

Generated on Mon Dec 15 11:15:34 2008 for rl_raysuplib by  doxygen 1.5.6