Functions | |
void | loadXML (const char *filename, Parratt *par) |
Parses the XML file. | |
void | parseOutput (xmlDocPtr doc, xmlNodePtr nod, Parratt *par) |
Parses the XML <output> tag. | |
void | parseFit (xmlDocPtr doc, xmlNodePtr nod, Parratt *par) |
Parses the XML <fit> tag. | |
void | parseModel (xmlDocPtr doc, xmlNodePtr nod, Parratt *par) |
Parses the XML <model> tag. | |
void | parseLayer (xmlDocPtr doc, xmlNodePtr lay, Parratt *par, int type) |
Parses the XML <layer> tag. | |
void | parseRepeat (xmlDocPtr doc, xmlNodePtr rep, Parratt *par) |
Parses the XML <repeat> tag. |
void loadXML | ( | const char * | filename, | |
Parratt * | par | |||
) |
This function validates and parses the XML file. The root layer here is <parratt>, and the only expected children are
<fit>,
<output>, and
<model>
00024 { 00025 xmlValidCtxtPtr ctx; 00026 xmlDocPtr doc; 00027 xmlNodePtr nod; 00028 xmlChar *buf; 00029 00030 /*==================================================== 00031 * Bunch of error checking and document validation 00032 */ 00033 doc = xmlParseFile(filename); 00034 if (doc == NULL ) error("Document not parsed successfully"); 00035 00036 ctx = xmlNewValidCtxt(); 00037 if (ctx == NULL) error("Failed to allocate parser context"); 00038 00039 if (xmlValidateDocument(ctx, doc)!=1) error("Not validated"); 00040 00041 nod = xmlDocGetRootElement(doc); 00042 if (nod == NULL) 00043 { 00044 xmlFreeDoc(doc); 00045 error("Empty document"); 00046 } 00047 00048 if (xmlStrcmp(nod->name, (const xmlChar *) "parratt")) 00049 { 00050 xmlFreeDoc(doc); 00051 error("Document of the wrong type, root node != parratt"); 00052 } 00053 /*====================================================*/ 00054 00055 /*---------------------------------- 00056 * Determine the type of parratt. 00057 */ 00058 buf = xmlGetProp(nod, (unsigned char*)"type"); 00059 if (strncmp((char *)buf,"parratt",7)==0) par->s.pntp = PARRATT; 00060 else if (strncmp((char *)buf,"polarized",7)==0) par->s.pntp = POLARIZED; 00061 else error("Unknown parratt type"); 00062 xmlFree(buf); 00063 if (par->s.pntp == PARRATT) fprintf(stdout, "Parratt: Parratt\n"); 00064 else fprintf(stdout, "Parratt: Polarized Parratt\n"); 00065 00066 /*---------------------------------- 00067 * Determine whether to do fitting. 00068 */ 00069 buf = xmlGetProp(nod, (unsigned char*)"do_fit"); 00070 if (strncmp((char *)buf,"yes",3)==0) par->s.doit = 1; 00071 else par->s.doit = 0; 00072 xmlFree(buf); 00073 if (par->s.doit) fprintf(stdout, "Parratt: Do fit: Yes\n"); 00074 else fprintf(stdout, "Parratt: Do fit: No\n"); 00075 00076 /*---------------------------------- 00077 * Run through the children of the root node 00078 * If not fitting, then skip reading the fit section 00079 */ 00080 nod = nod->xmlChildrenNode; 00081 while (nod != NULL) 00082 { 00083 if ((!xmlStrcmp(nod->name, (const xmlChar *)"output"))) 00084 { 00085 parseOutput(doc, nod, par); 00086 } 00087 if ((!xmlStrcmp(nod->name, (const xmlChar *)"model"))) 00088 { 00089 parseModel(doc, nod, par); 00090 } 00091 if ((!xmlStrcmp(nod->name, (const xmlChar *)"fit"))) 00092 { 00093 if (par->s.doit) parseFit(doc, nod, par); 00094 } 00095 nod = nod->next; 00096 } 00097 00098 xmlCleanupParser(); 00099 return; 00100 }
void parseOutput | ( | xmlDocPtr | doc, | |
xmlNodePtr | nod, | |||
Parratt * | par | |||
) |
This function parses the children of the <output> tag. It performs error checking for the successfully reading of the data.
00103 { 00104 xmlNodePtr lay; 00105 xmlChar *buf; 00106 int i; 00107 00108 lay = nod->xmlChildrenNode; 00109 while (lay != NULL) 00110 { 00111 if ((!xmlStrcmp(lay->name, (const xmlChar *)"reflectivity"))) 00112 { 00113 for (i=0; i<64; i++) par->s.refl[i]=0; 00114 buf = xmlNodeListGetString(doc, lay->xmlChildrenNode, 1); 00115 if (strlen((char *)buf) > 64) error("reflec. filename too big"); 00116 strcpy(par->s.refl, (char *)buf); 00117 fprintf(stdout, "Parratt: Reflectivity file: %s\n", par->s.refl); 00118 } 00119 if ((!xmlStrcmp(lay->name, (const xmlChar *)"profile"))) 00120 { 00121 for (i=0; i<64; i++) par->s.prof[i]=0; 00122 buf = xmlNodeListGetString(doc, lay->xmlChildrenNode, 1); 00123 if (strlen((char *)buf) > 64) error("profile filename too big"); 00124 strcpy(par->s.prof, (char *)buf); 00125 fprintf(stdout, "Parratt: Profile file: %s\n", par->s.prof); 00126 } 00127 if ((!xmlStrcmp(lay->name, (const xmlChar *)"q_max"))) 00128 { 00129 buf = xmlNodeListGetString(doc, lay->xmlChildrenNode, 1); 00130 i=sscanf((char *)buf,"%lf",&par->s.qmax); 00131 if (i!=1) error("Can't read q_max"); 00132 xmlFree(buf); 00133 } 00134 if ((!xmlStrcmp(lay->name, (const xmlChar *)"q_min"))) 00135 { 00136 buf = xmlNodeListGetString(doc, lay->xmlChildrenNode, 1); 00137 i=sscanf((char *)buf,"%lf",&par->s.qmin); 00138 if (i!=1) error("Can't read q_min"); 00139 xmlFree(buf); 00140 } 00141 if ((!xmlStrcmp(lay->name, (const xmlChar *)"num_q"))) 00142 { 00143 buf = xmlNodeListGetString(doc, lay->xmlChildrenNode, 1); 00144 i=sscanf((char *)buf,"%u",&par->s.numq); 00145 if (i!=1) error("Can't read num_q"); 00146 xmlFree(buf); 00147 } 00148 if ((!xmlStrcmp(lay->name, (const xmlChar *)"num_z"))) 00149 { 00150 buf = xmlNodeListGetString(doc, lay->xmlChildrenNode, 1); 00151 i=sscanf((char *)buf,"%u",&par->s.numz); 00152 if (i!=1) error("Can't read num_z"); 00153 xmlFree(buf); 00154 } 00155 lay = lay->next; 00156 } 00157 return; 00158 }
void parseFit | ( | xmlDocPtr | doc, | |
xmlNodePtr | nod, | |||
Parratt * | par | |||
) |
This function parses the children of the <fit> tag. It performs some error checking for the successful reading of the data.
00161 { 00162 xmlNodePtr lay; 00163 xmlChar *type = NULL; 00164 xmlChar *algo = NULL; 00165 xmlChar *buf; 00166 char i = 0, j = 0; 00167 00168 lay = nod->xmlChildrenNode; 00169 while (lay != NULL) 00170 { 00171 if ((!xmlStrcmp(lay->name, (const xmlChar *)"data"))) 00172 { 00173 if (par->s.pntp == POLARIZED) error("Please provide </data_up>"); 00174 00175 buf = xmlNodeListGetString(doc, lay->xmlChildrenNode, 1); 00176 fprintf(stdout,"Parratt: Data file: %s\n", buf); 00177 if (strlen((char *)buf) > 50) error("Name too long"); 00178 strcpy(par->d1.nam, (char *)buf); 00179 xmlFree(buf); 00180 } 00181 if ((!xmlStrcmp(lay->name, (const xmlChar *)"data_up"))) 00182 { 00183 buf = xmlNodeListGetString(doc, lay->xmlChildrenNode, 1); 00184 fprintf(stdout,"Parratt: Data UP file: %s\n", buf); 00185 if (strlen((char *)buf) > 50) error("Name too long"); 00186 strcpy(par->d1.nam, (char *)buf); 00187 xmlFree(buf); 00188 } 00189 if ((!xmlStrcmp(lay->name, (const xmlChar *)"data_down"))) 00190 { 00191 buf = xmlNodeListGetString(doc, lay->xmlChildrenNode, 1); 00192 fprintf(stdout,"Parratt: Data DOWN file: %s\n", buf); 00193 if (strlen((char *)buf) > 50) error("Name too long"); 00194 strcpy(par->d2.nam, (char *)buf); 00195 xmlFree(buf); 00196 } 00197 if ((!xmlStrcmp(lay->name, (const xmlChar *)"weight"))) 00198 { 00199 buf = xmlNodeListGetString(doc, lay->xmlChildrenNode, 1); 00200 fprintf(stdout,"Parratt: Use weighting: %s\n", buf); 00201 if (strncmp((char *)buf,"WEIGHT_NONE", 11)==0) 00202 par->d1.wgt = WEIGHT_NONE; 00203 else if (strncmp((char *)buf,"WEIGHT_R", 8)==0) 00204 par->d1.wgt = WEIGHT_R; 00205 else if (strncmp((char *)buf,"WEIGHT_SQRT", 11)==0) 00206 par->d1.wgt = WEIGHT_SQRT; 00207 else if (strncmp((char *)buf,"WEIGHT_ERR", 10)==0) 00208 par->d1.wgt = WEIGHT_ERR; 00209 else error("Unknown weighting"); 00210 xmlFree(buf); 00211 par->d2.wgt = par->d1.wgt; 00212 } 00213 if ((!xmlStrcmp(lay->name, (const xmlChar *)"type"))) 00214 { 00215 type = xmlNodeListGetString(doc, lay->xmlChildrenNode, 1); 00216 fprintf(stdout,"Parratt: Solver type: %s\n", type); 00217 i = 1; 00218 } 00219 if ((!xmlStrcmp(lay->name, (const xmlChar *)"algo"))) 00220 { 00221 algo = xmlNodeListGetString(doc, lay->xmlChildrenNode, 1); 00222 fprintf(stdout,"Parratt: Solver algorithm: %s\n", algo); 00223 j = 1; 00224 } 00225 lay = lay->next; 00226 } 00227 initMethod((char *)type, (char *)algo); 00228 if (i) xmlFree(type); 00229 if (j) xmlFree(algo); 00230 return; 00231 }
void parseModel | ( | xmlDocPtr | doc, | |
xmlNodePtr | nod, | |||
Parratt * | par | |||
) |
This function parses the children of the <model> tag. It performs error checking for the successful reading of the data.
00234 { 00235 unsigned int i; 00236 xmlNodePtr lay; 00237 xmlChar *buf; 00238 00239 lay = nod->xmlChildrenNode; 00240 while (lay != NULL) 00241 { 00242 if ((!xmlStrcmp(lay->name, (const xmlChar *)"bulk"))) 00243 { 00244 parseLayer(doc, lay, par, BULK); 00245 } 00246 if ((!xmlStrcmp(lay->name, (const xmlChar *)"layer"))) 00247 { 00248 parseLayer(doc, lay, par, LAYR); 00249 } 00250 if ((!xmlStrcmp(lay->name, (const xmlChar *)"repeat"))) 00251 { 00252 parseRepeat(doc, lay, par); 00253 } 00254 if ((!xmlStrcmp(lay->name, (const xmlChar *)"substrate"))) 00255 { 00256 parseLayer(doc, lay, par, SUBS); 00257 } 00258 if ((!xmlStrcmp(lay->name, (const xmlChar *)"backgd"))) 00259 { 00260 buf = xmlNodeListGetString(doc, lay->xmlChildrenNode, 1); 00261 i=sscanf((char *)buf,"%lf",&par->m.par[0]); 00262 if (i!=1) error("Can't read backgd"); 00263 xmlFree(buf); 00264 00265 buf = xmlGetProp(lay, (unsigned char *)"fix"); 00266 i=sscanf((char *)buf,"%u",&par->m.fix[0]); 00267 if (i!=1) error("Can't read backgd fix"); 00268 xmlFree(buf); 00269 } 00270 if ((!xmlStrcmp(lay->name, (const xmlChar *)"coverg"))) 00271 { 00272 buf = xmlNodeListGetString(doc, lay->xmlChildrenNode, 1); 00273 i=sscanf((char *)buf,"%lf",&par->m.par[1]); 00274 if (i!=1) error("Can't read coverg"); 00275 xmlFree(buf); 00276 00277 buf = xmlGetProp(lay, (unsigned char *)"fix"); 00278 i=sscanf((char *)buf,"%u",&par->m.fix[1]); 00279 if (i!=1) error("Can't read coverg fix"); 00280 xmlFree(buf); 00281 } 00282 if ((!xmlStrcmp(lay->name, (const xmlChar *)"resoln"))) 00283 { 00284 par->g.rl = SINGLE; 00285 00286 buf = xmlGetProp(lay, (unsigned char *)"type"); 00287 if (strncmp((char *)buf,"dq",3)==0) 00288 par->g.rtp = CONSTANT; 00289 else if (strncmp((char *)buf,"dq/q",3)==0) 00290 par->g.rtp = RELATIVE; 00291 else if (strncmp((char *)buf,"array-dq",9)==0) 00292 { 00293 par->g.rtp = CONSTANT; 00294 par->g.rl = ARRAY; 00295 } 00296 else if (strncmp((char *)buf,"array-dq/q",9)==0) 00297 { 00298 par->g.rtp = RELATIVE; 00299 par->g.rl = ARRAY; 00300 } 00301 else error("Can't read resolution type"); 00302 xmlFree(buf); 00303 00304 if (par->g.rl == SINGLE) 00305 { 00306 buf = xmlNodeListGetString(doc, lay->xmlChildrenNode, 1); 00307 i=sscanf((char *)buf,"%lf",&par->g.rsn); 00308 if (i!=1) error("Can't read resoln"); 00309 xmlFree(buf); 00310 } 00311 else if (par->g.rl == ARRAY) 00312 { 00313 for (i=0; i<64; i++) par->g.rnam[i]=0; 00314 buf = xmlNodeListGetString(doc, lay->xmlChildrenNode, 1); 00315 if (strlen((char *)buf) > 64) error("resolution filename too big"); 00316 strcpy(par->g.rnam, (char *)buf); 00317 fprintf(stdout, "Parratt: Resolution file: %s\n", par->g.rnam); 00318 xmlFree(buf); 00319 } 00320 else error("Resolution type not set properly"); 00321 00322 00323 } 00324 lay = lay->next; 00325 } 00326 return; 00327 }
void parseLayer | ( | xmlDocPtr | doc, | |
xmlNodePtr | lay, | |||
Parratt * | par, | |||
int | type | |||
) |
This function parses the children of the <layer> tag. It performs error checking for the successful reading of the data.
00330 { 00331 unsigned int i, idx; 00332 xmlNodePtr cur; 00333 xmlChar *buf; 00334 00335 idx = par->m.num; 00336 cur = lay->xmlChildrenNode; 00337 while (cur != NULL) 00338 { 00339 if ((!xmlStrcmp(cur->name, (const xmlChar *)"name"))) 00340 { 00341 buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); 00342 if (strlen((char *)buf) > 64) error("Name too long"); 00343 strcpy(par->l.nam[par->l.num], (char *)buf); 00344 xmlFree(buf); 00345 } 00346 if ((!xmlStrcmp(cur->name, (const xmlChar *)"thik"))) 00347 { 00348 buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); 00349 if ((!xmlStrcmp(buf, (const xmlChar *)"n/a"))) 00350 { 00351 par->m.par[idx+0] = 0.0; 00352 par->m.fix[idx+0] = 1; 00353 } 00354 else 00355 { 00356 i=sscanf((char *)buf,"%lf",&par->m.par[idx+0]); 00357 if (i!=1) error("Can't read thik"); 00358 xmlFree(buf); 00359 00360 buf = xmlGetProp(cur, (unsigned char*)"fix"); 00361 i=sscanf((char *)buf,"%u",&par->m.fix[idx+0]); 00362 if (i!=1) error("Can't read thik fix"); 00363 xmlFree(buf); 00364 } 00365 } 00366 if ((!xmlStrcmp(cur->name, (const xmlChar *)"sigz"))) 00367 { 00368 buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); 00369 if ((!xmlStrcmp(buf, (const xmlChar *)"n/a"))) 00370 { 00371 par->m.par[idx+1] = 0.0; 00372 par->m.fix[idx+1] = 1; 00373 } 00374 else 00375 { 00376 i=sscanf((char *)buf,"%lf",&par->m.par[idx+1]); 00377 if (i!=1) error("Can't read sigz"); 00378 xmlFree(buf); 00379 00380 buf = xmlGetProp(cur, (unsigned char*)"fix"); 00381 i=sscanf((char *)buf,"%u",&par->m.fix[idx+1]); 00382 if (i!=1) error("Can't read sigz fix"); 00383 xmlFree(buf); 00384 } 00385 } 00386 if ((!xmlStrcmp(cur->name, (const xmlChar *)"rsld"))) 00387 { 00388 buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); 00389 i=sscanf((char *)buf,"%lf",&par->m.par[idx+2]); 00390 if (i!=1) error("Can't read rsld"); 00391 xmlFree(buf); 00392 00393 buf = xmlGetProp(cur, (unsigned char*)"fix"); 00394 i=sscanf((char *)buf,"%u",&par->m.fix[idx+2]); 00395 if (i!=1) error("Can't read rsld fix"); 00396 xmlFree(buf); 00397 } 00398 if ((!xmlStrcmp(cur->name, (const xmlChar *)"isld"))) 00399 { 00400 buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); 00401 i=sscanf((char *)buf,"%lf",&par->m.par[idx+3]); 00402 if (i!=1) error("Can't read isld"); 00403 xmlFree(buf); 00404 00405 buf = xmlGetProp(cur, (unsigned char*)"fix"); 00406 i=sscanf((char *)buf,"%u",&par->m.fix[idx+3]); 00407 if (i!=1) error("Can't read isld fix"); 00408 xmlFree(buf); 00409 } 00410 if ((!xmlStrcmp(cur->name, (const xmlChar *)"rmag"))) 00411 { 00412 buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); 00413 i=sscanf((char *)buf,"%lf",&par->m.par[idx+4]); 00414 if (i!=1) error("Can't read rmag"); 00415 xmlFree(buf); 00416 00417 buf = xmlGetProp(cur, (unsigned char*)"fix"); 00418 i=sscanf((char *)buf,"%u",&par->m.fix[idx+4]); 00419 if (i!=1) error("Can't read rmag fix"); 00420 xmlFree(buf); 00421 } 00422 if ((!xmlStrcmp(cur->name, (const xmlChar *)"imag"))) 00423 { 00424 buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); 00425 i=sscanf((char *)buf,"%lf",&par->m.par[idx+5]); 00426 if (i!=1) error("Can't read imag"); 00427 xmlFree(buf); 00428 00429 buf = xmlGetProp(cur, (unsigned char*)"fix"); 00430 i=sscanf((char *)buf,"%u",&par->m.fix[idx+5]); 00431 if (i!=1) error("Can't read imag fix"); 00432 xmlFree(buf); 00433 } 00434 cur = cur->next; 00435 } 00436 par->l.idx[par->l.num] = par->m.num; 00437 par->l.typ[par->l.num] = type; 00438 /* 00439 * For each added layer, there are six new parameters. 00440 */ 00441 par->m.num += 6; 00442 par->l.num += 1; 00443 return; 00444 }
void parseRepeat | ( | xmlDocPtr | doc, | |
xmlNodePtr | rep, | |||
Parratt * | par | |||
) |
This function parses the children of the <repeat> tag. It performs error checking for the successful reading of the data.
00447 { 00448 xmlNodePtr curt; 00449 unsigned int rept[20]; 00450 xmlChar *buff; 00451 int nl, nr, j, i=0; 00452 00453 /*--------------- 00454 * Get the number of repeats. 00455 */ 00456 buff = xmlGetProp(rep, (unsigned char*)"num"); 00457 i=sscanf((char *)buff,"%d",&nr); 00458 if (i!=1) error("Can't read repeat num"); 00459 xmlFree(buff); 00460 00461 /*---------------- 00462 * Parse the children of the repeat tag. 00463 * Store the index in the rept array. 00464 */ 00465 nl=0; 00466 curt = rep->xmlChildrenNode; 00467 while (curt != NULL) 00468 { 00469 if ((!xmlStrcmp(curt->name, (const xmlChar *)"layer"))) 00470 { 00471 rept[nl] = par->m.num; 00472 parseLayer(doc, curt, par, REPT); 00473 nl++; 00474 } 00475 curt = curt->next; 00476 } 00477 00478 /*===================================================== 00479 * Add to the layer's index array, pointing to the correct 00480 * values of the parameters array. 00481 */ 00482 for(i=1; i<nr; i++) 00483 { 00484 for(j=0; j<nl; j++) 00485 { 00486 /* Copy the layer name for each repeating layer */ 00487 strcpy(par->l.nam[par->l.num], par->l.nam[par->l.num-nl]); 00488 00489 /* The correct index is in the rept array */ 00490 par->l.idx[par->l.num] = rept[j]; 00491 00492 /* The layer type is REPEAT */ 00493 par->l.typ[par->l.num] = REPT; 00494 00495 /* One more layer has been added */ 00496 par->l.num += 1; 00497 } 00498 } 00499 00500 return; 00501 }