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