86extern gchar *
wnpos[3];
90extern void sort (
int dim,
int * tab);
107gchar *
cif_coord_opts[40][2] = {{
"b1",
"Monoclinic unique axis b, cell choice 1, abc"},
108 {
"b2",
"Monoclinic unique axis b, cell choice 2, abc"},
109 {
"b3",
"Monoclinic unique axis b, cell choice 3, abc"},
110 {
"-b1",
"Monoclinic unique axis b, cell choice 1, c-ba"},
111 {
"-b2",
"Monoclinic unique axis b, cell choice 2, c-ba"},
112 {
"-b3",
"Monoclinic unique axis b, cell choice 3, c-ba"},
113 {
"c1",
"Monoclinic unique axis c, cell choice 1, abc"},
114 {
"c2",
"Monoclinic unique axis c, cell choice 2, abc"},
115 {
"c3",
"Monoclinic unique axis c, cell choice 3, abc"},
116 {
"-c1",
"Monoclinic unique axis c, cell choice 1, ba-c"},
117 {
"-c2",
"Monoclinic unique axis c, cell choice 2, ba-c"},
118 {
"-c3",
"Monoclinic unique axis c, cell choice 3, ba-c"},
119 {
"a1",
"Monoclinic unique axis a, cell choice 1, abc"},
120 {
"a2",
"Monoclinic unique axis a, cell choice 2, abc"},
121 {
"a3",
"Monoclinic unique axis a, cell choice 3, abc"},
122 {
"-a1",
"Monoclinic unique axis a, cell choice 1, -acb"},
123 {
"-a2",
"Monoclinic unique axis a, cell choice 2, -acb"},
124 {
"-a3",
"Monoclinic unique axis a, cell choice 3, -acb"},
125 {
"abc",
"Orthorhombic"},
126 {
"ba-c",
"Orthorhombic"},
127 {
"cab",
"Orthorhombic"},
128 {
"-cba",
"Orthorhombic"},
129 {
"bca",
"Orthorhombic"},
130 {
"a-cb",
"Orthorhombic"},
131 {
"1abc",
"Orthorhombic origin choice 1"},
132 {
"1ba-c",
"Orthorhombic origin choice 1"},
133 {
"1cab",
"Orthorhombic origin choice 1"},
134 {
"1-cba",
"Orthorhombic origin choice 1"},
135 {
"1bca",
"Orthorhombic origin choice 1"},
136 {
"1a-cb",
"rthorhombic origin choice 1"},
137 {
"2abc",
"Orthorhombic origin choice 2"},
138 {
"2ba-c",
"Orthorhombic origin choice 2"},
139 {
"2cab",
"Orthorhombic origin choice 2"},
140 {
"2-cba",
"Orthorhombic origin choice 2"},
141 {
"2bca",
"Orthorhombic origin choice 2"},
142 {
"2a-cb",
"Orthorhombic origin choice 2"},
143 {
"1",
"Tetragonal or cubic origin choice 1"},
144 {
"2",
"Tetragonal or cubic origin choice 2"},
145 {
"h",
"Trigonal using hexagonal axes"},
146 {
"r",
"Trigonal using rhombohedral axes "}};
149 typedef intptr_t ssize_t;
151 ssize_t getline(
char **lineptr,
size_t *n, FILE *stream)
156 if (lineptr == NULL || stream == NULL || n == NULL)
163 if (
c == EOF)
return -1;
165 if (*lineptr == NULL)
167 *lineptr = malloc(128);
168 if (*lineptr == NULL)
return -1;
177 size_t new_size = *
n + (*
n >> 2);
182 char *new_ptr = realloc(*lineptr, new_size);
183 if (new_ptr == NULL)
return -1;
188 ((
unsigned char *)(*lineptr))[pos ++] =
c;
189 if (
c ==
'\n')
break;
193 (*lineptr)[pos] =
'\0';
223 gchar * init = g_strdup_printf (
"%s", line);
224 char * co_word = strtok_r (init,
" ", & co_line);
226 for (i=0; i<mid-1; i++)
228 co_word = strtok_r (NULL,
" ", & co_line);
246 gchar * init = g_strdup_printf (
"%s", line);
247 char * at_word = strtok_r (init,
" ", & at_line);
249 for (i=0; i<lid-1; i++) at_word = strtok_r (NULL,
" ", & at_line);
253 str = g_strdup_printf (
"%d", i);
261 return g_strdup_printf (
"%c%c", at_word[0], tolower(at_word[1]));
275 gchar * init = g_strdup_printf (
"%s", line);
276 char * wy_word = strtok_r (init,
" ", & wy_line);
279 for (i=0; i<wid-1; i++) wy_word = strtok_r (NULL,
" ", & wy_line);
303 gchar * init = g_strdup_printf (
"%s", line);
304 char * at_word = strtok_r (init,
" ", & at_line);
306 for (i=0; i<lid-1; i++) at_word = strtok_r (NULL,
" ", & at_line);
327 i = GPOINTER_TO_INT(data);
328 GtkTreeModel * cmodel = gtk_combo_box_get_model (
box);
331 gboolean done = TRUE;
332 if (gtk_combo_box_get_active_iter (
box, & iter))
334 gtk_tree_model_get_value (cmodel, & iter, 0, &
val);
335 str = g_strdup_printf (
"%s", (
char *)g_value_get_string (&
val));
343 if (! j) done = FALSE;
347 str = (done) ? g_strdup_printf (
APPLY) : g_strdup_printf (
DELETEB);
366 gchar * labpick =
"<b>To continue and build the crystal according to the information of the CIF file\n"
367 "it is required to provide a suitable value for each and every missing parameter(s).</b>"
368 "\n\nPlease select an atom type for the following object(s):";
372 GtkCellRenderer * renderer;
373 GtkTreeModel *
model;
379 str = g_strdup_printf (
"Type N°%d:\t<b>%s</b>", i+1,
this_reader ->
label[i]);
384 but = gtk_combo_box_new_with_model (
model);
385 g_object_unref (
model);
386 renderer = gtk_cell_renderer_combo_new ();
387 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (but), renderer, TRUE);
388 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (but), renderer,
"text", 0, NULL);
390 g_signal_connect (G_OBJECT(but),
"changed", G_CALLBACK(
set_cif_to_insert), GINT_TO_POINTER(i));
396 gchar * endpick =
"In case of a molecule: insert an extra type of atom and run a substitution afterwards.";
415 for (i=0; i<line_id; i++)
tail =
tail -> next;
436int cif_get_value (gchar * kroot, gchar * keyw,
int lstart,
int lend, gchar ** cif_word,
437 gboolean rec_val, gboolean all_ligne, gboolean total_num, gboolean record_position,
int * line_position)
443 gchar * str_w, * str_a, * str_b;
453 int numth = omp_get_max_threads ();
454 #pragma omp parallel for num_threads(numth) private(i,m,the_line,saved_line,the_word,mot,str_a,str_b,str_w) shared(j,k,l,this_reader,coord_line,cif_word,rec_val,all_ligne,kroot,keyw,total_num,record_position,line_position,res)
455 for (i=lstart; i<lend; i++)
458 if (
res && ! total_num)
goto endi;
459 the_line = g_strdup_printf (
"%s",
coord_line[i]);
460 the_word = strtok_r (the_line,
" ", & saved_line);
464 str_w = g_ascii_strdown (str_w, strlen(str_w));
465 if (strlen(str_w) == l)
467 str_a = g_strdup_printf (
"%c", str_w[0]);
468 for (m=1; m<j; m++) str_a = g_strdup_printf (
"%s%c", str_a, str_w[m]);
469 str_b = g_strdup_printf (
"%c", str_w[j+1]);
470 for (m=j+2; m<l; m++) str_b = g_strdup_printf (
"%s%c", str_b, str_w[m]);
471 if (g_strcmp0(str_a, kroot) == 0 && g_strcmp0(str_b,keyw) == 0)
473 the_word = strtok_r (NULL,
" ", & saved_line);
476 if (rec_val || all_ligne)
478 str = g_strdup_printf (
"Wrong file format: searching for <b>%s</b> - error at line <b>%d</b> !\n", keyw, i+1);
494 line_position[
res] = i + 1;
506 mot = g_strdup_printf (
"%s", the_word);
507 the_word = strtok_r (NULL,
" ", & saved_line);
510 mot = g_strdup_printf (
"%s%s",
mot, the_word);
511 the_word = strtok_r (NULL,
" ", & saved_line);
513 the_word = g_strdup_printf (
"%s",
mot);
516 if (the_word && rec_val)
529 the_word = strtok_r (NULL,
" ", & saved_line);
542 the_line = g_strdup_printf (
"%s",
tail -> line);
543 the_word = strtok_r (the_line,
" ", & saved_line);
547 str_w = g_ascii_strdown (str_w, strlen(str_w));
548 if (strlen(str_w) == l)
550 str_a = g_strdup_printf (
"%c", str_w[0]);
551 for (m=1; m<j; m++) str_a = g_strdup_printf (
"%s%c", str_a, str_w[m]);
552 str_b = g_strdup_printf (
"%c", str_w[j+1]);
553 for (m=j+2; m<l; m++) str_b = g_strdup_printf (
"%s%c", str_b, str_w[m]);
554 if (g_strcmp0(str_a, kroot) == 0 && g_strcmp0(str_b,keyw) == 0)
556 the_word = strtok_r (NULL,
" ", & saved_line);
559 if (rec_val || all_ligne)
561 str = g_strdup_printf (
"Wrong file format: searching for <b>%s</b> - error at line <b>%d</b> !\n", keyw, i+1);
574 mot = g_strdup_printf (
"%s", the_word);
575 the_word = strtok_r (NULL,
" ", & saved_line);
578 mot = g_strdup_printf (
"%s%s",
mot, the_word);
579 the_word = strtok_r (NULL,
" ", & saved_line);
581 the_word = g_strdup_printf (
"%s",
mot);
584 if (the_word && rec_val)
592 line_position[
res] = i + 1;
617 the_word = strtok_r (NULL,
" ", & saved_line);
637 gboolean
res = FALSE;
647 the_line = g_strdup_printf (
"%s",
coord_line[lid+i]);
648 the_word = strtok_r (the_line,
" ", & saved_line);
649 if (the_word[0] ==
'_')
670 the_line = g_strdup_printf (
"%s",
tail -> line);
671 the_word = strtok_r (the_line,
" ", & saved_line);
672 if (the_word[0] ==
'_')
707 for (i=lid-1; i>-1; i--)
709 the_line = g_strdup_printf (
"%s",
coord_line[i]);
710 the_word = strtok_r (the_line,
" ", & saved_line);
713 str_w = g_ascii_strdown (the_word, strlen(the_word));
727 the_line = g_strdup_printf (
"%s",
tail -> line);
728 the_word = strtok_r (the_line,
" ", & saved_line);
731 str_w = g_ascii_strdown (the_word, strlen(the_word));
764 steps =
cif_get_value (key_a, key_b, 0, linec, NULL, FALSE, FALSE, TRUE, TRUE, line_numbers);
769 gchar * str = g_strdup_printf (
"<b>CIF get loop line</b>: something is wrong for keyword: %s_%s\n"
770 " -> keyword found= %d times\n"
771 " -> configurations in CIF file= %d !\n", key_a, key_b, steps,
this_reader -> steps);
774 g_free (line_numbers);
777 sort (steps, line_numbers);
778 lli = line_numbers[conf];
779 g_free (line_numbers);
784 lli =
cif_get_value (key_a, key_b, 0, linec, NULL, FALSE, FALSE, FALSE, FALSE, NULL);
802gchar *
cif_retrieve_value (
int linec,
int conf, gchar * key_a, gchar * key_b, gboolean all_ligne, gboolean in_loop, gboolean warning)
805 gchar * cif_value = NULL;
813 steps =
cif_get_value (key_a, key_b, 0, linec, NULL, FALSE, FALSE, TRUE, TRUE, line_numbers);
819 str = g_strdup_printf (
"<b>CIF retrieve value</b>: keyword: %s_%s\n"
820 " -> keyword found= %d times\n"
821 " -> configurations in CIF file= %d !\n", key_a, key_b, steps,
this_reader -> steps);
825 g_free (line_numbers);
829 sort (steps, line_numbers);
834 loop_pos[1] = (loop_pos[0] + 1000) > linec ? linec : (loop_pos[0] + 1000);
838 loop_pos[0] = (! line_numbers[conf]) ? line_numbers[conf] : line_numbers[conf] - 1;
839 loop_pos[1] = (loop_pos[0] + 1000) > linec ? linec : (loop_pos[0] + 1000);
842 g_free (line_numbers);
851 if (!
cif_get_value (key_a, key_b, loop_pos[0], loop_pos[1], & cif_value, TRUE, all_ligne, FALSE, FALSE, NULL) && warning)
854 g_debug (
"CIF:: retrieve:: keyword: %s_%s not found for conf %d between loop_pos[0]= %d and loop_pos[1]= %d\n", key_a, key_b, conf, loop_pos[0], loop_pos[1]);
856 str = g_strdup_printf (
"<b>Key positions</b>: keyword: %s_%s\n"
857 " -> not found for conf %d between loop_pos[0]= %d and loop_pos[1]= %d\n", key_a, key_b, conf, loop_pos[0], loop_pos[1]);
876 gboolean
res = FALSE;
884 while (!
res && (lid+i) < linec)
886 the_line = g_strdup_printf (
"%s",
coord_line[lid+i]);
887 the_word = strtok_r (the_line,
" ", & saved_line);
891 if (! j) init = the_word[0];
893 the_word = strtok_r (NULL,
" ", & saved_line);
895 if (j == nelem && init !=
'_')
909 the_line = g_strdup_printf (
"%s",
tail -> line);
910 the_word = strtok_r (the_line,
" ", & saved_line);
914 if (j == 0) init = the_word[0];
916 the_word = strtok_r (NULL,
" ", & saved_line);
918 if (j == nelem && init !=
'_')
997 gboolean done = TRUE;
1001 int numth = omp_get_max_threads ();
1002 #pragma omp parallel for num_threads(numth) private(i,j,v,cline,str) shared(this_reader,coord_line,at_step,done,lin,cid)
1005 cline = g_strdup_printf (
"%s",
coord_line[i+lin]);
1008 #pragma omp critical
1052 cline = g_strdup_printf (
"%s",
tail -> line);
1107 gchar * labkeys[2] = {
"type_symbol",
"label"};
1108 gchar * frackeys[3] = {
"fract_x",
"fract_y",
"fract_z"};
1109 gchar * cartkeys[3] = {
"cartn_x",
"cartn_y",
"cartn_z"};
1110 gchar * symkeys[4] = {
"wyckoff_symbol",
"occupancy",
"symmetry_multiplicity",
"disorder_group"};
1143 loop_max = (loop_line + 1000 > linec) ? linec : loop_line + 1000;
1147 cid[j] =
cif_get_value (
"_atom_site", labkeys[j], loop_line, loop_max, NULL, FALSE, FALSE, FALSE, FALSE, NULL);
1151 cid[j] -= loop_line;
1156 add_reader_info (
"<b>Atomic coordinates</b>: impossible to find atomic label(s) ...", 0);
1161 cid[i+2] =
cif_get_value (
"_atom_site", (
this_reader -> cartesian) ? cartkeys[i] : frackeys[i], loop_line, loop_max, NULL, FALSE, FALSE, FALSE, FALSE, NULL);
1164 cid[i+2] -= loop_line;
1168 str = g_strdup_printf (
"<b>Atomic coordinates</b>: impossible to find '%s' ...", (
this_reader -> cartesian) ? cartkeys[i] : frackeys[i]);
1178 cid[i+5] =
cif_get_value (
"_atom_site", symkeys[i], loop_line, loop_max, NULL, FALSE, FALSE, FALSE, FALSE, NULL);
1181 cid[i+5] -= loop_line;
1184 this_reader -> rounding =
iask (
"Please select how to handle occupancy",
"Select how to handle occupancy", 5,
MainWindow);
1203 str = g_strdup_printf (
"<b>Atomic coordinates</b>: the number of atom(s) changes !\n"
1204 " - configuration N°%d\t :: atoms= %d\n"
1243 for (k=i-1; k>-1; k--)
1245 if (tmp_z[k] <= v)
break;
1246 tmp_z[k+1] = tmp_z[k];
1247 tmp_nsps[k+1] = tmp_nsps[k];
1265 str = g_strdup_printf (
"<b>Atomic coordinates</b>: the number of chemical species changes !\n"
1266 " - configuration N°%d\t :: species= %d\n"
1277 str = g_strdup_printf (
"<b>Atomic coordinates</b>: the number of atom(s) for species %d changes !\n"
1278 " - configuration N°%d\t :: atom(s)= %d\n"
1279 " - initialization \t\t :: atom(s)= %d\n", conf, i+1,
this_reader -> nsps[i],
cif_nsps[i]);
1304 add_reader_info (
"<b>Atomic coordinates</b>: a site was found to have an occupancy > 1.0 !\n", 0);
1319 gboolean new_occ, new_order;
1320 int occupancies = 1;
1324 num_occ[0] = num_order[0] = 1;
1327 new_occ = new_order = TRUE;
1328 for (j=0; j<occupancies; j++)
1339 test_occ = g_realloc (test_occ, (occupancies+1)*
sizeof*test_occ);
1341 u =
min (u, test_occ[occupancies]);
1342 v =
max (v, test_occ[occupancies]);
1343 num_occ = g_realloc (num_occ, (occupancies+1)*
sizeof*num_occ);
1344 num_occ[occupancies] = 1;
1347 for (j=0; j<disorders; j++)
1358 test_order = g_realloc (test_order, (disorders+1)*
sizeof*test_order);
1359 test_order[disorders] =
this_reader -> disorder[i];
1360 num_order = g_realloc (num_order, (disorders+1)*
sizeof*num_order);
1361 num_order[disorders] = 1;
1371 for (i=0; i<occupancies; i++)
1373 if (num_occ[i] !=
this_reader -> natomes/occupancies)
1382 for (i=0; i<disorders; i++)
1384 if (num_order[i] !=
this_reader -> natomes/disorders)
1405 gboolean
res = FALSE;
1413 the_line = g_strdup_printf (
"%s",
coord_line[lid+i]);
1416 the_line = g_strdup_printf (
"%s",
tail -> line);
1418 the_word = strtok_r (the_line,
" ", & saved_line);
1419 if (the_word[0] ==
'_' || g_strcmp0(the_word,
"loop_") == 0)
1435 gchar * sym_pos_line;
1440 sym_pos_line = g_strdup_printf (
"%s",
coord_line[lid+j]);
1443 sym_pos_line = g_strdup_printf (
"%s",
tail -> line);
1445 the_line = g_strdup_printf (
"%s", sym_pos_line);
1446 the_word = strtok_r (the_line,
" ", & saved_line);
1447 k_word = g_strdup_printf (
"%s", the_word);
1448 str = g_strdup_printf (
"%d", j+1);
1449 if (g_strcmp0(k_word, str) == 0)
1453 for (k=strlen(k_word); k<strlen(sym_pos_line); k++)
1457 the_line = g_strdup_printf (
"%c", sym_pos_line[k]);
1461 the_line = g_strdup_printf (
"%s%c", the_line, sym_pos_line[k]);
1467 the_line = g_strdup_printf (
"%s", sym_pos_line);
1471 g_free (sym_pos_line);
1475 the_word = strtok_r (the_line,
" ", & saved_line);
1478 this_reader -> sym_pos[j][k] = g_strdup_printf (
"%s", the_word);
1479 the_word = strtok_r (NULL,
" ", & saved_line);
1499 gchar * pos_key[2]={
"_symmetry_equiv_pos_as",
"_space_group_symop_operation"};
1508 line_id =
cif_get_value (pos_key[i],
"xyz", loop_line, linec, NULL, FALSE, FALSE, FALSE, FALSE, NULL);
1512 if (! loop_line)
return FALSE;
1529 gchar * hm = g_strdup_printf (
"%s",
replace_markup (hmk,
"S", NULL));
1530 for (i=0; i<230; i++)
1533 if (g_strcmp0(str, hm) == 0)
1542 if (g_strcmp0(str, hm) == 0)
1552 for (i=0; i<230; i++)
1556 if (g_strrstr(str,
"-"))
1559 if (g_strcmp0(str, hm) == 0)
1594 str = g_strdup_printf (
"%s",
wnpos[1]);
1622 if (g_strcmp0(str, hmk) == 0)
1630 if (g_strcmp0(str, hmk) == 0 &&
this_reader ->
lattice.sp_group -> settings[j].origin == end+1)
1654 if (g_strcmp0(str, hmk) == 0)
1657 str = g_strdup_printf (
"<b>Space group</b>: CIF file information could be inaccurate !\n"
1658 " CIF file space group: <b>%s</b>, CIF file H-M symbol: <b>%s</b>\n",
1667 if (g_strcmp0(str, hmk) == 0 &&
this_reader ->
lattice.sp_group -> settings[j].origin == end+1)
1670 str = g_strdup_printf (
"<b>Space group</b>: CIF file information could be inaccurate !\n"
1671 " CIF file space group: <b>%s</b>, CIF file H-M symbol: <b>%s</b>\n",
1701 gchar * exts[2] = {
"h",
"r"};
1702 gchar * orig[2] = {
"1",
"2"};
1709 if (strstr(hmkey,
":"))
1711 key = g_strdup_printf (
"%s", hmkey);
1712 hmk = g_strdup_printf (
"%s", strtok (key,
":"));
1713 hma = g_strdup_printf (
"%s:", hmk);
1716 hmb = g_ascii_strdown (hmb, i);
1719 if (g_strcmp0(hmb, exts[i]) == 0)
1731 if (g_strcmp0(hmb, orig[i]) == 0)
1738 str = g_strdup_printf (
"<b>Space group</b>: CIF file information could be inaccurate !\n"
1739 " CIF file space group: <b>%s</b>, CIF file H-M symbol: <b>%s</b>\n",
1755 hmk = g_strdup_printf (
"%s", hmkey);
1762 str = g_strdup_printf (
"<b>Space group</b>: CIF file information could be inaccurate !\n"
1763 " CIF file space group: <b>%s</b>, CIF file H-M symbol: <b>%s</b>\n",
1769 return (spg) ? (j) ? j : spg : j;
1782 gchar * cellkeys[3] = {
"length_a",
"length_b",
"length_c"};
1783 gchar * cellangs[3] = {
"angle_alpha",
"angle_beta",
"angle_gamma",};
1796 str = g_strdup_printf (
"<b>Lattice parameters</b>: impossible to retrieve the '%s' parameter !\n",
box_prop[0][j]);
1813 str = g_strdup_printf (
"<b>Lattice parameters</b>: impossible to retrieve the '%s' parameter !\n",
box_prop[1][j]);
1825 g_debug (
"CIF:: angle[%d][%d]= %f", i, j,
this_reader ->
lattice.box[i].param[1][j]);
1844 gchar * symkey[2] = {
"int_tables_number",
"group_it_number"};
1860 str =
cif_retrieve_value (linec, conf,
"_space_group",
"it_number", TRUE, FALSE, FALSE);
1866 gchar * hmkey = NULL;
1868 hmkey =
cif_retrieve_value (linec, conf,
"_symmetry",
"space_group_name_h-m", TRUE, FALSE, FALSE);
1871 hmkey =
cif_retrieve_value (linec, conf,
"_symmetry",
"name_h-m_alt", TRUE, FALSE, FALSE);
1873 if (! hmkey && ! spg)
1875 add_reader_info (
"<b>Space group</b>: no space group and no H-M symbol found !\n", 1);
1879 if (spg) g_debug (
"CIF:: Space group:: N°= %d, name= %s", spg,
groups[spg-1]);
1880 if (hmkey) g_debug (
"CIF:: H-M symbol:: %s", hmkey);
1891 add_reader_info (
"<b>Space group</b>: no space group found, unknown H-M symbol !\n", 1);
1893 g_debug (
"CIF:: No space group found, unknown H-M symbol !");
1896 else if (spg && ! i)
1898 str = g_strdup_printf (
"<b>Space group</b>: space group and H-M symbol do not match !\n"
1899 " CIF file space group: <b>%s</b>, CIF file H-M symbol: <b>%s</b>\n",
groups[spg-1], hmkey);
1903 g_debug (
"CIF:: Space group and H-M symbol do not match:: spg= %d, hm= %d", spg, i);
1906 else if (i && ! spg)
1919 str =
cif_retrieve_value (linec, conf,
"_space_group",
"it_coordinate_system_code", TRUE, FALSE, FALSE);
1923 for (i=0; i<40; i++)
1929 if (spg < 3 || spg > 15)
1937 str = g_strdup_printf (
"%c%c", str[0], str[1]);
1942 str = g_strdup_printf (
"%c", str[0]);
1950 if (g_strcmp0(lat, str) == 0) l ++;
1953 if (j < this_reader -> setting)
add_reader_info (
"<b>Space group</b>: ambiguous space group setting !\n", 1);
1961 if (spg < 16 || spg > 74)
1967 if (str[0] ==
'1' || str[0]==
'2')
1975 lat = g_strdup_printf (
"%s%s%s",
1979 if (g_strcmp0(lat, str) == 0)
1981 if (j < this_reader -> setting ||
this_reader ->
lattice.sp_group -> settings[j].origin != k)
1983 add_reader_info (
"<b>Space group</b>: ambiguous space group setting !\n", 1);
1990 if (! l)
add_reader_info (
"<b>Space group</b>: ambiguous space group setting !\n", 1);
1994 if (spg < 75 || (spg > 142 && spg < 195))
2000 if (j < this_reader -> setting)
add_reader_info (
"<b>Space group</b>: ambiguous space group setting !\n", 1);
2005 if (spg < 143 || spg > 165)
2011 if (j < this_reader -> setting)
add_reader_info (
"<b>Space group</b>: ambiguous space group setting !\n", 1);
2019 if (spg > 142 && spg < 168)
2022 gboolean correct_this = FALSE;
2031 correct_this = TRUE;
2040 correct_this = TRUE;
2047 gchar * setc[2] = {
"<b>hexagonal</b>",
"<b>rhombohedral</b>"};
2048 str = g_strdup_printf (
"<b>Space group</b>: found trigonal space group N°%d-%s, %s setting\n"
2049 "but the lattice parameters were found in %s format ...\n"
2050 "\t ... the space group setting was modified accordingly !\n",
2062 str = g_strdup_printf (
"<b>Space group</b> and <b>lattice parameters</b> are not compatible !\n"
2063 "\nCheck a, b, c, and α, β, ɣ, with the type of crystal system.\n");
2085 int i, j, k, l, m, n;
2093 g_debug (
"CIF:: SP group changes between configuration:: conf= %d, saved_group= %d, new_group= %d", conf,
saved_group, i);
2095 add_reader_info (
"Space group changes between configurations !\n", 0);
2110 g_debug (
"CIF:: Impossible to retrieve space group information !");
2166 gchar * str = g_strdup_printf (
"<b>Building crystal using symmetry positions: </b> \n"
2167 " 1) evaluate candidate atomic positions using data in CIF file: \n"
2168 " - symmetry positions\n"
2169 " - atomic coordinates + occupancy\n"
2170 " 2) fill each candidate position using the associated occupancy: \n"
2177 double spgpos[3][4];
2179 gboolean dist_message = FALSE;
2180 gboolean low_occ = FALSE;
2183 gboolean * save_pos =
allocbool (max_pos);
2188 vec3_t * all_pos = g_malloc0(max_pos*
sizeof*all_pos);
2189 int * all_origin =
allocint (max_pos);
2192 double ** occ_pos = g_malloc0(
sizeof*occ_pos);
2193 int ** lot_pos = g_malloc0(
sizeof*lot_pos);
2208 for (j=i-1; j>-1; j--)
2210 if (list_occ[j] >=
val)
break;
2211 list_occ[j+1] = list_occ[j];
2212 list_pos[j+1] = list_pos[j];
2214 list_occ[j+1] =
val;
2215 list_pos[j+1] = vbl;
2230 for (l=0; l<3; l++) cryst_pos[num_pos][l] =
this_reader -> coord[k][l];
2231 cif_pos[num_pos] = 1;
2243 for (l=0; l<num_pos; l++)
2255 for (l=0; l<3; l++) cryst_pos[num_pos][l] =
this_reader -> coord[k][l];
2256 cif_pos[num_pos] = 1;
2272 pos_max =
max (pos_max, cif_pos[l]);
2284 for (i=0; i<num_pos; i++)
2287 for (j=0; j<cif_pos[i]; j++)
2319 pos_mat = mat4 (spgpos[0][0], spgpos[0][1], spgpos[0][2], spgpos[0][3],
2320 spgpos[1][0], spgpos[1][1], spgpos[1][2], spgpos[1][3],
2321 spgpos[2][0], spgpos[2][1], spgpos[2][2], spgpos[2][3],
2322 0.0, 0.0, 0.0, 1.0);
2323 for (j=0; j<num_pos; j++)
2325 f_pos = vec3 (cryst_pos[j][0], cryst_pos[j][1], cryst_pos[j][2]);
2326 f_pos = m4_mul_coord (pos_mat, f_pos);
2328 all_pos[l].
x = c_pos.
x;
2329 all_pos[l].
y = c_pos.
y;
2330 all_pos[l].
z = c_pos.
z;
2335 at.
x = all_pos[l].
x;
2336 at.
y = all_pos[l].
y;
2337 at.
z = all_pos[l].
z;
2340 bt.
x = all_pos[k].
x;
2341 bt.
y = all_pos[k].
y;
2342 bt.
z = all_pos[k].
z;
2344 if (
dist.length < 0.1)
2346 dist_message = TRUE;
2352 save_pos[l] = save_it;
2363 gboolean ** taken_pos = g_malloc0 (num_pos*
sizeof*taken_pos);
2364 int ** site_lot = g_malloc0 (num_pos*
sizeof*site_lot);
2367 for (i=0; i<num_pos; i++)
2371 for (j=0; j<cif_pos[i]; j++)
2373 u = occ_pos[i][j]*all_id[i];
2374 if (u < 1.0 && tot_pos < all_id[i]) u = 1.0;
2382 CPU_time = clock ();
2383 m = (CPU_time - (j+17)*all_id[i]);
2385 m = round (prob * (all_id[i]-1));
2386 pick_it = ! taken_pos[i][m];
2390 taken_pos[i][m] = TRUE;
2400 int * from_origin =
allocint (num_pos);
2401 for (j=0; j<max_pos; j++)
2407 if (taken_pos[k][l])
2409 cryst -> coord[i] = g_malloc0(
sizeof*cryst -> coord[i]);
2410 cryst -> coord[i][0].x = all_pos[j].
x;
2411 cryst -> coord[i][0].y = all_pos[j].
y;
2412 cryst -> coord[i][0].
z = all_pos[j].
z;
2413 cryst -> pos_by_object[i] = 1;
2414 cryst_lot[i] = site_lot[k][l];
2415 if (cryst_lot[i] < 0)
2421 cryst -> at_by_object[i] = 1;
2429 g_free (all_origin);
2430 g_free (from_origin);
2436 for (j=0; j<cryst ->
objects; j++)
2438 i += cryst -> at_by_object[j] * cryst -> pos_by_object[j];
2448 for (j=0; j<cryst ->
objects; j++)
2450 if (cryst_lot[j] < 0)
2452 k = - cryst_lot[j] - 1;
2454 for (l=0; l<c_obj ->
atoms; l++)
2456 m = c_obj -> at_list[l].sp;
2457 n = c_obj -> old_z[m];
2481 for (j=0; j<120; j++)
2485 tmp_nsps[i] = spec_num[j];
2497 for (j=0; j<120; j++)
2514 add_reader_info (
"The crystal will be created however some objects might be missing,\n"
2515 "Occupancy is too low compared to the number of site(s) per cell.\n\n"
2516 "<b>To build a crystal matching the defined occupancy</b>:\n"
2517 "\t <b>1)</b> If you are trying to read a CIF file, use the crystal builder instead.\n"
2518 "\t <b>2)</b> Modify the occupancy set-up to 'Completely random'.\n"
2519 "\t <b>3)</b> Increase the number of unit cells up to get rid of this message.\n\n", 1);
2523 add_reader_info (
"Object(s) at equivalent positions have been removed\n"
2524 "to ensure the consistency of the model\n"
2525 "when using <b>P</b>eriodic <b>B</b>oundary <b>C</b>onditions\n ", 1);
2533 g_debug (
"CIF:: Impossible to retrieve atomic coordinates !");
2549 gchar * frackeys[3] = {
"fract_x",
"fract_y",
"fract_z"};
2550 gchar * cartkeys[3] = {
"cartn_x",
"cartn_y",
"cartn_z"};
2570 cif_occup =
cif_get_value (
"_atom_site",
"occupancy", 0, linec, NULL, FALSE, FALSE, TRUE, FALSE, NULL);
2573 this_reader -> rounding =
iask (
"Please select how to handle occupancy",
"Select how to handle occupancy", 5,
MainWindow);
2586 str = g_strdup_printf (
"It seems the CIF file contains <b>%d</b> distinct configurations\n",
this_reader -> steps);
2591 str = g_strdup_printf (
"Impossible to use symmetry positions with multiple configurations\n");
2599 cif_site =
cif_get_value (
"_atom_site",
"disorder_group", 0, linec, NULL, FALSE, FALSE, TRUE, FALSE, NULL);
2600 if (cif_occup ==
this_reader -> steps && cif_occup == cif_site)
2602 add_reader_info (
"This CIF file could be describing a trajectory or a chemical reaction.\n", 1);
2613 cif_action =
iask (
"Please select how to process the data in the CIF file",
"Select how to process data", 4,
MainWindow);
2617 add_reader_info (
"This CIF file could be describing a trajectory.\n", 1);
2618 cif_action =
iask (
"Please select how to process the data in the CIF file",
"Select how to process data", 4,
MainWindow);
2629 str = g_strdup_printf (
"Select the configuration, in [1- %d]",
this_reader -> steps);
2633 cif_step =
iask (
"Please select the configuration to work on", str, 0,
MainWindow);
2634 if (cif_step < 1 || cif_step >
this_reader -> steps) cif_step = 0;
2643 str = g_strdup_printf (
"Working on configuration N°%d\n", cif_step);
atom_search * allocate_atom_search(int proj, int action, int searchid, int tsize)
allocate atom search data structure
Function declarations for the mode edition window.
GtkTreeModel * replace_combo_tree(gboolean insert, int proj)
replace combo box in the tree view
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)
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
Binding to the Fortran90 subroutines.
gchar * substitute_string(gchar *init, gchar *o_motif, gchar *n_motif)
substitute all patterns in string
double get_val_from_wyckoff(gchar *pos, gchar *wval)
get point value from wyckoff position
int occupancy(double occ, int cif_occ)
handle occupancy integer rouding
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.
void allocatoms(project *this_proj)
allocate project data
gchar * replace_markup(char *init, char *key, char *rep)
replace pattern in string
void label(cairo_t *cr, double val, int axe, int p, project *this_proj)
draw axis label
int * duplicate_int(int num, int *old_val)
copy a list of int
int ** allocdint(int xal, int yal)
allocate an int ** pointer
double * duplicate_double(int num, double *old_val)
copy a list of double
gboolean * allocbool(int val)
allocate a gboolean * pointer
double ** allocddouble(int xal, int yal)
allocate a double ** pointer
double * allocdouble(int val)
allocate a double * pointer
int * allocint(int val)
allocate an int * pointer
gboolean cif_use_symmetry_positions
double string_to_double(gpointer string)
convert string to double
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
GtkWidget * dialogmodal(gchar *str, GtkWindow *parent)
Create a new dialog modal window.
void combo_set_markup(GtkWidget *combo)
use pango markup in combo widget
element_data periodic_table_info[]
void combo_set_active(GtkWidget *combo, int pos)
set the active item's position
GtkWidget * stock_image(const gchar *stock_id)
create a GtkImage for the Gtk database
GtkWidget * dialog_get_content_area(GtkWidget *widg)
prepare GtkWidget to insert content in a GtkDialog window
GtkWidget * markup_label(gchar *text, int dimx, int dimy, float ax, float ay)
create a GtkLabel with pango markup
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.
GtkWidget * create_hbox(int spacing)
create a GtkBox with horizontal orientation
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
void set_image_from_icon_name(GtkWidget *widg, gchar *icon)
set a image from a stock icon name
struct model model
data structure to describe the topology
int iask(char *question, char *lab, int id, GtkWidget *win)
enter an integer value - prepare the dialog
Messaging function declarations.
integer(kind=c_int) function lattice(totl, lid, vectors, vmod, angles, lat, cfrac, apbc)
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.
gchar * get_atom_disorder(gchar *line, int lid)
read atom disorder group from CIF file
gboolean cif_get_atomic_coordinates(int linec, int conf)
void file_get_to_line(int line_id)
reach line in CIF file
gchar * get_string_from_origin(space_group *spg)
get the space group origin from its name
int cif_file_get_number_of_positions(int lid)
get the number of symmetry positions
G_MODULE_EXPORT void set_cif_to_insert(GtkComboBox *box, gpointer data)
change the object to insert at an empty cif position
int cif_get_space_group(int linec, int conf)
get the space group from the CIF file
double get_z_from_periodic_table(gchar *lab)
get Z from atom label
gboolean cif_file_get_atoms_data(int conf, int lin, int cid[9])
void compute_lattice_properties(cell_info *cell, int box_id)
compute lattice parameters following cell description
void check_for_to_lab(int ato, gchar *stlab)
check atom label
int get_atom_wyckoff(gchar *line, int wid)
read Wyckoff position from CIF file
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
gboolean cif_get_symmetry_positions(int linec, int conf)
read the symmetry positions from the CIF file
gboolean cif_get_cell_data(int linec, int conf)
get the cell data from the CIF file
int read_space_group(builder_edition *cbuilder, int spg)
read space group N°spg data from file
int cif_file_get_data_in_loop(int linec, int lid)
get the number of "_" motifs in a line
void get_wyck_char(float val, int ax, int bx)
convert wyckoff value to string
int get_loop_line_id(int lid)
reach a line in the CIF file
float get_atom_coord(gchar *line, int mid)
read atom coordinates from CIF file
int cif_file_get_number_of_atoms(int linec, int lid, int nelem)
get the number of atom(s) in a CIF file
int cif_get_value(gchar *kroot, gchar *keyw, int lstart, int lend, gchar **cif_word, gboolean rec_val, gboolean all_ligne, gboolean total_num, gboolean record_position, int *line_position)
read pattern in CIF file
gboolean get_missing_object_from_user()
get missing atomic number in CIF file from the user
int get_setting_from_hm(gchar *hmk, int end)
Getting the space group parameters using the HM Key.
int get_loop_line_for_key(int linec, int conf, gchar *key_a, gchar *key_b)
search a string
void get_origin(space_group *spg)
get space group origin matrices
int open_cif_file(int linec)
open CIF file
gchar * cif_coord_opts[40][2]
gchar * get_atom_label(gchar *line, int lid)
read atom label from CIF file
int get_atom_id_from_periodic_table(atom_search *asearch)
get atom Z from selection in the periodic table
gchar * cif_retrieve_value(int linec, int conf, gchar *key_a, gchar *key_b, gboolean all_ligne, gboolean in_loop, gboolean warning)
retrieve a field value as string in the CIF file
int open_cif_configuration(int linec, int conf)
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
void sort(int dim, int *tab)
sort, nim to max, a table by integer value
gchar * get_cif_word(gchar *mot)
get string from CIF file, EOL can be ugly
atomic_object * cif_object
distance distance_3d(cell_info *cell, int mdstep, atom *at, atom *bt)
distance between atom a and b in 3D
void add_reader_info(gchar *info, int mid)
append information message to the reader information
Functions declaration to read atomic coordinates.