00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00018 #define _CRT_SECURE_NO_DEPRECATE
00019
00020 #include "yanera.h"
00021 #include "yanera_util.h"
00022 #include "yanera_xml_input.h"
00023 #include "yanera_mdmin.h"
00024 #include "yanera_lstsq.h"
00025 #include "yanera_profile.h"
00026 #include "yanera_quadrature.h"
00027 #include "yanera_reflectivity.h"
00028 #include "yanera_xml_output.h"
00029
00030 yanera_container *yanera_initialize(const char *filename)
00031 {
00032 unsigned short i, j;
00033 yanera_container *yanera;
00034
00035 fprintf(stdout,"YANERA : 2.0 beta\n");
00036 fprintf(stdout," Date : %s\n", __DATE__ );
00037 fprintf(stdout," :\n");
00038
00039
00040
00041
00042 yanera = (yanera_container *)malloc(sizeof(yanera_container));
00043 if (yanera == NULL)
00044 {
00045 yanera_error("No memory for new yanera_container", \
00046 __FILE__, __LINE__, NULL);
00047 }
00048
00049
00050
00051 yanera->filename = (char *)calloc((1+strlen(filename)),sizeof(char));
00052 if (yanera->filename == NULL)
00053 {
00054 yanera_error("No memory for new yanera XML filename", \
00055 __FILE__, __LINE__, yanera);
00056 }
00057 strcpy(yanera->filename, filename);
00058
00059
00060
00061
00062 yanera->type = MODEL_LAYER;
00063 yanera->parrattFunction = &calcParrattFromModel;
00064 yanera->profileFunctionReal = &layerProfileReal;
00065 yanera->profileFunctionImag = &layerProfileImag;
00066
00067
00068
00069 for (i=0; i<10; i++)
00070 {
00071 yanera->models_xml[i].data_idref = NULL;
00072 yanera->models_xml[i].name = NULL;
00073 yanera->models_xml[i].background = -1;
00074 yanera->models_xml[i].polarized = POLARIZED_NONE;
00075 yanera->models_xml[i].first_layer = NULL;
00076 yanera->models_xml[i].last_layer = NULL;
00077 yanera->models_xml[i].slabs.number_of_slab_edges = 0;
00078 yanera->models_xml[i].slabs.number_of_slabs = 0;
00079 for (j=0; j<USHRT_MAX; j++)
00080 {
00081 yanera->models_xml[i].slabs.zpos[j] = 0.0;
00082 yanera->models_xml[i].slabs.thik[j] = 0.0;
00083 yanera->models_xml[i].slabs.rsld[j] = 0.0;
00084 yanera->models_xml[i].slabs.isld[j] = 0.0;
00085 }
00086
00087 yanera->models_complete[i].data_idref = NULL;
00088 yanera->models_complete[i].name = NULL;
00089 yanera->models_complete[i].background = -1;
00090 yanera->models_complete[i].polarized = POLARIZED_NONE;
00091 yanera->models_complete[i].first_layer = NULL;
00092 yanera->models_complete[i].last_layer = NULL;
00093 yanera->models_complete[i].slabs.number_of_slab_edges = 0;
00094 yanera->models_complete[i].slabs.number_of_slabs = 0;
00095 for (j=0; j<USHRT_MAX; j++)
00096 {
00097 yanera->models_complete[i].slabs.zpos[j] = 0.0;
00098 yanera->models_complete[i].slabs.thik[j] = 0.0;
00099 yanera->models_complete[i].slabs.rsld[j] = 0.0;
00100 yanera->models_complete[i].slabs.isld[j] = 0.0;
00101 }
00102
00103 yanera->data[i].data_id = NULL;
00104 yanera->data[i].file_name = NULL;
00105 yanera->data[i].n = 0;
00106 yanera->data[i].q = NULL;
00107 yanera->data[i].R = NULL;
00108 yanera->data[i].e = NULL;
00109 yanera->data[i].idx = 0;
00110 yanera->data[i].resolution.type = RESOLUTION_NONE;
00111 yanera->data[i].resolution.value = NULL;
00112 yanera->data[i].resolution.q = NULL;
00113 yanera->data[i].resolution.n = 0;
00114 yanera->data[i].resolution.file_name = NULL;
00115 }
00116 yanera->number_of_models = 0;
00117 yanera->number_of_data = 0;
00118 yanera->idx = 0;
00119
00120
00121
00122
00123 yanera->parameters.p = NULL;
00124 yanera->parameters.f = NULL;
00125 yanera->parameters.min = NULL;
00126 yanera->parameters.max = NULL;
00127 yanera->parameters.con = NULL;
00128 yanera->parameters.n = 0;
00129 yanera->parameters.tmp = NULL;
00130 yanera->parameters.idx = 0;
00131
00132
00133
00134
00135 yanera->components = NULL;
00136
00137
00138
00139
00140 yanera->misc.write_results = NO;
00141 yanera->misc.write_profile = YES;
00142 yanera->misc.write_reflectivity = YES;
00143 yanera->misc.write_slabs = NO;
00144 yanera->misc.q_min = 1.0E-05;
00145 yanera->misc.q_max = 0.2;
00146 yanera->misc.q_num = 201;
00147 yanera->misc.z_num = 201;
00148 yanera->misc.quadrature_error = 0.5E-02;
00149 yanera->misc.quadrature_thik = 100.0;
00150 yanera->misc.fit_do = NO;
00151 yanera->misc.fit_weighting = WEIGHT_NONE;
00152 yanera->misc.fit_iterations = 25;
00153 yanera->misc.fit_write_iterations = 10;
00154 yanera->misc.fit_method = LMSDR;
00155 yanera->misc.fit_method_mdmin = \
00156 gsl_multimin_fdfminimizer_conjugate_fr;
00157 yanera->misc.fit_method_mdmin_simplex = \
00158 gsl_multimin_fminimizer_nmsimplex;
00159 yanera->misc.fit_method_lstsq = gsl_multifit_fdfsolver_lmsder;
00160 #ifdef HAVE_OOL
00161 yanera->misc.fit_method_ool = ool_conmin_minimizer_spg;
00162 #endif
00163 return yanera;
00164 }
00165
00166 void yanera_free(yanera_container *yanera)
00167 {
00168 struct _postfix_queue_element *postfix1, *postfix2;
00169 short i;
00170 yanera_layer *layer_pointer_1, *layer_pointer_2;
00171
00172
00173 free(yanera->filename);
00174
00175 free(yanera->parameters.p);
00176 free(yanera->parameters.f);
00177 free(yanera->parameters.tmp);
00178 free(yanera->parameters.min);
00179 free(yanera->parameters.max);
00180 free(yanera->parameters.con);
00181
00182 for (i=0; i<10; i++)
00183 {
00184
00185 layer_pointer_1 = yanera->models_xml[i].first_layer;
00186 while (layer_pointer_1 != NULL)
00187 {
00188 free(layer_pointer_1->layer_id);
00189 free(layer_pointer_1->layer_idref);
00190 free(layer_pointer_1->component_id);
00191 free(layer_pointer_1->component_idref);
00192 free(layer_pointer_1->name);
00193 free(layer_pointer_1->func);
00194 free(layer_pointer_1->parm_names);
00195 free(layer_pointer_1->parm_values);
00196
00197 layer_pointer_2 = layer_pointer_1;
00198 layer_pointer_1 = layer_pointer_1->next;
00199 free(layer_pointer_2);
00200 };
00201
00202 free(yanera->models_xml[i].data_idref);
00203 free(yanera->models_xml[i].name);
00204 };
00205
00206 for (i=0; i<10; i++)
00207 {
00208
00209 layer_pointer_1 = yanera->models_complete[i].first_layer;
00210 while (layer_pointer_1 != NULL)
00211 {
00212 free(layer_pointer_1->layer_id);
00213 free(layer_pointer_1->layer_idref);
00214 free(layer_pointer_1->component_id);
00215 free(layer_pointer_1->component_idref);
00216 free(layer_pointer_1->name);
00217 free(layer_pointer_1->func);
00218 if (layer_pointer_1->type == LAYER_FUNCTION)
00219 {
00220 postfix1 = layer_pointer_1->func_postfix->front;
00221 while (postfix1 != NULL)
00222 {
00223 postfix2 = postfix1;
00224 postfix1 = postfix1->next;
00225 free(postfix2);
00226 }
00227 }
00228 free(layer_pointer_1->func_postfix);
00229 free(layer_pointer_1->parm_names);
00230 free(layer_pointer_1->parm_values);
00231 layer_pointer_2 = layer_pointer_1;
00232 layer_pointer_1 = layer_pointer_1->next;
00233 free(layer_pointer_2);
00234 };
00235
00236 free(yanera->models_complete[i].data_idref);
00237 free(yanera->models_complete[i].name);
00238 };
00239
00240
00241
00242 layer_pointer_1 = yanera->components;
00243 while (layer_pointer_1 != NULL)
00244 {
00245 free(layer_pointer_1->layer_id);
00246 free(layer_pointer_1->layer_idref);
00247 free(layer_pointer_1->component_id);
00248 free(layer_pointer_1->component_idref);
00249 free(layer_pointer_1->name);
00250 free(layer_pointer_1->func);
00251 free(layer_pointer_1->parm_names);
00252 free(layer_pointer_1->parm_values);
00253
00254 layer_pointer_2 = layer_pointer_1;
00255 layer_pointer_1 = layer_pointer_1->next;
00256 free(layer_pointer_2);
00257 };
00258
00259
00260 for (i=0; i<10; i++)
00261 {
00262 free(yanera->data[i].file_name);
00263 free(yanera->data[i].data_id);
00264 free(yanera->data[i].resolution.value);
00265 free(yanera->data[i].resolution.q);
00266 free(yanera->data[i].resolution.file_name);
00267 free(yanera->data[i].q);
00268 free(yanera->data[i].R);
00269 free(yanera->data[i].e);
00270 };
00271
00272 free(yanera);
00273 yanera = NULL;
00274 }
00275
00276 void yanera_error(const char *reason, \
00277 const char *file, \
00278 int line, \
00279 yanera_container *yanera)
00280 {
00281 fprintf(stdout, " :\n");
00282 fprintf(stdout, "YANERA ERROR : %s\n", reason);
00283 fprintf(stdout, " In file : %s\n", file);
00284 fprintf(stdout, " At line : %d\n", line);
00285 fprintf(stdout, "\n");
00286
00287 if (yanera != NULL) yanera_free(yanera);
00288
00289 exit(EXIT_FAILURE);
00290 }
00291
00292 void yanera_report(yanera_container *yanera, \
00293 int iteration, \
00294 void *solver)
00295 {
00296 int j, i;
00297 gsl_multifit_fdfsolver *mfs;
00298 gsl_multimin_fdfminimizer *mms;
00299 gsl_multimin_fminimizer *mms2;
00300 #ifdef HAVE_OOL
00301 ool_conmin_minimizer *oos;
00302 #endif
00303
00304
00305 if (iteration >= 0)
00306 {
00307 fprintf(stderr," Iteration :%3u \n", iteration);
00308
00309 if ((yanera->misc.fit_method == LMSDR) || \
00310 (yanera->misc.fit_method == LMDR) || \
00311 (yanera->misc.fit_method == CLMDR) || \
00312 (yanera->misc.fit_method == CLMSDR))
00313 {
00314 if (solver != NULL)
00315 {
00316 mfs = (gsl_multifit_fdfsolver *)solver;
00317 for (j=0; j<yanera->parameters.n; j++)
00318 { yanera->parameters.p[j] = gsl_vector_get(mfs->x, j); }
00319 fprintf(stderr," Chi-squared : %12.6e\n", mdmin_chisq(yanera));
00320 }
00321 }
00322 if ((yanera->misc.fit_method == CONJUGATE_FR) || \
00323 (yanera->misc.fit_method == CONJUGATE_PR) || \
00324 (yanera->misc.fit_method == VECTOR_BFGS) || \
00325 (yanera->misc.fit_method == STEEP_DESC) || \
00326 (yanera->misc.fit_method == NMSIMPLEX))
00327 { fprintf(stderr," Chi-squared : %12.6e\n", mdmin_chisq(yanera)); }
00328 #ifdef HAVE_OOL
00329 if ((yanera->misc.fit_method == OOL_SPG) || \
00330 (yanera->misc.fit_method == OOL_GENCAN))
00331 { fprintf(stderr," Chi-squared : %12.6e\n", mdmin_chisq(yanera)); }
00332 #endif
00333 #ifdef HAVE_LEVMAR
00334 if (yanera->misc.fit_method == LEVMAR)
00335 { fprintf(stderr," Chi-squared : %12.6e\n", mdmin_chisq(yanera)); }
00336 #endif
00337 }
00338
00339
00340 if (iteration == -1)
00341 {
00342 fprintf(stderr,"YANERA FINISHED: \n");
00343
00344 if (solver != NULL)
00345 {
00346 if ((yanera->misc.fit_method == LMSDR) || \
00347 (yanera->misc.fit_method == LMDR) || \
00348 (yanera->misc.fit_method == CLMDR) || \
00349 (yanera->misc.fit_method == CLMSDR))
00350 {
00351 mfs = (gsl_multifit_fdfsolver *)solver;
00352
00353
00354
00355 for (j=0; j<yanera->parameters.n; j++)
00356 { yanera->parameters.p[j] = gsl_vector_get(mfs->x, j); }
00357 fprintf(stderr," Chi-squared : %12.6e\n", mdmin_chisq(yanera));
00358 }
00359 if ((yanera->misc.fit_method == CONJUGATE_FR) || \
00360 (yanera->misc.fit_method == CONJUGATE_PR) || \
00361 (yanera->misc.fit_method == VECTOR_BFGS) || \
00362 (yanera->misc.fit_method == STEEP_DESC))
00363 {
00364 mms = (gsl_multimin_fdfminimizer *)solver;
00365 for (j=0; j<yanera->parameters.n; j++)
00366 { yanera->parameters.p[j] = gsl_vector_get(mms->x, j); }
00367 fprintf(stderr," Chi-squared : %12.6e\n", mdmin_chisq(yanera));
00368 }
00369 if (yanera->misc.fit_method == NMSIMPLEX)
00370 {
00371 mms2 = (gsl_multimin_fminimizer *)solver;
00372 for (j=0, i=0; j<yanera->parameters.n; j++)
00373 {
00374 if (yanera->parameters.f[j] == NO)
00375 {
00376 yanera->parameters.p[j] = gsl_vector_get(mms2->x, i);
00377 i++;
00378 }
00379 }
00380 fprintf(stderr," Chi-squared : %12.6e\n", mdmin_chisq(yanera));
00381 }
00382 #ifdef HAVE_OOL
00383 if ((yanera->misc.fit_method == OOL_SPG) || \
00384 (yanera->misc.fit_method == OOL_GENCAN))
00385 {
00386 oos = (ool_conmin_minimizer *)solver;
00387 for (j=0; j<yanera->parameters.n; j++)
00388 { yanera->parameters.p[j] = gsl_vector_get(oos->x, j); }
00389 fprintf(stderr," Chi-squared : %12.6e\n", mdmin_chisq(yanera));
00390 }
00391 #endif
00392 }
00393 if (yanera->misc.fit_method == SIMAN)
00394 {
00395 fprintf(stderr," Chi-squared : %12.6e\n", mdmin_chisq(yanera));
00396 }
00397 #ifdef HAVE_LEVMAR
00398 if (yanera->misc.fit_method == LEVMAR)
00399 {
00400 fprintf(stderr," Chi-squared : %12.6e\n", mdmin_chisq(yanera));
00401 }
00402 #endif
00403 }
00404 if (((fmod(iteration,yanera->misc.fit_write_iterations) == 0) && \
00405 (iteration > 0)) || \
00406 (iteration == -1))
00407 {
00408 fprintf(stderr," Writing out :");
00409
00410
00411
00412
00413 if (yanera->misc.write_profile == YES)
00414 {
00415 fprintf(stderr,"...profile");
00416 yanera_write_profile(yanera);
00417 }
00418
00419
00420
00421 if (yanera->misc.write_slabs == YES)
00422 {
00423 if (yanera->type != MODEL_LAYER)
00424 {
00425 yanera_write_slabs(yanera);
00426 fprintf(stderr,"...slabs");
00427 }
00428 }
00429
00430
00431
00432 if (yanera->misc.write_reflectivity == YES)
00433 {
00434 yanera_write_reflectivity(yanera);
00435 fprintf(stderr,"...reflectivity");
00436 }
00437
00438
00439
00440 if (yanera->misc.write_results == YES)
00441 {
00442 if (yanera->misc.fit_do == YES) yanera_find_errors(yanera);
00443 yanera_write_xml(yanera);
00444 fprintf(stderr,"...results\n");
00445 }
00446 }
00447
00448 return;
00449 }
00450
00451 int yanera_find_errors(yanera_container *yanera)
00452 {
00453 int i, count;
00454 gsl_matrix *covar;
00455 gsl_matrix *jacob;
00456 gsl_vector *guess;
00457
00458 for (i=0, count=0; i<yanera->number_of_models; i++)
00459 {
00460 count += yanera->data[i].n;
00461 }
00462 jacob = gsl_matrix_alloc(count,yanera->parameters.n);
00463
00464 covar = gsl_matrix_alloc(yanera->parameters.n, yanera->parameters.n);
00465
00466 guess = gsl_vector_alloc(yanera->parameters.n);
00467 for (i=0; i<yanera->parameters.n; i++)
00468 {
00469 gsl_vector_set(guess, i, yanera->parameters.p[i]);
00470 }
00471
00472 lstsq_df(guess, (void *)yanera, jacob);
00473 gsl_multifit_covar(jacob, 0.0, covar);
00474
00475 for (i=0; i<yanera->parameters.n; i++)
00476 {
00477 yanera->parameters.tmp[i] = gsl_matrix_get(covar,i,i);
00478 }
00479
00480 gsl_matrix_free(covar);
00481 gsl_matrix_free(jacob);
00482 gsl_vector_free(guess);
00483
00484 return GSL_SUCCESS;
00485 }