atomes 1.1.16
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
read_cif.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-2024 by CNRS and University of Strasbourg */
15
22/*
23* This file: 'read_cif.c'
24*
25* Contains:
26*
27
28 - The functions to read CIF files
29
30*
31* List of functions:
32
33 int get_atom_wyckoff (gchar * line, int wid);
34 int cif_get_value (gchar * kroot, gchar * keyw, int linec, int lstart, gchar ** cif_word, gboolean rec_val, gboolean all_ligne, gboolean in_loop);
35 int cif_file_get_data_in_loop (int linec, int lid);
36 int cif_file_get_number_of_atoms (int linec, int lid, int nelem);
37 int get_loop_line_id (int linec, int lid);
38 int get_loop_line_for_key (gchar * key_a, gchar * key_b, int linec);
39 int cif_file_get_number_of_positions (int linec, int lid);
40 int get_space_group_from_hm (gchar * hmk);
41 int get_setting_from_hm (gchar * hmk, int end);
42 int group_info_from_hm_key (int spg, gchar * key_hm);
43 int cif_get_space_group (int linec);
44 int open_cif_file (int linec);
45
46 float get_atom_coord (gchar * line, int mid);
47
48 gboolean get_missing_object_from_user ();
49 gboolean cif_file_get_atoms_data (int lin, int cid[8]);
50 gboolean cif_get_atomic_coordinates (int linec);
51 gboolean cif_get_symmetry_positions (int linec);
52 gboolean cif_get_cell_data (int linec);
53
54 gchar * get_cif_word (gchar * mot);
55 gchar * get_atom_label (gchar * line, int lid);
56 gchar * get_string_from_origin (space_group * spg);
57
58 G_MODULE_EXPORT void set_cif_to_insert (GtkComboBox * box, gpointer data);
59 void file_get_to_line (int line_id);
60 void check_for_to_lab (int ato, gchar * stlab);
61
62*/
63
64#include "global.h"
65#include "bind.h"
66#include "interface.h"
67#include "project.h"
68#include "atom_edit.h"
69#include "cbuild_edit.h"
70#include "readers.h"
71#include <ctype.h>
72#ifdef OPENMP
73# include <omp.h>
74#endif
75
76extern int get_atom_id_from_periodic_table (atom_search * asearch);
77extern double get_z_from_periodic_table (gchar * lab);
78extern void get_origin (space_group * spg);
79extern void compute_lattice_properties (cell_info * cell);
80extern int test_lattice (builder_edition * cbuilder, cell_info * cif_cell);
81extern int read_space_group (builder_edition * cbuilder, int spg);
82extern gchar * wnpos[3];
83extern void get_wyck_char (float val, int ax, int bx);
85extern int build_crystal (gboolean visible, project * this_proj, gboolean to_wrap, gboolean show_clones, cell_info * cell, GtkWidget * widg);
86extern distance distance_3d (cell_info * cell, int mdstep, atom * at, atom * bt);
87extern void sort (int dim, int * tab);
88
89extern gchar * tmp_pos;
90
91FILE * cifp;
92char * line_ptr;
93int * keylines = NULL;
95
96gchar * cif_coord_opts[40][2] = {{"b1", "Monoclinic unique axis b, cell choice 1, abc"}, // 0
97 {"b2", "Monoclinic unique axis b, cell choice 2, abc"}, // 1
98 {"b3", "Monoclinic unique axis b, cell choice 3, abc"}, // 2
99 {"-b1", "Monoclinic unique axis b, cell choice 1, c-ba"}, // 3
100 {"-b2", "Monoclinic unique axis b, cell choice 2, c-ba"}, // 4
101 {"-b3", "Monoclinic unique axis b, cell choice 3, c-ba"}, // 5
102 {"c1", "Monoclinic unique axis c, cell choice 1, abc"}, // 6
103 {"c2", "Monoclinic unique axis c, cell choice 2, abc"}, // 7
104 {"c3", "Monoclinic unique axis c, cell choice 3, abc"}, // 8
105 {"-c1", "Monoclinic unique axis c, cell choice 1, ba-c"}, // 9
106 {"-c2", "Monoclinic unique axis c, cell choice 2, ba-c"}, // 10
107 {"-c3", "Monoclinic unique axis c, cell choice 3, ba-c"}, // 11
108 {"a1", "Monoclinic unique axis a, cell choice 1, abc"}, // 12
109 {"a2", "Monoclinic unique axis a, cell choice 2, abc"}, // 13
110 {"a3", "Monoclinic unique axis a, cell choice 3, abc"}, // 14
111 {"-a1", "Monoclinic unique axis a, cell choice 1, -acb"}, // 15
112 {"-a2", "Monoclinic unique axis a, cell choice 2, -acb"}, // 16
113 {"-a3", "Monoclinic unique axis a, cell choice 3, -acb"}, // 17
114 {"abc", "Orthorhombic"}, // 18
115 {"ba-c", "Orthorhombic"}, // 10
116 {"cab", "Orthorhombic"}, // 20
117 {"-cba", "Orthorhombic"}, // 21
118 {"bca", "Orthorhombic"}, // 22
119 {"a-cb", "Orthorhombic"}, // 23
120 {"1abc", "Orthorhombic origin choice 1"}, // 24
121 {"1ba-c", "Orthorhombic origin choice 1"}, // 25
122 {"1cab", "Orthorhombic origin choice 1"}, // 26
123 {"1-cba", "Orthorhombic origin choice 1"}, // 27
124 {"1bca", "Orthorhombic origin choice 1"}, // 28
125 {"1a-cb", "rthorhombic origin choice 1"}, // 29
126 {"2abc", "Orthorhombic origin choice 2"}, // 30
127 {"2ba-c", "Orthorhombic origin choice 2"}, // 31
128 {"2cab", "Orthorhombic origin choice 2"}, // 32
129 {"2-cba", "Orthorhombic origin choice 2"}, // 33
130 {"2bca", "Orthorhombic origin choice 2"}, // 34
131 {"2a-cb", "Orthorhombic origin choice 2"}, // 35
132 {"1", "Tetragonal or cubic origin choice 1"}, // 36
133 {"2", "Tetragonal or cubic origin choice 2"}, // 37
134 {"h", "Trigonal using hexagonal axes"}, // 38
135 {"r", "Trigonal using rhombohedral axes "}}; // 39
136
137#ifdef G_OS_WIN32
138 typedef intptr_t ssize_t;
139
140 ssize_t getline(char **lineptr, size_t *n, FILE *stream)
141 {
142 size_t pos;
143 int c;
144
145 if (lineptr == NULL || stream == NULL || n == NULL)
146 {
147 errno = EINVAL;
148 return -1;
149 }
150
151 c = getc(stream);
152 if (c == EOF) return -1;
153
154 if (*lineptr == NULL)
155 {
156 *lineptr = malloc(128);
157 if (*lineptr == NULL) return -1;
158 *n = 128;
159 }
160
161 pos = 0;
162 while(c != EOF)
163 {
164 if (pos + 1 >= *n)
165 {
166 size_t new_size = *n + (*n >> 2);
167 if (new_size < 128)
168 {
169 new_size = 128;
170 }
171 char *new_ptr = realloc(*lineptr, new_size);
172 if (new_ptr == NULL) return -1;
173 *n = new_size;
174 *lineptr = new_ptr;
175 }
176
177 ((unsigned char *)(*lineptr))[pos ++] = c;
178 if (c == '\n') break;
179 c = getc(stream);
180 }
181
182 (*lineptr)[pos] = '\0';
183 return pos;
184 }
185#endif // G_OS_WIN_32
186
194gchar * get_cif_word (gchar * mot)
195{
196 gchar * word = substitute_string (mot, "\n", NULL);
197 word = substitute_string (word, "\r", NULL);
198 return word;
199}
200
209float get_atom_coord (gchar * line, int mid)
210{
211 gchar * co_line = g_strdup_printf ("%s", line);
212 char * co_word = strtok_r (co_line, " ", & line);
213 int i;
214 for (i=0; i<mid-1; i++)
215 {
216 co_word = strtok_r (NULL, " ", & line);
217 }
218 double v = string_to_double ((gpointer)get_cif_word(co_word));
219 co_line = NULL;
220 co_word = NULL;
221 return v;
222}
223
232gchar * get_atom_label (gchar * line, int lid)
233{
234 gchar * at_line = g_strdup_printf ("%s", line);
235 char * at_word = strtok_r (at_line, " ", & line);
236 int i;
237 for (i=0; i<lid-1; i++) at_word = strtok_r (NULL, " ", & line);
238 gchar * str;
239 for (i=0; i<10; i++)
240 {
241 str = g_strdup_printf ("%d", i);
242 at_word = substitute_string (at_word, str, NULL);
243 g_free (str);
244 }
245 at_word = get_cif_word (at_word);
246 at_word = substitute_string (at_word, "-", NULL);
247 at_word = substitute_string (at_word, "+", NULL);
248 g_free (at_line);
249 return g_strdup_printf ("%c%c", at_word[0], tolower(at_word[1]));
250}
251
260int get_atom_wyckoff (gchar * line, int wid)
261{
262 gchar * wy_line = g_strdup_printf ("%s", line);
263 char * wy_word = strtok_r (wy_line, " ", & line);
264 int i, j;
265 j = 0;
266 for (i=0; i<wid-1; i++) wy_word = strtok_r (NULL, " ", & line);
267 for (i=0; i<this_reader -> lattice.sp_group -> numw; i++)
268 {
269 if (g_strcmp0(get_cif_word(wy_word), this_reader -> lattice.sp_group -> wyckoff[i].let) == 0)
270 {
271 j = i;
272 break;
273 }
274 }
275 wy_line = NULL;
276 wy_word = NULL;
277 return j;
278}
279
280GtkWidget ** img_cif;
283
292G_MODULE_EXPORT void set_cif_to_insert (GtkComboBox * box, gpointer data)
293{
294 GValue val = {0, };
295 int i, j, k;
296 i = GPOINTER_TO_INT(data);
297 GtkTreeModel * cmodel = gtk_combo_box_get_model (box);
298 GtkTreeIter iter;
299 gchar * str;
300 gboolean done = TRUE;
301 if (gtk_combo_box_get_active_iter (box, & iter))
302 {
303 gtk_tree_model_get_value (cmodel, & iter, 0, & val);
304 str = g_strdup_printf ("%s", (char *)g_value_get_string (& val));
305 j = get_selected_object_id (FALSE, activep, str, cif_search);
307 if (j > 0)
308 {
309 gtk_tree_store_set (GTK_TREE_STORE(cmodel), & iter, 0, periodic_table_info[j].lab, -1);
310 }
311 cif_search -> todo[i] = (! j) ? 0 : 1;
312 if (! j) done = FALSE;
313 cif_search -> in_selection = 0;
314 for (k=0; k<this_reader -> object_to_insert; k++) cif_search -> in_selection += cif_search -> todo[k];
315 }
316 str = (done) ? g_strdup_printf (APPLY) : g_strdup_printf (DELETEB);
318 g_free (str);
319 if (! done) gtk_combo_box_set_active (box, 0);
320}
321
328{
329 cif_search = allocate_atom_search (activep, REPLACE, 0, this_reader -> object_to_insert);
330 cif_object = NULL;
331 GtkWidget * info = dialogmodal ("Error while reading CIF file", GTK_WINDOW(MainWindow));
332 GtkWidget * vbox, * hbox;
333 gchar * str;
335 gchar * labpick = "<b>To continue and build the crystal according to the information of the CIF file\n"
336 "it is required to provide a suitable value for each and every missing parameter(s).</b>"
337 "\n\nPlease select an atom type for the following object(s):";
338 add_box_child_start (GTK_ORIENTATION_VERTICAL, vbox, markup_label (labpick, 200, -1, 0.5, 0.5), FALSE, FALSE, 10);
339 img_cif = g_malloc0(this_reader -> object_to_insert*sizeof*img_cif);
340 GtkWidget * but;
341 GtkCellRenderer * renderer;
342 GtkTreeModel * model;
343 GList * cell_list;
344 int i;
345 for (i=0; i<this_reader -> object_to_insert; i++)
346 {
347 hbox = create_hbox(0);
348 add_box_child_start (GTK_ORIENTATION_VERTICAL, vbox, hbox, FALSE, FALSE, 5);
349 str = g_strdup_printf ("Type NĀ°%d:\t<b>%s</b>", i+1, this_reader -> label[i]);
350 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, markup_label(str, 150, -1, 0.0, 0.5), FALSE, FALSE, 20);
351 g_free (str);
354 but = gtk_combo_box_new_with_model (model);
355 g_object_unref (model);
356 renderer = gtk_cell_renderer_combo_new ();
357 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (but), renderer, TRUE);
358 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (but), renderer, "text", 0, NULL);
359 gtk_combo_box_set_active (GTK_COMBO_BOX(but), 0);
360 g_signal_connect (G_OBJECT(but), "changed", G_CALLBACK(set_cif_to_insert), GINT_TO_POINTER(i));
361 cell_list = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(but));
362 if(cell_list && cell_list -> data)
363 {
364 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(but), cell_list -> data, "markup", 0, NULL);
365 }
366 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, but, FALSE, FALSE, 0);
367 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, img_cif[i], FALSE, FALSE, 30);
368 }
369
370 gchar * endpick = "In case of a molecule: insert an extra type of atom and run a substitution afterwards.";
371 add_box_child_start (GTK_ORIENTATION_VERTICAL, vbox, markup_label (endpick, 200, -1, 0.5, 0.5), FALSE, FALSE, 10);
372 run_this_gtk_dialog (info, G_CALLBACK(run_destroy_dialog), NULL);
373 g_free (img_cif);
374 return (cif_search -> in_selection == this_reader -> object_to_insert) ? TRUE : FALSE;
375}
376
377#ifndef OPENMP
385void file_get_to_line (int line_id)
386{
387 int i;
388 tail = head;
389 for (i=0; i<line_id; i++) tail = tail -> next;
390}
391#endif
392
407int cif_get_value (gchar * kroot, gchar * keyw, int linec, int lstart, gchar ** cif_word, gboolean rec_val, gboolean all_ligne, gboolean in_loop)
408{
409 int res = 0;
410 int i;
411 size_t j, k, l, m;
412 gchar * str;
413 gchar * str_w, * str_a, * str_b;
414 gchar * mot;
415 j = strlen(kroot);
416 k = strlen(keyw);
417 l = j+k+1;
418#ifdef OPENMP
419 int numth = (in_loop) ? 1 : omp_get_max_threads ();
420 gchar * saved_line;
421 #pragma omp parallel for num_threads(numth) private(i,m,this_line,saved_line,this_word,str_a,str_b,str_w) shared(j,k,l,this_reader,res,coord_line,cif_word,mot,rec_val,all_ligne,in_loop,kroot,keyw)
422 for (i=lstart; i<linec; i++)
423 {
424 if (res) goto endi;
425 this_line = g_strdup_printf ("%s", coord_line[i]);
426 saved_line = g_strdup_printf ("%s", this_line);
427 this_word = strtok_r (this_line, " ", & saved_line);
428 while (this_word)
429 {
430 if (in_loop && this_word[0] != '_')
431 {
432 res = -1;
433 goto endi;
434 }
435 str_w = get_cif_word (this_word);
436 str_w = g_ascii_strdown (str_w, strlen(str_w));
437 if (strlen(str_w) == l)
438 {
439 str_a = g_strdup_printf ("%c", str_w[0]);
440 for (m=1; m<j; m++) str_a = g_strdup_printf ("%s%c", str_a, str_w[m]);
441 str_b = g_strdup_printf ("%c", str_w[j+1]);
442 for (m=j+2; m<l; m++) str_b = g_strdup_printf ("%s%c", str_b, str_w[m]);
443 if (g_strcmp0(str_a, kroot) == 0 && g_strcmp0(str_b,keyw) == 0)
444 {
445 this_word = strtok_r (NULL, " ", & saved_line);
446 if (! this_word)
447 {
448 if (rec_val || all_ligne)
449 {
450 str = g_strdup_printf ("Wrong file format: searching for <b>%s</b> - error at line <b>%d</b> !", keyw, i+1);
451 add_reader_info (str, 0);
452 g_free (str);
453 g_free (str_w);
454 g_free (str_a);
455 g_free (str_b);
456 res = -1;
457 goto endi;
458 }
459 }
460 res = i+1;
461 if (all_ligne)
462 {
463 mot = g_strdup_printf ("%s", this_word);
464 this_word = strtok_r (NULL, " ", & saved_line);
465 while (this_word)
466 {
467 mot = g_strdup_printf ("%s%s", mot, this_word);
468 this_word = strtok_r (NULL, " ", & saved_line);
469 }
470 this_word = g_strdup_printf ("%s", mot);
471 g_free (mot);
472 }
473 if (this_word) * cif_word = get_cif_word (this_word);
474 g_free (str_w);
475 g_free (str_a);
476 g_free (str_b);
477 goto endi;
478 }
479 g_free (str_a);
480 g_free (str_b);
481 }
482 g_free (str_w);
483 this_word = strtok_r (NULL, " ", & saved_line);
484 }
485 endi:;
486 }
487 if (res < 0) res = 0;
488#else
489 file_get_to_line (lstart);
490 res = 0;
491 i = lstart;
492 while (tail)
493 {
494 this_line = g_strdup_printf ("%s", tail -> line);
495 this_word = strtok (this_line, " ");
496 while (this_word)
497 {
498 if (in_loop && this_word[0] != '_') return 0;
499 str_w = get_cif_word(this_word);
500 str_w = g_ascii_strdown (str_w, strlen(str_w));
501 if (strlen(str_w) == l)
502 {
503 str_a = g_strdup_printf ("%c", str_w[0]);
504 for (m=1; m<j; m++) str_a = g_strdup_printf ("%s%c", str_a, str_w[m]);
505 str_b = g_strdup_printf ("%c", str_w[j+1]);
506 for (m=j+2; m<l; m++) str_b = g_strdup_printf ("%s%c", str_b, str_w[m]);
507 if (g_strcmp0(str_a, kroot) == 0 && g_strcmp0(str_b,keyw) == 0)
508 {
509 this_word = strtok (NULL, " ");
510 if (! this_word)
511 {
512 if (rec_val || all_ligne)
513 {
514 str = g_strdup_printf ("Wrong file format: searching for <b>%s</b> - error at line <b>%d</b> !", keyw, i+1);
515 add_reader_info (str, 0);
516 g_free (str);
517 g_free (str_w);
518 g_free (str_a);
519 g_free (str_b);
520 return 0;
521 }
522 }
523 if (all_ligne)
524 {
525 mot = g_strdup_printf ("%s", this_word);
526 this_word = strtok (NULL, " ");
527 while (this_word)
528 {
529 mot = g_strdup_printf ("%s%s", mot, this_word);
530 this_word = strtok (NULL, " ");
531 }
532 this_word = g_strdup_printf ("%s", mot);
533 g_free (mot);
534 }
535 if (this_word) * cif_word = get_cif_word (this_word);
536 g_free (str_w);
537 g_free (str_a);
538 g_free (str_b);
539 return i+1;
540 }
541 g_free (str_a);
542 g_free (str_b);
543 }
544 g_free (str_w);
545 this_word = strtok (NULL, " ");
546 }
547 tail = tail -> next;
548 i ++;
549 }
550#endif
551 return res;
552}
553
562int cif_file_get_data_in_loop (int linec, int lid)
563{
564 gboolean res = FALSE;
565 int i = 0;
566#ifdef OPENMP
567 while (! res)
568 {
569 if (lid+i < linec)
570 {
571 this_line = g_strdup_printf ("%s", coord_line[lid+i]);
572 this_word = strtok (this_line, " ");
573 if (this_word[0] == '_')
574 {
575 i ++;
576 }
577 else
578 {
579 res = TRUE;
580 }
581 }
582 else
583 {
584 res = TRUE;
585 }
586 }
587#else
588 file_get_to_line (lid);
589 while (! res)
590 {
591 if (tail)
592 {
593 this_line = g_strdup_printf ("%s", tail -> line);
594 this_word = strtok (this_line, " ");
595 if (this_word[0] == '_')
596 {
597 i ++;
598 tail = tail -> next;
599 }
600 else
601 {
602 res = TRUE;
603 }
604 }
605 else
606 {
607 res = TRUE;
608 }
609 }
610#endif
611 return i;
612}
613
623int cif_file_get_number_of_atoms (int linec, int lid, int nelem)
624{
625 gboolean res = FALSE;
626 int i, j;
627 char init;
628 i = 0;
629#ifdef OPENMP
630 while (! res && (lid+i) < linec)
631 {
632 this_line = g_strdup_printf ("%s", coord_line[lid+i]);
633 this_word = strtok (this_line, " ");
634 j = 0;
635 while (this_word)
636 {
637 if (! j) init = this_word[0];
638 j ++;
639 this_word = strtok (NULL, " ");
640 }
641 if (j == nelem && init != '_')
642 {
643 i ++;
644 }
645 else
646 {
647 res = TRUE;
648 }
649 }
650#else
651 file_get_to_line (lid);
652 while (! res && tail)
653 {
654 this_line = g_strdup_printf ("%s", tail -> line);
655 this_word = strtok (this_line, " ");
656 j = 0;
657 while (this_word)
658 {
659 if (j == 0) init = this_word[0];
660 j ++;
661 this_word = strtok (NULL, " ");
662 }
663 if (j == nelem && init != '_')
664 {
665 i ++;
666 }
667 else
668 {
669 res = TRUE;
670 }
671 tail = tail -> next;
672 }
673#endif
674 return i;
675}
676
685void check_for_to_lab (int ato, gchar * stlab)
686{
687 int i, j;
688 j = -1;
689 // First is the label of 'ato' already listed
690 for (i=0; i<this_reader -> object_to_insert; i++)
691 {
692 if (g_strcmp0(this_reader -> label[i], stlab) == 0)
693 {
694 j = i;
695 break;
696 }
697 }
698 if (j < 0)
699 {
700 if (this_reader -> label)
701 {
702 this_reader -> label = g_realloc (this_reader -> label, (this_reader -> object_to_insert+1)*sizeof*this_reader -> label);
703 }
704 else
705 {
706 this_reader -> label = g_malloc0 (1*sizeof*this_reader -> label);
707 }
708 this_reader -> label[this_reader -> object_to_insert] = g_strdup_printf ("%s", stlab);
709 this_reader -> object_to_insert ++;
710 j = this_reader -> object_to_insert-1;
711 }
712 if (this_reader -> object_list)
713 {
714 this_reader -> object_list = g_realloc (this_reader -> object_list, (this_reader -> atom_unlabelled+1)*sizeof*this_reader -> object_list);
715 this_reader -> u_atom_list = g_realloc (this_reader -> u_atom_list, (this_reader -> atom_unlabelled+1)*sizeof*this_reader -> u_atom_list);
716 }
717 else
718 {
719 this_reader -> object_list = g_malloc0 (1*sizeof*this_reader -> object_list);
720 this_reader -> u_atom_list = g_malloc0 (1*sizeof*this_reader -> u_atom_list);
721 }
722 this_reader -> object_list[this_reader -> atom_unlabelled] = j;
723 this_reader -> u_atom_list[this_reader -> atom_unlabelled] = ato;
724 this_reader -> atom_unlabelled ++;
725}
726
735gboolean cif_file_get_atoms_data (int lin, int cid[8])
736{
737 int i, j;
738 double v;
739 gchar * str;
740 gboolean done = TRUE;
741 gchar * cline;
742#ifdef OPENMP
743 int numth = omp_get_max_threads ();
744 #pragma omp parallel for num_threads(numth) private(i,j,v,cline,str) shared(this_reader,coord_line,done)
745 for (i=0; i<this_reader -> natomes; i++)
746 {
747 cline = g_strdup_printf ("%s", coord_line[i+lin]);
748 str = get_atom_label (cline, (cid[0]) ? cid[0] : cid[1]);
750 #pragma omp critical
751 {
752 if (v)
753 {
754 check_for_species (v, i);
755 }
756 else
757 {
758 done = FALSE;
759 check_for_to_lab (i, str);
760 }
761 }
762 if (this_reader -> cartesian)
763 {
764 active_project -> atoms[0][i].x = get_atom_coord (cline, cid[2]);
765 active_project -> atoms[0][i].y = get_atom_coord (cline, cid[3]);
766 active_project -> atoms[0][i].z = get_atom_coord (cline, cid[4]);
767 }
768 else
769 {
770 for (j=0; j<3; j++) this_reader -> coord[i][j] = get_atom_coord (cline, cid[j+2]);
771 }
772 if (! this_reader -> cartesian)
773 {
774 this_reader -> wyckoff[i] = (cid[5]) ? get_atom_wyckoff (cline, cid[5]) : 0;
775 this_reader -> occupancy[i] = (cid[6]) ? get_atom_coord (cline, cid[6]) : 1.0;
776 this_reader -> multi[i] = (cid[7]) ? get_atom_coord (cline, cid[7]) : 0.0;
777 }
778 if (cline) g_free (cline);
779 if (str) g_free (str);
780 }
781#else
782 file_get_to_line (lin);
783 for (i=0; i<this_reader -> natomes; i++)
784 {
785 cline = g_strdup_printf ("%s", tail -> line);
786 str = get_atom_label (cline, (cid[0]) ? cid[0] : cid[1]);
788 if (v)
789 {
790 check_for_species (v, i);
791 }
792 else
793 {
794 done = FALSE;
795 check_for_to_lab (i, str);
796 }
797 if (this_reader -> cartesian)
798 {
799 active_project -> atoms[0][i].x = get_atom_coord (cline, cid[2]);
800 active_project -> atoms[0][i].y = get_atom_coord (cline, cid[3]);
801 active_project -> atoms[0][i].z = get_atom_coord (cline, cid[4]);
802 }
803 else
804 {
805 for (j=0; j<3; j++) this_reader -> coord[i][j] = get_atom_coord (cline, cid[j+2]);
806 }
807 if (! this_reader -> cartesian)
808 {
809 this_reader -> wyckoff[i] = (cid[5]) ? get_atom_wyckoff (cline, cid[5]) : 0;
810 this_reader -> occupancy[i] = (cid[6]) ? get_atom_coord (cline, cid[6]) : 1.0;
811 this_reader -> multi[i] = (cid[7]) ? get_atom_coord (cline, cid[7]) : 0.0;
812 }
813/* #ifdef DEBUG
814 j = this_reader -> wyckoff[i];
815 g_debug ("CIF:: At= %s, w_letter[%d]= %s, occ= %f, x= %f, y= %f, z= %f", this_reader -> label[i],
816 j, this_reader -> lattice.sp_group -> wyckoff[j].let, this_reader -> occupancy[i],
817 this_reader -> coord[i][0], this_reader -> coord[i][1], this_reader -> coord[i][2]);
818#endif */
819 tail = tail -> next;
820 g_free (tail -> prev);
821 }
822#endif
823
824 if (! done)
825 {
826 done = (cif_search) ? TRUE : get_missing_object_from_user ();
827 }
828 return done;
829}
830
839int get_loop_line_id (int linec, int lid)
840{
841 int i;
842 gchar * str_w;
843#ifdef OPENMP
844 gchar * saved_line;
845 for (i=lid-1; i>-1; i--)
846 {
847 this_line = g_strdup_printf ("%s", coord_line[i]);
848 saved_line = g_strdup_printf ("%s", this_line);
849 this_word = strtok_r (this_line, " ", & saved_line);
850 if (this_word)
851 {
852 str_w = g_ascii_strdown (this_word, strlen(this_word));
853 if (g_strcmp0 ("loop_", get_cif_word(str_w)) == 0)
854 {
855 g_free (str_w);
856 return i+1;
857 }
858 g_free (str_w);
859 }
860 }
861#else
862 file_get_to_line (lid);
863 i = lid;
864 while (tail)
865 {
866 this_line = g_strdup_printf ("%s", tail -> line);
867 this_word = strtok (this_line, " ");
868 if (this_word)
869 {
870 str_w = g_ascii_strdown (this_word, strlen(this_word));
871 if (g_strcmp0 ("loop_", get_cif_word(str_w)) == 0)
872 {
873 g_free (str_w);
874 return i+1;
875 }
876 g_free (str_w);
877 }
878 i --;
879 tail = tail -> prev;
880 }
881#endif
882 return 0;
883}
884
894int get_loop_line_for_key (gchar * key_a, gchar * key_b, int linec)
895{
896 int i;
897 gchar * str;
898 i = cif_get_value (key_a, key_b, linec, 0, & str, FALSE, FALSE, FALSE);
899 return (i) ? get_loop_line_id (linec, i) : 0;
900}
901
909gboolean cif_get_atomic_coordinates (int linec)
910{
911 gchar * labkeys[2] = {"type_symbol", "label"};
912 gchar * frackeys[3] = {"fract_x", "fract_y", "fract_z"};
913 gchar * cartkeys[3] = {"cartn_x", "cartn_y", "cartn_z"};
914 gchar * symkeys[3] = {"wyckoff_symbol", "occupancy", "symmetry_multiplicity"};
915 gchar * str = NULL;
916 int cid[8];
917 int loop_line;
918 int i, j, k, l;
919
920 loop_line = get_loop_line_for_key ("_atom_site", cartkeys[0], linec);
921 if (! loop_line)
922 {
923 loop_line = get_loop_line_for_key ("_atom_site", frackeys[0], linec);
924 if (! loop_line)
925 {
926 return FALSE;
927 }
928 }
929 else
930 {
931 this_reader -> cartesian = TRUE;
932 }
933 i = 0;
934 for (j=0; j<2; j++)
935 {
936 cid[j] = cif_get_value ("_atom_site", labkeys[j], linec, loop_line, & str, FALSE, FALSE, TRUE);
937 if (cid[j])
938 {
939 i ++;
940 cid[j] -= loop_line;
941 }
942 }
943 if (! i)
944 {
945 add_reader_info ("<b>Atomic coordinates</b>: impossible to find atomic label(s) ...", 0);
946 return FALSE;
947 }
948
949 i = 0;
950 for (j=0; j<3; j++)
951 {
952 cid[j+2] = cif_get_value ("_atom_site", cartkeys[j], linec, loop_line, & str, FALSE, FALSE, TRUE);
953 if (cid[j+2])
954 {
955 i ++;
956 cid[j+2] -= loop_line;
957 }
958 else if (this_reader -> cartesian)
959 {
960 str = g_strdup_printf ("<b>Atomic coordinates</b>: impossible to find '%s' ...", cartkeys[j]);
961 add_reader_info (str, 1);
962 g_free (str);
963 this_reader -> cartesian = FALSE;
964 }
965 }
966 if (i < 3)
967 {
968 j = 0;
969 for (l=0; l<3; l++)
970 {
971 cid[l+2] = cif_get_value ("_atom_site", frackeys[l], linec, loop_line, & str, FALSE, FALSE, TRUE);
972 if (cid[l+2])
973 {
974 cid[l+2] -= loop_line;
975 j ++;
976 }
977 else
978 {
979 str = g_strdup_printf ("<b>Atomic coordinates</b>: impossible to find '%s' ...", frackeys[l]);
980 add_reader_info (str, 1);
981 g_free (str);
982 }
983 }
984 if (j < 3)
985 {
986 add_reader_info ("<b>Atomic coordinates</b>: no complete cartesian coordinates !", 0);
987 add_reader_info ("<b>Atomic coordinates</b>: no complete fractional coordinates !", 0);
988 return FALSE;
989 }
990 }
991 else
992 {
993 this_reader -> cartesian = TRUE;
994 }
995
996 if (! this_reader -> cartesian)
997 {
998 for (i=0; i<3; i++)
999 {
1000 cid[i+5] = cif_get_value ("_atom_site", symkeys[i], linec, loop_line, & str, FALSE, FALSE, TRUE);
1001 if (cid[i+5])
1002 {
1003 cid[i+5] -= loop_line;
1004 }
1005 }
1006 }
1007 i = cif_file_get_data_in_loop (linec, loop_line);
1008#ifdef DEBUG
1009 g_debug ("CIF:: Num of field in loop= %d", i);
1010#endif
1011 this_reader -> natomes = cif_file_get_number_of_atoms (linec, loop_line+i, i);
1012#ifdef DEBUG
1013 g_debug ("CIF:: Number of atoms in CIF file= %d", this_reader -> natomes);
1014#endif
1015 if (! this_reader -> natomes) return FALSE;
1016 if (this_reader -> cartesian)
1017 {
1018 active_project -> steps = 1;
1019 active_project -> natomes = this_reader -> natomes;
1021 }
1022 else
1023 {
1024 this_reader -> coord = allocddouble (this_reader -> natomes, 3);
1025 }
1026 if (! this_reader -> cartesian)
1027 {
1028 this_reader -> lot = allocint (this_reader -> natomes);
1029 this_reader -> wyckoff = allocint (this_reader -> natomes);
1030 this_reader -> occupancy = allocdouble (this_reader -> natomes);
1031 this_reader -> multi = allocint (this_reader -> natomes);
1032 }
1033 this_reader -> z = allocdouble (1);
1034 this_reader -> nsps = allocint (1);
1035 if (! cif_file_get_atoms_data (loop_line+i, cid)) return FALSE;
1036 if (! this_reader -> cartesian)
1037 {
1038 this_reader -> occupied = g_malloc0(this_reader -> natomes*sizeof*this_reader -> occupied);
1039 double v;
1040 for (i=0; i<this_reader -> natomes; i++)
1041 {
1042 for (j=0; j<2; j++)
1043 {
1044 k = 1;
1045 v = this_reader -> occupancy[i];
1046 for (l=0; l<this_reader -> natomes; l++)
1047 {
1048 if (l != i)
1049 {
1050 if (this_reader -> coord[i][0] == this_reader -> coord[l][0]
1051 && this_reader -> coord[i][1] == this_reader -> coord[l][1]
1052 && this_reader -> coord[i][2] == this_reader -> coord[l][2])
1053 {
1054 v += this_reader -> occupancy[l];
1055 k ++;
1056 if (j) this_reader -> occupied[i][k] = l;
1057 if (v > 1.00001)
1058 {
1059 add_reader_info ("<b>Atomic coordinates</b>: a site was found to have an occupancy > 1.0 !", 0);
1060 return FALSE;
1061 }
1062 }
1063 }
1064 }
1065 if (! j)
1066 {
1067 this_reader -> occupied[i] = allocint (k+1);
1068 this_reader -> occupied[i][0] = k;
1069 this_reader -> occupied[i][1] = i;
1070 }
1071 }
1072 }
1073 }
1074 return TRUE;
1075}
1076
1085int cif_file_get_number_of_positions (int linec, int lid)
1086{
1087 gboolean res = FALSE;
1088 int i = 0;
1089 while (! res)
1090 {
1091#ifdef OPENMP
1092 this_line = g_strdup_printf ("%s", coord_line[lid+i]);
1093#else
1094 file_get_to_line (lid+i);
1095 this_line = g_strdup_printf ("%s", tail -> line);
1096#endif
1097 this_word = strtok (this_line, " ");
1098 if (this_word[0] == '_' || g_strcmp0(this_word, "loop_") == 0)
1099 {
1100 res = TRUE;
1101 break;
1102 }
1103 else
1104 {
1105 i ++;
1106 }
1107 }
1108 if (i)
1109 {
1110 this_reader -> sym_pos = g_malloc0(i*sizeof*this_reader -> sym_pos);
1111 int j, k;
1112 gchar * str;
1113 gchar * k_word;
1114 gchar * sym_pos_line;
1115 for (j=0; j<i; j++)
1116 {
1117 this_reader -> sym_pos[j] = g_malloc0(3*sizeof*this_reader -> sym_pos[j]);
1118#ifdef OPENMP
1119 sym_pos_line = g_strdup_printf ("%s", coord_line[lid+j]);
1120#else
1121 file_get_to_line (lid+j);
1122 sym_pos_line = g_strdup_printf ("%s", tail -> line);
1123#endif
1124 this_line = g_strdup_printf ("%s", sym_pos_line);
1125 this_word = strtok (this_line, " ");
1126 k_word = g_strdup_printf ("%s", this_word);
1127 str = g_strdup_printf ("%d", j+1);
1128 if (g_strcmp0(k_word, str) == 0)
1129 {
1130 g_free (this_line);
1131 this_line = NULL;
1132 for (k=strlen(k_word); k<strlen(sym_pos_line); k++)
1133 {
1134 if (! this_line)
1135 {
1136 this_line = g_strdup_printf ("%c", sym_pos_line[k]);
1137 }
1138 else
1139 {
1140 this_line = g_strdup_printf ("%s%c", this_line, sym_pos_line[k]);
1141 }
1142 }
1143 }
1144 g_free (k_word);
1145 g_free (str);
1146 g_free (sym_pos_line);
1147 this_line = substitute_string (this_line, "'", NULL);
1149 this_word = strtok (this_line, " ");
1150 for (k=0; k<3; k++)
1151 {
1152 this_reader -> sym_pos[j][k] = g_strdup_printf ("%s", this_word);
1153 this_word = strtok (NULL, " ");
1154 }
1155 }
1156 }
1157 return i;
1158}
1159
1167gboolean cif_get_symmetry_positions (int linec)
1168{
1169 gchar * pos_key[2]={"_symmetry_equiv_pos_as", "_space_group_symop_operation"};
1170 gchar * str;
1171 int loop_line;
1172 int line_id;
1173 int i;
1174 for (i=0; i<2; i++)
1175 {
1176 loop_line = get_loop_line_for_key (pos_key[i], "xyz", linec);
1177 if (loop_line)
1178 {
1179 line_id = cif_get_value (pos_key[i], "xyz", linec, loop_line, & str, FALSE, FALSE, TRUE);
1180 break;
1181 }
1182 }
1183 if (! loop_line) return FALSE;
1184 // Read lines after the instruction, as many positions as line until _ or loop
1185 this_reader -> num_sym_pos = cif_file_get_number_of_positions (linec, line_id);
1186 return TRUE;
1187}
1188
1197{
1198 int i;
1199 gchar * str;
1200 gchar * hm = g_strdup_printf ("%s", replace_markup (hmk, "S", NULL));
1201 for (i=0; i<230; i++)
1202 {
1203 str = substitute_string (hmsymbols[i], " ", NULL);
1204 if (g_strcmp0(str, hm) == 0)
1205 {
1206 g_free (str);
1207 g_free (hm);
1208 return i+1;
1209 }
1210 g_free (str);
1211 str = substitute_string (groups[i], "<sub>", NULL);
1212 str = substitute_string (str, "</sub>", NULL);
1213 if (g_strcmp0(str, hm) == 0)
1214 {
1215 g_free (str);
1216 g_free (hm);
1217 return i+1;
1218 }
1219 g_free (str);
1220 }
1221 // Cross checking for erroneus writting in the CIF file
1222 // ie. Fm3m in place of Fm-3m
1223 for (i=0; i<230; i++)
1224 {
1225 str = substitute_string (groups[i], "<sub>", NULL);
1226 str = substitute_string (str, "</sub>", NULL);
1227 if (g_strrstr(str, "-"))
1228 {
1229 str = substitute_string (str, "-", NULL);
1230 if (g_strcmp0(str, hm) == 0)
1231 {
1232 g_free (str);
1233 g_free (hm);
1234 return i+1;
1235 }
1236 }
1237 g_free (str);
1238 }
1239 g_free (hm);
1240 return 0;
1241}
1242
1251{
1252 gchar * str = NULL;
1253 if (wnpos[1])
1254 {
1255 g_free (wnpos[1]);
1256 wnpos[1] = NULL;
1257 }
1258
1259 get_wyck_char (spg -> coord_origin.m01, 1, 0);
1260 get_wyck_char (spg -> coord_origin.m11, 1, 1);
1261 get_wyck_char (spg -> coord_origin.m21, 1, 2);
1262
1263 if (wnpos[1])
1264 {
1265 str = g_strdup_printf ("%s", wnpos[1]);
1266 g_free (wnpos[1]);
1267 wnpos[1] = NULL;
1268 }
1269 return str;
1270}
1271
1280int get_setting_from_hm (gchar * hmk, int end)
1281{
1282 int i, j;
1283 gchar * str;
1284 if (this_reader -> lattice.sp_group)
1285 {
1286 i = this_reader -> lattice.sp_group -> nums;
1287 for (j=0; j<i; j++)
1288 {
1289 str = replace_markup (this_reader -> lattice.sp_group -> settings[j].name, "s", "/");
1290 str = substitute_string (str, "_", NULL);
1291 if (end < 0)
1292 {
1293 if (g_strcmp0(str, hmk) == 0)
1294 {
1295 g_free (str);
1296 return j;
1297 }
1298 }
1299 else
1300 {
1301 if (g_strcmp0(str, hmk) == 0 && this_reader -> lattice.sp_group -> settings[j].origin == end+1)
1302 {
1303 g_free (str);
1304 return j;
1305 }
1306 }
1307 g_free (str);
1308 }
1309 if (this_reader -> lattice.sp_group -> id > 2 && this_reader -> lattice.sp_group -> id < 16)
1310 {
1311 // This is a way around the way this familly of SG is often written,
1312 // using incomplete or inexact hmk keyword, ex: P21/a instead of P121/a1
1313 for (j=0; j<i; j++)
1314 {
1315 str = replace_markup (this_reader -> lattice.sp_group -> settings[j].name, "s", "/");
1316 str = substitute_string (str, "_", NULL);
1317 str = substitute_string (str, "12", "2");
1318 str = substitute_string (str, "/a1", "/a");
1319 str = substitute_string (str, "/b1", "/b");
1320 str = substitute_string (str, "/c1", "/c");
1321 str = substitute_string (str, "/m1", "/m");
1322 str = substitute_string (str, "/n1", "/n");
1323 if (end < 0)
1324 {
1325 if (g_strcmp0(str, hmk) == 0)
1326 {
1327 g_free (str);
1328 str = g_strdup_printf ("<b>Space group</b>: CIF file information could be inaccurate !\n"
1329 " CIF file space group: <b>%s</b>, CIF file H-M symbol: <b>%s</b>",
1330 groups[this_reader -> lattice.sp_group -> id-1], hmk);
1331 add_reader_info (str, 1);
1332 g_free (str);
1333 return j;
1334 }
1335 }
1336 else
1337 {
1338 if (g_strcmp0(str, hmk) == 0 && this_reader -> lattice.sp_group -> settings[j].origin == end+1)
1339 {
1340 g_free (str);
1341 str = g_strdup_printf ("<b>Space group</b>: CIF file information could be inaccurate !\n"
1342 " CIF file space group: <b>%s</b>, CIF file H-M symbol: <b>%s</b>",
1343 groups[this_reader -> lattice.sp_group -> id-1], hmk);
1344 add_reader_info (str, 1);
1345 g_free (str);
1346 return j;
1347 }
1348 }
1349 g_free (str);
1350 }
1351 }
1352 return -1;
1353 }
1354 else
1355 {
1356 return -1;
1357 }
1358}
1359
1368int group_info_from_hm_key (int spg, gchar * key_hm)
1369{
1370 int i, j;
1371 gchar * str;
1372 gchar * exts[2] = {"h", "r"};
1373 gchar * orig[2] = {"1", "2"};
1374 gchar * key = NULL;
1375 gchar * hmk = NULL;
1376 gchar * hma, * hmb;
1377 gchar * hmkey = substitute_string (key_hm, "'", NULL);
1378 //hmkey = substitute_string (hmkey, "/", "s");
1379 this_reader -> setting = -1;
1380 if (strstr(hmkey,":"))
1381 {
1382 key = g_strdup_printf ("%s", hmkey);
1383 hmk = g_strdup_printf ("%s", strtok (key, ":"));
1384 hma = g_strdup_printf ("%s:", hmk);
1385 hmb = replace_markup (hmkey, hma, NULL);
1386 i = strlen(hmb);
1387 hmb = g_ascii_strdown (hmb, i);
1388 for (i=0; i<2; i++)
1389 {
1390 if (g_strcmp0(hmb, exts[i]) == 0)
1391 {
1392 this_reader -> setting = i;
1393 break;
1394 }
1395 }
1396 g_free (hma);
1397 g_free (key);
1398 if (this_reader -> setting < 0)
1399 {
1400 for (i=0; i<2; i++)
1401 {
1402 if (g_strcmp0(hmb, orig[i]) == 0)
1403 {
1404 j = get_space_group_from_hm (hmk);
1405 this_reader -> setting = (spg) ? get_setting_from_hm (hmk, i) : 0;
1406 if (! j && this_reader -> setting < 0)
1407 {
1408 this_reader -> setting = 0;
1409 str = g_strdup_printf ("<b>Space group</b>: CIF file information could be inaccurate !\n"
1410 " CIF file space group: <b>%s</b>, CIF file H-M symbol: <b>%s</b>",
1411 groups[this_reader -> lattice.sp_group -> id-1], key_hm);
1412 add_reader_info (str, 1);
1413 g_free (str);
1414 }
1415 if (this_reader -> setting < 0) this_reader -> setting = 0;
1416 g_free (hmk);
1417 g_free (hmb);
1418 return j;
1419 }
1420 }
1421 }
1422 g_free (hmb);
1423 }
1424 else
1425 {
1426 hmk = g_strdup_printf ("%s", hmkey);
1427 }
1428 j = get_space_group_from_hm (hmk);
1429 this_reader -> setting = (spg || j) ? get_setting_from_hm (hmk, -1) : 0;
1430 g_free (hmk);
1431 if (! j && this_reader -> setting < 0)
1432 {
1433 str = g_strdup_printf ("<b>Space group</b>: CIF file information could be inaccurate !\n"
1434 " CIF file space group: <b>%s</b>, CIF file H-M symbol: <b>%s</b>",
1435 groups[this_reader -> lattice.sp_group -> id-1], key_hm);
1436 add_reader_info (str, 1);
1437 g_free (str);
1438 }
1439 if (this_reader -> setting < 0) this_reader -> setting = 0;
1440 return (spg) ? (j) ? j : spg : j;
1441}
1442
1450gboolean cif_get_cell_data (int linec)
1451{
1452 gchar * cellkeys[3] = {"length_a", "length_b", "length_c"};
1453 gchar * cellangs[3] = {"angle_alpha", "angle_beta", "angle_gamma",};
1454 gchar * str = NULL;
1455 int i;
1456 this_reader -> lattice.box = g_malloc0(sizeof*this_reader -> lattice.box);
1457 for (i=0; i<3; i++)
1458 {
1459 if (! cif_get_value ("_cell", cellkeys[i], linec, 0, & str, TRUE, FALSE, FALSE))
1460 {
1461 str = g_strdup_printf ("<b>Lattice parameters</b>: impossible to retrieve the '%s' parameter !", box_prop[0][i]);
1462 add_reader_info (str, 0);
1463 g_free (str);
1464 return FALSE;
1465 }
1466 this_reader -> lattice.box[0].param[0][i] = string_to_double ((gpointer)str);
1467#ifdef DEBUG
1468 g_debug ("CIF:: box[0][%d]= %f", i, this_reader -> lattice.box[0].param[0][i]);
1469#endif
1470 if (! cif_get_value ("_cell", cellangs[i], linec, 0, & str, TRUE, FALSE, FALSE))
1471 {
1472 str = g_strdup_printf ("<b>Lattice parameters</b>: impossible to retrieve the '%s' parameter !", box_prop[1][i]);
1473 add_reader_info (str, 0);
1474 g_free (str);
1475 return FALSE;
1476 }
1477 this_reader -> lattice.box[0].param[1][i] = string_to_double ((gpointer)str);
1478#ifdef DEBUG
1479 g_debug ("CIF:: box[1][%d]= %f", i, this_reader -> lattice.box[0].param[1][i]);
1480#endif
1481 }
1482 this_reader -> lattice.ltype = 0;
1484 for (i=0; i<3; i++) this_reader -> lattice.cextra[i] = 1;
1485 return TRUE;
1486}
1487
1495int cif_get_space_group (int linec)
1496{
1497 gchar * symkey[2] = {"int_tables_number", "group_it_number"};
1498 gchar * str = NULL;
1499 int spg = 0;
1500 int i, j, k, l;
1501 for (i=0; i<2; i++)
1502 {
1503 if (cif_get_value ("_symmetry", symkey[i], linec, 0, & str, TRUE, FALSE, FALSE))
1504 {
1505 spg = (int)string_to_double ((gpointer)str);
1506 break;
1507 }
1508 }
1509 if (! spg)
1510 {
1511 if (cif_get_value ("_space_group", "it_number", linec, 0, & str, TRUE, FALSE, FALSE))
1512 {
1513 spg = (int)string_to_double ((gpointer)str);
1514 }
1515 }
1516 gchar * hmkey = NULL;
1517 if (! cif_get_value ("_symmetry", "space_group_name_h-m", linec, 0, & hmkey, FALSE, TRUE, FALSE))
1518 {
1519 cif_get_value ("_space_group", "name_h-m_alt", linec, 0, & hmkey, FALSE, TRUE, FALSE);
1520 }
1521 if (! hmkey && ! spg)
1522 {
1523 add_reader_info ("<b>Space group</b>: no space group and no H-M symbol found !", 1);
1524 return FALSE;
1525 }
1526#ifdef DEBUG
1527 if (spg) g_debug ("CIF:: Space group:: NĀ°= %d, name= %s", spg, groups[spg-1]);
1528 if (hmkey) g_debug ("CIF:: H-M symbol:: %s", hmkey);
1529#endif
1530 if (spg)
1531 {
1532 if (! read_space_group (NULL, spg-1)) return FALSE;
1533 }
1534 if (hmkey)
1535 {
1536 i = group_info_from_hm_key (spg, hmkey);
1537 if (! spg && ! i)
1538 {
1539 add_reader_info ("<b>Space group</b>: no space group found, unknown H-M symbol !", 1);
1540#ifdef DEBUG
1541 g_debug ("CIF:: No space group found, unknown H-M symbol !");
1542#endif
1543 }
1544 else if (spg && ! i)
1545 {
1546 str = g_strdup_printf ("<b>Space group</b>: space group and H-M symbol do not match !\n"
1547 " CIF file space group: <b>%s</b>, CIF file H-M symbol: <b>%s</b>", groups[spg-1], hmkey);
1548 add_reader_info (str, 1);
1549 g_free (str);
1550#ifdef DEBUG
1551 g_debug ("CIF:: Space group and H-M symbol do not match:: spg= %d, hm= %d", spg, i);
1552#endif
1553 }
1554 else if (i && ! spg)
1555 {
1556 spg = i;
1557 }
1558 if (! this_reader -> lattice.sp_group)
1559 {
1560 if (! read_space_group (NULL, spg-1)) return FALSE;
1561 }
1562 }
1563 gchar * lat;
1564 int res = spg;
1565 if (spg > 1)
1566 {
1567 if (cif_get_value ("_space_group", "it_coordinate_system_code", linec, 0, & str, FALSE, FALSE, FALSE))
1568 {
1569 str = substitute_string (str, "'", NULL);
1570 for (i=0; i<40; i++)
1571 {
1572 if (g_strcmp0(str, cif_coord_opts[i][0]) == 0)
1573 {
1574 if (i < 18)
1575 {
1576 if (spg < 3 || spg > 15)
1577 {
1578 res = 0;
1579 break;
1580 }
1581 if (str[0] == '-')
1582 {
1583 k = (int) string_to_double ((gpointer)g_strdup_printf ("%c", str[2]));
1584 str = g_strdup_printf ("%c%c", str[0], str[1]);
1585 }
1586 else
1587 {
1588 k = (int) string_to_double ((gpointer)g_strdup_printf ("%c", str[1]));
1589 str = g_strdup_printf ("%c", str[0]);
1590 }
1591 l = 0;
1592 for (j=0; j< this_reader -> lattice.sp_group -> nums; j++)
1593 {
1594 this_reader -> lattice.sp_group -> sid = j;
1595 get_origin (this_reader -> lattice.sp_group);
1596 lat = get_string_from_origin (this_reader -> lattice.sp_group);
1597 if (g_strcmp0(lat, str) == 0) l ++;
1598 if (l == k)
1599 {
1600 if (j < this_reader -> setting) add_reader_info ("<b>Space group</b>: ambiguous space group setting !", 1);
1601 this_reader -> setting = j;
1602 break;
1603 }
1604 }
1605 }
1606 else if (i < 36)
1607 {
1608 if (spg < 16 || spg > 74)
1609 {
1610 res = 0;
1611 break;
1612 }
1613 k = 0;
1614 if (str[0] == '1' || str[0]=='2')
1615 {
1616 k = (int) string_to_double ((gpointer)g_strdup_printf ("%c", str[0]));
1617 str = replace_markup (str, g_strdup_printf("%d", k), NULL);
1618 }
1619 l = 0;
1620 for (j=0; j< this_reader -> lattice.sp_group -> nums; j++)
1621 {
1622 lat = g_strdup_printf ("%s%s%s",
1623 this_reader -> lattice.sp_group -> settings[j].pos[0],
1624 this_reader -> lattice.sp_group -> settings[j].pos[1],
1625 this_reader -> lattice.sp_group -> settings[j].pos[2]);
1626 if (g_strcmp0(lat, str) == 0)
1627 {
1628 if (j < this_reader -> setting || this_reader -> lattice.sp_group -> settings[j].origin != k)
1629 {
1630 add_reader_info ("<b>Space group</b>: ambiguous space group setting !", 1);
1631 }
1632 this_reader -> setting = j;
1633 l = 1;
1634 break;
1635 }
1636 }
1637 if (! l) add_reader_info ("<b>Space group</b>: ambiguous space group setting !", 1);
1638 }
1639 else if (i < 38)
1640 {
1641 if (spg < 75 || (spg > 142 && spg < 195))
1642 {
1643 res = 0;
1644 break;
1645 }
1646 j = i - 36;
1647 if (j < this_reader -> setting) add_reader_info ("<b>Space group</b>: ambiguous space group setting !", 1);
1648 this_reader -> setting = j;
1649 }
1650 else
1651 {
1652 if (spg < 143 || spg > 165)
1653 {
1654 res = 0;
1655 break;
1656 }
1657 j = i - 38;
1658 if (j < this_reader -> setting) add_reader_info ("<b>Space group</b>: ambiguous space group setting !", 1);
1659 this_reader -> setting = j;
1660 }
1661 }
1662 }
1663 g_free (str);
1664 }
1665
1666 if (spg > 142 && spg < 168)
1667 {
1668 // Trigonal space group
1669 gboolean correct_this = FALSE;
1670 box_info * box = & this_reader -> lattice.box[0];
1671 switch (this_reader -> setting)
1672 {
1673 case 0:
1674 if (box -> param[0][0] == box -> param[0][1] && box -> param[0][0] == box -> param[0][2])
1675 {
1676 if (box -> param[1][0] == box -> param[1][1] && box -> param[1][0] == box -> param[1][2])
1677 {
1678 correct_this = TRUE;
1679 }
1680 }
1681 break;
1682 case 1:
1683 if (box -> param[0][0] == box -> param[0][1] && box -> param[0][0] != box -> param[0][2])
1684 {
1685 if (box -> param[1][0] == box -> param[1][1] && box -> param[1][0] == 90.0 && box -> param[1][2] == 120.0)
1686 {
1687 correct_this = TRUE;
1688 }
1689 }
1690 break;
1691 }
1692 if (correct_this)
1693 {
1694 gchar * setc[2] = {"<b>hexagonal</b>", "<b>rhombohedral</b>"};
1695 str = g_strdup_printf ("<b>Space group</b>: found trigonal space group NĀ°%d-%s, %s setting\n"
1696 "but the lattice parameters were found in %s format ...\n"
1697 "\t ... the space group setting was modified accordingly !",
1698 spg, groups[spg-1], setc[this_reader -> setting], setc[! this_reader -> setting]);
1699 add_reader_info (str, 1);
1700 g_free (str);
1701 this_reader -> setting = ! this_reader -> setting;
1702 }
1703 }
1704
1705 // Test space group vs. box parameters:
1706 this_reader -> lattice.sp_group -> sid = this_reader -> setting;
1707 if (! test_lattice (NULL, & this_reader -> lattice))
1708 {
1709 str = g_strdup_printf ("<b>Space group</b> and <b>lattice paramters</b> are not compatible !\n"
1710 "\nCheck a, b, c, and &#x3B1;, &#x3B2;, &#x263;, with the type of crystal system.");
1711 add_reader_info (str, 0);
1712 g_free (str);
1713 res = -1;
1714 }
1715 }
1716 this_reader -> lattice.sp_group -> sid = this_reader -> setting;
1717 get_origin (this_reader -> lattice.sp_group);
1718 return res;
1719}
1720
1728int open_cif_file (int linec)
1729{
1730 int res;
1731 int i, j, k, l, m, n;
1732
1733 if (cif_get_cell_data (linec))
1734 {
1735 i = cif_get_space_group (linec);
1736 if (i > 0)
1737 {
1738#ifdef DEBUG
1739 g_debug ("CIF:: SP setting:: %d, name= %s", this_reader -> setting+1, this_reader -> lattice.sp_group -> settings[this_reader -> setting].name);
1740#endif
1741 if (this_reader -> lattice.sp_group) get_origin (this_reader -> lattice.sp_group);
1742 }
1743 else if (i == 0)
1744 {
1745 // No space group found
1746#ifdef DEBUG
1747 g_debug ("CIF:: Impossible to retrieve space group information !");
1748#endif
1749 }
1750 else
1751 {
1752 // Error in space group
1753 return 3;
1754 }
1755 }
1756 // Reading positions
1757 if (cif_get_symmetry_positions (linec))
1758 {
1759 if (! cif_use_symmetry_positions && this_reader -> num_sym_pos)
1760 {
1761 add_reader_info ("Symmetry position(s) in CIF file\n", 1);
1762 }
1763 }
1764 if (cif_use_symmetry_positions && ! this_reader -> num_sym_pos)
1765 {
1766 add_reader_info ("No symmetry position(s) in CIF file\n", 0);
1767 return 3;
1768 }
1769 if (cif_get_atomic_coordinates (linec))
1770 {
1771 if (! this_reader -> cartesian)
1772 {
1773 for (i=0; i<3; i++)
1774 {
1775 for (j=0; j<3; j++)
1776 {
1777 if (i < 2)
1778 {
1779 active_box -> param[i][j] = this_reader -> lattice.box[0].param[i][j];
1780 }
1781 active_box -> vect[i][j] = this_reader -> lattice.box[0].vect[i][j];
1782 }
1783 }
1784 active_cell -> ltype = 1;
1785 active_cell -> pbc = TRUE;
1786 active_cell -> has_a_box = TRUE;
1787 if (this_reader -> lattice.sp_group)
1788 {
1789 active_cell -> crystal = TRUE;
1790 active_cell -> sp_group = duplicate_space_group (this_reader -> lattice.sp_group);
1791 }
1792 }
1793 res = 0;
1795 {
1796 this_reader -> cartesian = TRUE;
1798 active_project -> steps = 1;
1799 double spgpos[3][4];
1800 int max_pos = this_reader -> num_sym_pos * this_reader -> natomes;
1801 gboolean dist_message = FALSE;
1802 gboolean low_occ = FALSE;
1803 gboolean save_it;
1804 vec3_t f_pos, c_pos;
1805 gboolean * save_pos = allocbool (max_pos);
1806 mat4_t pos_mat;
1807 atom at, bt;
1808 distance dist;
1809 double u;
1810 vec3_t * all_pos = g_malloc0(max_pos*sizeof*all_pos);
1811 int * all_origin = allocint (max_pos);
1812 int * cif_pos = allocint (this_reader -> natomes);
1813 double ** cryst_pos = allocddouble (this_reader -> natomes, 3);
1814 double ** occ_pos = g_malloc0(sizeof*occ_pos);
1815 int ** lot_pos = g_malloc0(sizeof*lot_pos);
1816 int num_pos = 0;
1817 int pos_max = 0;
1818 for (i=0; i<2; i++)
1819 {
1820 for (j=0; j<this_reader -> natomes; j++)
1821 {
1822 if (! j)
1823 {
1824 num_pos = 0;
1825 for (k=0; k<3; k++) cryst_pos[num_pos][k] = this_reader -> coord[j][k];
1826 cif_pos[num_pos] = 1;
1827 if (i)
1828 {
1829 occ_pos[num_pos][0] = this_reader -> occupancy[j];
1830 lot_pos[num_pos][0] = this_reader -> lot[j];
1831 }
1832 num_pos ++;
1833 pos_max = 1;
1834 }
1835 else
1836 {
1837 save_it = TRUE;
1838 for (k=0; k<num_pos; k++)
1839 {
1840 if (this_reader -> coord[j][0] == cryst_pos[k][0]
1841 && this_reader -> coord[j][1] == cryst_pos[k][1]
1842 && this_reader -> coord[j][2] == cryst_pos[k][2])
1843 {
1844 save_it = FALSE;
1845 break;
1846 }
1847 }
1848 if (save_it)
1849 {
1850 for (k=0; k<3; k++) cryst_pos[num_pos][k] = this_reader -> coord[j][k];
1851 cif_pos[num_pos] = 1;
1852 if (i)
1853 {
1854 occ_pos[num_pos][0] = this_reader -> occupancy[j];
1855 lot_pos[num_pos][0] = this_reader -> lot[j];
1856 }
1857 num_pos ++;
1858 }
1859 else
1860 {
1861 if (i)
1862 {
1863 occ_pos[k][cif_pos[k]] = this_reader -> occupancy[j];
1864 lot_pos[k][cif_pos[k]] = this_reader -> lot[j];
1865 }
1866 cif_pos[k] ++;
1867 pos_max = max (pos_max, cif_pos[k]);
1868 }
1869 }
1870 }
1871 if (! i)
1872 {
1873 occ_pos = allocddouble (num_pos, pos_max);
1874 lot_pos = allocdint (num_pos, pos_max);
1875 }
1876 }
1877 for (i=0; i<num_pos; i++)
1878 {
1879 u = 0;
1880 for (j=0; j<cif_pos[i]; j++)
1881 {
1882 u += occ_pos[i][j];
1883 }
1884 if (u < 1.0)
1885 {
1886 low_occ = TRUE;
1887 break;
1888 }
1889 }
1890 int * all_id = allocint (num_pos);
1891 l = m = 0;
1892 for (i=0; i<this_reader -> num_sym_pos; i++)
1893 {
1894 for (j=0; j<3; j++)
1895 {
1896 tmp_pos = g_strdup_printf ("%s", this_reader -> sym_pos[i][j]);
1897 for (k=0; k<3; k++)
1898 {
1899 spgpos[j][k] = get_val_from_wyckoff (vect_comp[k], this_reader -> sym_pos[i][j]);
1900 }
1901 if (tmp_pos)
1902 {
1903 spgpos[j][3] = get_value_from_pos (tmp_pos);
1904 g_free (tmp_pos);
1905 tmp_pos = NULL;
1906 }
1907 else
1908 {
1909 spgpos[j][3] = 0.0;
1910 }
1911 }
1912 pos_mat = mat4 (spgpos[0][0], spgpos[0][1], spgpos[0][2], spgpos[0][3],
1913 spgpos[1][0], spgpos[1][1], spgpos[1][2], spgpos[1][3],
1914 spgpos[2][0], spgpos[2][1], spgpos[2][2], spgpos[2][3],
1915 0.0, 0.0, 0.0, 1.0);
1916 for (j=0; j<num_pos; j++)
1917 {
1918 f_pos = vec3 (cryst_pos[j][0], cryst_pos[j][1], cryst_pos[j][2]);
1919 f_pos = m4_mul_coord (pos_mat, f_pos);
1920 c_pos = m4_mul_coord (this_reader -> lattice.box[0].frac_to_cart, f_pos);
1921 all_pos[l].x = c_pos.x;
1922 all_pos[l].y = c_pos.y;
1923 all_pos[l].z = c_pos.z;
1924 all_origin[l] = j;
1925 save_it = TRUE;
1926 at.x = all_pos[l].x;
1927 at.y = all_pos[l].y;
1928 at.z = all_pos[l].z;
1929 for (k=0; k<l; k++)
1930 {
1931 bt.x = all_pos[k].x;
1932 bt.y = all_pos[k].y;
1933 bt.z = all_pos[k].z;
1934 dist = distance_3d (active_cell, 0, & at, & bt);
1935 if (dist.length < 0.1)
1936 {
1937 dist_message = TRUE;
1938 save_it = FALSE;
1939 break;
1940 }
1941 }
1942 save_pos[l] = save_it;
1943 l ++;
1944 if (save_it)
1945 {
1946 all_id[j] ++;
1947 m ++;
1948 }
1949 }
1950 }
1951 double prob;
1952 gboolean pick_it;
1953 gboolean ** taken_pos = g_malloc0 (num_pos*sizeof*taken_pos);
1954 int ** site_lot = g_malloc0 (num_pos*sizeof*site_lot);
1955 clock_t CPU_time;
1956 int tot_pos = 0;
1957 for (i=0; i<num_pos; i++)
1958 {
1959 taken_pos[i] = allocbool(all_id[i]);
1960 site_lot[i] = allocint(all_id[i]);
1961 for (j=0; j<cif_pos[i]; j++)
1962 {
1963 u = occ_pos[i][j]*all_id[i];
1964 if (u < 1.0 && tot_pos < all_id[i]) u = 1.0;
1965 k = lot_pos[i][j];
1966 l = 0;
1967 while (l < (int)u)
1968 {
1969 CPU_time = clock ();
1970 m = (CPU_time - (j+17)*all_id[i]);
1971 prob = random3_(& m);
1972 m = round (prob * (all_id[i]-1));
1973 pick_it = ! taken_pos[i][m];
1974 if (pick_it)
1975 {
1976 site_lot[i][m] = k;
1977 taken_pos[i][m] = TRUE;
1978 l ++;
1979 tot_pos ++;
1980 }
1981 }
1982 }
1983 }
1984 crystal_data * cryst = allocate_crystal_data (tot_pos, this_reader -> nspec + this_reader -> object_to_insert);
1985 i = 0;
1986 int * cryst_lot = allocint (cryst -> objects);
1987 int * from_origin = allocint (num_pos);
1988 for (j=0; j<max_pos; j++)
1989 {
1990 if (save_pos[j])
1991 {
1992 k = all_origin[j];
1993 l = from_origin[k];
1994 if (taken_pos[k][l])
1995 {
1996 cryst -> coord[i] = g_malloc0(sizeof*cryst -> coord[i]);
1997 cryst -> coord[i][0].x = all_pos[j].x;
1998 cryst -> coord[i][0].y = all_pos[j].y;
1999 cryst -> coord[i][0].z = all_pos[j].z;
2000 cryst -> pos_by_object[i] = 1;
2001 cryst_lot[i] = site_lot[k][l];
2002 if (cryst_lot[i] < 0)
2003 {
2004 cryst -> at_by_object[i] = get_atomic_object_by_origin (cif_object, - cryst_lot[i] - 1, 0) -> atoms;
2005 }
2006 else
2007 {
2008 cryst -> at_by_object[i] = 1;
2009 }
2010 i ++;
2011 }
2012 from_origin[k] ++;
2013 }
2014 }
2015 g_free (site_lot);
2016 g_free (all_origin);
2017 g_free (from_origin);
2018 g_free (all_pos);
2019 g_free (save_pos);
2020 g_free (taken_pos);
2021 g_free (all_id);
2022 i = 0;
2023 for (j=0; j<cryst -> objects; j++)
2024 {
2025 i += cryst -> at_by_object[j] * cryst -> pos_by_object[j];
2026 }
2027 active_project -> natomes = i;
2029 atomic_object * c_obj;
2030 int * spec_num = allocint (120);
2031 i = 0;
2032 for (j=0; j<cryst -> objects; j++)
2033 {
2034 if (cryst_lot[j] < 0)
2035 {
2036 k = - cryst_lot[j] - 1;
2038 for (l=0; l<c_obj -> atoms; l++)
2039 {
2040 m = c_obj -> at_list[l].sp;
2041 n = c_obj -> old_z[m];
2042 spec_num[n] ++;
2043 active_project -> atoms[0][i].sp = n;
2044 active_project -> atoms[0][i].x = cryst -> coord[j][0].x + c_obj -> at_list[l].x;
2045 active_project -> atoms[0][i].y = cryst -> coord[j][0].y + c_obj -> at_list[l].y;
2046 active_project -> atoms[0][i].z = cryst -> coord[j][0].z + c_obj -> at_list[l].z;
2047 i ++;
2048 }
2049 }
2050 else
2051 {
2052 k = (int)this_reader -> z[cryst_lot[j]];
2053 spec_num[k] ++;
2054 active_project -> atoms[0][i].sp = k;
2055 active_project -> atoms[0][i].x = cryst -> coord[j][0].x;
2056 active_project -> atoms[0][i].y = cryst -> coord[j][0].y;
2057 active_project -> atoms[0][i].z = cryst -> coord[j][0].z;
2058 i ++;
2059 }
2060 }
2061 g_free (this_reader -> nsps);
2062 int * tmp_nsps = allocint (120);
2063 int * tmp_spid = allocint (120);
2064 i = 0;
2065 for (j=0; j<120; j++)
2066 {
2067 if (spec_num[j])
2068 {
2069 tmp_nsps[i] = spec_num[j];
2070 tmp_spid[j] = i;
2071 i++;
2072 }
2073 }
2074 this_reader -> nspec = i;
2075 this_reader -> nsps = allocint (i);
2076 for (i=0; i<this_reader -> nspec; i++) this_reader -> nsps[i] = tmp_nsps[i];
2077 g_free (tmp_nsps);
2078 g_free (this_reader -> z);
2079 this_reader -> z = allocdouble(i);
2080 i = 0;
2081 for (j=0; j<120; j++)
2082 {
2083 if (spec_num[j])
2084 {
2085 this_reader -> z[i] = (double)j;
2086 i ++;
2087 }
2088 }
2089 for (i=0; i<active_project -> natomes; i++)
2090 {
2091 j = active_project -> atoms[0][i].sp;
2092 k = tmp_spid[j];
2093 active_project -> atoms[0][i].sp = k;
2094 }
2095 g_free (tmp_spid);
2096 if (low_occ)
2097 {
2098 add_reader_info ("The crystal will be created however some objects might be missing,\n"
2099 "Occupancy is too low compared to the number of site(s) per cell.\n\n"
2100 "<b>To build a crystal matching the defined occupancy</b>:\n"
2101 "\t <b>1)</b> If you are trying to read a CIF file, use the crystal builder instead.\n"
2102 "\t <b>2)</b> Modify the occupancy set-up to 'Completely random'.\n"
2103 "\t <b>3)</b> Increase the number of unit cells up to get rid of this message.\n\n", 1);
2104 }
2105 if (dist_message)
2106 {
2107 add_reader_info ("Object(s) at equivalent positions have been removed\n"
2108 "to ensure the consistency of the model\n"
2109 "when using <b>P</b>eriodic <b>B</b>oundary <b>C</b>onditions\n ", 1);
2110 }
2111 }
2112 }
2113 else
2114 {
2115 // No coordinates found
2116#ifdef DEBUG
2117 g_debug ("CIF:: Impossible to retrieve atomic coordinates !");
2118#endif
2119 res = 2;
2120 }
2121 return res;
2122}
atom_search * allocate_atom_search(int proj, int action, int searchid, int tsize)
allocate atom search data structure
Definition atom_edit.c:392
Function declarations for the mode edition window.
GtkTreeModel * replace_combo_tree(gboolean insert, int proj)
replace combo box in the tree view
Definition w_search.c:2615
int get_selected_object_id(gboolean visible, int p, gchar *str, atom_search *asearch)
get the id of the object selected (in contextual menu, or in combo box)
Definition w_search.c:2385
gchar * mot[2][2]
Definition popup.c:3293
void to_insert_in_project(int stat, int orig, project *this_proj, atom_search *asearch, gboolean visible)
to insert object in project
atomic_object * get_atomic_object_by_origin(atomic_object *first, int oid, int aid)
get insert object from a list by id
Definition w_search.c:474
Binding to the Fortran90 subroutines.
double random3_(int *)
gchar * substitute_string(gchar *init, gchar *o_motif, gchar *n_motif)
substitute all patterns in string
Definition w_library.c:372
double get_val_from_wyckoff(gchar *pos, gchar *wval)
get point value from wyckoff position
crystal_data * allocate_crystal_data(int objects, int species)
allocate crystal data pointer
double get_value_from_pos(gchar *pos)
get position double value from string description
Function declarations for the crystal builder.
gchar * groups[230]
Definition cbuild_sg.c:43
void allocatoms(project *this_proj)
allocate project data
Definition open_p.c:160
gchar * hmsymbols[230]
Definition cbuild_sg.c:274
gchar * replace_markup(char *init, char *key, char *rep)
replace pattern in string
Definition w_library.c:339
gchar * param[2]
double ax
Definition curve.c:70
void label(cairo_t *cr, double val, int axe, int p, project *this_proj)
draw axis label
Definition labels.c:56
double dist
Definition d_measures.c:73
int atoms[NUM_STYLES][2]
float val
Definition dlp_init.c:117
int multi
Definition dlp_init.c:121
char * box_prop[2][3]
Definition edit_menu.c:73
int ** allocdint(int xal, int yal)
allocate an int ** pointer
Definition global.c:330
int activep
Definition global.c:159
gboolean * allocbool(int val)
allocate a gboolean * pointer
Definition global.c:254
double ** allocddouble(int xal, int yal)
allocate a double ** pointer
Definition global.c:475
double * allocdouble(int val)
allocate a double * pointer
Definition global.c:459
GtkWidget * MainWindow
Definition global.c:201
int * allocint(int val)
allocate an int * pointer
Definition global.c:314
gboolean cif_use_symmetry_positions
Definition global.c:189
double string_to_double(gpointer string)
convert string to double
Definition global.c:624
Global variable declarations Global convenience function declarations Global data structure defin...
void run_this_gtk_dialog(GtkWidget *dial, GCallback handler, gpointer data)
run a GTK (3 and 4) basic GtkDialog
Definition gtk-misc.c:492
GtkWidget * dialogmodal(gchar *str, GtkWindow *parent)
Create a new dialog modal window.
Definition gtk-misc.c:510
cell_info * active_cell
Definition project.c:50
element_data periodic_table_info[]
Definition w_library.c:71
struct model model
data structure to describe the topology
Definition global.h:825
GtkWidget * stock_image(const gchar *stock_id)
create a GtkImage for the Gtk database
Definition gtk-misc.c:1364
#define APPLY
Definition global.h:220
box_info * active_box
Definition project.c:51
GtkWidget * dialog_get_content_area(GtkWidget *widg)
prepare GtkWidget to insert content in a GtkDialog window
Definition gtk-misc.c:825
GtkWidget * markup_label(gchar *text, int dimx, int dimy, float ax, float ay)
Definition gtk-misc.c:1585
void add_box_child_start(int orientation, GtkWidget *widg, GtkWidget *child, gboolean expand, gboolean fill, int padding)
Add a GtkWidget in a GtkBox at the initial position.
Definition gtk-misc.c:299
#define DELETEB
Definition global.h:222
GtkWidget * create_hbox(int spacing)
create a GtkBox with horizontal orientation
Definition gtk-misc.c:813
G_MODULE_EXPORT void run_destroy_dialog(GtkDialog *dialog, gint response_id, gpointer data)
to destroy a GtkDialog when the dialog emit the closing signal
Definition gtk-misc.c:2102
void set_image_from_icon_name(GtkWidget *widg, gchar *icon)
set a image from a stock icon name
Definition gtk-misc.c:1894
project * active_project
Definition project.c:47
#define max(a, b)
Definition global.h:80
@ REPLACE
Definition glview.h:225
int objects[3]
Definition selection.c:212
Messaging function declarations.
char * vect_comp[3]
Definition edit_menu.c:82
integer(kind=c_int) function lattice(totl, lid, vectors, vmod, angles, lat, cfrac, apbc)
Definition lattice.F90:162
double z
Definition ogl_draw.c:57
Function declarations for reading atomes project file Function declarations for saving atomes proje...
void check_for_species(double v, int ato)
Fill the species for each atom and the associated data.
Definition read_coord.c:196
void file_get_to_line(int line_id)
reach line in CIF file
Definition read_cif.c:385
int * keylines
Definition read_cif.c:93
gchar * get_string_from_origin(space_group *spg)
get the space group origin from its name
Definition read_cif.c:1250
gboolean cif_get_symmetry_positions(int linec)
read the symmetry positions from the CIF file
Definition read_cif.c:1167
G_MODULE_EXPORT void set_cif_to_insert(GtkComboBox *box, gpointer data)
change the object to insert at an empty cif position
Definition read_cif.c:292
double get_z_from_periodic_table(gchar *lab)
get Z from atom label
Definition w_library.c:304
int build_crystal(gboolean visible, project *this_proj, gboolean to_wrap, gboolean show_clones, cell_info *cell, GtkWidget *widg)
build crystal
int get_loop_line_for_key(gchar *key_a, gchar *key_b, int linec)
search a string
Definition read_cif.c:894
gboolean cif_get_atomic_coordinates(int linec)
read the atomic coordinates from the CIF file
Definition read_cif.c:909
void check_for_to_lab(int ato, gchar *stlab)
check atom label
Definition read_cif.c:685
GtkWidget ** img_cif
Definition read_cif.c:280
gboolean cif_file_get_atoms_data(int lin, int cid[8])
get atoms data from the CIF file
Definition read_cif.c:735
gboolean cif_get_cell_data(int linec)
get the cell data from the CIF file
Definition read_cif.c:1450
int get_atom_wyckoff(gchar *line, int wid)
read Wyckoff position from CIF file
Definition read_cif.c:260
space_group * duplicate_space_group(space_group *spg)
duplicate space ground information
int group_info_from_hm_key(int spg, gchar *key_hm)
get the space group information using the HM key from the CIF file
Definition read_cif.c:1368
int cif_get_space_group(int linec)
get the space group from the CIF file
Definition read_cif.c:1495
int read_space_group(builder_edition *cbuilder, int spg)
read space group NĀ°spg data from file
gchar * tmp_pos
int cif_file_get_data_in_loop(int linec, int lid)
get the number of "_" motifs in a line
Definition read_cif.c:562
int cif_loop_id
Definition read_cif.c:94
void get_wyck_char(float val, int ax, int bx)
convert wyckoff value to string
float get_atom_coord(gchar *line, int mid)
read atom coordinates from CIF file
Definition read_cif.c:209
int cif_file_get_number_of_atoms(int linec, int lid, int nelem)
get the number of atom(s) in a CIF file
Definition read_cif.c:623
FILE * cifp
Definition read_cif.c:91
gboolean get_missing_object_from_user()
get missing atomic number in CIF file from the user
Definition read_cif.c:327
int cif_get_value(gchar *kroot, gchar *keyw, int linec, int lstart, gchar **cif_word, gboolean rec_val, gboolean all_ligne, gboolean in_loop)
read pattern in CIF file
Definition read_cif.c:407
char * line_ptr
Definition read_cif.c:92
int cif_file_get_number_of_positions(int linec, int lid)
get the number of symmetry positions
Definition read_cif.c:1085
int get_setting_from_hm(gchar *hmk, int end)
Getting the space group parameters using the HM Key.
Definition read_cif.c:1280
void get_origin(space_group *spg)
get space group origin matrices
int open_cif_file(int linec)
open CIF file
Definition read_cif.c:1728
gchar * cif_coord_opts[40][2]
Definition read_cif.c:96
gchar * get_atom_label(gchar *line, int lid)
read atom label from CIF file
Definition read_cif.c:232
int get_atom_id_from_periodic_table(atom_search *asearch)
get atom Z from selection in the periodic table
Definition w_periodic.c:672
void compute_lattice_properties(cell_info *cell)
compute lattice parameters following cell description
int test_lattice(builder_edition *cbuilder, cell_info *cif_cell)
test lattice parameters
int get_space_group_from_hm(gchar *hmk)
retrieve space group using the HM Key
Definition read_cif.c:1196
atom_search * cif_search
Definition read_cif.c:281
gchar * wnpos[3]
Definition cbuild_info.c:74
int get_loop_line_id(int linec, int lid)
reach a line in the CIF file
Definition read_cif.c:839
void sort(int dim, int *tab)
sort, nim to max, a table by integer value
Definition glview.c:380
gchar * get_cif_word(gchar *mot)
get string from CIF file, EOL can be ugly
Definition read_cif.c:194
atomic_object * cif_object
Definition read_cif.c:282
distance distance_3d(cell_info *cell, int mdstep, atom *at, atom *bt)
distance between atom a and b in 3D
Definition ogl_utils.c:81
line_node * head
Definition read_coord.c:75
gchar ** coord_line
Definition read_coord.c:72
coord_file * this_reader
Definition read_coord.c:71
line_node * tail
Definition read_coord.c:76
void add_reader_info(gchar *info, int mid)
append information message to the reader information
Definition read_coord.c:86
char * this_word
Definition read_coord.c:74
gchar * this_line
Definition read_coord.c:73
Functions declaration to read atomic coordinates.
Definition global.h:886
double z
Definition global.h:892
double y
Definition global.h:891
double x
Definition global.h:890
double * z
Definition cbuild_edit.h:42
float y
Definition math_3d.h:130
float x
Definition math_3d.h:130
float z
Definition math_3d.h:130
int c
Definition tab-1.c:95
gchar * settings[3][10]
Definition w_advance.c:119
GtkWidget * res[2]
Definition w_encode.c:212
GtkWidget * hbox
Definition workspace.c:71
GtkWidget * vbox
Definition workspace.c:72
GtkWidget * lab
Definition workspace.c:73