00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <rl_Multilayer_rdb.h>
00029
00030 #include <rl_raylib/rl_Traits.h>
00031 #include <rl_DielectricPOD_rdb.h>
00032 #include <tracefct/exiterrvals.h>
00033 #include <tracefctxx/TraceFct.h>
00034
00035 #include <cctype>
00036
00037
00038 #include <mst_rdb/mst_rdb.h>
00039 #include <suplib/str.h>
00040
00041
00042
00043
00044 static TokListToken
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
00058
00059 rl_Multilayer_rdb::
00060 ~rl_Multilayer_rdb()
00061 {}
00062
00063
00064
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
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
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
00236
00237 free( rdb_filename );
00238 rdb_free_map(map);
00239 rdb_free_hdr(hdr);
00240 fclose(in);
00241 }
00242 #undef SET_FIELD
00243 #undef CHECK_FIELD