1 /* This code is part of the tng binary trajectory format.
3 * Written by Magnus Lundborg
4 * Copyright (c) 2012-2014, The GROMACS development team.
5 * Check out http://www.gromacs.org for more information.
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the Revised BSD License.
12 #ifdef USE_STD_INTTYPES_H
18 #include "../../include/tng_io.h"
20 static tng_function_status tng_test_setup_molecules(tng_trajectory_t traj)
22 tng_molecule_t molecule;
24 tng_residue_t residue;
28 tng_molecule_add(traj, "water", &molecule);
29 tng_molecule_chain_add(traj, molecule, "W", &chain);
30 tng_chain_residue_add(traj, chain, "WAT", &residue);
31 if(tng_residue_atom_add(traj, residue, "O", "O", &atom) == TNG_CRITICAL)
35 if(tng_residue_atom_add(traj, residue, "HO1", "H", &atom) == TNG_CRITICAL)
39 if(tng_residue_atom_add(traj, residue, "HO2", "H", &atom) == TNG_CRITICAL)
43 tng_molecule_cnt_set(traj, molecule, 200);
44 tng_molecule_cnt_get(traj, molecule, &cnt);
45 /* printf("Created %"PRId64" %s molecules.\n", cnt, molecule->name); */
47 /* traj->molecule_cnt_list[traj->n_molecules-1] = 5;
48 // tng_molecule_name_set(traj, &traj->molecules[1], "ligand");
49 // tng_molecule_name_set(traj, &traj->molecules[2], "water");
50 // tng_molecule_name_set(traj, &traj->molecules[3], "dummy");
51 // traj->molecules[0].id = 0;
52 // traj->molecules[1].id = 1;
53 // traj->molecules[2].id = 2;
54 // traj->molecules[3].id = 3;
56 // if(tng_add_atom_to_molecule(traj, &traj->molecules[0], "atom1", "type1") == TNG_CRITICAL)
58 // return(TNG_CRITICAL);
60 // if(tng_add_atom_to_molecule(traj, &traj->molecules[0], "atom2", "type1") == TNG_CRITICAL)
62 // return(TNG_CRITICAL);
64 // if(tng_add_atom_to_molecule(traj, &traj->molecules[0], "atom3", "type1") == TNG_CRITICAL)
66 // return(TNG_CRITICAL);
68 // if(tng_add_atom_to_molecule(traj, &traj->molecules[0], "atom4", "type2") == TNG_CRITICAL)
70 // return(TNG_CRITICAL);
72 // if(tng_add_atom_to_molecule(traj, &traj->molecules[0], "atom5", "type2") == TNG_CRITICAL)
74 // return(TNG_CRITICAL);
76 // if(tng_add_atom_to_molecule(traj, &traj->molecules[0], "atom6", "type2") == TNG_CRITICAL)
78 // return(TNG_CRITICAL);
80 // if(tng_add_atom_to_molecule(traj, &traj->molecules[0], "atom7", "type3") == TNG_CRITICAL)
82 // return(TNG_CRITICAL);
84 // if(tng_add_atom_to_molecule(traj, &traj->molecules[1], "C1", "C") == TNG_CRITICAL)
86 // return(TNG_CRITICAL);
88 // if(tng_add_atom_to_molecule(traj, &traj->molecules[1], "O1", "O") == TNG_CRITICAL)
90 // return(TNG_CRITICAL);
92 // if(tng_add_atom_to_molecule(traj, &traj->molecules[1], "H11", "H") == TNG_CRITICAL)
94 // return(TNG_CRITICAL);
96 // if(tng_add_atom_to_molecule(traj, &traj->molecules[1], "H12", "H") == TNG_CRITICAL)
98 // return(TNG_CRITICAL);
100 // if(tng_add_atom_to_molecule(traj, &traj->molecules[1], "H13", "H") == TNG_CRITICAL)
102 // return(TNG_CRITICAL);
108 static tng_function_status tng_test_read_and_write_file
109 (tng_trajectory_t traj)
111 tng_function_status stat;
113 stat = tng_file_headers_read(traj, TNG_USE_HASH);
114 if(stat == TNG_CRITICAL)
118 stat = tng_file_headers_write(traj, TNG_USE_HASH);
119 if(stat == TNG_CRITICAL)
124 while(stat == TNG_SUCCESS)
126 stat = tng_frame_set_read_next(traj, TNG_USE_HASH);
127 if(stat != TNG_SUCCESS)
131 stat = tng_frame_set_write(traj, TNG_USE_HASH);
137 static tng_function_status tng_test_write_and_read_traj(tng_trajectory_t *traj)
139 int i, j, k, nr, cnt;
140 float *data, *molpos, *charges;
141 int64_t mapping[300], n_particles, n_frames_per_frame_set, tot_n_mols;
144 char atom_type[16], annotation[128];
145 tng_function_status stat = TNG_SUCCESS;
147 tng_medium_stride_length_set(*traj, 10);
148 tng_long_stride_length_set(*traj, 100);
150 tng_first_user_name_set(*traj, "User1");
151 tng_first_program_name_set(*traj, "tng_testing");
153 /* Create molecules */
154 if(tng_test_setup_molecules(*traj) == TNG_CRITICAL)
156 return(TNG_CRITICAL);
159 /* Set the box shape */
160 box_shape[1] = box_shape[2] = box_shape[3] = box_shape[5] = box_shape[6] =
162 box_shape[0] = 150.0;
163 box_shape[4] = 145.5;
164 box_shape[8] = 155.5;
165 if(tng_data_block_add(*traj, TNG_TRAJ_BOX_SHAPE, "BOX SHAPE", TNG_DOUBLE_DATA,
166 TNG_NON_TRAJECTORY_BLOCK, 1, 9, 1, TNG_UNCOMPRESSED,
167 box_shape) == TNG_CRITICAL)
169 tng_trajectory_destroy(traj);
170 printf("Cannot write trajectory box shape.\n");
174 /* Set partial charges (treat the water as TIP3P. */
175 tng_num_particles_get(*traj, &n_particles);
176 charges = malloc(sizeof(float) * n_particles);
177 for(i = 0; i < n_particles; i++)
179 stat = tng_atom_type_of_particle_nr_get(*traj, i, atom_type,
181 if(stat == TNG_CRITICAL)
185 if(atom_type[0] == 'O')
189 else if(atom_type[0] == 'H')
194 if(stat == TNG_CRITICAL)
197 printf("Failed setting partial charges.\n");
198 return(TNG_CRITICAL);
201 stat = tng_particle_data_block_add(*traj, TNG_TRAJ_PARTIAL_CHARGES, "PARTIAL CHARGES",
202 TNG_FLOAT_DATA, TNG_NON_TRAJECTORY_BLOCK,
203 1, 1, 1, 0, n_particles,
204 TNG_UNCOMPRESSED, charges);
206 if(stat != TNG_SUCCESS)
208 printf("Failed adding partial charges\n");
209 return(TNG_CRITICAL);
213 /* Generate a custom annotation data block */
214 strcpy(annotation, "This trajectory was generated from tng_io_testing. "
215 "It is not a real MD trajectory.");
216 if(tng_data_block_add(*traj, TNG_TRAJ_GENERAL_COMMENTS, "COMMENTS", TNG_CHAR_DATA,
217 TNG_NON_TRAJECTORY_BLOCK, 1, 1, 1, TNG_UNCOMPRESSED,
218 annotation) != TNG_SUCCESS)
220 printf("Failed adding details annotation data block.\n");
221 return(TNG_CRITICAL);
224 /* Write file headers (includes non trajectory data blocks */
225 if(tng_file_headers_write(*traj, TNG_SKIP_HASH) == TNG_CRITICAL)
227 printf("Cannot write file headers.\n");
231 tng_num_frames_per_frame_set_get(*traj, &n_frames_per_frame_set);
233 data = malloc(sizeof(float) * n_particles *
234 n_frames_per_frame_set * 3);
237 printf("Cannot allocate memory. %s: %d\n", __FILE__, __LINE__);
238 return(TNG_CRITICAL);
241 tng_num_molecules_get(*traj, &tot_n_mols);
242 molpos = malloc(sizeof(float) * tot_n_mols * 3);
244 /* Set initial coordinates */
245 for(i = 0; i < tot_n_mols; i++)
248 /* Somewhat random coordinates (between 0 and 100),
249 * but not specifying a random seed */
250 molpos[nr] = 100.0 * rand() / (RAND_MAX + 1.0);
251 molpos[nr+1] = 100.0 * rand() / (RAND_MAX + 1.0);
252 molpos[nr+2] = 100.0 * rand() / (RAND_MAX + 1.0);
255 /* Generate 200 frame sets - each with 100 frames (by default) */
256 for(i = 0; i < 200; i++)
259 for(j = 0; j < n_frames_per_frame_set; j++)
261 for(k = 0; k < tot_n_mols; k++)
265 molpos[nr] += 2 * (rand() / (RAND_MAX + 1.0)) - 1;
266 molpos[nr+1] += 2 * (rand() / (RAND_MAX + 1.0)) - 1;
267 molpos[nr+2] += 2 * (rand() / (RAND_MAX + 1.0)) - 1;
269 data[cnt++] = molpos[nr];
270 data[cnt++] = molpos[nr + 1];
271 data[cnt++] = molpos[nr + 2];
272 data[cnt++] = molpos[nr] + 1;
273 data[cnt++] = molpos[nr + 1] + 1;
274 data[cnt++] = molpos[nr + 2] + 1;
275 data[cnt++] = molpos[nr] - 1;
276 data[cnt++] = molpos[nr + 1] - 1;
277 data[cnt++] = molpos[nr + 2] - 1;
280 if(tng_frame_set_new(*traj, i * n_frames_per_frame_set,
281 n_frames_per_frame_set) != TNG_SUCCESS)
283 printf("Error creating frame set %d. %s: %d\n",
284 i, __FILE__, __LINE__);
287 return(TNG_CRITICAL);
290 tng_frame_set_particle_mapping_free(*traj);
292 /* Setup particle mapping. Use 4 different mapping blocks with arbitrary
298 if(tng_particle_mapping_add(*traj, 0, 150, mapping) != TNG_SUCCESS)
300 printf("Error creating particle mapping. %s: %d\n",
304 return(TNG_CRITICAL);
310 if(tng_particle_mapping_add(*traj, 150, 150, mapping) != TNG_SUCCESS)
312 printf("Error creating particle mapping. %s: %d\n",
316 return(TNG_CRITICAL);
322 if(tng_particle_mapping_add(*traj, 300, 150, mapping) != TNG_SUCCESS)
324 printf("Error creating particle mapping. %s: %d\n",
328 return(TNG_CRITICAL);
334 if(tng_particle_mapping_add(*traj, 450, 150, mapping) != TNG_SUCCESS)
336 printf("Error creating particle mapping. %s: %d\n",
340 return(TNG_CRITICAL);
343 /* Add the positions in a data block */
344 if(tng_particle_data_block_add(*traj, TNG_TRAJ_POSITIONS,
347 TNG_TRAJECTORY_BLOCK,
348 n_frames_per_frame_set, 3,
350 /* TNG_UNCOMPRESSED, */
351 TNG_GZIP_COMPRESSION,
352 data) != TNG_SUCCESS)
354 printf("Error adding data. %s: %d\n", __FILE__, __LINE__);
357 return(TNG_CRITICAL);
359 /* Write the frame set */
360 if(tng_frame_set_write(*traj, TNG_SKIP_HASH) != TNG_SUCCESS)
362 printf("Error writing frame set. %s: %d\n", __FILE__, __LINE__);
365 return(TNG_CRITICAL);
369 /* Write two more frame sets one frame at a time */
371 /* Make a new frame set - if always using the same mapping blocks
372 * it is not necessary to explicitly add a new frame set - it will
373 * be added automatically when adding data for a frame */
374 /* if(tng_frame_set_new(*traj, i * n_frames_per_frame_set,
375 n_frames_per_frame_set) != TNG_SUCCESS)
377 printf("Error creating frame set %d. %s: %d\n",
378 i, __FILE__, __LINE__);
381 return(TNG_CRITICAL);
384 frame_nr = i * n_frames_per_frame_set;
390 *//* Just use two particle mapping blocks in this frame set *//*
391 if(tng_particle_mapping_add(*traj, 0, 300, mapping) != TNG_SUCCESS)
393 printf("Error creating particle mapping. %s: %d\n",
397 return(TNG_CRITICAL);
403 if(tng_particle_mapping_add(*traj, 300, 300, mapping) != TNG_SUCCESS)
405 printf("Error creating particle mapping. %s: %d\n",
409 return(TNG_CRITICAL);
412 *//* Add the data block to the current frame set *//*
413 if(tng_particle_data_block_add(*traj, TNG_TRAJ_POSITIONS,
416 TNG_TRAJECTORY_BLOCK,
417 n_frames_per_frame_set, 3,
422 printf("Error adding data. %s: %d\n", __FILE__, __LINE__);
425 return(TNG_CRITICAL);
428 *//* Write the frame set to disk *//*
429 if(tng_frame_set_write(*traj, TNG_SKIP_HASH) != TNG_SUCCESS)
431 printf("Error writing frame set. %s: %d\n", __FILE__, __LINE__);
434 return(TNG_CRITICAL);
437 *//* Write particle data to disk - one frame at a time *//*
438 for(i = 0; i < n_frames_per_frame_set * 2; i++)
440 for(j = 0; j < 2; j++)
443 for(k = 0; k < tot_n_mols/2; k++)
446 *//* Move -1 to 1 *//*
447 molpos[nr] += 2 * (rand() / (RAND_MAX + 1.0)) - 1;
448 molpos[nr+1] += 2 * (rand() / (RAND_MAX + 1.0)) - 1;
449 molpos[nr+2] += 2 * (rand() / (RAND_MAX + 1.0)) - 1;
451 data[cnt++] = molpos[nr];
452 data[cnt++] = molpos[nr + 1];
453 data[cnt++] = molpos[nr + 2];
454 data[cnt++] = molpos[nr] + 1;
455 data[cnt++] = molpos[nr + 1] + 1;
456 data[cnt++] = molpos[nr + 2] + 1;
457 data[cnt++] = molpos[nr] - 1;
458 data[cnt++] = molpos[nr + 1] - 1;
459 data[cnt++] = molpos[nr + 2] - 1;
461 if(tng_frame_particle_data_write(*traj, frame_nr + i,
462 TNG_TRAJ_POSITIONS, j * 300, 300,
463 data, TNG_SKIP_HASH) != TNG_SUCCESS)
465 printf("Error adding data. %s: %d\n", __FILE__, __LINE__);
468 return(TNG_CRITICAL);
476 tng_trajectory_destroy(traj);
477 tng_trajectory_init(traj);
478 tng_input_file_set(*traj, TNG_EXAMPLE_FILES_DIR "tng_test.tng");
480 stat = tng_file_headers_read(*traj, TNG_SKIP_HASH);
482 while(stat == TNG_SUCCESS)
484 stat = tng_frame_set_read_next(*traj, TNG_SKIP_HASH);
490 /* This test relies on knowing that the box shape is stored as double */
491 tng_function_status tng_test_get_box_data(tng_trajectory_t traj)
493 int64_t n_frames, n_values_per_frame;
494 union data_values **values = 0;
497 if(tng_data_get(traj, TNG_TRAJ_BOX_SHAPE, &values, &n_frames,
498 &n_values_per_frame, &type) != TNG_SUCCESS)
500 printf("Failed getting box shape. %s: %d\n", __FILE__, __LINE__);
501 return(TNG_CRITICAL);
506 // printf("Box shape:");
507 // for(i=0; i<n_frames; i++)
509 // for(j=0; j<n_values_per_frame; j++)
511 // printf("\t%f", (values[i][j]).d);
516 tng_data_values_free(traj, values, n_frames, n_values_per_frame, type);
521 /* This test relies on knowing that the positions are stored as float
522 * and that the data is not sparse (i.e. as many frames in the data
523 * as in the frame set */
524 tng_function_status tng_test_get_positions_data(tng_trajectory_t traj)
526 int64_t n_frames, n_particles, n_values_per_frame;
527 union data_values ***values = 0;
530 if(tng_particle_data_get(traj, TNG_TRAJ_POSITIONS, &values, &n_frames,
531 &n_particles, &n_values_per_frame, &type) !=
534 printf("Failed getting particle positions. %s: %d\n", __FILE__, __LINE__);
535 return(TNG_CRITICAL);
540 // struct tng_trajectory_frame_set *frame_set =
541 // &traj->current_trajectory_frame_set;
542 // for(i = 0; i<n_frames; i++)
544 // printf("Frame %"PRId64"\n", frame_set->first_frame + i);
545 // for(j = 0; j<n_particles; j++)
547 // printf("Particle %"PRId64":", j);
548 // for(k=0; k<n_values_per_frame; k++)
550 // printf("\t%f", (values[i][j][k]).f);
556 tng_particle_data_values_free(traj, values, n_frames, n_particles,
557 n_values_per_frame, type);
561 tng_particle_data_interval_get(traj, TNG_TRAJ_POSITIONS, 11000, 11499,
562 TNG_SKIP_HASH, &values, &n_particles,
563 &n_values_per_frame, &type);
565 /* Here the particle positions can be printed */
567 tng_particle_data_values_free(traj, values, 500, n_particles,
568 n_values_per_frame, type);
574 tng_function_status tng_test_append(tng_trajectory_t traj)
576 tng_function_status stat;
578 stat = tng_util_trajectory_open(TNG_EXAMPLE_FILES_DIR "tng_test.tng", 'a', &traj);
579 if(stat != TNG_SUCCESS)
584 tng_last_user_name_set(traj, "User2");
585 tng_last_program_name_set(traj, "tng_testing");
586 tng_file_headers_write(traj, TNG_USE_HASH);
588 stat = tng_util_trajectory_close(&traj);
595 tng_trajectory_t traj;
596 tng_function_status stat;
597 char time_str[TNG_MAX_DATE_STR_LEN];
599 if(tng_trajectory_init(&traj) != TNG_SUCCESS)
601 tng_trajectory_destroy(&traj);
602 printf("Test Init trajectory:\t\t\t\tFailed. %s: %d.\n",
606 printf("Test Init trajectory:\t\t\t\tSucceeded.\n");
608 tng_time_get_str(traj, time_str);
610 printf("Creation time: %s\n", time_str);
612 tng_input_file_set(traj, TNG_EXAMPLE_FILES_DIR "tng_example.tng");
613 tng_output_file_set(traj, TNG_EXAMPLE_FILES_DIR "tng_example_out.tng");
616 if(tng_test_read_and_write_file(traj) == TNG_CRITICAL)
618 printf("Test Read and write file:\t\t\tFailed. %s: %d\n",
623 printf("Test Read and write file:\t\t\tSucceeded.\n");
626 if(tng_test_get_box_data(traj) != TNG_SUCCESS)
628 printf("Test Get data:\t\t\t\t\tFailed. %s: %d\n",
633 printf("Test Get data:\t\t\t\t\tSucceeded.\n");
636 if(tng_trajectory_destroy(&traj) == TNG_CRITICAL ||
637 tng_trajectory_init(&traj) == TNG_CRITICAL)
639 printf("Test Destroy and init trajectory:\t\tFailed. %s: %d\n",
644 printf("Test Destroy and init trajectory:\t\tSucceeded.\n");
648 tng_output_file_set(traj, TNG_EXAMPLE_FILES_DIR "tng_test.tng");
650 if(tng_test_write_and_read_traj(&traj) == TNG_CRITICAL)
652 printf("Test Write and read file:\t\t\tFailed. %s: %d\n",
657 printf("Test Write and read file:\t\t\tSucceeded.\n");
660 if(tng_test_get_positions_data(traj) != TNG_SUCCESS)
662 printf("Test Get particle data:\t\t\t\tFailed. %s: %d\n",
667 printf("Test Get particle data:\t\t\t\tSucceeded.\n");
670 if(tng_trajectory_destroy(&traj) == TNG_CRITICAL)
672 printf("Test Destroy trajectory:\t\t\tFailed. %s: %d.\n",
678 printf("Test Destroy trajectory:\t\t\tSucceeded.\n");
682 stat = tng_util_trajectory_open(TNG_EXAMPLE_FILES_DIR "tng_test.tng", 'r', &traj);
684 if(stat != TNG_SUCCESS)
686 printf("Test Utility function open:\t\t\tFailed. %s: %d.\n",
692 printf("Test Utility function open:\t\t\tSucceeded.\n");
695 stat = tng_util_trajectory_close(&traj);
696 if(stat != TNG_SUCCESS)
698 printf("Test Utility function close:\t\t\tFailed. %s: %d.\n",
704 printf("Test Utility function close:\t\t\tSucceeded.\n");
707 if(tng_test_append(traj) != TNG_SUCCESS)
709 printf("Test Append:\t\t\t\t\tFailed. %s: %d.\n",
715 printf("Test Append:\t\t\t\t\tSucceeded.\n");
718 printf("Tests finished\n");