pxmli.c File Reference


Detailed Description

This file parses the XML file, and if needed, loads the data. See the DTD and introduction for complete information on the XML tag structure. Parsing the XML file requires libxml2 library.


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.


Function Documentation

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 }


Generated on Wed Mar 14 13:24:56 2007 for Parratt by  doxygen 1.4.7