atomes 1.3.2
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
read_sml.c
Go to the documentation of this file.
1/* This file is part of the 'atomes' software
2
3'atomes' is free software: you can redistribute it and/or modify it under the terms
4of the GNU Affero General Public License as published by the Free Software Foundation,
5either version 3 of the License, or (at your option) any later version.
6
7'atomes' is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
8without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9See the GNU General Public License for more details.
10
11You should have received a copy of the GNU Affero General Public License along with 'atomes'.
12If not, see <https://www.gnu.org/licenses/>
13
14Copyright (C) 2022-2026 by CNRS and University of Strasbourg */
15
21
22/*
23* This file: 'save_sml.c'
24*
25* Contains:
26*
27
28 - The functions to save atomic coordinates in SML format
29 SML "Simple Chemical Library - XML" is file format of atomes library
30
31*
32* List of functions:
33
34 int save_sml_chemistry (xmlTextWriterPtr writer, project * this_proj);
35 int save_sml_coordinates (xmlTextWriterPtr writer, project * this_proj);
36 int sml_writer (project * this_proj);
37 int write_sml (project * this_proj);
38 int open_sml_file_out_of_library ();
39
40*/
41
42#include "global.h"
43#include "callbacks.h"
44#include "interface.h"
45#include "project.h"
46#include "bind.h"
47#include "readers.h"
48
49#include <libxml/encoding.h>
50#include <libxml/xmlwriter.h>
51#include <libxml/xmlreader.h>
52#include <libxml/parser.h>
53
54extern int clean_xml_data (xmlDoc * doc, xmlTextReaderPtr reader);
55extern xmlNodePtr findnode (xmlNodePtr startnode, char * nname);
56extern double get_z_from_periodic_table (gchar * lab);
57
66int save_sml_chemistry (xmlTextWriterPtr writer, project * this_proj)
67{
68 int rc;
69 rc = xmlTextWriterStartElement(writer, BAD_CAST (const xmlChar *)"chemistry");
70 if (rc < 0) return 1;
71 rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST (const xmlChar *)"atoms", "%d", this_proj -> natomes);
72 if (rc < 0) return 1;
73 rc = xmlTextWriterStartElement(writer, BAD_CAST (const xmlChar *)"species");
74 if (rc < 0) return 1;
75 gchar * val;
76 val = g_strdup_printf("%d", this_proj -> nspec);
77 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST (const xmlChar *)"number", BAD_CAST val);
78 g_free (val);
79 if (rc < 0) return 1;
80 int i;
81 for ( i=0 ; i<this_proj -> nspec ; i++ )
82 {
83 rc = xmlTextWriterStartElement(writer, BAD_CAST (const xmlChar *)"label");
84 if (rc < 0) return 1;
85 val = g_strdup_printf("%d", i);
86 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST (const xmlChar *)"id", BAD_CAST val);
87 g_free (val);
88 if (rc < 0) return 1;
89
90 val = g_strdup_printf("%d", this_proj -> chemistry -> nsps[i]);
91 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST (const xmlChar *)"num", BAD_CAST val);
92 g_free (val);
93 if (rc < 0) return 1;
94
95 rc = xmlTextWriterWriteFormatString (writer, "%s", exact_name(this_proj -> chemistry -> label[i]));
96 if (rc < 0) return 1;
97 rc = xmlTextWriterEndElement(writer);
98 if (rc < 0) return 1;
99 }
100 rc = xmlTextWriterEndElement(writer);
101 if (rc < 0) return 1;
102 rc = xmlTextWriterEndElement(writer);
103 if (rc < 0) return 1;
104
105 return 0;
106}
107
116int save_sml_coordinates (xmlTextWriterPtr writer, project * this_proj)
117{
118 int rc;
119 rc = xmlTextWriterStartElement(writer, BAD_CAST (const xmlChar *)"coordinates");
120 if (rc < 0) return 1;
121 int i;
122 gchar * val;
123 for ( i=0 ; i<this_proj -> natomes ; i++ )
124 {
125 rc = xmlTextWriterStartElement(writer, BAD_CAST (const xmlChar *)"atom");
126 if (rc < 0) return 1;
127 val = g_strdup_printf("%d", i+1);
128 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST (const xmlChar *)"id", BAD_CAST val);
129 g_free (val);
130 if (rc < 0) return 1;
131
132 val = g_strdup_printf("%d", this_proj -> atoms[0][i].sp);
133 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST (const xmlChar *)"sp", BAD_CAST val);
134 g_free (val);
135 if (rc < 0) return 1;
136
137 val = g_strdup_printf("%f", this_proj -> atoms[0][i].x);
138 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST (const xmlChar *)"x", BAD_CAST val);
139 g_free (val);
140 if (rc < 0) return 1;
141 val = g_strdup_printf("%f", this_proj -> atoms[0][i].y);
142 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST (const xmlChar *)"y", BAD_CAST val);
143 g_free (val);
144 if (rc < 0) return 1;
145 val = g_strdup_printf("%f", this_proj -> atoms[0][i].z);
146 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST (const xmlChar *)"z", BAD_CAST val);
147 g_free (val);
148 if (rc < 0) return 1;
149 rc = xmlTextWriterEndElement(writer);
150 if (rc < 0) return 1;
151 }
152 rc = xmlTextWriterEndElement(writer);
153 if (rc < 0) return 1;
154
155 return 0;
156}
157
165int sml_writer (project * this_proj)
166{
167 int rc;
168 xmlTextWriterPtr writer;
169 /* Create a new XmlWriter with no compression. */
170 writer = xmlNewTextWriterFilename(this_proj -> coordfile, 0);
171 if (writer == NULL) return 1;
172 rc = xmlTextWriterSetIndent(writer, 1);
173 if (rc < 0) return 1;
174
175 /* Start the document with the xml default for the version,
176 * encoding MY_ENCODING and the default for the standalone
177 * declaration. */
178 rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL);
179 if (rc < 0) return 1;
180
181 rc = xmlTextWriterWriteComment(writer, (const xmlChar *)_(" Simple chemical library XML file "));
182 if (rc < 0) return 1;
183 rc = xmlTextWriterStartElement(writer, BAD_CAST "scl-xml");
184 if (rc < 0) return 1;
185
186 // class : corresponding family of molecule in the atomes software library
187 // Setting-up "Misc" as default
188 rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST (const xmlChar *)"class", "%s", "Misc");
189 if (rc < 0) return 1;
190
191 // Starting "names" section
192 rc = xmlTextWriterStartElement(writer, BAD_CAST (const xmlChar *)"names");
193 if (rc < 0) return 1;
194
195 // Library name = name displayed in atomes library, ask for it ?
196 rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST (const xmlChar *)"library-name", "%s", "Name in atomes library");
197 if (rc < 0) return 1;
198
199 // Ask for IUPAC name ?
200 rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST (const xmlChar *)"iupac-name", "%s", "IUPAC name");
201 if (rc < 0) return 1;
202
203 // Ask for other name(s) ?
204 // rc = xmlTextWriterStartElement(writer, BAD_CAST (const xmlChar *)"other-names");
205 // if (rc < 0) return 1;
206 // rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST (const xmlChar *)"name", "%s", "If any other name here !");
207 // if (rc < 0) return 1;
208 // rc = xmlTextWriterEndElement(writer);
209 // if (rc < 0) return 1;
210
211 // End "names" section
212 rc = xmlTextWriterEndElement(writer);
213 if (rc < 0) return 1;
214
215 // Ask for information ?
216 // xmlTextWriterWriteFormatElement(writer, BAD_CAST (const xmlChar *)"information", "%s", "Information");
217 // if (rc < 0) return 1;
218
219 if (save_sml_chemistry (writer, this_proj) < 0) return 1;
220
221 if (save_sml_coordinates (writer, this_proj) < 0) return 1;
222
223 // Closing "</scl-xml>"
224 rc = xmlTextWriterEndElement(writer);
225 if (rc < 0) return 1;
226
227 rc = xmlTextWriterEndDocument(writer);
228 if (rc < 0) return 1;
229
230 xmlFreeTextWriter(writer);
231 return 0;
232}
233
241int write_sml (project * this_proj)
242{
243 /* first, the file version */
244 int res = sml_writer (this_proj);
245 /*
246 * Cleanup function for the XML library.
247 */
248 xmlCleanupParser();
249 /*
250 * this is to debug memory for regression tests
251 */
252 xmlMemoryDump();
253 return res;
254}
255
256//
263{
264 xmlDoc * doc;
265 xmlTextReaderPtr reader;
266 const xmlChar sml[8]="scl-xml";
267 xmlNodePtr racine, chem_node;
268 xmlNodePtr at_node, sp_node, coord_node;
269 xmlNodePtr spec_node, lab_node, lot_node;
270 xmlAttrPtr xspec;
271 xmlChar * content;
272 int i;
273 gchar * val;
274 /*
275 * build an xmlReader for that file
276 */
277 reader = xmlReaderForFile (active_project -> coordfile, NULL, 0);
278 if (reader == NULL)
279 {
280 return 0;
281 }
282 else
283 {
284 doc = xmlParseFile (active_project -> coordfile);
285 if (doc == NULL) return 0;
286 racine = xmlDocGetRootElement(doc);
287 if (g_strcmp0 ((char *)(racine -> name), (char *)sml) != 0)
288 {
289 return clean_xml_data (doc, reader);
290 }
291
292 chem_node = findnode(racine -> children, "chemistry");
293 if (chem_node == NULL) return clean_xml_data (doc, reader);
294 at_node = findnode (chem_node -> children, "atoms");
295 if (at_node == NULL) return clean_xml_data (doc, reader);
296 content = xmlNodeGetContent(at_node);
297 this_reader -> natomes = (int)string_to_double ((gpointer)content);
298 xmlFree (content);
299 this_reader -> steps = 1; // Always single configuration in SML file
300
301 sp_node = findnode (chem_node -> children, "species");
302 if (sp_node == NULL) return clean_xml_data (doc, reader);
303 spec_node = sp_node -> properties -> children;
304 if (spec_node == NULL) return clean_xml_data (doc, reader);
305 content = xmlNodeGetContent(spec_node);
306 this_reader -> nspec = (int)string_to_double ((gpointer)content);
307 xmlFree (content);
308 if (this_reader -> natomes < 1 || this_reader -> nspec < 1) return clean_xml_data (doc, reader);
309 lab_node = sp_node -> children;
310 if (lab_node == NULL) return clean_xml_data (doc, reader);
311
312 this_reader -> z = allocdouble (this_reader -> nspec);
313 this_reader -> nsps = allocint (this_reader -> nspec);
314 for (i=0; i<this_reader -> nspec; i++)
315 {
316 lab_node = findnode (lab_node, "label");
317 if (lab_node == NULL) return clean_xml_data (doc, reader);
318 content = xmlNodeGetContent(lab_node);
319 val = g_strdup_printf ("%s", content);
320 xmlFree (content);
322 g_free (val);
323
324 xspec = lab_node -> properties;
325 if (xspec == NULL) return clean_xml_data (doc, reader);
326 while (xspec)
327 {
328 lot_node = xspec -> children;
329 if (lot_node == NULL) return clean_xml_data (doc, reader);
330 if (g_strcmp0 ("num",(char *)xspec -> name) == 0)
331 {
332 content = xmlNodeGetContent(lot_node);
333 this_reader -> nsps[i] = (int)string_to_double ((gpointer)content);
334 xmlFree (content);
335 }
336 xspec = xspec -> next;
337 }
338 lab_node = lab_node -> next;
339 }
340
341 active_project -> steps = this_reader -> steps;
342 active_project -> natomes = this_reader -> natomes;
344
345 at_node = findnode (racine -> children, "coordinates");
346 if (at_node == NULL) return clean_xml_data (doc, reader);
347 coord_node = at_node -> children;
348 if (coord_node == NULL) return clean_xml_data (doc, reader);
349 for (i=0; i<this_reader -> natomes; i++)
350 {
351 coord_node = findnode (coord_node, "atom");
352 if (coord_node == NULL) return clean_xml_data (doc, reader);
353 xspec = coord_node -> properties;
354 if (xspec == NULL) return clean_xml_data (doc, reader);
355 while (xspec)
356 {
357 lot_node = xspec -> children;
358 if (lot_node == NULL) return clean_xml_data (doc, reader);
359 content = xmlNodeGetContent(lot_node);
360 if (g_strcmp0 ("x",(char *)xspec -> name) == 0)
361 {
362 active_project -> atoms[0][i].x = string_to_double ((gpointer)content);
363 }
364 else if (g_strcmp0 ("y",(char *)xspec -> name) == 0)
365 {
366 active_project -> atoms[0][i].y = string_to_double ((gpointer)content);
367 }
368 else if (g_strcmp0 ("z",(char *)xspec -> name) == 0)
369 {
370 active_project -> atoms[0][i].z = string_to_double ((gpointer)content);
371 }
372 else if (g_strcmp0 ("sp",(char *)xspec -> name) == 0)
373 {
374 active_project -> atoms[0][i].sp = (int)string_to_double ((gpointer)content);
375 active_project -> atoms[0][i].show[0] = TRUE;
376 }
377 xmlFree (content);
378 xspec = xspec -> next;
379 }
380 coord_node = coord_node -> next;
381 }
382 xmlFreeDoc(doc);
383 xmlFreeTextReader(reader);
384 xmlCleanupParser();
385 return 1;
386 }
387}
Binding to the Fortran90 subroutines.
Callback declarations for main window.
void allocatoms(project *this_proj)
allocate project data
Definition open_p.c:177
integer(kind=c_int) function chemistry()
Definition chemistry.F90:22
int atoms[NUM_STYLES][2]
float val
Definition dlp_init.c:117
double * allocdouble(int val)
allocate a double * pointer
Definition global.c:447
int * allocint(int val)
allocate an int * pointer
Definition global.c:302
double string_to_double(gpointer string)
convert string to double
Definition global.c:612
Global variable declarations Global convenience function declarations Global data structure defin...
#define MY_ENCODING
Definition global.h:104
project * active_project
Definition project.c:47
gchar * exact_name(gchar *name)
short cut to print string without spaces
Definition interface.c:434
Messaging function declarations.
double z
Definition ogl_draw.c:63
double y
Definition ogl_draw.c:63
double x
Definition ogl_draw.c:63
Function declarations for reading atomes project file Function declarations for saving atomes proje...
coord_file * this_reader
Definition read_coord.c:74
int open_sml_file_out_of_library()
read 'Simple chemical library XML' file outside of atomes library
Definition read_sml.c:262
xmlNodePtr findnode(xmlNodePtr startnode, char *nname)
find XML node
int save_sml_coordinates(xmlTextWriterPtr writer, project *this_proj)
write content of SML file
Definition read_sml.c:116
double get_z_from_periodic_table(gchar *lab)
get Z from atom label
Definition w_library.c:308
int save_sml_chemistry(xmlTextWriterPtr writer, project *this_proj)
write content of SML file
Definition read_sml.c:66
int clean_xml_data(xmlDoc *doc, xmlTextReaderPtr reader)
free XML data
Definition w_library.c:326
int sml_writer(project *this_proj)
write content of SML file
Definition read_sml.c:165
int write_sml(project *this_proj)
write SML file
Definition read_sml.c:241
Functions declaration to read atomic coordinates.
GtkWidget * res[2]
Definition w_encode.c:342
GtkWidget * lab
Definition workspace.c:73