Eötvös Quantum Utilities  v5.0.144
Providing the Horsepowers in the Quantum Realm
read_SiestaXML.cpp
Go to the documentation of this file.
1 
19 #include "mex.h"
20 #include <unistd.h>
21 #include <string.h>
22 #include "EQuUs_MATLAB.h"
23 
24 #ifndef MAX_PROP_LENGTH
25 #define MAX_PROP_LENGTH 100
26 #endif
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 
33 #ifdef __INTEL_COMPILER
34 void fox_sax_equus_mp_read_xml_( char* fnamget_eq_structurese, long *fname_len, char** property_names, int* numodProperties );
35 void fox_sax_equus_mp_get_eq_structure_( EQstruct* eq_struct , int* idx);
36 void fox_sax_equus_mp_deallocatetargetnodes_();
37 int fox_sax_equus_mp_numtargetnodes_;
38 #else
39 void __fox_sax_equus_MOD_read_xml( char* fnamget_eq_structurese, long *fname_len, char** property_names, int* numodProperties );
40 void __fox_sax_equus_MOD_get_eq_structure( EQstruct* eq_struct , int* idx);
43 #endif
44 
45 #ifdef __cplusplus
46  }
47 #endif
48 
53 void XMLnode2MatlabStruct( EQstruct* eq_struct, mxArray* Mstruct );
54 
55 
62 void mexFunction(int nlhs, mxArray *plhs[],
63  int nrhs, const mxArray *prhs[])
64 {
65  /* input filename */
66  char *filename;
67  /* length of the filename */
68  long buflen;
69  /* field names of the output structure */
70  char **fieldnames;
71  /* names of the properties to be retrived from the XML */
72  char** property_names;
73  /* number of the properties to be retrived from the XML */
74  int numofProperties;
75  /* NUmber of obtained target XML nodes */
76  int numTargetNodes;
77 
78 /*-----------------------------------------------------------------------*/
79 /* Check for proper number of arguments. */
80 
81  if(nrhs != 2) {
82  mexErrMsgIdAndTxt ("siesta_EQuUs:read_SiestaXML:nInput", "Two inputs required.");
83  }
84  else if (nlhs > 1) {
85  mexErrMsgIdAndTxt ("siesta_EQuUs:read_SiestaXML:nOutput", "Too many output arguments.");
86  }
87 
88  /* Validate inputs */
89 
90  /* Check that the first input is a string.*/
91  if ((mxIsChar(prhs[0]) != 1)) {
92  mexErrMsgIdAndTxt ("siesta_EQuUs:read_SiestaXML:NonString", "First input must be a string.");
93  }
94 
95 
96  /* copy the string data from prhs[0] into a C string. */
97  filename = mxArrayToString(prhs[0]);
98 #ifdef DEBUG
99  mexPrintf( "%s\n", filename );
100 #endif
101 
102  if (access(filename, F_OK) == -1) {
103  mexErrMsgIdAndTxt ("siesta_EQuUs:read_SiestaXML:FileNotExist", "The given file %s does not exist.", filename);
104  }
105 
106 
107 
108  /* Check that the second input is a cell of strings.*/
109  int idx;
110  mxArray* cell;
111  if ((mxIsCell(prhs[1]) != 1)) {
112  mexErrMsgIdAndTxt ("siesta_EQuUs:read_SiestaXML:NonCell", "Second input must be a cell.");
113  }
114  if ( (mxGetN(prhs[1]) >1) && (mxGetM(prhs[1]) >1) ) {
115  mexErrMsgIdAndTxt ("siesta_EQuUs:read_SiestaXML:NonVector", "Second input must be a cell vector.");
116  }
117  numofProperties = mxGetN(prhs[1]) * mxGetM(prhs[1]);
118  property_names = (char**)malloc( numofProperties*sizeof(char*) );
119  for ( idx = 0; idx<numofProperties; idx++ ) {
120  cell = mxGetCell( prhs[1], idx);
121  if ( mxGetN(cell)*mxGetM(cell)+1 > MAX_PROP_LENGTH ) {
122  mexErrMsgIdAndTxt ("siesta_EQuUs:read_SiestaXML:MAX_PROP_LENGTH", "Increase the maximal length of the proeprty names.");
123  }
124  if (!mxIsChar(cell)) {
125  mexErrMsgIdAndTxt ("siesta_EQuUs:read_SiestaXML:NonString", "Second input must contain of strings.");
126  }
127  property_names[idx] = (char*)malloc( MAX_PROP_LENGTH*sizeof(char) );
128  buflen = (mxGetM(cell) * mxGetN(cell)) + 1;
129  mxGetString(cell, property_names[idx], MAX_PROP_LENGTH);
131  }
132 
133 
134 
135  /* get the length of the input file */
136  buflen = (mxGetM(prhs[0]) * mxGetN(prhs[0])) + 1;
137 
138  /* Call the fortran routines to parse the XML file */
139 #ifdef __INTEL_COMPILER
140  fox_sax_equus_mp_read_xml_( filename, &buflen, property_names, &numofProperties);
141  numTargetNodes = fox_sax_equus_mp_numtargetnodes_;
142 #else
143  __fox_sax_equus_MOD_read_hsx( filename, &buflen, eq_structs);
144  numTargetNodes = __fox_sax_equus_MOD_numtargetnodes;
145 #endif
146 
147 
148 #ifdef DEBUG
149  mexPrintf( "Number of obtained target nodes: %d\n", numTargetNodes);
150 #endif
151 
152 
153  /* creating en empty structure for MATLAB */
154  plhs[0] = mxCreateStructMatrix(1, 1, 0, NULL);
155 
156 
157  /* retriving the obtained XML nodes */
158  EQstruct eq_struct;
159  for( idx=1; idx<=numTargetNodes; idx++ ) {
160 
161 #ifdef __INTEL_COMPILER
162  fox_sax_equus_mp_get_eq_structure_( &eq_struct, &idx );
163 #else
164  __fox_sax_equus_MOD_get_eq_structure( eq_struct, &idx );
165 #endif
166 
167  /* regularize the obtained structure */
168  regularizeEQstruct( &eq_struct );
169 //continue;
170  /* adding XML node to the output structure */
171  XMLnode2MatlabStruct( &eq_struct, plhs[0] );
172 
173 
174  }
175 
176 #ifdef DEBUG
177  mexPrintf( "\nDeallocating Target nodes\n*********************************\n" );
178 #endif
179 
180 #ifdef __INTEL_COMPILER
181  fox_sax_equus_mp_deallocatetargetnodes_();
182 #else
184 #endif
185 
186 }
187 
188 
193 void XMLnode2MatlabStruct( EQstruct* eq_struct, mxArray* Mstruct ) {
194 
195 
196  int idx;
197  EQelement* field;
198  mxArray* struct_tmp;
199  char** localname = NULL;
200 
201  if (mxIsStruct( Mstruct ) == 0) {
202  mexErrMsgIdAndTxt ("read_SiestaXML:XMLnode2MatlabStruct:NotStructure", "The given mxArray is not a structure.");
203  }
204 
205  struct_tmp = mxCreateStructMatrix(1, 1, 0, NULL);
206 
207  for( idx=0; idx<=eq_struct->numfields-1; idx++ ) {
208  field = &eq_struct->fields[idx];
209  if (( strcmp(field->elementname, "localname") == 0) && localname==NULL) {
210  localname = (char**)field->value;
211  }
212  else if ( strcmp(field->elementname, "subnodes") == 0) {
213  EQstruct* subnodes = (EQstruct*)field->value;
214  EQstruct* subnode;
215  mxArray* Msubnode = mxCreateStructMatrix(1, 1, 0, NULL);
216 #ifdef DEBUG
217  mexPrintf("number of subnodes: %d\n", subnodes->numfields );
218 #endif
219  int jdx;
220  for( jdx=0; jdx<subnodes->numfields; jdx++ ) {
221  subnode = (EQstruct*) subnodes->fields[jdx].value;
222  XMLnode2MatlabStruct( subnode, Msubnode );
223  }
224  setField( Msubnode, field->elementname, struct_tmp );
225  }
226  else {
227  setField( field, struct_tmp );
228  }
229  }
230 
231 
232  if ( localname == NULL ) {
233  localname = (char**)mxMalloc( sizeof(char*) );
234  strcpy( localname[0], "Unknown");
235  }
236 
237  setField( struct_tmp, localname[0], Mstruct );
238 
239  return;
240 }
241 
242 
243 
244 
245 
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Gateway routine to read in the hsx structure generated by the SIESTA package (see http://www....
void __fox_sax_equus_MOD_read_xml(char *fnamget_eq_structurese, long *fname_len, char **property_names, int *numodProperties)
void __fox_sax_equus_MOD_get_eq_structure(EQstruct *eq_struct, int *idx)
int numfields
Definition: EQuUs_MATLAB.h:17
void __fox_sax_equus_MOD_deallocatetargetnodes()
void * value
Definition: EQuUs_MATLAB.h:9
#define MAX_PROP_LENGTH
====================================================================== Gateway routine to read in the...
void convert2FortranString(char *cstring, int strlength)
Converts a C string into fortran compatible character array.
void regularizeEQstruct(EQstruct *eq_struct)
Sort out invalid EQelements from an EQstruct structure prototype.
void setField(EQelement *eq_field, mxArray *Mstruct)
Set a field in a MATLAB structure.
void XMLnode2MatlabStruct(EQstruct *eq_struct, mxArray *Mstruct)
Routine to turn nested EQstruct structure prototypes into MATLAB structure.
int __fox_sax_equus_MOD_numtargetnodes
EQelement * fields
Definition: EQuUs_MATLAB.h:16
char * elementname
Definition: EQuUs_MATLAB.h:11
character(len=max_prop_length, kind=c_char), dimension(:), pointer property_names