yanera_xml_input.c

Go to the documentation of this file.
00001 /*============================================================================
00002 Copyright 2006 Thad Harroun, Kevin Yager
00003 
00004 This file is part of "yanera 2.0".
00005 
00006 "yanera 2.0" is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
00007 
00008 "yanera 2.0" is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
00009 
00010 You should have received a copy of the GNU General Public License along with "yanera 2.0"; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 
00011 ==============================================================================*/
00012 /*============================================================================*/
00018 #define _CRT_SECURE_NO_DEPRECATE
00019 
00020 #include "yanera.h"
00021 #include "yanera_xml_input.h"
00022 #include "yanera_util.h"
00023 #include "yanera_xml_util.h"
00024 #include "yanera_reflectivity.h"
00025 #include "yanera_profile.h"
00026 /*============================================================================*/
00027 void yanera_read_xml(yanera_container *yanera) 
00028 {
00029   xmlValidCtxtPtr  xml_ctxt; 
00030   xmlDocPtr        xml_doc;
00031   xmlNodePtr       xml_node;
00032  
00033   /*====================================================
00034    *  Bunch of error checking and document validation
00035    */
00036   xmlSetStructuredErrorFunc(NULL, xmlErrorFunc);
00037    
00038   xml_doc = xmlParseFile(yanera->filename);
00039   if (xml_doc == NULL )
00040   {
00041     yanera_error("XML document not parsed successfully", \
00042      __FILE__, __LINE__, yanera);
00043   }
00044     
00045   xml_ctxt = xmlNewValidCtxt();
00046   if (xml_ctxt == NULL) 
00047   {
00048     yanera_error("Failed to allocate XML parser context", \
00049                  __FILE__, __LINE__, yanera);
00050   }
00051   if (xmlValidateDocument(xml_ctxt, xml_doc)!=1)
00052   {
00053     yanera_error("XML document not validated.", __FILE__, __LINE__, yanera);
00054   }
00055   if (xmlValidateDocumentFinal(xml_ctxt, xml_doc)!=1)
00056   {
00057      yanera_error("XML document not validated.", __FILE__, __LINE__, yanera);
00058   }
00059   xmlFreeValidCtxt(xml_ctxt);
00060   
00061   xml_node = xmlDocGetRootElement(xml_doc);
00062   if (xml_node == NULL) 
00063   {
00064     xmlFreeDoc(xml_doc);
00065     yanera_error("Empty XML document.", yanera->filename, 0, yanera);
00066   }
00067 
00068   if (xmlStrcmp(xml_node->name, (const xmlChar *) "yanera")) 
00069   {
00070     xmlFreeDoc(xml_doc);
00071     yanera_error("XML document of the wrong type: root node is not <yanera/>", \
00072                   yanera->filename, xml_node->line, yanera);
00073   }
00074   /*====================================================*/
00075 
00076   /*----------------------------------
00077    *  Run through the children of the root node.
00078    *  <miscellaneous_section/>
00079    *  <data_section/>
00080    *  <model_section/>
00081    */
00082   xml_node = xml_node->xmlChildrenNode;
00083   while (xml_node != NULL)
00084   {
00085     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"miscellaneous_section")))
00086     {
00087       parseMiscellaneousSection(xml_doc, xml_node, yanera);
00088     }
00089     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"data_section")))
00090     {
00091       parseDataSection(xml_doc, xml_node, yanera);
00092     }
00093     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"model_section")))
00094     {
00095       parseModelSection(xml_doc, xml_node, yanera);
00096     }
00097     xml_node = xml_node->next;
00098   }
00099   
00100   /*
00101    * Free memory used by libxml
00102    */
00103   xmlFreeDoc(xml_doc);
00104   xmlCleanupParser();
00105   return;
00106 }
00107 /*============================================================================*/
00108 void parseModelSection(xmlDocPtr xml_doc, xmlNodePtr xml_parent_node, \
00109                        yanera_container *yanera) 
00110 {
00111   xmlNodePtr     xml_node;
00112   xmlChar       *buf;
00113   yanera_layer  *layer;
00114   
00115   xml_node = xml_parent_node->xmlChildrenNode;
00116   while (xml_node != NULL)
00117   {
00118     /*
00119      *  Get the model_type
00120      */
00121     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"model_type")))
00122     {
00123       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00124       if      (strncmp((char *)buf,"MODEL_LAYER", 11)==0) 
00125       {
00126         yanera->type = MODEL_LAYER;
00127         yanera->parrattFunction = &calcParrattFromModel;
00128         yanera->profileFunctionReal = &layerProfileReal;
00129         yanera->profileFunctionImag = &layerProfileImag;
00130       }
00131       else if (strncmp((char *)buf,"MODEL_COMPONENT", 15)==0) 
00132       {
00133         yanera->type = MODEL_COMPONENT;
00134         yanera->parrattFunction = &calcParrattFromSlabs;
00135         yanera->profileFunctionReal = &componentProfileReal;
00136         yanera->profileFunctionImag = &componentProfileImag;
00137       }
00138       else if (strncmp((char *)buf,"MODEL_SLAB", 10)==0) 
00139       {
00140         yanera->type = MODEL_SLAB;
00141         yanera->parrattFunction = &calcParrattFromSlabs;
00142         yanera->profileFunctionReal = &layerProfileReal;
00143         yanera->profileFunctionImag = &layerProfileImag;
00144       }
00145       else if (strncmp((char *)buf,"MODEL_FUNCTION", 14)==0) 
00146       {
00147         yanera->type = MODEL_FUNCTION;
00148         yanera->parrattFunction = &calcParrattFromSlabs;
00149         yanera->profileFunctionReal = &functionProfileReal;
00150         yanera->profileFunctionImag = &functionProfileImag;
00151       }
00152       else
00153       {
00154         yanera_error("Incorrect <model_type/>", \
00155                       yanera->filename, xml_node->line, yanera);
00156       }
00157       xmlFree(buf);
00158     }
00159     /*
00160      * Get the model
00161      */
00162     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"model")))
00163     {
00164       /*
00165        *  Get the data_idref of the model
00166        */
00167       buf = xmlGetProp(xml_node, (unsigned char*)"data_idref");
00168       yanera->models_xml[yanera->number_of_models].data_idref = \
00169           (char *)calloc((strlen((const char *)buf)+1), sizeof(char));
00170       strcpy(yanera->models_xml[yanera->number_of_models].data_idref, \
00171              (char *)buf);
00172       xmlFree(buf);
00173       /*
00174        * Parse the model.
00175        */
00176       parseModel(xml_doc, xml_node, \
00177                  &yanera->models_xml[yanera->number_of_models], yanera);
00178       yanera->number_of_models += 1;
00179     }
00180     /*
00181      * Get the components, if any.
00182      */
00183     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"component")))
00184     {
00185       layer = newLayer(LAYER_COMPONENT);
00186       linkComponentIntoContainer(layer, yanera);
00187       parseLayer(xml_doc, xml_node, layer, yanera);
00188     }
00189     
00190     xml_node = xml_node->next;
00191   } 
00192   return;
00193 }
00194 /*============================================================================*/
00195 void parseModel(xmlDocPtr xml_doc, xmlNodePtr xml_node_model, \
00196                 yanera_model *model, yanera_container *yanera) 
00197 {
00198   unsigned short i1, i2;
00199   short          i3;
00200   double         d1;
00201   xmlNodePtr     xml_node;
00202   xmlChar       *buf;
00203   yanera_layer  *layer;
00204   
00205   xml_node = xml_node_model->xmlChildrenNode;
00206   while (xml_node != NULL)
00207   {
00208     /*
00209      * <name>
00210      */
00211     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"name")))
00212     {
00213       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00214       model->name = (char *)calloc((strlen((const char *)buf)+1),sizeof(char));
00215       strcpy(model->name, (char *)buf);
00216       xmlFree(buf);
00217     }
00218     /*
00219      * <polarized>
00220      */
00221     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"polarized")))
00222     {
00223       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00224       if      (strncmp((char *)buf,"POLARIZED_UP", 12)==0) 
00225         model->polarized = POLARIZED_UP;
00226       else if (strncmp((char *)buf,"POLARIZED_DOWN", 14)==0) 
00227         model->polarized = POLARIZED_DOWN;
00228       else if (strncmp((char *)buf,"POLARIZED_UNPOLARIZED", 21)==0) 
00229         model->polarized = POLARIZED_UNPOLARIZED;
00230       else 
00231       {
00232         yanera_error("Incorrect <polarized/>", \
00233                       yanera->filename, xml_node->line, yanera);
00234       }
00235       xmlFree(buf);
00236     }
00237     /*
00238      * <bulk>
00239      */
00240     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"bulk")))
00241     {
00242       layer = newLayer(LAYER_BULK);
00243       linkLayerIntoModel(layer, model);
00244       parseLayer(xml_doc, xml_node, layer, yanera);
00245     }
00246     /*
00247      * <layer>
00248      */
00249     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"layer")))
00250     {
00251       layer = newLayer(LAYER_LAYER);
00252       linkLayerIntoModel(layer, model);
00253       parseLayer(xml_doc, xml_node, layer, yanera);
00254     }
00255     /*
00256      * <repeat> and its property "number".
00257      */
00258     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"repeat")))
00259     {
00260       buf = xmlGetProp(xml_node, (unsigned char*)"number");
00261       i2=sscanf((char *)buf, "%hu", &i1);
00262       if (i2!=1) 
00263       {
00264         yanera_error("Can't read <repeat/> number property.", \
00265                      yanera->filename, xml_node->line, yanera);
00266       }
00267       xmlFree(buf);
00268       parseRepeat(xml_doc, xml_node, i1, model, yanera);
00269     }
00270     /*
00271      * <substrate>
00272      */
00273     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"substrate")))
00274     {
00275       layer = newLayer(LAYER_SUBSTRATE);
00276       linkLayerIntoModel(layer, model);
00277       parseLayer(xml_doc, xml_node, layer, yanera);
00278     }
00279     /*
00280      * <background> : The only node type parsed without need for another 
00281      * function call.
00282      */
00283      if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"background")))
00284     {
00285       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00286       i2=sscanf((char *)buf,"%lf",&d1);
00287       if (i2!=1) 
00288       {
00289         yanera_error("Can't read background", \
00290                       yanera->filename, xml_node->line, yanera);
00291       }
00292       xmlFree(buf);
00293       
00294       buf = xmlGetProp(xml_node, (unsigned char*)"fix");
00295       i3 = getYesNoBooleanFromString((char *)buf);
00296       if (i3 == ERROR)
00297       {
00298         yanera_error("Can't read background fix", \
00299                       yanera->filename, xml_node->line, yanera);
00300       }
00301       xmlFree(buf);
00302         
00303       model->background = newParameter(d1, i3, yanera); 
00304       
00305       /* ---- */
00306       parseMinMax(xml_doc,xml_node,model->background,yanera);
00307     }
00308     xml_node = xml_node->next;
00309   } 
00310 }
00311 /*============================================================================*/
00312 void parseLayer(xmlDocPtr xml_doc, xmlNodePtr xml_node_layer, \
00313                 yanera_layer *layer, yanera_container *yanera) 
00314 {
00315   short          i1, i2;
00316   double         d1;
00317   char           c1;
00318   xmlNodePtr     xml_node;
00319   xmlChar       *buf;
00320   
00321   /*---------------------------------------------------------------------------
00322    *  ID's and IDREF's are XML properties and not children of <layer/>
00323    */
00324   /*
00325    *  Get the component_id of the layer
00326    */
00327   buf = xmlGetProp(xml_node_layer, (unsigned char*)"component_id");
00328   if (buf != NULL)
00329   {
00330     layer->component_id = (char *)calloc((strlen((const char *)buf)+1), \
00331                                           sizeof(char));
00332     strcpy(layer->component_id, (char *)buf);
00333   }
00334   xmlFree(buf);
00335   /*
00336    *  Get the component_idref of the layer
00337    */
00338   buf = xmlGetProp(xml_node_layer, (unsigned char*)"component_idref");
00339   if (buf != NULL)
00340   {
00341     layer->component_idref = (char *)calloc((strlen((const char *)buf)+1), \
00342                                              sizeof(char));
00343     strcpy(layer->component_idref, (char *)buf);
00344   }
00345   xmlFree(buf);
00346   /*
00347    *  Get the layer_idref of the layer
00348    */
00349   buf = xmlGetProp(xml_node_layer, (unsigned char*)"layer_idref");
00350   if (buf != NULL)
00351   {
00352     layer->layer_idref = (char *)calloc((strlen((const char *)buf)+1), \
00353                                         sizeof(char));
00354     strcpy(layer->layer_idref, (char *)buf);
00355   }
00356   xmlFree(buf);
00357   /*
00358    *  Get the layer_id of the layer
00359    */
00360   buf = xmlGetProp(xml_node_layer, (unsigned char*)"layer_id");
00361   if (buf != NULL)
00362   {
00363     layer->layer_id = (char *)calloc((strlen((const char *)buf)+1), \
00364                                       sizeof(char));
00365     strcpy(layer->layer_id, (char *)buf);
00366   }
00367   xmlFree(buf);
00368   /*  
00369    * ----------------------------------------------------------------
00370    */
00371   xml_node = xml_node_layer->xmlChildrenNode;
00372   while (xml_node != NULL) 
00373   {
00374     /*---------------------------------------------------------------
00375      *  General layer information
00376      */
00377     /* 
00378      * Extract the layer component type. This overwrites the layer->type, 
00379      * but should it?
00380      */
00381     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"type")))
00382     {
00383       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00384       if (strncmp((char *)buf,"gaussian",8)==0) 
00385         layer->type = LAYER_GAUSSIAN;
00386       else if (strncmp((char *)buf,"box",3)==0) 
00387         layer->type = LAYER_BOX;
00388       else if (strncmp((char *)buf,"function",8)==0) 
00389         layer->type = LAYER_FUNCTION;
00390       else yanera_error("Incorrect <layer/> <type/>", \
00391                          yanera->filename, xml_node->line, yanera);
00392       xmlFree(buf);
00393     }
00394     /* 
00395      * Extract the layer name.
00396      */
00397     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"name")))
00398     {
00399       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00400       layer->name = (char *)calloc((strlen((const char *)buf)+1),sizeof(char));
00401       strcpy(layer->name, (char *)buf);
00402       xmlFree(buf);
00403     }
00404     /*---------------------------------------------------------------
00405      *  Information regarding function type layers
00406      */
00407     /* 
00408      * Extract the layer function.
00409      */
00410     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"func")))
00411     {
00412       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00413       layer->func = (char *)calloc((strlen((const char *)buf)+1),sizeof(char));
00414       strcpy(layer->func, (char *)buf);
00415       xmlFree(buf);
00416     }
00417     /*---------------------------------------------------------------
00418      *  All adjustable paramters
00419      */
00420     /* 
00421      * Extract the layer function parameters
00422      * d1 is the value
00423      * c1 is the name (eg. 'a', 'b', etc.)
00424      * i1 is the fix property
00425      */
00426     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"parm")))
00427     {
00428       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00429       i2=sscanf((char *)buf,"%lf",&d1);
00430       if (i2!=1) 
00431       {
00432         yanera_error("Can't read <parm/>", yanera->filename, xml_node->line, yanera);
00433       }
00434       xmlFree(buf);
00435       
00436       buf = xmlGetProp(xml_node, (unsigned char*)"fix");
00437       i1 = getYesNoBooleanFromString((char *)buf);
00438       if (i1 == ERROR) 
00439       {
00440         yanera_error("Can't read <parm/> fix property", \
00441                      yanera->filename, xml_node->line, yanera);
00442       }
00443       xmlFree(buf);
00444       
00445       buf = xmlGetProp(xml_node, (unsigned char*)"name");
00446       i2=sscanf((char *)buf,"%c",&c1);
00447       if (i2!=1) 
00448       {
00449         yanera_error("Can't read <parm/> name property", \
00450                       yanera->filename, xml_node->line, yanera);
00451       }
00452       xmlFree(buf);
00453       
00454       i2 = newFuncParameter(c1, d1, i1, layer, yanera);
00455       
00456       /* ---- */
00457       parseMinMax(xml_doc,xml_node,i2,yanera);
00458     }
00459     /* 
00460      * Extract the layer thickness
00461      */
00462     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"thik")))
00463     {
00464       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00465       if ((!xmlStrcmp(buf, (const xmlChar *)"n/a")))
00466       { 
00467         layer->thik = -2;
00468         xmlFree(buf);
00469       }
00470       else
00471       {
00472         i2=sscanf((char *)buf, "%lf", &d1);
00473         if (i2!=1) 
00474         {
00475           yanera_error("Can't read <thik/>", yanera->filename, xml_node->line, yanera);
00476         }
00477         xmlFree(buf);
00478       
00479         buf = xmlGetProp(xml_node, (unsigned char*)"fix");
00480         i1 = getYesNoBooleanFromString((char *)buf);
00481         if (i1 == ERROR)
00482         {
00483           yanera_error("Can't read <thik/> fix", yanera->filename, xml_node->line, yanera);
00484         }
00485         xmlFree(buf);
00486         
00487         layer->thik = newParameter(d1, i1, yanera);
00488         
00489         /* ---- */
00490         parseMinMax(xml_doc,xml_node,layer->thik,yanera);
00491       }
00492     }
00493     /* 
00494      * Extract the layer roughness
00495      */
00496     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"sigz")))
00497     {
00498       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00499       if ((!xmlStrcmp(buf, (const xmlChar *)"n/a")))
00500       { 
00501         layer->sigz = -2;
00502         xmlFree(buf);
00503       }
00504       else
00505       {
00506         i2=sscanf((char *)buf, "%lf", &d1);
00507         if (i2!=1)
00508         {
00509           yanera_error("Can't read <sigz/>", yanera->filename, xml_node->line, yanera);
00510         }
00511         xmlFree(buf);
00512       
00513         buf = xmlGetProp(xml_node, (unsigned char*)"fix");
00514         i1 = getYesNoBooleanFromString((char *)buf);
00515         if (i1 == ERROR) 
00516         {
00517           yanera_error("Can't read <sigz/> fix", yanera->filename, xml_node->line, yanera);
00518         }
00519         xmlFree(buf);
00520         
00521         layer->sigz = newParameter(d1, i1, yanera);
00522         
00523         /* ---- */
00524         parseMinMax(xml_doc,xml_node,layer->sigz,yanera);
00525       }
00526     }
00527     /* 
00528      * Extract the layer center
00529      */
00530     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"cntr")))
00531     {
00532       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00533       if ((!xmlStrcmp(buf, (const xmlChar *)"n/a")))
00534       { 
00535         layer->cntr = -2;
00536         xmlFree(buf);
00537       }
00538       else
00539       {
00540         i2=sscanf((char *)buf,"%lf",&d1);
00541         if (i2!=1)
00542         {
00543           yanera_error("Can't read <cntr/>", yanera->filename, xml_node->line, yanera);
00544         }
00545         xmlFree(buf);
00546       
00547         buf = xmlGetProp(xml_node, (unsigned char*)"fix");
00548         i1 = getYesNoBooleanFromString((char *)buf);
00549         if (i1 == ERROR)
00550         {
00551           yanera_error("Can't read <cntr/> fix", yanera->filename, xml_node->line, yanera);
00552         }
00553         xmlFree(buf);
00554         
00555         layer->cntr = newParameter(d1, i1, yanera);
00556         
00557         /* ---- */
00558         parseMinMax(xml_doc,xml_node,layer->cntr,yanera);
00559       }
00560     }
00561     /* 
00562      * Extract the layer real sld
00563      */
00564     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"rsld")))
00565     {
00566       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00567       if ((!xmlStrcmp(buf, (const xmlChar *)"n/a")))
00568       { 
00569         layer->rsld = -2;
00570         xmlFree(buf);
00571       }
00572       else
00573       {
00574         i2=sscanf((char *)buf,"%lf",&d1);
00575         if (i2!=1)
00576         {
00577           yanera_error("Can't read <rsld/>", yanera->filename, xml_node->line, yanera);
00578         }
00579         xmlFree(buf);
00580       
00581         buf = xmlGetProp(xml_node, (unsigned char*)"fix");
00582         i1 = getYesNoBooleanFromString((char *)buf);
00583         if (i1 == ERROR)
00584         {
00585           yanera_error("Can't read <rsld/> fix", yanera->filename, xml_node->line, yanera);
00586         }
00587         xmlFree(buf);
00588         
00589         layer->rsld = newParameter(d1, i1, yanera);
00590         
00591         /* ---- */
00592         parseMinMax(xml_doc,xml_node,layer->rsld,yanera);
00593       }
00594     }
00595     /* 
00596      * Extract the layer imaginary sld
00597      */
00598     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"isld")))
00599     {
00600       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00601       if ((!xmlStrcmp(buf, (const xmlChar *)"n/a")))
00602       { 
00603         layer->isld = -2;
00604         xmlFree(buf);
00605       }
00606       else
00607       {
00608         i2=sscanf((char *)buf,"%lf",&d1);
00609         if (i2!=1)
00610         {
00611           yanera_error("Can't read <isld/>", yanera->filename, xml_node->line, yanera);
00612         }
00613         xmlFree(buf);
00614       
00615         buf = xmlGetProp(xml_node, (unsigned char*)"fix");
00616         i1 = getYesNoBooleanFromString((char *)buf);
00617         if (i1 == ERROR)
00618         {
00619           yanera_error("Can't read <isld/> fix", yanera->filename, xml_node->line, yanera);
00620         }
00621         xmlFree(buf);
00622         
00623         layer->isld = newParameter(d1, i1, yanera);
00624         
00625         /* ---- */
00626         parseMinMax(xml_doc,xml_node,layer->isld,yanera);
00627       }
00628     }
00629     /* 
00630      * Extract the layer real magnetic sld
00631      */
00632     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"rmag")))
00633     {
00634       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00635       if ((!xmlStrcmp(buf, (const xmlChar *)"n/a")))
00636       { 
00637         layer->rmag = -2;
00638         xmlFree(buf);
00639       }
00640       else
00641       {
00642         i2=sscanf((char *)buf,"%lf",&d1);
00643         if (i2!=1)
00644         {
00645           yanera_error("Can't read <rmag/>", yanera->filename, xml_node->line, yanera);
00646         }
00647         xmlFree(buf);
00648       
00649         buf = xmlGetProp(xml_node, (unsigned char*)"fix");
00650         i1 = getYesNoBooleanFromString((char *)buf);
00651         if (i1 == ERROR)
00652         {
00653           yanera_error("Can't read <rmag/> fix", yanera->filename, xml_node->line, yanera);
00654         }
00655         xmlFree(buf);
00656         
00657         layer->rmag = newParameter(d1, i1, yanera);
00658         
00659         /* ---- */
00660         parseMinMax(xml_doc,xml_node,layer->rmag,yanera);
00661       }
00662     }
00663     /*---------------------------------------------------------------
00664      *  Additional information flags
00665      */
00666     /* 
00667      * Extract the layer include flag
00668      */
00669     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"include")))
00670     {
00671       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00672       if (strncmp((char *)buf, "yes", 3)==0) 
00673         layer->include_flag = YES;
00674       else if (strncmp((char *)buf, "no", 2)==0) 
00675         layer->include_flag = NO;
00676       else 
00677       {
00678         yanera_error("Incorrect <include/>", yanera->filename, xml_node->line, yanera);
00679       }
00680       xmlFree(buf);
00681     }
00682     
00683     /* Go to the next child of the layer */   
00684     xml_node = xml_node->next;
00685   }
00686 
00687   return;
00688 }
00689 /*============================================================================*/
00690 void parseRepeat(xmlDocPtr xml_doc, xmlNodePtr xml_node_parent, \
00691                  unsigned short repeat_number, \
00692                  yanera_model *model, yanera_container *yanera) 
00693 {
00694   xmlNodePtr     xml_node;
00695   yanera_layer  *layer, *layer_copy, *ptr1, *ptr2;
00696   yanera_model   temporary_model;
00697   unsigned short i1;
00698   
00699   /*
00700    * Make a temporary model for holding the group of repeating layers.
00701    */
00702   temporary_model.data_idref   = NULL;
00703   temporary_model.name         = NULL;
00704   temporary_model.background   = -1;
00705   temporary_model.polarized    = POLARIZED_NONE;
00706   temporary_model.first_layer  = NULL;
00707   temporary_model.last_layer   = NULL;
00708   temporary_model.slabs.number_of_slab_edges = 0;
00709   temporary_model.slabs.number_of_slabs      = 0;
00710 
00711   for (i1=0; i1<USHRT_MAX; i1++)
00712   {
00713     temporary_model.slabs.zpos[i1] = 0.0;
00714     temporary_model.slabs.thik[i1] = 0.0;
00715     temporary_model.slabs.rsld[i1] = 0.0;
00716   }
00717   
00718   /*
00719    * Loop through the child nodes of <repeat/>
00720    */
00721   xml_node = xml_node_parent->xmlChildrenNode;
00722   while (xml_node != NULL)
00723   {
00724     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"layer")))
00725     {
00726       /* 
00727        * Add new layers into the model, as usual.
00728        */ 
00729       layer = newLayer(LAYER_REPEAT);
00730       linkLayerIntoModel(layer, model);
00731       parseLayer(xml_doc, xml_node, layer, yanera);
00732       /*
00733        * Normally repeat_flag = 0, but now we will use it, incrementing by 
00734        * one each time the group of layers is repeated.
00735        */
00736       layer->repeat_flag = 1;
00737       /*
00738        * Also, make a copy of the layers.
00739        */
00740       layer_copy = copyLayer(layer);
00741       linkLayerIntoModel(layer_copy, &temporary_model);
00742     }
00743     xml_node = xml_node->next;
00744   }
00745   
00746   /*
00747    * Copy the repeating layers into the model the correct number of times.
00748    */
00749   for (i1 = 2; i1 <= repeat_number; i1++)
00750   {
00751     ptr1 = temporary_model.first_layer;
00752     while (ptr1 != NULL)
00753     {
00754       layer = copyLayer(ptr1);
00755       layer->repeat_flag = i1;
00756       linkLayerIntoModel(layer, model);
00757 
00758       ptr1 = ptr1->next;
00759     }
00760   }
00761   
00762   /*
00763    * Free the memory used by the repeating copy.
00764    */
00765   ptr1 = temporary_model.first_layer;
00766   while (ptr1 != NULL)
00767   {
00768     free(ptr1->name);
00769     free(ptr1->layer_id);
00770     free(ptr1->layer_idref);
00771     free(ptr1->component_id);
00772     free(ptr1->component_idref);
00773     free(ptr1->func);
00774     free(ptr1->parm_names);
00775     free(ptr1->parm_values);
00776     
00777     ptr2 = ptr1;
00778     ptr1 = ptr1->next;
00779     free(ptr2);
00780   };
00781   
00782   return;
00783 }
00784 /*============================================================================*/
00785 void parseDataSection(xmlDocPtr xml_doc, xmlNodePtr xml_node_parent, \
00786                           yanera_container *yanera) 
00787 {
00788   xmlNodePtr        xml_node;
00789   xmlChar          *buf;
00790   
00791   xml_node = xml_node_parent->xmlChildrenNode;
00792   while (xml_node != NULL)
00793   {
00794     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"data")))
00795     {
00796       /*
00797        *  Get the data_id of the data
00798        */
00799       buf = xmlGetProp(xml_node, (unsigned char*)"data_id");
00800       yanera->data[yanera->number_of_data].data_id = \
00801              (char *)calloc((strlen((const char *)buf)+1), sizeof(char));
00802       strcpy(yanera->data[yanera->number_of_data].data_id, (char *)buf);
00803       xmlFree(buf);
00804       /*
00805        * Create a new yanera_data
00806        */ 
00807       parseData(xml_doc, xml_node, &yanera->data[yanera->number_of_data]);
00808       yanera->number_of_data += 1;
00809     }
00810     
00811     xml_node = xml_node->next;
00812   } 
00813   return;
00814 }
00815 /*============================================================================*/
00816 void parseData(xmlDocPtr xml_doc, xmlNodePtr xml_node_parent, \
00817                yanera_data *data) 
00818 {
00819   xmlNodePtr   xml_node;
00820   xmlChar     *buf;
00821   
00822   xml_node = xml_node_parent->xmlChildrenNode;
00823   while (xml_node != NULL)
00824   {
00825     /*
00826      * <file_name>
00827      */
00828     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"file_name")))
00829     {
00830       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00831       data->file_name = (char *)calloc((strlen((const char *)buf)+1), \
00832                                        sizeof(char));
00833       strcpy(data->file_name, (char *)buf);
00834       xmlFree(buf);     
00835     }
00836     /*
00837      * <resolution>
00838      */
00839     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"resolution")))
00840     {
00841       parseResolution(xml_doc, xml_node, data);
00842     }
00843     
00844     xml_node = xml_node->next;
00845   }
00846   return;
00847 }
00848 /*============================================================================*/
00849 void parseResolution(xmlDocPtr xml_doc, xmlNodePtr xml_node_data, \
00850                      yanera_data *data) 
00851 {
00852   xmlNodePtr     xml_node;
00853   xmlChar       *buf;
00854   short          i1;
00855   
00856   buf = NULL;
00857   xml_node = xml_node_data->xmlChildrenNode;
00858   while (xml_node != NULL)
00859   {
00860     /*
00861      * Read the resolution type.
00862      */
00863     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"type")))
00864     {
00865       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00866       if      (strncmp((char *)buf,"RESOLUTION_NONE", 15)==0) 
00867         data->resolution.type = RESOLUTION_NONE;
00868       else if (strncmp((char *)buf,"RESOLUTION_CONSTANT", 19)==0) 
00869         data->resolution.type = RESOLUTION_CONSTANT;
00870       else if (strncmp((char *)buf,"RESOLUTION_RELATIVE", 19)==0) 
00871         data->resolution.type = RESOLUTION_RELATIVE;
00872       else if (strncmp((char *)buf,"RESOLUTION_ARRAY_CONSTANT", 25)==0) 
00873         data->resolution.type = RESOLUTION_ARRAY_CONSTANT;
00874       else if (strncmp((char *)buf,"RESOLUTION_ARRAY_RELATIVE", 25)==0) 
00875         data->resolution.type = RESOLUTION_ARRAY_RELATIVE;
00876       else 
00877       {
00878         yanera_error("Incorrect <resolution/> <type/>", \
00879                       __FILE__, __LINE__, NULL);
00880       }
00881       xmlFree(buf); buf = NULL;
00882     }
00883     /*
00884      * Read the resolution value. If present then there will be only one value.
00885      */
00886     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"value")))
00887     {
00888       if (data->resolution.n > 0) 
00889       { 
00890         yanera_error("Is resolution a single value or an array?", \
00891                      __FILE__, __LINE__, NULL);
00892       }
00893       if (xml_node->xmlChildrenNode != NULL)
00894       {
00895         data->resolution.value = (double *)malloc(sizeof(double));
00896         buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00897         i1=sscanf((const char *)buf,"%lf",&data->resolution.value[0]);
00898         if (i1!=1) 
00899         {
00900           yanera_error("Can't read <resolution/> <value/>", \
00901                        __FILE__, __LINE__, NULL);
00902         }
00903         data->resolution.n = 1;
00904       }
00905       xmlFree(buf); buf = NULL;
00906     }
00907     /*
00908      * Read the resolution array file_name.
00909      */
00910     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"file_name")))
00911     {
00912       if (xml_node->xmlChildrenNode != NULL)
00913       {
00914         buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00915         data->resolution.file_name = \
00916              (char *)calloc((strlen((const char *)buf)+1), sizeof(char));
00917         strcpy(data->resolution.file_name, (char *)buf);
00918         xmlFree(buf); buf = NULL;
00919       }
00920     } 
00921     xml_node = xml_node->next;
00922   }
00923   
00924   return; 
00925 }
00926 /*============================================================================*/
00927 void parseMiscellaneousSection(xmlDocPtr xml_doc, xmlNodePtr xml_parent_node, \
00928                                yanera_container *yanera) 
00929 {
00930   unsigned int i2;
00931   xmlNodePtr     xml_node;
00932   xmlChar       *buf;
00933   
00934   xml_node = xml_parent_node->xmlChildrenNode;
00935   while (xml_node != NULL)
00936   {
00937     /*
00938      * <write_results>
00939      */
00940     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"write_results")))
00941     {
00942       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00943       yanera->misc.write_results = getYesNoBooleanFromString((char *)buf);
00944       if (yanera->misc.write_results == ERROR)
00945       {
00946         yanera_error("Can't read <write_results/>", __FILE__, __LINE__, yanera);
00947       }
00948       xmlFree(buf);
00949     }
00950     /*
00951      * <write_profile>
00952      */
00953     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"write_profile")))
00954     {
00955       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00956       yanera->misc.write_profile = getYesNoBooleanFromString((char *)buf);
00957       if (yanera->misc.write_profile == ERROR) 
00958       {
00959         yanera_error("Can't read <write_profile/>", __FILE__, __LINE__, yanera);
00960       }
00961       xmlFree(buf);
00962     }
00963     /*
00964      * <write_reflectivity>
00965      */
00966     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"write_reflectivity")))
00967     {
00968       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00969       yanera->misc.write_reflectivity = getYesNoBooleanFromString((char *)buf);
00970       if (yanera->misc.write_reflectivity == ERROR) 
00971       {
00972         yanera_error("Can't read <write_reflectivity/>", \
00973                      __FILE__, __LINE__, yanera);
00974       }
00975       xmlFree(buf);
00976     }
00977     /*
00978      * <write_slabs>
00979      */
00980     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"write_slabs")))
00981     {
00982       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00983       yanera->misc.write_slabs = getYesNoBooleanFromString((char *)buf);
00984       if (yanera->misc.write_slabs == ERROR)
00985       {
00986         yanera_error("Can't read <write_slabs/>", __FILE__, __LINE__, yanera);
00987       }
00988       xmlFree(buf);
00989     }
00990     /*
00991      * <q_min>
00992      */
00993     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"q_min")))
00994     {
00995       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
00996       i2=sscanf((char *)buf,"%lf",&yanera->misc.q_min);
00997       if (i2!=1)
00998       {
00999         yanera_error("Can't read <q_min/>", __FILE__, __LINE__, yanera);
01000       }
01001       xmlFree(buf);
01002     }
01003     /*
01004      * <q_max>
01005      */
01006     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"q_max")))
01007     {
01008       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
01009       i2=sscanf((char *)buf,"%lf",&yanera->misc.q_max);
01010       if (i2!=1)
01011       {
01012         yanera_error("Can't read <q_max/>", __FILE__, __LINE__, yanera);
01013       }
01014       xmlFree(buf);
01015     }
01016     /*
01017      * <q_num>
01018      */
01019     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"q_num")))
01020     {
01021       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
01022       i2=sscanf((char *)buf,"%hd",&yanera->misc.q_num);
01023       if (i2!=1)
01024       {
01025         yanera_error("Can't read <q_num/>", __FILE__, __LINE__, yanera);
01026       }
01027       xmlFree(buf);
01028     }
01029     /*
01030      * <z_num>
01031      */
01032     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"z_num")))
01033     {
01034       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
01035       i2=sscanf((char *)buf,"%hd",&yanera->misc.z_num);
01036       if (i2!=1)
01037       {
01038         yanera_error("Can't read <z_num/>", __FILE__, __LINE__, yanera);
01039       }
01040       xmlFree(buf);
01041     }
01042     /*
01043      * <quadrature_error>
01044      */
01045     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"quadrature_error")))
01046     {
01047       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
01048       i2=sscanf((char *)buf,"%lf",&yanera->misc.quadrature_error);
01049       if (i2!=1)
01050       {
01051         yanera_error("Can't read <quadrature_error/>", __FILE__, __LINE__, yanera);
01052       }
01053       xmlFree(buf);
01054     }
01055     /*
01056      * <quadrature_thik>
01057      */
01058     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"quadrature_thik")))
01059     {
01060       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
01061       i2=sscanf((char *)buf,"%lf",&yanera->misc.quadrature_thik);
01062       if (i2!=1)
01063       {
01064         yanera_error("Can't read <quadrature_thik/>", __FILE__, __LINE__, yanera);
01065       }
01066       xmlFree(buf);
01067     }   
01068     /*
01069      * <fit_do>
01070      */
01071     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"fit_do")))
01072     {
01073       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
01074       yanera->misc.fit_do = getYesNoBooleanFromString((char *)buf);
01075       if (yanera->misc.fit_do == ERROR)
01076       {
01077         yanera_error("Can't read <fit_do/>", __FILE__, __LINE__, yanera);
01078       }
01079       xmlFree(buf);
01080     }
01081     /*
01082      * <fit_weighting>
01083      */
01084     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"fit_weighting")))
01085     {
01086       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
01087       if (strncmp((char *)buf,"WEIGHT_NONE",11)==0) 
01088         yanera->misc.fit_weighting = WEIGHT_NONE;
01089       else if (strncmp((char *)buf,"WEIGHT_R",8)==0) 
01090         yanera->misc.fit_weighting = WEIGHT_R;
01091       else if (strncmp((char *)buf,"WEIGHT_SQRT",11)==0) 
01092         yanera->misc.fit_weighting = WEIGHT_SQRT;
01093       else if (strncmp((char *)buf,"WEIGHT_DATA",11)==0) 
01094         yanera->misc.fit_weighting = WEIGHT_DATA;
01095       else 
01096       {
01097         yanera_error("Can't read <fit_weighting/>", __FILE__, __LINE__, yanera);
01098       }
01099       xmlFree(buf);
01100     }
01101     /*
01102      * <fit_iterations>
01103      */
01104     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"fit_iterations")))
01105     {
01106       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
01107       i2=sscanf((char *)buf,"%hd",&yanera->misc.fit_iterations);
01108       if (i2!=1)
01109       {
01110         yanera_error("Can't read <fit_iterations/>", \
01111                      __FILE__, __LINE__, yanera);
01112       }
01113       xmlFree(buf);
01114     }
01115     /*
01116      * <fit_write_iterations>
01117      */
01118     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"fit_write_iterations")))
01119     {
01120       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
01121       i2=sscanf((char *)buf,"%hd",&yanera->misc.fit_write_iterations);
01122       if (i2!=1)
01123       {
01124         yanera_error("Can't read <fit_write_iterations/>", \
01125                      __FILE__, __LINE__, yanera);
01126       }
01127       xmlFree(buf);
01128     }
01129     /*
01130      * <fit_method>
01131      */
01132     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"fit_method")))
01133     {
01134       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
01135       if      (strncmp((char *)buf,"CONJUGATE_FR",12)==0) 
01136       {  
01137         yanera->misc.fit_method = CONJUGATE_FR;
01138         yanera->misc.fit_method_mdmin = gsl_multimin_fdfminimizer_conjugate_fr;
01139       }
01140       else if (strncmp((char *)buf,"CONJUGATE_PR",12)==0)
01141       {
01142         yanera->misc.fit_method = CONJUGATE_PR;
01143         yanera->misc.fit_method_mdmin = gsl_multimin_fdfminimizer_conjugate_pr;
01144       }
01145       else if (strncmp((char *)buf,"VECTOR_BFGS",11)==0)
01146       {
01147         yanera->misc.fit_method = VECTOR_BFGS;
01148         yanera->misc.fit_method_mdmin = gsl_multimin_fdfminimizer_vector_bfgs;
01149       }
01150       else if (strncmp((char *)buf,"STEEP_DESC",10)==0)
01151       {
01152         yanera->misc.fit_method = STEEP_DESC;
01153         yanera->misc.fit_method_mdmin = \
01154                                     gsl_multimin_fdfminimizer_steepest_descent;
01155       }
01156       else if (strncmp((char *)buf,"NMSIMPLEX",10)==0)
01157       {
01158         yanera->misc.fit_method = NMSIMPLEX;
01159         yanera->misc.fit_method_mdmin_simplex = \
01160                                     gsl_multimin_fminimizer_nmsimplex;
01161       }
01162       else if (strncmp((char *)buf,"SIMAN",5)==0)
01163       {
01164         yanera->misc.fit_method = SIMAN;
01165       }
01166       else if (strncmp((char *)buf,"LMSDR",5)==0)
01167       {
01168         yanera->misc.fit_method = LMSDR;
01169         yanera->misc.fit_method_lstsq = gsl_multifit_fdfsolver_lmsder;
01170       }
01171       else if (strncmp((char *)buf,"LMDR",4)==0)
01172       {
01173         yanera->misc.fit_method = LMDR;
01174         yanera->misc.fit_method_lstsq = gsl_multifit_fdfsolver_lmder;
01175       }
01176 #ifdef HAVE_OOL
01177       else if (strncmp((char *)buf,"OOL_SPG",7)==0)
01178       {  
01179         yanera->misc.fit_method = OOL_SPG;
01180         yanera->misc.fit_method_ool = ool_conmin_minimizer_spg;
01181       }
01182       else if (strncmp((char *)buf,"OOL_GENCAN",10)==0)
01183       {
01184         yanera->misc.fit_method = OOL_GENCAN;
01185         yanera->misc.fit_method_ool = ool_conmin_minimizer_gencan;
01186       }
01187 #endif
01188       else if (strncmp((char *)buf,"CLMSDR",17)==0)
01189       {
01190         yanera->misc.fit_method = CLMSDR;
01191         yanera->misc.fit_method_lstsq = gsl_multifit_fdfsolver_lmsder;
01192       }
01193       else if (strncmp((char *)buf,"CLMDR",16)==0)
01194       {
01195         yanera->misc.fit_method = CLMDR;
01196         yanera->misc.fit_method_lstsq = gsl_multifit_fdfsolver_lmder;
01197       }
01198 #ifdef HAVE_LEVMAR
01199       else if (strncmp((char *)buf,"LEVMAR",6)==0)
01200       {
01201         yanera->misc.fit_method = LEVMAR;
01202       }
01203 #endif
01204       else
01205       {
01206         yanera_error("Can't read <fit_method/>", __FILE__, __LINE__, yanera);
01207       }
01208       xmlFree(buf);
01209     }
01210     xml_node = xml_node->next;
01211   } 
01212   return;
01213 }
01214 /*============================================================================*/
01215 void parseMinMax(xmlDocPtr xml_doc, xmlNodePtr xml_node_parent, \
01216                  unsigned short parm_index, yanera_container *yanera)
01217 {  
01218   unsigned int   i2;
01219   xmlNodePtr     xml_node;
01220   xmlChar       *buf;
01221   
01222 
01223   xml_node = xml_node_parent->xmlChildrenNode;
01224   while (xml_node != NULL)
01225   {
01226     /*
01227      * <max>
01228      */
01229     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"max")))
01230     {
01231       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
01232       i2=sscanf((char *)buf,"%lf",&yanera->parameters.max[parm_index]);
01233       if (i2!=1)
01234       {
01235         yanera_error("Can't read <max/>", __FILE__, __LINE__, yanera);
01236       }
01237       xmlFree(buf);
01238       if (yanera->parameters.con[parm_index] == CONSTRAIN_MIN)
01239       {
01240         yanera->parameters.con[parm_index] = CONSTRAIN_BOTH;
01241       }
01242       else
01243       {
01244         yanera->parameters.con[parm_index] = CONSTRAIN_MAX;
01245       }
01246     }
01247     /*
01248      * <min>
01249      */
01250     if ((!xmlStrcmp(xml_node->name, (const xmlChar *)"min")))
01251     {
01252       buf = xmlNodeListGetString(xml_doc, xml_node->xmlChildrenNode, 1);
01253       i2=sscanf((char *)buf,"%lf",&yanera->parameters.min[parm_index]);
01254       if (i2!=1)
01255       {
01256         yanera_error("Can't read <min/>", __FILE__, __LINE__, yanera);
01257       }
01258       xmlFree(buf);
01259       if (yanera->parameters.con[parm_index] == CONSTRAIN_MAX)
01260       {
01261         yanera->parameters.con[parm_index] = CONSTRAIN_BOTH;
01262       }
01263       else
01264       {
01265         yanera->parameters.con[parm_index] = CONSTRAIN_MIN;
01266       }
01267     }
01268     xml_node = xml_node->next;
01269   } 
01270   return;
01271 }

Generated on Thu May 29 10:56:33 2008 by  doxygen 1.5.5