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 "tng/tng_io.h"
19 #include "tng/version.h"
21 static tng_function_status
tng_test_setup_molecules(tng_trajectory_t traj
)
23 tng_molecule_t molecule
;
25 tng_residue_t residue
;
29 tng_molecule_add(traj
, "water", &molecule
);
30 tng_molecule_chain_add(traj
, molecule
, "W", &chain
);
31 tng_chain_residue_add(traj
, chain
, "WAT", &residue
);
32 if(tng_residue_atom_add(traj
, residue
, "O", "O", &atom
) == TNG_CRITICAL
)
36 if(tng_residue_atom_add(traj
, residue
, "HO1", "H", &atom
) == TNG_CRITICAL
)
40 if(tng_residue_atom_add(traj
, residue
, "HO2", "H", &atom
) == TNG_CRITICAL
)
44 tng_molecule_cnt_set(traj
, molecule
, 200);
45 tng_molecule_cnt_get(traj
, molecule
, &cnt
);
46 /* printf("Created %"PRId64" %s molecules.\n", cnt, molecule->name); */
48 /* traj->molecule_cnt_list[traj->n_molecules-1] = 5;
49 // tng_molecule_name_set(traj, &traj->molecules[1], "ligand");
50 // tng_molecule_name_set(traj, &traj->molecules[2], "water");
51 // tng_molecule_name_set(traj, &traj->molecules[3], "dummy");
52 // traj->molecules[0].id = 0;
53 // traj->molecules[1].id = 1;
54 // traj->molecules[2].id = 2;
55 // traj->molecules[3].id = 3;
57 // if(tng_add_atom_to_molecule(traj, &traj->molecules[0], "atom1", "type1") == TNG_CRITICAL)
59 // return(TNG_CRITICAL);
61 // if(tng_add_atom_to_molecule(traj, &traj->molecules[0], "atom2", "type1") == TNG_CRITICAL)
63 // return(TNG_CRITICAL);
65 // if(tng_add_atom_to_molecule(traj, &traj->molecules[0], "atom3", "type1") == TNG_CRITICAL)
67 // return(TNG_CRITICAL);
69 // if(tng_add_atom_to_molecule(traj, &traj->molecules[0], "atom4", "type2") == TNG_CRITICAL)
71 // return(TNG_CRITICAL);
73 // if(tng_add_atom_to_molecule(traj, &traj->molecules[0], "atom5", "type2") == TNG_CRITICAL)
75 // return(TNG_CRITICAL);
77 // if(tng_add_atom_to_molecule(traj, &traj->molecules[0], "atom6", "type2") == TNG_CRITICAL)
79 // return(TNG_CRITICAL);
81 // if(tng_add_atom_to_molecule(traj, &traj->molecules[0], "atom7", "type3") == TNG_CRITICAL)
83 // return(TNG_CRITICAL);
85 // if(tng_add_atom_to_molecule(traj, &traj->molecules[1], "C1", "C") == TNG_CRITICAL)
87 // return(TNG_CRITICAL);
89 // if(tng_add_atom_to_molecule(traj, &traj->molecules[1], "O1", "O") == TNG_CRITICAL)
91 // return(TNG_CRITICAL);
93 // if(tng_add_atom_to_molecule(traj, &traj->molecules[1], "H11", "H") == TNG_CRITICAL)
95 // return(TNG_CRITICAL);
97 // if(tng_add_atom_to_molecule(traj, &traj->molecules[1], "H12", "H") == TNG_CRITICAL)
99 // return(TNG_CRITICAL);
101 // if(tng_add_atom_to_molecule(traj, &traj->molecules[1], "H13", "H") == TNG_CRITICAL)
103 // return(TNG_CRITICAL);
109 static tng_function_status tng_test_read_and_write_file
110 (tng_trajectory_t traj
)
112 tng_function_status stat
;
114 stat
= tng_file_headers_read(traj
, TNG_USE_HASH
);
115 if(stat
== TNG_CRITICAL
)
119 stat
= tng_file_headers_write(traj
, TNG_USE_HASH
);
120 if(stat
== TNG_CRITICAL
)
125 while(stat
== TNG_SUCCESS
)
127 stat
= tng_frame_set_read_next(traj
, TNG_USE_HASH
);
128 if(stat
!= TNG_SUCCESS
)
132 stat
= tng_frame_set_write(traj
, TNG_USE_HASH
);
138 static tng_function_status
tng_test_write_and_read_traj(tng_trajectory_t
*traj
)
140 int i
, j
, k
, nr
, cnt
;
141 float *data
, *molpos
, *charges
;
142 int64_t mapping
[300], n_particles
, n_frames_per_frame_set
, tot_n_mols
;
145 char atom_type
[16], annotation
[128];
146 tng_function_status stat
= TNG_SUCCESS
;
148 tng_medium_stride_length_set(*traj
, 10);
149 tng_long_stride_length_set(*traj
, 100);
151 tng_first_user_name_set(*traj
, "User1");
152 tng_first_program_name_set(*traj
, "tng_testing");
154 /* Create molecules */
155 if(tng_test_setup_molecules(*traj
) == TNG_CRITICAL
)
157 return(TNG_CRITICAL
);
160 /* Set the box shape */
161 box_shape
[1] = box_shape
[2] = box_shape
[3] = box_shape
[5] = box_shape
[6] =
163 box_shape
[0] = 150.0;
164 box_shape
[4] = 145.5;
165 box_shape
[8] = 155.5;
166 if(tng_data_block_add(*traj
, TNG_TRAJ_BOX_SHAPE
, "BOX SHAPE", TNG_DOUBLE_DATA
,
167 TNG_NON_TRAJECTORY_BLOCK
, 1, 9, 1, TNG_UNCOMPRESSED
,
168 box_shape
) == TNG_CRITICAL
)
170 tng_trajectory_destroy(traj
);
171 printf("Cannot write trajectory box shape.\n");
175 /* Set partial charges (treat the water as TIP3P. */
176 tng_num_particles_get(*traj
, &n_particles
);
177 charges
= malloc(sizeof(float) * n_particles
);
178 for(i
= 0; i
< n_particles
; i
++)
180 stat
= tng_atom_type_of_particle_nr_get(*traj
, i
, atom_type
,
182 if(stat
== TNG_CRITICAL
)
186 if(atom_type
[0] == 'O')
190 else if(atom_type
[0] == 'H')
195 if(stat
== TNG_CRITICAL
)
198 printf("Failed setting partial charges.\n");
199 return(TNG_CRITICAL
);
202 stat
= tng_particle_data_block_add(*traj
, TNG_TRAJ_PARTIAL_CHARGES
, "PARTIAL CHARGES",
203 TNG_FLOAT_DATA
, TNG_NON_TRAJECTORY_BLOCK
,
204 1, 1, 1, 0, n_particles
,
205 TNG_UNCOMPRESSED
, charges
);
207 if(stat
!= TNG_SUCCESS
)
209 printf("Failed adding partial charges\n");
210 return(TNG_CRITICAL
);
214 /* Generate a custom annotation data block */
215 strcpy(annotation
, "This trajectory was generated from tng_io_testing. "
216 "It is not a real MD trajectory.");
217 if(tng_data_block_add(*traj
, TNG_TRAJ_GENERAL_COMMENTS
, "COMMENTS", TNG_CHAR_DATA
,
218 TNG_NON_TRAJECTORY_BLOCK
, 1, 1, 1, TNG_UNCOMPRESSED
,
219 annotation
) != TNG_SUCCESS
)
221 printf("Failed adding details annotation data block.\n");
222 return(TNG_CRITICAL
);
225 /* Write file headers (includes non trajectory data blocks */
226 if(tng_file_headers_write(*traj
, TNG_SKIP_HASH
) == TNG_CRITICAL
)
228 printf("Cannot write file headers.\n");
232 tng_num_frames_per_frame_set_get(*traj
, &n_frames_per_frame_set
);
234 data
= malloc(sizeof(float) * n_particles
*
235 n_frames_per_frame_set
* 3);
238 printf("Cannot allocate memory. %s: %d\n", __FILE__
, __LINE__
);
239 return(TNG_CRITICAL
);
242 tng_num_molecules_get(*traj
, &tot_n_mols
);
243 molpos
= malloc(sizeof(float) * tot_n_mols
* 3);
245 /* Set initial coordinates */
246 for(i
= 0; i
< tot_n_mols
; i
++)
249 /* Somewhat random coordinates (between 0 and 100),
250 * but not specifying a random seed */
251 molpos
[nr
] = 100.0 * rand() / (RAND_MAX
+ 1.0);
252 molpos
[nr
+1] = 100.0 * rand() / (RAND_MAX
+ 1.0);
253 molpos
[nr
+2] = 100.0 * rand() / (RAND_MAX
+ 1.0);
256 /* Generate 200 frame sets - each with 100 frames (by default) */
257 for(i
= 0; i
< 200; i
++)
260 for(j
= 0; j
< n_frames_per_frame_set
; j
++)
262 for(k
= 0; k
< tot_n_mols
; k
++)
266 molpos
[nr
] += 2 * (rand() / (RAND_MAX
+ 1.0)) - 1;
267 molpos
[nr
+1] += 2 * (rand() / (RAND_MAX
+ 1.0)) - 1;
268 molpos
[nr
+2] += 2 * (rand() / (RAND_MAX
+ 1.0)) - 1;
270 data
[cnt
++] = molpos
[nr
];
271 data
[cnt
++] = molpos
[nr
+ 1];
272 data
[cnt
++] = molpos
[nr
+ 2];
273 data
[cnt
++] = molpos
[nr
] + 1;
274 data
[cnt
++] = molpos
[nr
+ 1] + 1;
275 data
[cnt
++] = molpos
[nr
+ 2] + 1;
276 data
[cnt
++] = molpos
[nr
] - 1;
277 data
[cnt
++] = molpos
[nr
+ 1] - 1;
278 data
[cnt
++] = molpos
[nr
+ 2] - 1;
281 if(tng_frame_set_new(*traj
, i
* n_frames_per_frame_set
,
282 n_frames_per_frame_set
) != TNG_SUCCESS
)
284 printf("Error creating frame set %d. %s: %d\n",
285 i
, __FILE__
, __LINE__
);
288 return(TNG_CRITICAL
);
291 tng_frame_set_particle_mapping_free(*traj
);
293 /* Setup particle mapping. Use 4 different mapping blocks with arbitrary
299 if(tng_particle_mapping_add(*traj
, 0, 150, mapping
) != TNG_SUCCESS
)
301 printf("Error creating particle mapping. %s: %d\n",
305 return(TNG_CRITICAL
);
311 if(tng_particle_mapping_add(*traj
, 150, 150, mapping
) != TNG_SUCCESS
)
313 printf("Error creating particle mapping. %s: %d\n",
317 return(TNG_CRITICAL
);
323 if(tng_particle_mapping_add(*traj
, 300, 150, mapping
) != TNG_SUCCESS
)
325 printf("Error creating particle mapping. %s: %d\n",
329 return(TNG_CRITICAL
);
335 if(tng_particle_mapping_add(*traj
, 450, 150, mapping
) != TNG_SUCCESS
)
337 printf("Error creating particle mapping. %s: %d\n",
341 return(TNG_CRITICAL
);
344 /* Add the positions in a data block */
345 if(tng_particle_data_block_add(*traj
, TNG_TRAJ_POSITIONS
,
348 TNG_TRAJECTORY_BLOCK
,
349 n_frames_per_frame_set
, 3,
351 /* TNG_UNCOMPRESSED, */
352 TNG_GZIP_COMPRESSION
,
353 data
) != TNG_SUCCESS
)
355 printf("Error adding data. %s: %d\n", __FILE__
, __LINE__
);
358 return(TNG_CRITICAL
);
360 /* Write the frame set */
361 if(tng_frame_set_write(*traj
, TNG_SKIP_HASH
) != TNG_SUCCESS
)
363 printf("Error writing frame set. %s: %d\n", __FILE__
, __LINE__
);
366 return(TNG_CRITICAL
);
370 /* Write two more frame sets one frame at a time */
372 /* Make a new frame set - if always using the same mapping blocks
373 * it is not necessary to explicitly add a new frame set - it will
374 * be added automatically when adding data for a frame */
375 /* if(tng_frame_set_new(*traj, i * n_frames_per_frame_set,
376 n_frames_per_frame_set) != TNG_SUCCESS)
378 printf("Error creating frame set %d. %s: %d\n",
379 i, __FILE__, __LINE__);
382 return(TNG_CRITICAL);
385 frame_nr = i * n_frames_per_frame_set;
391 *//* Just use two particle mapping blocks in this frame set *//*
392 if(tng_particle_mapping_add(*traj, 0, 300, mapping) != TNG_SUCCESS)
394 printf("Error creating particle mapping. %s: %d\n",
398 return(TNG_CRITICAL);
404 if(tng_particle_mapping_add(*traj, 300, 300, mapping) != TNG_SUCCESS)
406 printf("Error creating particle mapping. %s: %d\n",
410 return(TNG_CRITICAL);
413 *//* Add the data block to the current frame set *//*
414 if(tng_particle_data_block_add(*traj, TNG_TRAJ_POSITIONS,
417 TNG_TRAJECTORY_BLOCK,
418 n_frames_per_frame_set, 3,
423 printf("Error adding data. %s: %d\n", __FILE__, __LINE__);
426 return(TNG_CRITICAL);
429 *//* Write the frame set to disk *//*
430 if(tng_frame_set_write(*traj, TNG_SKIP_HASH) != TNG_SUCCESS)
432 printf("Error writing frame set. %s: %d\n", __FILE__, __LINE__);
435 return(TNG_CRITICAL);
438 *//* Write particle data to disk - one frame at a time *//*
439 for(i = 0; i < n_frames_per_frame_set * 2; i++)
441 for(j = 0; j < 2; j++)
444 for(k = 0; k < tot_n_mols/2; k++)
447 *//* Move -1 to 1 *//*
448 molpos[nr] += 2 * (rand() / (RAND_MAX + 1.0)) - 1;
449 molpos[nr+1] += 2 * (rand() / (RAND_MAX + 1.0)) - 1;
450 molpos[nr+2] += 2 * (rand() / (RAND_MAX + 1.0)) - 1;
452 data[cnt++] = molpos[nr];
453 data[cnt++] = molpos[nr + 1];
454 data[cnt++] = molpos[nr + 2];
455 data[cnt++] = molpos[nr] + 1;
456 data[cnt++] = molpos[nr + 1] + 1;
457 data[cnt++] = molpos[nr + 2] + 1;
458 data[cnt++] = molpos[nr] - 1;
459 data[cnt++] = molpos[nr + 1] - 1;
460 data[cnt++] = molpos[nr + 2] - 1;
462 if(tng_frame_particle_data_write(*traj, frame_nr + i,
463 TNG_TRAJ_POSITIONS, j * 300, 300,
464 data, TNG_SKIP_HASH) != TNG_SUCCESS)
466 printf("Error adding data. %s: %d\n", __FILE__, __LINE__);
469 return(TNG_CRITICAL);
477 tng_trajectory_destroy(traj
);
478 tng_trajectory_init(traj
);
479 tng_input_file_set(*traj
, TNG_EXAMPLE_FILES_DIR
"tng_test.tng");
481 stat
= tng_file_headers_read(*traj
, TNG_SKIP_HASH
);
483 while(stat
== TNG_SUCCESS
)
485 stat
= tng_frame_set_read_next(*traj
, TNG_SKIP_HASH
);
491 /* This test relies on knowing that the box shape is stored as double */
492 tng_function_status
tng_test_get_box_data(tng_trajectory_t traj
)
494 int64_t n_frames
, n_values_per_frame
;
495 union data_values
**values
= 0;
498 if(tng_data_get(traj
, TNG_TRAJ_BOX_SHAPE
, &values
, &n_frames
,
499 &n_values_per_frame
, &type
) != TNG_SUCCESS
)
501 printf("Failed getting box shape. %s: %d\n", __FILE__
, __LINE__
);
502 return(TNG_CRITICAL
);
507 // printf("Box shape:");
508 // for(i=0; i<n_frames; i++)
510 // for(j=0; j<n_values_per_frame; j++)
512 // printf("\t%f", (values[i][j]).d);
517 tng_data_values_free(traj
, values
, n_frames
, n_values_per_frame
, type
);
522 /* This test relies on knowing that the positions are stored as float
523 * and that the data is not sparse (i.e. as many frames in the data
524 * as in the frame set */
525 tng_function_status
tng_test_get_positions_data(tng_trajectory_t traj
)
527 int64_t n_frames
, n_particles
, n_values_per_frame
;
528 union data_values
***values
= 0;
531 if(tng_particle_data_get(traj
, TNG_TRAJ_POSITIONS
, &values
, &n_frames
,
532 &n_particles
, &n_values_per_frame
, &type
) !=
535 printf("Failed getting particle positions. %s: %d\n", __FILE__
, __LINE__
);
536 return(TNG_CRITICAL
);
541 // struct tng_trajectory_frame_set *frame_set =
542 // &traj->current_trajectory_frame_set;
543 // for(i = 0; i<n_frames; i++)
545 // printf("Frame %"PRId64"\n", frame_set->first_frame + i);
546 // for(j = 0; j<n_particles; j++)
548 // printf("Particle %"PRId64":", j);
549 // for(k=0; k<n_values_per_frame; k++)
551 // printf("\t%f", (values[i][j][k]).f);
557 tng_particle_data_values_free(traj
, values
, n_frames
, n_particles
,
558 n_values_per_frame
, type
);
562 tng_particle_data_interval_get(traj
, TNG_TRAJ_POSITIONS
, 11000, 11499,
563 TNG_SKIP_HASH
, &values
, &n_particles
,
564 &n_values_per_frame
, &type
);
566 /* Here the particle positions can be printed */
568 tng_particle_data_values_free(traj
, values
, 500, n_particles
,
569 n_values_per_frame
, type
);
575 tng_function_status
tng_test_append(tng_trajectory_t traj
)
577 tng_function_status stat
;
579 stat
= tng_util_trajectory_open(TNG_EXAMPLE_FILES_DIR
"tng_test.tng", 'a', &traj
);
580 if(stat
!= TNG_SUCCESS
)
585 tng_last_user_name_set(traj
, "User2");
586 tng_last_program_name_set(traj
, "tng_testing");
587 tng_file_headers_write(traj
, TNG_USE_HASH
);
589 stat
= tng_util_trajectory_close(&traj
);
596 tng_trajectory_t traj
;
597 tng_function_status stat
;
598 char time_str
[TNG_MAX_DATE_STR_LEN
];
599 char version_str
[TNG_MAX_STR_LEN
];
601 tng_version(traj
, version_str
, TNG_MAX_STR_LEN
);
602 if(strncmp(TNG_VERSION
, version_str
, TNG_MAX_STR_LEN
) == 0)
604 printf("Test version control: \t\t\t\tSucceeded.\n");
608 printf("Test version control: \t\t\t\tFailed.\n");
611 if(tng_trajectory_init(&traj
) != TNG_SUCCESS
)
613 tng_trajectory_destroy(&traj
);
614 printf("Test Init trajectory:\t\t\t\tFailed. %s: %d.\n",
618 printf("Test Init trajectory:\t\t\t\tSucceeded.\n");
620 tng_time_get_str(traj
, time_str
);
622 printf("Creation time: %s\n", time_str
);
624 tng_input_file_set(traj
, TNG_EXAMPLE_FILES_DIR
"tng_example.tng");
625 tng_output_file_set(traj
, TNG_EXAMPLE_FILES_DIR
"tng_example_out.tng");
628 if(tng_test_read_and_write_file(traj
) == TNG_CRITICAL
)
630 printf("Test Read and write file:\t\t\tFailed. %s: %d\n",
635 printf("Test Read and write file:\t\t\tSucceeded.\n");
638 if(tng_test_get_box_data(traj
) != TNG_SUCCESS
)
640 printf("Test Get data:\t\t\t\t\tFailed. %s: %d\n",
645 printf("Test Get data:\t\t\t\t\tSucceeded.\n");
648 if(tng_trajectory_destroy(&traj
) == TNG_CRITICAL
||
649 tng_trajectory_init(&traj
) == TNG_CRITICAL
)
651 printf("Test Destroy and init trajectory:\t\tFailed. %s: %d\n",
656 printf("Test Destroy and init trajectory:\t\tSucceeded.\n");
660 tng_output_file_set(traj
, TNG_EXAMPLE_FILES_DIR
"tng_test.tng");
662 if(tng_test_write_and_read_traj(&traj
) == TNG_CRITICAL
)
664 printf("Test Write and read file:\t\t\tFailed. %s: %d\n",
669 printf("Test Write and read file:\t\t\tSucceeded.\n");
672 if(tng_test_get_positions_data(traj
) != TNG_SUCCESS
)
674 printf("Test Get particle data:\t\t\t\tFailed. %s: %d\n",
679 printf("Test Get particle data:\t\t\t\tSucceeded.\n");
682 if(tng_trajectory_destroy(&traj
) == TNG_CRITICAL
)
684 printf("Test Destroy trajectory:\t\t\tFailed. %s: %d.\n",
690 printf("Test Destroy trajectory:\t\t\tSucceeded.\n");
694 stat
= tng_util_trajectory_open(TNG_EXAMPLE_FILES_DIR
"tng_test.tng", 'r', &traj
);
696 if(stat
!= TNG_SUCCESS
)
698 printf("Test Utility function open:\t\t\tFailed. %s: %d.\n",
704 printf("Test Utility function open:\t\t\tSucceeded.\n");
707 stat
= tng_util_trajectory_close(&traj
);
708 if(stat
!= TNG_SUCCESS
)
710 printf("Test Utility function close:\t\t\tFailed. %s: %d.\n",
716 printf("Test Utility function close:\t\t\tSucceeded.\n");
719 if(tng_test_append(traj
) != TNG_SUCCESS
)
721 printf("Test Append:\t\t\t\t\tFailed. %s: %d.\n",
727 printf("Test Append:\t\t\t\t\tSucceeded.\n");
730 printf("Tests finished\n");