1 /* This code is part of the tng binary trajectory format.
5 * Written by Magnus Lundborg
6 * Copyright (c) 2012-2013, The GROMACS development team.
7 * Check out http://www.gromacs.org for more information.
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the Revised BSD License.
14 #ifdef USE_STD_INTTYPES_H
27 #include "../../include/tng_io.h"
28 #include "../../include/md5.h"
29 #include "../../include/compression/tng_compress.h"
33 /** One of the atoms of the bond */
35 /** The other atom of the bond */
40 /** The residue containing this atom */
41 tng_residue_t residue
;
42 /** A unique (per molecule) ID number of the atom */
44 /** The atom_type (depending on the forcefield) */
46 /** The name of the atom */
51 /** The chain containing this residue */
53 /** A unique (per chain) ID number of the residue */
55 /** The name of the residue */
57 /** The number of atoms in the residue */
59 /** A list of atoms in the residue */
64 /** The molecule containing this chain */
65 tng_molecule_t molecule
;
66 /** A unique (per molecule) ID number of the chain */
68 /** The name of the chain */
70 /** The number of residues in the chain */
72 /** A list of residues in the chain */
73 tng_residue_t residues
;
77 /** A unique ID number of the molecule */
79 /** Quaternary structure of the molecule.
84 int64_t quaternary_str
;
85 /** The number of chains in the molecule */
87 /** The number of residues in the molecule */
89 /** The number of atoms in the molecule */
91 /** The number of bonds in the molecule. If the bonds are not specified this
94 /** The name of the molecule */
96 /** A list of chains in the molecule */
98 /** A list of residues in the molecule */
99 tng_residue_t residues
;
100 /** A list of the atoms in the molecule */
102 /** A list of the bonds in the molecule */
106 struct tng_gen_block
{
107 /** The size of the block header in bytes */
108 int64_t header_contents_size
;
109 /** The size of the block contents in bytes */
110 int64_t block_contents_size
;
111 /** The ID of the block to determine its type */
113 /** The MD5 hash of the block to verify integrity */
114 char md5_hash
[TNG_MD5_HASH_LEN
];
115 /** The name of the block */
117 /** The library version used to write the block */
118 int64_t block_version
;
119 int64_t alt_hash_type
;
120 int64_t alt_hash_len
;
122 int64_t signature_type
;
123 int64_t signature_len
;
125 /** The full block header contents */
126 char *header_contents
;
127 /** The full block contents */
128 char *block_contents
;
131 struct tng_particle_mapping
{
132 /** The index number of the first particle in this mapping block */
133 int64_t num_first_particle
;
134 /** The number of particles list in this mapping block */
136 /** the mapping of index numbers to the real particle numbers in the
137 * trajectory. real_particle_numbers[0] is the real particle number
138 * (as it is numbered in the molecular system) of the first particle
139 * in the data blocks covered by this particle mapping block */
140 int64_t *real_particle_numbers
;
143 struct tng_trajectory_frame_set
{
144 /** The number of different particle mapping blocks present. */
145 int64_t n_mapping_blocks
;
146 /** The atom mappings of this frame set */
147 struct tng_particle_mapping
*mappings
;
148 /** The first frame of this frame set */
150 /** The number of frames in this frame set */
152 /** The number of written frames in this frame set (used when writing one
153 * frame at a time). */
154 int64_t n_written_frames
;
155 /** The number of frames not yet written to file in this frame set
156 * (used from the utility functions to finish the writing properly. */
157 int64_t n_unwritten_frames
;
160 /** A list of the number of each molecule type - only used when using
161 * variable number of atoms */
162 int64_t *molecule_cnt_list
;
163 /** The number of particles/atoms - only used when using variable number
166 /** The file position of the next frame set */
167 int64_t next_frame_set_file_pos
;
168 /** The file position of the previous frame set */
169 int64_t prev_frame_set_file_pos
;
170 /** The file position of the frame set one long stride step ahead */
171 int64_t medium_stride_next_frame_set_file_pos
;
172 /** The file position of the frame set one long stride step behind */
173 int64_t medium_stride_prev_frame_set_file_pos
;
174 /** The file position of the frame set one long stride step ahead */
175 int64_t long_stride_next_frame_set_file_pos
;
176 /** The file position of the frame set one long stride step behind */
177 int64_t long_stride_prev_frame_set_file_pos
;
178 /** Time stamp (in seconds) of first frame in frame set */
179 double first_frame_time
;
181 /* The data blocks in a frame set are trajectory data blocks */
182 /** The number of trajectory data blocks of particle dependent data */
183 int n_particle_data_blocks
;
184 /** A list of data blocks containing particle dependent data */
185 struct tng_particle_data
*tr_particle_data
;
186 /** The number of trajectory data blocks independent of particles */
188 /** A list of data blocks containing particle indepdendent data */
189 struct tng_non_particle_data
*tr_data
;
192 /* FIXME: Should there be a pointer to a tng_gen_block from each data block? */
193 struct tng_particle_data
{
194 /** The block ID of the data block containing this particle data.
195 * This is used to determine the kind of data that is stored */
197 /** The name of the data block. This is used to determine the kind of
198 * data that is stored */
200 /** The type of data stored. */
202 /** The frame number of the first data value */
203 int64_t first_frame_with_data
;
204 /** The number of frames in this frame set */
206 /** The number of values stored per frame */
207 int64_t n_values_per_frame
;
208 /** The number of frames between each data point - e.g. when
209 * storing sparse data. */
210 int64_t stride_length
;
211 /** ID of the CODEC used for compression 0 == no compression. */
213 /** If reading one frame at a time this is the last read frame */
214 int64_t last_retrieved_frame
;
215 /** The multiplier used for getting integer values for compression */
216 double compression_multiplier
;
217 /** A 1-dimensional array of values of length
218 * [sizeof (datatype)] * n_frames * n_particles * n_values_per_frame */
220 /** If storing character data store it in a 3-dimensional array */
224 struct tng_non_particle_data
{
225 /** The ID of the data block */
227 /** The name of the data block. This is used to determine the kind of
228 * data that is stored */
230 /** The type of data stored. */
232 /** The first frame number of the first data value */
233 int64_t first_frame_with_data
;
234 /** The number of frames in this data block */
236 /** The number of values stored per frame */
237 int64_t n_values_per_frame
;
238 /** The number of frames between each data value, e.g. if storing data
239 * that is not saved every frame. */
240 int64_t stride_length
;
241 /** ID of the CODEC used for compression. 0 == no compression. */
243 /** If reading one frame at a time this is the last read frame */
244 int64_t last_retrieved_frame
;
245 /** Compressed data is stored as integers. This compression multiplier is
246 * the multiplication factor to convert from integer to float/double */
247 double compression_multiplier
;
248 /** A 1-dimensional array of values of length
249 * [sizeof (datatype)] * n_frames * n_values_per_frame */
251 /** If storing character data store it in a 3-dimensional array */
257 struct tng_trajectory
{
258 /** The path of the input trajectory file */
259 char *input_file_path
;
260 /** A handle to the input file */
262 /** The length of the input file */
264 /** The path of the output trajectory file */
265 char *output_file_path
;
266 /** A handle to the output file */
268 /** Function to swap 32 bit values to and from the endianness of the
270 tng_function_status (*input_endianness_swap_func_32
)(const tng_trajectory_t
, int32_t *);
271 /** Function to swap 64 bit values to and from the endianness of the
273 tng_function_status (*input_endianness_swap_func_64
)(const tng_trajectory_t
, int64_t *);
274 /** Function to swap 32 bit values to and from the endianness of the
276 tng_function_status (*output_endianness_swap_func_32
)(const tng_trajectory_t
, int32_t *);
277 /** Function to swap 64 bit values to and from the endianness of the
279 tng_function_status (*output_endianness_swap_func_64
)(const tng_trajectory_t
, int64_t *);
280 /** The endianness of 32 bit values of the current computer */
282 /** The endianness of 64 bit values of the current computer */
285 /** The name of the program producing this trajectory */
286 char *first_program_name
;
287 /** The forcefield used in the simulations */
288 char *forcefield_name
;
289 /** The name of the user running the simulations */
290 char *first_user_name
;
291 /** The name of the computer on which the simulations were performed */
292 char *first_computer_name
;
293 /** The PGP signature of the user creating the file. */
294 char *first_pgp_signature
;
295 /** The name of the program used when making last modifications to the
297 char *last_program_name
;
298 /** The name of the user making the last modifications to the file */
299 char *last_user_name
;
300 /** The name of the computer on which the last modifications were made */
301 char *last_computer_name
;
302 /** The PGP signature of the user making the last modifications to the
304 char *last_pgp_signature
;
305 /** The time (n seconds since 1970) when the file was created */
307 /** The exponential of the value of the distance unit used. The default
308 * distance unit is nm (1e-9), i.e. distance_unit_exponential = -9. If
309 * the measurements are in Ã… the distance_unit_exponential = -10. */
310 int64_t distance_unit_exponential
;
312 /** A flag indicating if the number of atoms can vary throughout the
313 * simulation, e.g. using a grand canonical ensemble */
314 char var_num_atoms_flag
;
315 /** The number of frames in a frame set. It is allowed to have frame sets
316 * with fewer frames, but this will help searching for specific frames */
317 int64_t frame_set_n_frames
;
318 /** The number of frame sets in a medium stride step */
319 int64_t medium_stride_length
;
320 /** The number of frame sets in a long stride step */
321 int64_t long_stride_length
;
322 /** The current (can change from one frame set to another) time length
323 * (in seconds) of one frame */
324 double time_per_frame
;
326 /** The number of different kinds of molecules in the trajectory */
328 /** A list of molecules in the trajectory */
329 tng_molecule_t molecules
;
330 /** A list of the count of each molecule - if using variable number of
331 * particles this will be specified in each frame set */
332 int64_t *molecule_cnt_list
;
333 /** The total number of particles/atoms. If using variable number of
334 * particles this will be specified in each frame set */
337 /** The pos in the src file of the first frame set */
338 int64_t first_trajectory_frame_set_input_file_pos
;
339 /** The pos in the dest file of the first frame set */
340 int64_t first_trajectory_frame_set_output_file_pos
;
341 /** The pos in the src file of the last frame set */
342 int64_t last_trajectory_frame_set_input_file_pos
;
343 /** The pos in the dest file of the last frame set */
344 int64_t last_trajectory_frame_set_output_file_pos
;
345 /** The currently active frame set */
346 struct tng_trajectory_frame_set current_trajectory_frame_set
;
347 /** The pos in the src file of the current frame set */
348 long current_trajectory_frame_set_input_file_pos
;
349 /** The pos in the dest file of the current frame set */
350 long current_trajectory_frame_set_output_file_pos
;
351 /** The number of frame sets in the trajectory N.B. Not saved in file and
352 * cannot be trusted to be up-to-date */
353 int64_t n_trajectory_frame_sets
;
355 /** The number of trajectory blocks in the file */
356 int64_t n_trajectory_blocks
;
358 /* These data blocks are non-trajectory data blocks */
359 /** The number of non-frame dependent particle dependent data blocks */
360 int n_particle_data_blocks
;
361 /** A list of data blocks containing particle dependent data */
362 struct tng_particle_data
*non_tr_particle_data
;
364 /** The number of frame and particle independent data blocks */
366 /** A list of frame and particle indepdendent data blocks */
367 struct tng_non_particle_data
*non_tr_data
;
369 /** TNG compression algorithm for compressing positions */
370 int *compress_algo_pos
;
371 /** TNG compression algorithm for compressing velocities */
372 int *compress_algo_vel
;
373 /** The precision used for lossy compression */
374 double compression_precision
;
378 #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
380 #endif /* win32... */
381 #endif /* not defined USE_WINDOWS */
384 #define TNG_INLINE __inline
385 #define TNG_SNPRINTF _snprintf
387 #define TNG_INLINE inline
388 #define TNG_SNPRINTF snprintf
391 static TNG_INLINE
int tng_min_i(int a
, int b
)
393 return (a
< b
? a
: b
);
397 static TNG_INLINE int tng_max_i(int a, int b)
399 return (a > b ? a : b);
402 static TNG_INLINE
int64_t tng_min_i64(int64_t a
, int64_t b
)
404 return (a
< b
? a
: b
);
407 static TNG_INLINE
int64_t tng_max_i64(int64_t a
, int64_t b
)
409 return (a
> b
? a
: b
);
413 static TNG_INLINE float tng_min_f(float a, float b)
415 return (a < b ? a : b);
418 static TNG_INLINE float tng_max_f(float a, float b)
420 return (a > b ? a : b);
423 static TNG_INLINE double tng_min_d(double a, double b)
425 return (a < b ? a : b);
428 static TNG_INLINE double tng_max_d(double a, double b)
430 return (a > b ? a : b);
434 /** This function swaps the byte order of a 32 bit numerical variable
436 * It does not only work with integer, but e.g. floats need casting.
437 * If the byte order is already big endian no change is needed.
438 * @param tng_data is a trajectory data container.
439 * @param v is a pointer to a 32 bit numerical value (float or integer).
440 * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the current
441 * byte order is not recognised.
443 static tng_function_status tng_swap_byte_order_big_endian_32
444 (const tng_trajectory_t tng_data
, int32_t *v
)
446 switch(tng_data
->endianness_32
)
448 case TNG_LITTLE_ENDIAN_32
: /* Byte order is reversed. */
449 *v
= ((*v
& 0xFF000000) >> 24) | /* Move first byte to end */
450 ((*v
& 0x00FF0000) >> 8) | /* Move 2nd byte to pos 3 */
451 ((*v
& 0x0000FF00) << 8) | /* Move 3rd byte to pos 2 */
452 ((*v
& 0x000000FF) << 24); /* Move last byte to first */
456 case TNG_BYTE_PAIR_SWAP_32
: /* byte pair swap */
457 *v
= ((*v
& 0xFFFF0000) >> 16) |
458 ((*v
& 0x0000FFFF) << 16);
462 case TNG_BIG_ENDIAN_32
: /* Already correct */
470 /** This function swaps the byte order of a 64 bit numerical variable
472 * It does not only work with integer, but e.g. floats need casting.
473 * The byte order swapping routine can convert four different byte
474 * orders to big endian.
475 * If the byte order is already big endian no change is needed.
476 * @param tng_data is a trajectory data container.
477 * @param v is a pointer to a 64 bit numerical value (double or integer).
478 * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the current
479 * byte order is not recognised.
481 static tng_function_status tng_swap_byte_order_big_endian_64
482 (const tng_trajectory_t tng_data
, int64_t *v
)
484 switch(tng_data
->endianness_64
)
486 case TNG_LITTLE_ENDIAN_64
: /* Byte order is reversed. */
487 *v
= ((*v
& 0xFF00000000000000LL
) >> 56) | /* Move first byte to end */
488 ((*v
& 0x00FF000000000000LL
) >> 40) | /* Move 2nd byte to pos 7 */
489 ((*v
& 0x0000FF0000000000LL
) >> 24) | /* Move 3rd byte to pos 6 */
490 ((*v
& 0x000000FF00000000LL
) >> 8 ) | /* Move 4th byte to pos 5 */
491 ((*v
& 0x00000000FF000000LL
) << 8 ) | /* Move 5th byte to pos 4 */
492 ((*v
& 0x0000000000FF0000LL
) << 24) | /* Move 6th byte to pos 3 */
493 ((*v
& 0x000000000000FF00LL
) << 40) | /* Move 7th byte to pos 2 */
494 ((*v
& 0x00000000000000FFLL
) << 56); /* Move last byte to first */
498 case TNG_QUAD_SWAP_64
: /* Byte quad swap */
499 *v
= ((*v
& 0xFFFFFFFF00000000LL
) >> 32) |
500 ((*v
& 0x00000000FFFFFFFFLL
) << 32);
504 case TNG_BYTE_PAIR_SWAP_64
: /* Byte pair swap */
505 *v
= ((*v
& 0xFFFF0000FFFF0000LL
) >> 16) |
506 ((*v
& 0x0000FFFF0000FFFFLL
) << 16);
510 case TNG_BYTE_SWAP_64
: /* Byte swap */
511 *v
= ((*v
& 0xFF00FF00FF00FF00LL
) >> 8) |
512 ((*v
& 0x00FF00FF00FF00FFLL
) << 8);
516 case TNG_BIG_ENDIAN_64
: /* Already correct */
524 /** This function swaps the byte order of a 32 bit numerical variable
526 * It does not only work with integer, but e.g. floats need casting.
527 * If the byte order is already little endian no change is needed.
528 * @param tng_data is a trajectory data container.
529 * @param v is a pointer to a 32 bit numerical value (float or integer).
530 * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the current
531 * byte order is not recognised.
533 static tng_function_status tng_swap_byte_order_little_endian_32
534 (const tng_trajectory_t tng_data
, int32_t *v
)
536 switch(tng_data
->endianness_32
)
538 case TNG_LITTLE_ENDIAN_32
: /* Already correct */
541 case TNG_BYTE_PAIR_SWAP_32
: /* byte pair swapped big endian to little endian */
542 *v
= ((*v
& 0xFF00FF00) >> 8) |
543 ((*v
& 0x00FF00FF) << 8);
547 case TNG_BIG_ENDIAN_32
: /* Byte order is reversed. */
548 *v
= ((*v
& 0xFF000000) >> 24) | /* Move first byte to end */
549 ((*v
& 0x00FF0000) >> 8) | /* Move 2nd byte to pos 3 */
550 ((*v
& 0x0000FF00) << 8) | /* Move 3rd byte to pos 2 */
551 ((*v
& 0x000000FF) << 24); /* Move last byte to first */
560 /** This function swaps the byte order of a 64 bit numerical variable
562 * It does not only work with integer, but e.g. floats need casting.
563 * The byte order swapping routine can convert four different byte
564 * orders to little endian.
565 * If the byte order is already little endian no change is needed.
566 * @param tng_data is a trajectory data container.
567 * @param v is a pointer to a 64 bit numerical value (double or integer).
568 * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the current
569 * byte order is not recognised.
571 static tng_function_status tng_swap_byte_order_little_endian_64
572 (const tng_trajectory_t tng_data
, int64_t *v
)
574 switch(tng_data
->endianness_64
)
576 case TNG_LITTLE_ENDIAN_64
: /* Already correct */
579 case TNG_QUAD_SWAP_64
: /* Byte quad swapped big endian to little endian */
580 *v
= ((*v
& 0xFF000000FF000000LL
) >> 24) |
581 ((*v
& 0x00FF000000FF0000LL
) >> 8) |
582 ((*v
& 0x0000FF000000FF00LL
) << 8) |
583 ((*v
& 0x000000FF000000FFLL
) << 24);
587 case TNG_BYTE_PAIR_SWAP_64
: /* Byte pair swapped big endian to little endian */
588 *v
= ((*v
& 0xFF00FF0000000000LL
) >> 40) |
589 ((*v
& 0x00FF00FF00000000LL
) >> 24) |
590 ((*v
& 0x00000000FF00FF00LL
) << 24) |
591 ((*v
& 0x0000000000FF00FFLL
) << 40);
595 case TNG_BYTE_SWAP_64
: /* Byte swapped big endian to little endian */
596 *v
= ((*v
& 0xFFFF000000000000LL
) >> 48) |
597 ((*v
& 0x0000FFFF00000000LL
) >> 16) |
598 ((*v
& 0x00000000FFFF0000LL
) << 16) |
599 ((*v
& 0x000000000000FFFFLL
) << 48);
603 case TNG_BIG_ENDIAN_64
: /* Byte order is reversed. */
604 *v
= ((*v
& 0xFF00000000000000LL
) >> 56) | /* Move first byte to end */
605 ((*v
& 0x00FF000000000000LL
) >> 40) | /* Move 2nd byte to pos 7 */
606 ((*v
& 0x0000FF0000000000LL
) >> 24) | /* Move 3rd byte to pos 6 */
607 ((*v
& 0x000000FF00000000LL
) >> 8 ) | /* Move 4th byte to pos 5 */
608 ((*v
& 0x00000000FF000000LL
) << 8 ) | /* Move 5th byte to pos 4 */
609 ((*v
& 0x0000000000FF0000LL
) << 24) | /* Move 6th byte to pos 3 */
610 ((*v
& 0x000000000000FF00LL
) << 40) | /* Move 7th byte to pos 2 */
611 ((*v
& 0x00000000000000FFLL
) << 56); /* Move last byte to first */
619 /** Generate the md5 hash of a block.
620 * The hash is created based on the actual block contents.
621 * @param block is a general block container.
622 * @return TNG_SUCCESS (0) if successful.
624 static tng_function_status
tng_block_md5_hash_generate(tng_gen_block_t block
)
626 md5_state_t md5_state
;
628 md5_init(&md5_state
);
629 md5_append(&md5_state
, (md5_byte_t
*)block
->block_contents
,
630 (int)block
->block_contents_size
);
631 md5_finish(&md5_state
, (md5_byte_t
*)block
->md5_hash
);
636 /** Compare the current block md5 hash (e.g. read from file) with the md5 hash
637 * calculated from the current contents.
638 * If the current md5 hash is not set skip the comparison.
639 * @param block is a general block container.
640 * @param results If the hashes match results is set to TNG_TRUE, otherwise it is
641 * set to TNG_FALSE. If the hash was not set results is set to TNG_TRUE.
642 * @return TNG_SUCCESS (0) if successful or TNG_FAILURE (1) if the hash was not
645 static tng_function_status
tng_md5_hash_match_verify(tng_gen_block_t block
,
648 md5_state_t md5_state
;
649 char hash
[TNG_MD5_HASH_LEN
];
651 TNG_ASSERT(block
->block_contents_size
> 0, "The block contents size must be > 0");
654 if(strncmp(block
->md5_hash
, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) == 0)
658 md5_init(&md5_state
);
659 md5_append(&md5_state
, (md5_byte_t
*)block
->block_contents
,
660 (int)block
->block_contents_size
);
661 md5_finish(&md5_state
, (md5_byte_t
*)hash
);
663 if(strncmp(block
->md5_hash
, hash
, 16) != 0)
665 *results
= TNG_FALSE
;
671 /** Open the input file if it is not already opened.
672 * @param tng_data is a trajectory data container.
673 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
676 static tng_function_status
tng_input_file_init(tng_trajectory_t tng_data
)
678 if(!tng_data
->input_file
)
680 if(!tng_data
->input_file_path
)
682 fprintf(stderr
, "TNG library: No file specified for reading. %s: %d\n",
684 return(TNG_CRITICAL
);
686 tng_data
->input_file
= fopen(tng_data
->input_file_path
, "rb");
687 if(!tng_data
->input_file
)
689 fprintf(stderr
, "TNG library: Cannot open file %s. %s: %d\n",
690 tng_data
->input_file_path
, __FILE__
, __LINE__
);
691 return(TNG_CRITICAL
);
697 /** Open the output file if it is not already opened
698 * @param tng_data is a trajectory data container.
699 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
702 static tng_function_status
tng_output_file_init(tng_trajectory_t tng_data
)
704 if(!tng_data
->output_file
)
706 if(!tng_data
->output_file_path
)
708 fprintf(stderr
, "TNG library: No file specified for writing. %s: %d\n",
710 return(TNG_CRITICAL
);
713 tng_data
->output_file
= fopen(tng_data
->output_file_path
, "wb+");
715 if(!tng_data
->output_file
)
717 fprintf(stderr
, "TNG library: Cannot open file %s. %s: %d\n",
718 tng_data
->output_file_path
, __FILE__
, __LINE__
);
719 return(TNG_CRITICAL
);
725 /** Setup a file block container.
726 * @param block_p a pointer to memory to initialise as a file block container.
727 * @details Memory is allocated during initialisation.
728 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
731 static tng_function_status
tng_block_init(struct tng_gen_block
**block_p
)
733 tng_gen_block_t block
;
735 *block_p
= malloc(sizeof(struct tng_gen_block
));
738 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
739 sizeof(struct tng_gen_block
), __FILE__
, __LINE__
);
740 return(TNG_CRITICAL
);
746 /* Reset the md5_hash */
747 memcpy(block
->md5_hash
, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", TNG_MD5_HASH_LEN
);
749 block
->block_version
= TNG_VERSION
;
750 block
->header_contents
= 0;
751 block
->header_contents_size
= 0;
752 block
->block_contents
= 0;
753 block
->block_contents_size
= 0;
759 * @brief Clean up a file block container.
760 * @param block_p a pointer to the file block container to destroy.
761 * @details All allocated memory in the data structure is freed, as well as
763 * @return TNG_SUCCESS (0) if successful.
765 static tng_function_status
tng_block_destroy(struct tng_gen_block
**block_p
)
767 tng_gen_block_t block
= *block_p
;
774 /* fprintf(stderr, "TNG library: Destroying block\n"); */
780 if(block
->header_contents
)
782 free(block
->header_contents
);
783 block
->header_contents
= 0;
785 if(block
->block_contents
)
787 free(block
->block_contents
);
788 block
->block_contents
= 0;
797 /** Read the header of a data block, regardless of its type
798 * @param tng_data is a trajectory data container.
799 * @param block is a general block container.
800 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
803 static tng_function_status tng_block_header_read
804 (tng_trajectory_t tng_data
, tng_gen_block_t block
)
808 TNG_ASSERT(block
!= 0, "TNG library: Trying to read to uninitialized block (NULL pointer).");
810 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
812 return(TNG_CRITICAL
);
815 /* First read the header size to be able to read the whole header. */
816 if(fread(&block
->header_contents_size
, sizeof(block
->header_contents_size
),
817 1, tng_data
->input_file
) == 0)
819 fprintf(stderr
, "TNG library: Cannot read header size. %s: %d\n",
821 return(TNG_CRITICAL
);
824 /* If this was the size of the general info block check the endianness */
825 if(ftell(tng_data
->input_file
) < 9)
827 /* File is little endian */
828 if ( *((const char*)&block
->header_contents_size
) != 0x00 &&
829 *((const char*)(&block
->header_contents_size
) + 7) == 0x00)
831 /* If the architecture endianness is little endian no byte swap
832 * will be needed. Otherwise use the functions to swap to little
834 if(tng_data
->endianness_32
== TNG_LITTLE_ENDIAN_32
)
836 tng_data
->input_endianness_swap_func_32
= 0;
840 tng_data
->input_endianness_swap_func_32
=
841 &tng_swap_byte_order_little_endian_32
;
843 if(tng_data
->endianness_64
== TNG_LITTLE_ENDIAN_64
)
845 tng_data
->input_endianness_swap_func_64
= 0;
849 tng_data
->input_endianness_swap_func_64
=
850 &tng_swap_byte_order_little_endian_64
;
853 /* File is big endian */
856 /* If the architecture endianness is big endian no byte swap
857 * will be needed. Otherwise use the functions to swap to big
859 if(tng_data
->endianness_32
== TNG_BIG_ENDIAN_32
)
861 tng_data
->input_endianness_swap_func_32
= 0;
865 tng_data
->input_endianness_swap_func_32
=
866 &tng_swap_byte_order_big_endian_32
;
868 if(tng_data
->endianness_64
== TNG_BIG_ENDIAN_64
)
870 tng_data
->input_endianness_swap_func_64
= 0;
874 tng_data
->input_endianness_swap_func_64
=
875 &tng_swap_byte_order_big_endian_64
;
880 if(tng_data
->input_endianness_swap_func_64
)
882 if(tng_data
->input_endianness_swap_func_64(tng_data
,
883 &block
->header_contents_size
)
886 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
891 /* Move the reading position to the beginning of the header. */
892 fseek(tng_data
->input_file
, -(long)sizeof(block
->header_contents_size
),
895 /* If there is already memory allocated for the contents free it (we do not
896 * know if the size is correct). */
897 if(block
->header_contents
)
899 free(block
->header_contents
);
902 block
->header_contents
= malloc(block
->header_contents_size
);
903 if(!block
->header_contents
)
905 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
906 block
->header_contents_size
, __FILE__
, __LINE__
);
907 return(TNG_CRITICAL
);
910 /* Read the whole header into header_contents. This way it can be saved
911 * even if it cannot be interpreted
912 * for one reason or another. */
913 if(fread(block
->header_contents
, block
->header_contents_size
, 1,
914 tng_data
->input_file
) == 0)
916 fprintf(stderr
, "TNG library: Cannot read header. %s: %d\n", __FILE__
, __LINE__
);
917 return(TNG_CRITICAL
);
920 /* The header contents size has already been read. Skip ahead. */
921 offset
= sizeof(block
->header_contents_size
);
924 /* Copy the respective parameters from the header contents block */
925 memcpy(&block
->block_contents_size
, block
->header_contents
+offset
,
926 sizeof(block
->block_contents_size
));
927 if(tng_data
->input_endianness_swap_func_64
)
929 if(tng_data
->input_endianness_swap_func_64(tng_data
,
930 &block
->block_contents_size
)
933 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
938 offset
+= sizeof(block
->block_contents_size
);
940 memcpy(&block
->id
, block
->header_contents
+offset
, sizeof(block
->id
));
941 if(tng_data
->input_endianness_swap_func_64
)
943 if(tng_data
->input_endianness_swap_func_64(tng_data
,
947 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
952 offset
+= sizeof(block
->id
);
954 memcpy(block
->md5_hash
, block
->header_contents
+offset
, TNG_MD5_HASH_LEN
);
955 offset
+= TNG_MD5_HASH_LEN
;
957 if(block
->name
&& strcmp(block
->name
, block
->header_contents
+offset
) != 0)
962 len
= tng_min_i((int)strlen(block
->header_contents
+offset
) + 1, TNG_MAX_STR_LEN
);
965 block
->name
= malloc(len
);
968 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
970 return(TNG_CRITICAL
);
972 strncpy(block
->name
, block
->header_contents
+offset
, len
);
976 memcpy(&block
->block_version
, block
->header_contents
+offset
,
977 sizeof(block
->block_version
));
978 if(tng_data
->input_endianness_swap_func_64
)
980 if(tng_data
->input_endianness_swap_func_64(tng_data
,
981 &block
->block_version
)
984 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
992 /** Write a whole block, both header and contents, regardless of it type
993 * @param tng_data is a trajectory data container.
994 * @param block is a general block container.
995 * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if a minor error
996 * has occurred or TNG_CRITICAL (2) if a major error has occured.
998 /* Disabled until it is used.*/
1000 // static tng_function_status tng_block_verbatim_write(tng_trajectory_t tng_data,
1001 // tng_gen_block_t block)
1003 // if(!block->header_contents)
1005 // fprintf(stderr, "TNG library: No contents to write. %s: %d\n", __FILE__, __LINE__);
1006 // return(TNG_FAILURE);
1008 // if(fwrite(block->header_contents, block->header_contents_size, 1,
1009 // tng_data->output_file) != 1)
1011 // fprintf(stderr, "TNG library: Could not write all header data. %s: %d\n",
1012 // __FILE__, __LINE__);
1013 // return(TNG_CRITICAL);
1016 // if(!block->block_contents)
1018 // fprintf(stderr, "TNG library: No block data to write. %s: %d\n",
1019 // __FILE__, __LINE__);
1020 // return(TNG_FAILURE);
1022 // if(fwrite(block->block_contents, block->block_contents_size, 1,
1023 // tng_data->output_file) != 1)
1025 // fprintf(stderr, "TNG library: Could not write all block data. %s: %d\n",
1026 // __FILE__, __LINE__);
1027 // return(TNG_CRITICAL);
1029 // return(TNG_SUCCESS);
1032 /** Write the header of a data block, regardless of its type
1033 * @param tng_data is a trajectory data container.
1034 * @param block is a general block container.
1035 * @param hash_mode is an option to decide whether to use the md5 hash or not.
1036 * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
1037 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
1038 * error has occured.
1040 static tng_function_status tng_block_header_write
1041 (tng_trajectory_t tng_data
,
1042 tng_gen_block_t block
,
1043 const char hash_mode
)
1045 int name_len
, offset
= 0;
1047 TNG_ASSERT(block
!= 0, "TNG library: Trying to write uninitialized block (NULL pointer).");
1049 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
1051 fprintf(stderr
, "TNG library: Cannot initialise destination file. %s: %d\n",
1052 __FILE__
, __LINE__
);
1053 return(TNG_CRITICAL
);
1058 block
->name
= malloc(1);
1061 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1062 __FILE__
, __LINE__
);
1063 return(TNG_CRITICAL
);
1068 name_len
= tng_min_i((int)strlen(block
->name
) + 1, TNG_MAX_STR_LEN
);
1070 if(hash_mode
== TNG_USE_HASH
)
1072 tng_block_md5_hash_generate(block
);
1075 /* Calculate the size of the header to write */
1076 block
->header_contents_size
= sizeof(block
->header_contents_size
) +
1077 sizeof(block
->block_contents_size
) +
1079 sizeof(block
->block_version
) +
1083 if(block
->header_contents
)
1085 free(block
->header_contents
);
1088 block
->header_contents
= malloc(block
->header_contents_size
);
1089 if(!block
->header_contents
)
1091 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
1092 block
->header_contents_size
, __FILE__
, __LINE__
);
1093 return(TNG_CRITICAL
);
1096 /* First copy all data into the header_contents block and finally write
1097 * the whole block at once. */
1098 memcpy(block
->header_contents
, &block
->header_contents_size
,
1099 sizeof(block
->header_contents_size
));
1100 if(tng_data
->output_endianness_swap_func_64
)
1102 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1103 (int64_t *)block
->header_contents
+offset
)
1106 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1107 __FILE__
, __LINE__
);
1110 offset
+= sizeof(block
->header_contents_size
);
1112 memcpy(block
->header_contents
+offset
, &block
->block_contents_size
,
1113 sizeof(block
->block_contents_size
));
1114 if(tng_data
->output_endianness_swap_func_64
)
1116 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1117 (int64_t *)block
->header_contents
+offset
)
1120 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1121 __FILE__
, __LINE__
);
1124 offset
+= sizeof(block
->block_contents_size
);
1126 memcpy(block
->header_contents
+offset
, &block
->id
, sizeof(block
->id
));
1127 if(tng_data
->output_endianness_swap_func_64
)
1129 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1130 (int64_t *)block
->header_contents
+offset
)
1133 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1134 __FILE__
, __LINE__
);
1137 offset
+= sizeof(block
->id
);
1139 memcpy(block
->header_contents
+offset
, block
->md5_hash
, TNG_MD5_HASH_LEN
);
1140 offset
+= TNG_MD5_HASH_LEN
;
1142 strncpy(block
->header_contents
+offset
, block
->name
, name_len
);
1145 memcpy(block
->header_contents
+offset
, &block
->block_version
,
1146 sizeof(block
->block_version
));
1147 if(tng_data
->output_endianness_swap_func_64
)
1149 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1150 (int64_t *)block
->header_contents
+offset
)
1153 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1154 __FILE__
, __LINE__
);
1158 if(fwrite(block
->header_contents
, block
->header_contents_size
,
1159 1, tng_data
->output_file
) != 1)
1161 fprintf(stderr
, "TNG library: Could not write all header data. %s: %d\n", __FILE__
, __LINE__
);
1162 return(TNG_CRITICAL
);
1164 return(TNG_SUCCESS
);
1167 /** Read a general info block. This is the first block of a TNG file.
1168 * Populate the fields in tng_data.
1169 * @param tng_data is a trajectory data container.
1170 * @param block is a general block container.
1171 * @param hash_mode is an option to decide whether to use the md5 hash or not.
1172 * If hash_mode == TNG_USE_HASH the written md5 hash in the file will be
1173 * compared to the md5 hash of the read contents to ensure valid data.
1174 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
1175 * error has occured.
1177 static tng_function_status tng_general_info_block_read
1178 (tng_trajectory_t tng_data
, tng_gen_block_t block
,
1179 const char hash_mode
)
1181 int len
, offset
= 0;
1186 TNG_ASSERT(block
!= 0, "TNG library: Trying to read data to an uninitialized block (NULL pointer)");
1188 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
1190 return(TNG_CRITICAL
);
1193 temp
= realloc(block
->block_contents
, block
->block_contents_size
);
1196 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
1197 block
->block_contents_size
, __FILE__
, __LINE__
);
1198 free(block
->block_contents
);
1199 block
->block_contents
= 0;
1200 return(TNG_CRITICAL
);
1202 block
->block_contents
= temp
;
1204 /* Read the whole block into block_contents to be able to write it to disk
1205 * even if it cannot be interpreted. */
1206 if(fread(block
->block_contents
, block
->block_contents_size
, 1,
1207 tng_data
->input_file
) == 0)
1209 fprintf(stderr
, "TNG library: Cannot read block. %s: %d\n", __FILE__
, __LINE__
);
1210 return(TNG_CRITICAL
);
1213 /* FIXME: Does not check if the size of the contents matches the expected
1214 * size or if the contents can be read. */
1216 if(hash_mode
== TNG_USE_HASH
)
1218 tng_md5_hash_match_verify(block
, &same_hash
);
1219 if(same_hash
!= TNG_TRUE
)
1221 fprintf(stderr
, "TNG library: General info block contents corrupt. Hashes do not match. "
1223 __FILE__
, __LINE__
);
1224 /* return(TNG_FAILURE); */
1228 len
= tng_min_i((int)strlen(block
->block_contents
) + 1, TNG_MAX_STR_LEN
);
1229 temp
= realloc(tng_data
->first_program_name
, len
);
1232 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
1233 __FILE__
, __LINE__
);
1234 free(tng_data
->first_program_name
);
1235 tng_data
->first_program_name
= 0;
1236 return(TNG_CRITICAL
);
1238 tng_data
->first_program_name
= temp
;
1239 strncpy(tng_data
->first_program_name
, block
->block_contents
, len
);
1242 len
= tng_min_i((int)strlen(block
->block_contents
+ offset
) + 1, TNG_MAX_STR_LEN
);
1243 temp
= realloc(tng_data
->last_program_name
, len
);
1246 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
1247 __FILE__
, __LINE__
);
1248 free(tng_data
->last_program_name
);
1249 tng_data
->last_program_name
= 0;
1250 return(TNG_CRITICAL
);
1252 tng_data
->last_program_name
= temp
;
1253 strncpy(tng_data
->last_program_name
, block
->block_contents
+ offset
, len
);
1256 len
= tng_min_i((int)strlen(block
->block_contents
+offset
) + 1, TNG_MAX_STR_LEN
);
1257 temp
= realloc(tng_data
->first_user_name
, len
);
1260 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
1261 __FILE__
, __LINE__
);
1262 free(tng_data
->first_user_name
);
1263 tng_data
->first_user_name
= 0;
1264 return(TNG_CRITICAL
);
1266 tng_data
->first_user_name
= temp
;
1267 strncpy(tng_data
->first_user_name
, block
->block_contents
+offset
, len
);
1270 len
= tng_min_i((int)strlen(block
->block_contents
+offset
) + 1, TNG_MAX_STR_LEN
);
1271 temp
= realloc(tng_data
->last_user_name
, len
);
1274 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
1275 __FILE__
, __LINE__
);
1276 free(tng_data
->last_user_name
);
1277 tng_data
->last_user_name
= 0;
1278 return(TNG_CRITICAL
);
1280 tng_data
->last_user_name
= temp
;
1281 strncpy(tng_data
->last_user_name
, block
->block_contents
+offset
, len
);
1284 len
= tng_min_i((int)strlen(block
->block_contents
+offset
) + 1, TNG_MAX_STR_LEN
);
1285 temp
= realloc(tng_data
->first_computer_name
, len
);
1288 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
1289 __FILE__
, __LINE__
);
1290 free(tng_data
->first_computer_name
);
1291 tng_data
->first_computer_name
= 0;
1292 return(TNG_CRITICAL
);
1294 tng_data
->first_computer_name
= temp
;
1295 strncpy(tng_data
->first_computer_name
, block
->block_contents
+offset
, len
);
1298 len
= tng_min_i((int)strlen(block
->block_contents
+offset
) + 1, TNG_MAX_STR_LEN
);
1299 temp
= realloc(tng_data
->last_computer_name
, len
);
1302 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
1303 __FILE__
, __LINE__
);
1304 free(tng_data
->last_computer_name
);
1305 tng_data
->last_computer_name
= 0;
1306 return(TNG_CRITICAL
);
1308 tng_data
->last_computer_name
= temp
;
1309 strncpy(tng_data
->last_computer_name
, block
->block_contents
+offset
, len
);
1312 len
= tng_min_i((int)strlen(block
->block_contents
+offset
) + 1, TNG_MAX_STR_LEN
);
1313 temp
= realloc(tng_data
->first_pgp_signature
, len
);
1316 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
1317 __FILE__
, __LINE__
);
1318 free(tng_data
->first_pgp_signature
);
1319 tng_data
->first_pgp_signature
= 0;
1320 return(TNG_CRITICAL
);
1322 tng_data
->first_pgp_signature
= temp
;
1323 strncpy(tng_data
->first_pgp_signature
, block
->block_contents
+offset
, len
);
1326 len
= tng_min_i((int)strlen(block
->block_contents
+offset
) + 1, TNG_MAX_STR_LEN
);
1327 temp
= realloc(tng_data
->last_pgp_signature
, len
);
1330 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
1331 __FILE__
, __LINE__
);
1332 free(tng_data
->last_pgp_signature
);
1333 tng_data
->last_pgp_signature
= 0;
1334 return(TNG_CRITICAL
);
1336 tng_data
->last_pgp_signature
= temp
;
1337 strncpy(tng_data
->last_pgp_signature
, block
->block_contents
+offset
, len
);
1340 len
= tng_min_i((int)strlen(block
->block_contents
+offset
) + 1, TNG_MAX_STR_LEN
);
1341 temp
= realloc(tng_data
->forcefield_name
, len
);
1344 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
1345 __FILE__
, __LINE__
);
1346 free(tng_data
->forcefield_name
);
1347 tng_data
->forcefield_name
= 0;
1348 return(TNG_CRITICAL
);
1350 tng_data
->forcefield_name
= temp
;
1351 strncpy(tng_data
->forcefield_name
, block
->block_contents
+offset
, len
);
1354 memcpy(&tng_data
->time
, block
->block_contents
+offset
,
1355 sizeof(tng_data
->time
));
1356 if(tng_data
->input_endianness_swap_func_64
)
1358 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1362 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1363 __FILE__
, __LINE__
);
1366 offset
+= sizeof(tng_data
->time
);
1368 memcpy(&tng_data
->var_num_atoms_flag
, block
->block_contents
+offset
,
1369 sizeof(tng_data
->var_num_atoms_flag
));
1370 offset
+= sizeof(tng_data
->var_num_atoms_flag
);
1372 memcpy(&tng_data
->frame_set_n_frames
, block
->block_contents
+offset
,
1373 sizeof(tng_data
->frame_set_n_frames
));
1374 if(tng_data
->input_endianness_swap_func_64
)
1376 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1377 &tng_data
->frame_set_n_frames
)
1380 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1381 __FILE__
, __LINE__
);
1384 offset
+= sizeof(tng_data
->frame_set_n_frames
);
1386 memcpy(&tng_data
->first_trajectory_frame_set_input_file_pos
,
1387 block
->block_contents
+offset
,
1388 sizeof(tng_data
->first_trajectory_frame_set_input_file_pos
));
1389 if(tng_data
->input_endianness_swap_func_64
)
1391 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1392 &tng_data
->first_trajectory_frame_set_input_file_pos
)
1395 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1396 __FILE__
, __LINE__
);
1399 offset
+= sizeof(tng_data
->first_trajectory_frame_set_input_file_pos
);
1401 tng_data
->current_trajectory_frame_set
.next_frame_set_file_pos
=
1402 tng_data
->first_trajectory_frame_set_input_file_pos
;
1405 memcpy(&tng_data
->last_trajectory_frame_set_input_file_pos
,
1406 block
->block_contents
+offset
,
1407 sizeof(tng_data
->last_trajectory_frame_set_input_file_pos
));
1408 if(tng_data
->input_endianness_swap_func_64
)
1410 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1411 &tng_data
->last_trajectory_frame_set_input_file_pos
)
1414 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1415 __FILE__
, __LINE__
);
1418 offset
+= sizeof(tng_data
->last_trajectory_frame_set_input_file_pos
);
1420 memcpy(&tng_data
->medium_stride_length
, block
->block_contents
+offset
,
1421 sizeof(tng_data
->medium_stride_length
));
1422 if(tng_data
->input_endianness_swap_func_64
)
1424 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1425 &tng_data
->medium_stride_length
)
1428 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1429 __FILE__
, __LINE__
);
1432 offset
+= sizeof(tng_data
->medium_stride_length
);
1434 memcpy(&tng_data
->long_stride_length
, block
->block_contents
+offset
,
1435 sizeof(tng_data
->long_stride_length
));
1436 if(tng_data
->input_endianness_swap_func_64
)
1438 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1439 &tng_data
->long_stride_length
)
1442 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1443 __FILE__
, __LINE__
);
1446 offset
+= sizeof(tng_data
->long_stride_length
);
1448 if(block
->block_version
>= 3)
1450 memcpy(&tng_data
->distance_unit_exponential
, block
->block_contents
+offset
,
1451 sizeof(tng_data
->distance_unit_exponential
));
1452 if(tng_data
->input_endianness_swap_func_64
)
1454 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1455 &tng_data
->distance_unit_exponential
)
1458 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1459 __FILE__
, __LINE__
);
1464 return(TNG_SUCCESS
);
1467 /** Write a general info block. This is the first block of a TNG file.
1468 * @param tng_data is a trajectory data container.
1469 * @param hash_mode is an option to decide whether to use the md5 hash or not.
1470 * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
1471 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
1472 * error has occured.
1474 static tng_function_status tng_general_info_block_write
1475 (tng_trajectory_t tng_data
,
1476 const char hash_mode
)
1478 int first_program_name_len
, first_user_name_len
;
1479 int first_computer_name_len
, first_pgp_signature_len
;
1480 int last_program_name_len
, last_user_name_len
;
1481 int last_computer_name_len
, last_pgp_signature_len
;
1482 int forcefield_name_len
, name_len
;
1484 tng_gen_block_t block
;
1486 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
1488 return(TNG_CRITICAL
);
1491 fseek(tng_data
->output_file
, 0, SEEK_SET
);
1493 /* If the strings are unallocated allocate memory for just string
1495 if(!tng_data
->first_program_name
)
1497 tng_data
->first_program_name
= malloc(1);
1498 if(!tng_data
->first_program_name
)
1500 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1501 __FILE__
, __LINE__
);
1502 return(TNG_CRITICAL
);
1504 tng_data
->first_program_name
[0] = 0;
1506 if(!tng_data
->last_program_name
)
1508 tng_data
->last_program_name
= malloc(1);
1509 if(!tng_data
->last_program_name
)
1511 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1512 __FILE__
, __LINE__
);
1513 return(TNG_CRITICAL
);
1515 tng_data
->last_program_name
[0] = 0;
1517 if(!tng_data
->first_user_name
)
1519 tng_data
->first_user_name
= malloc(1);
1520 if(!tng_data
->first_user_name
)
1522 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1523 __FILE__
, __LINE__
);
1524 return(TNG_CRITICAL
);
1526 tng_data
->first_user_name
[0] = 0;
1528 if(!tng_data
->last_user_name
)
1530 tng_data
->last_user_name
= malloc(1);
1531 if(!tng_data
->last_user_name
)
1533 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1534 __FILE__
, __LINE__
);
1535 return(TNG_CRITICAL
);
1537 tng_data
->last_user_name
[0] = 0;
1539 if(!tng_data
->first_computer_name
)
1541 tng_data
->first_computer_name
= malloc(1);
1542 if(!tng_data
->first_computer_name
)
1544 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1545 __FILE__
, __LINE__
);
1546 return(TNG_CRITICAL
);
1548 tng_data
->first_computer_name
[0] = 0;
1550 if(!tng_data
->last_computer_name
)
1552 tng_data
->last_computer_name
= malloc(1);
1553 if(!tng_data
->last_computer_name
)
1555 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1556 __FILE__
, __LINE__
);
1557 return(TNG_CRITICAL
);
1559 tng_data
->last_computer_name
[0] = 0;
1561 if(!tng_data
->first_pgp_signature
)
1563 tng_data
->first_pgp_signature
= malloc(1);
1564 if(!tng_data
->first_pgp_signature
)
1566 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1567 __FILE__
, __LINE__
);
1568 return(TNG_CRITICAL
);
1570 tng_data
->first_pgp_signature
[0] = 0;
1572 if(!tng_data
->last_pgp_signature
)
1574 tng_data
->last_pgp_signature
= malloc(1);
1575 if(!tng_data
->last_pgp_signature
)
1577 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1578 __FILE__
, __LINE__
);
1579 return(TNG_CRITICAL
);
1581 tng_data
->last_pgp_signature
[0] = 0;
1583 if(!tng_data
->forcefield_name
)
1585 tng_data
->forcefield_name
= malloc(1);
1586 if(!tng_data
->forcefield_name
)
1588 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1589 __FILE__
, __LINE__
);
1590 return(TNG_CRITICAL
);
1592 tng_data
->forcefield_name
[0] = 0;
1595 tng_block_init(&block
);
1597 name_len
= (int)strlen("GENERAL INFO");
1599 block
->name
= malloc(name_len
+ 1);
1602 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
1603 name_len
+1, __FILE__
, __LINE__
);
1604 tng_block_destroy(&block
);
1605 return(TNG_CRITICAL
);
1608 strcpy(block
->name
, "GENERAL INFO");
1609 block
->id
= TNG_GENERAL_INFO
;
1611 first_program_name_len
= tng_min_i((int)strlen(tng_data
->first_program_name
) + 1,
1613 last_program_name_len
= tng_min_i((int)strlen(tng_data
->last_program_name
) + 1,
1615 first_user_name_len
= tng_min_i((int)strlen(tng_data
->first_user_name
) + 1,
1617 last_user_name_len
= tng_min_i((int)strlen(tng_data
->last_user_name
) + 1,
1619 first_computer_name_len
= tng_min_i((int)strlen(tng_data
->first_computer_name
) + 1,
1621 last_computer_name_len
= tng_min_i((int)strlen(tng_data
->last_computer_name
) + 1,
1623 first_pgp_signature_len
= tng_min_i((int)strlen(tng_data
->first_pgp_signature
) + 1,
1625 last_pgp_signature_len
= tng_min_i((int)strlen(tng_data
->last_pgp_signature
) + 1,
1627 forcefield_name_len
= tng_min_i((int)strlen(tng_data
->forcefield_name
) + 1,
1630 block
->block_contents_size
= sizeof(tng_data
->time
) +
1631 sizeof(tng_data
->var_num_atoms_flag
) +
1632 sizeof(tng_data
->frame_set_n_frames
) +
1633 sizeof(tng_data
->first_trajectory_frame_set_input_file_pos
) +
1634 sizeof(tng_data
->last_trajectory_frame_set_input_file_pos
) +
1635 sizeof(tng_data
->medium_stride_length
) +
1636 sizeof(tng_data
->long_stride_length
) +
1637 sizeof(tng_data
->distance_unit_exponential
) +
1638 first_program_name_len
+
1639 last_program_name_len
+
1640 first_user_name_len
+
1641 last_user_name_len
+
1642 first_computer_name_len
+
1643 last_computer_name_len
+
1644 first_pgp_signature_len
+
1645 last_pgp_signature_len
+
1646 forcefield_name_len
;
1648 if(block
->block_contents
)
1650 free(block
->block_contents
);
1652 block
->block_contents
= malloc(block
->block_contents_size
);
1653 if(!block
->block_contents
)
1655 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
1656 block
->block_contents_size
, __FILE__
, __LINE__
);
1657 tng_block_destroy(&block
);
1658 return(TNG_CRITICAL
);
1661 strncpy(block
->block_contents
, tng_data
->first_program_name
, first_program_name_len
);
1662 offset
+= first_program_name_len
;
1664 strncpy(block
->block_contents
+offset
, tng_data
->last_program_name
, last_program_name_len
);
1665 offset
+= last_program_name_len
;
1667 strncpy(block
->block_contents
+offset
, tng_data
->first_user_name
, first_user_name_len
);
1668 offset
+= first_user_name_len
;
1670 strncpy(block
->block_contents
+offset
, tng_data
->last_user_name
, last_user_name_len
);
1671 offset
+= last_user_name_len
;
1673 strncpy(block
->block_contents
+offset
, tng_data
->first_computer_name
,
1674 first_computer_name_len
);
1675 offset
+= first_computer_name_len
;
1677 strncpy(block
->block_contents
+offset
, tng_data
->last_computer_name
,
1678 last_computer_name_len
);
1679 offset
+= last_computer_name_len
;
1681 strncpy(block
->block_contents
+offset
, tng_data
->first_pgp_signature
,
1682 first_pgp_signature_len
);
1683 offset
+= first_pgp_signature_len
;
1685 strncpy(block
->block_contents
+offset
, tng_data
->last_pgp_signature
,
1686 last_pgp_signature_len
);
1687 offset
+= last_pgp_signature_len
;
1689 strncpy(block
->block_contents
+offset
, tng_data
->forcefield_name
,
1690 forcefield_name_len
);
1691 offset
+= forcefield_name_len
;
1693 memcpy(block
->block_contents
+offset
, &tng_data
->time
,
1694 sizeof(tng_data
->time
));
1695 if(tng_data
->output_endianness_swap_func_64
)
1697 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1698 (int64_t *)block
->header_contents
+offset
)
1701 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1702 __FILE__
, __LINE__
);
1705 offset
+= sizeof(tng_data
->time
);
1707 memcpy(block
->block_contents
+offset
, &tng_data
->var_num_atoms_flag
,
1708 sizeof(tng_data
->var_num_atoms_flag
));
1709 offset
+= sizeof(tng_data
->var_num_atoms_flag
);
1711 memcpy(block
->block_contents
+offset
, &tng_data
->frame_set_n_frames
,
1712 sizeof(tng_data
->frame_set_n_frames
));
1713 if(tng_data
->output_endianness_swap_func_64
)
1715 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1716 (int64_t *)block
->header_contents
+offset
)
1719 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1720 __FILE__
, __LINE__
);
1723 offset
+= sizeof(tng_data
->frame_set_n_frames
);
1725 memcpy(block
->block_contents
+offset
,
1726 &tng_data
->first_trajectory_frame_set_input_file_pos
,
1727 sizeof(tng_data
->first_trajectory_frame_set_input_file_pos
));
1728 if(tng_data
->output_endianness_swap_func_64
)
1730 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1731 (int64_t *)block
->header_contents
+offset
)
1734 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1735 __FILE__
, __LINE__
);
1738 offset
+= sizeof(tng_data
->first_trajectory_frame_set_input_file_pos
);
1740 memcpy(block
->block_contents
+offset
,
1741 &tng_data
->last_trajectory_frame_set_input_file_pos
,
1742 sizeof(tng_data
->last_trajectory_frame_set_input_file_pos
));
1743 if(tng_data
->output_endianness_swap_func_64
)
1745 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1746 (int64_t *)block
->header_contents
+offset
)
1749 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1750 __FILE__
, __LINE__
);
1753 offset
+= sizeof(tng_data
->last_trajectory_frame_set_input_file_pos
);
1755 memcpy(block
->block_contents
+offset
, &tng_data
->medium_stride_length
,
1756 sizeof(tng_data
->medium_stride_length
));
1757 if(tng_data
->output_endianness_swap_func_64
)
1759 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1760 (int64_t *)block
->header_contents
+offset
)
1763 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1764 __FILE__
, __LINE__
);
1767 offset
+= sizeof(tng_data
->medium_stride_length
);
1769 memcpy(block
->block_contents
+offset
, &tng_data
->long_stride_length
,
1770 sizeof(tng_data
->long_stride_length
));
1771 if(tng_data
->output_endianness_swap_func_64
)
1773 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1774 (int64_t *)block
->header_contents
+offset
)
1777 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1778 __FILE__
, __LINE__
);
1781 offset
+= sizeof(tng_data
->long_stride_length
);
1783 memcpy(block
->block_contents
+offset
, &tng_data
->distance_unit_exponential
,
1784 sizeof(tng_data
->distance_unit_exponential
));
1785 if(tng_data
->output_endianness_swap_func_64
)
1787 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1788 (int64_t *)block
->header_contents
+offset
)
1791 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1792 __FILE__
, __LINE__
);
1796 if(tng_block_header_write(tng_data
, block
, hash_mode
) != TNG_SUCCESS
)
1798 fprintf(stderr
, "TNG library: Cannot write header of file %s. %s: %d\n",
1799 tng_data
->output_file_path
, __FILE__
, __LINE__
);
1800 tng_block_destroy(&block
);
1801 return(TNG_CRITICAL
);
1804 if(fwrite(block
->block_contents
, block
->block_contents_size
, 1,
1805 tng_data
->output_file
) != 1)
1807 fprintf(stderr
, "TNG library: Could not write all block data. %s: %d\n", __FILE__
, __LINE__
);
1808 tng_block_destroy(&block
);
1809 return(TNG_CRITICAL
);
1812 tng_block_destroy(&block
);
1814 return(TNG_SUCCESS
);
1817 /** Read the chain data of a molecules block.
1818 * @param tng_data is a trajectory data container.
1819 * @param block is a general block container.
1820 * @param chain is the chain data container.
1821 * @param offset is the offset of the block input and is updated when reading.
1822 * @return TNG_SUCCESS(0) is successful.
1824 static tng_function_status
tng_chain_data_read(tng_trajectory_t tng_data
,
1825 tng_gen_block_t block
,
1831 TNG_ASSERT(offset
!= 0, "TNG library: offset must not be a NULL pointer.");
1833 memcpy(&chain
->id
, block
->block_contents
+*offset
,
1835 if(tng_data
->input_endianness_swap_func_64
)
1837 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1841 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1842 __FILE__
, __LINE__
);
1845 *offset
+= sizeof(chain
->id
);
1847 len
= tng_min_i((int)strlen(block
->block_contents
+*offset
) + 1,
1849 chain
->name
= malloc(len
);
1850 strncpy(chain
->name
,
1851 block
->block_contents
+*offset
, len
);
1854 memcpy(&chain
->n_residues
, block
->block_contents
+*offset
,
1855 sizeof(chain
->n_residues
));
1856 if(tng_data
->input_endianness_swap_func_64
)
1858 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1862 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1863 __FILE__
, __LINE__
);
1866 *offset
+= sizeof(chain
->n_residues
);
1868 return(TNG_SUCCESS
);
1871 /** Write the chain data of a molecules block.
1872 * @param tng_data is a trajectory data container.
1873 * @param block is a general block container.
1874 * @param chain is the chain data container.
1875 * @param offset is the offset of the block output and is updated when writing.
1876 * @return TNG_SUCCESS(0) is successful.
1878 static tng_function_status
tng_chain_data_write(tng_trajectory_t tng_data
,
1879 tng_gen_block_t block
,
1885 TNG_ASSERT(offset
!= 0, "TNG library: offset must not be a NULL pointer.");
1887 memcpy(block
->block_contents
+*offset
, &chain
->id
, sizeof(chain
->id
));
1888 if(tng_data
->output_endianness_swap_func_64
)
1890 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1891 (int64_t *)block
->header_contents
+*offset
)
1894 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1895 __FILE__
, __LINE__
);
1898 *offset
+= sizeof(chain
->id
);
1900 len
= tng_min_i((int)strlen(chain
->name
) + 1, TNG_MAX_STR_LEN
);
1901 strncpy(block
->block_contents
+ *offset
, chain
->name
, len
);
1904 memcpy(block
->block_contents
+*offset
, &chain
->n_residues
,
1905 sizeof(chain
->n_residues
));
1906 if(tng_data
->output_endianness_swap_func_64
)
1908 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1909 (int64_t *)block
->header_contents
+*offset
)
1912 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1913 __FILE__
, __LINE__
);
1916 *offset
+= sizeof(chain
->n_residues
);
1918 return(TNG_SUCCESS
);
1921 /** Read the residue data of a molecules block.
1922 * @param tng_data is a trajectory data container.
1923 * @param block is a general block container.
1924 * @param residue is the residue data container.
1925 * @param offset is the offset of the block input and is updated when reading.
1926 * @return TNG_SUCCESS(0) is successful.
1928 static tng_function_status
tng_residue_data_read(tng_trajectory_t tng_data
,
1929 tng_gen_block_t block
,
1930 tng_residue_t residue
,
1935 TNG_ASSERT(offset
!= 0, "TNG library: offset must not be a NULL pointer.");
1937 memcpy(&residue
->id
, block
->block_contents
+*offset
,
1938 sizeof(residue
->id
));
1939 if(tng_data
->input_endianness_swap_func_64
)
1941 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1945 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1946 __FILE__
, __LINE__
);
1949 *offset
+= sizeof(residue
->id
);
1951 len
= tng_min_i((int)strlen(block
->block_contents
+*offset
) + 1,
1953 residue
->name
= malloc(len
);
1954 strncpy(residue
->name
,
1955 block
->block_contents
+*offset
, len
);
1958 memcpy(&residue
->n_atoms
, block
->block_contents
+*offset
,
1959 sizeof(residue
->n_atoms
));
1960 if(tng_data
->input_endianness_swap_func_64
)
1962 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1966 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1967 __FILE__
, __LINE__
);
1970 *offset
+= sizeof(residue
->n_atoms
);
1972 return(TNG_SUCCESS
);
1975 /** Write the residue data of a molecules block.
1976 * @param tng_data is a trajectory data container.
1977 * @param block is a general block container.
1978 * @param residue is the residue data container.
1979 * @param offset is the offset of the block output and is updated when writing.
1980 * @return TNG_SUCCESS(0) is successful.
1982 static tng_function_status
tng_residue_data_write(tng_trajectory_t tng_data
,
1983 tng_gen_block_t block
,
1984 tng_residue_t residue
,
1989 TNG_ASSERT(offset
!= 0, "TNG library: offset must not be a NULL pointer.");
1991 memcpy(block
->block_contents
+*offset
, &residue
->id
, sizeof(residue
->id
));
1992 if(tng_data
->output_endianness_swap_func_64
)
1994 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1995 (int64_t *)block
->header_contents
+*offset
)
1998 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1999 __FILE__
, __LINE__
);
2002 *offset
+= sizeof(residue
->id
);
2004 len
= tng_min_i((int)strlen(residue
->name
) + 1, TNG_MAX_STR_LEN
);
2005 strncpy(block
->block_contents
+ *offset
, residue
->name
, len
);
2008 memcpy(block
->block_contents
+*offset
, &residue
->n_atoms
,
2009 sizeof(residue
->n_atoms
));
2010 if(tng_data
->output_endianness_swap_func_64
)
2012 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2013 (int64_t *)block
->header_contents
+*offset
)
2016 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2017 __FILE__
, __LINE__
);
2020 *offset
+= sizeof(residue
->n_atoms
);
2022 return(TNG_SUCCESS
);
2025 /** Read the atom data of a molecules block.
2026 * @param tng_data is a trajectory data container.
2027 * @param block is a general block container.
2028 * @param atom is the atom data container.
2029 * @param offset is the offset of the block input and is updated when reading.
2030 * @return TNG_SUCCESS(0) is successful.
2032 static tng_function_status
tng_atom_data_read(tng_trajectory_t tng_data
,
2033 tng_gen_block_t block
,
2039 TNG_ASSERT(offset
!= 0, "TNG library: offset must not be a NULL pointer.");
2041 memcpy(&atom
->id
, block
->block_contents
+*offset
,
2043 if(tng_data
->input_endianness_swap_func_64
)
2045 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2049 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2050 __FILE__
, __LINE__
);
2053 *offset
+= sizeof(atom
->id
);
2055 len
= tng_min_i((int)strlen(block
->block_contents
+*offset
) + 1,
2057 atom
->name
= malloc(len
);
2059 block
->block_contents
+*offset
, len
);
2062 len
= tng_min_i((int)strlen(block
->block_contents
+*offset
) + 1,
2064 atom
->atom_type
= malloc(len
);
2065 strncpy(atom
->atom_type
,
2066 block
->block_contents
+*offset
, len
);
2069 return(TNG_SUCCESS
);
2072 /** Write the atom data of a molecules block.
2073 * @param tng_data is a trajectory data container.
2074 * @param block is a general block container.
2075 * @param atom is the atom data container.
2076 * @param offset is the offset of the block output and is updated when writing.
2077 * @return TNG_SUCCESS(0) is successful.
2079 static tng_function_status
tng_atom_data_write(tng_trajectory_t tng_data
,
2080 tng_gen_block_t block
,
2086 TNG_ASSERT(offset
!= 0, "TNG library: offset must not be a NULL pointer.");
2088 memcpy(block
->block_contents
+*offset
, &atom
->id
,
2090 if(tng_data
->output_endianness_swap_func_64
)
2092 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2093 (int64_t *)block
->header_contents
+*offset
)
2096 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2097 __FILE__
, __LINE__
);
2100 *offset
+= sizeof(atom
->id
);
2102 len
= tng_min_i((int)strlen(atom
->name
) + 1, TNG_MAX_STR_LEN
);
2103 strncpy(block
->block_contents
+ *offset
, atom
->name
, len
);
2106 len
= tng_min_i((int)strlen(atom
->atom_type
) + 1, TNG_MAX_STR_LEN
);
2107 strncpy(block
->block_contents
+ *offset
, atom
->atom_type
, len
);
2110 return(TNG_SUCCESS
);
2113 /** Read a molecules block. Contains chain, residue and atom data
2114 * @param tng_data is a trajectory data container.
2115 * @param block is a general block container.
2116 * @param hash_mode is an option to decide whether to use the md5 hash or not.
2117 * If hash_mode == TNG_USE_HASH the written md5 hash in the file will be
2118 * compared to the md5 hash of the read contents to ensure valid data.
2119 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
2120 * error has occured.
2122 static tng_function_status tng_molecules_block_read
2123 (tng_trajectory_t tng_data
,
2124 tng_gen_block_t block
,
2125 const char hash_mode
)
2128 int len
, offset
= 0;
2129 tng_molecule_t molecule
;
2131 tng_residue_t residue
;
2136 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
2138 return(TNG_CRITICAL
);
2141 if(block
->block_contents
)
2143 free(block
->block_contents
);
2146 block
->block_contents
= malloc(block
->block_contents_size
);
2147 if(!block
->block_contents
)
2149 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
2150 block
->block_contents_size
, __FILE__
, __LINE__
);
2151 return(TNG_CRITICAL
);
2154 /* Read the whole block into block_contents to be able to write it to disk
2155 * even if it cannot be interpreted. */
2156 if(fread(block
->block_contents
, block
->block_contents_size
, 1,
2157 tng_data
->input_file
) == 0)
2159 fprintf(stderr
, "TNG library: Cannot read block. %s: %d\n", __FILE__
, __LINE__
);
2162 /* FIXME: Does not check if the size of the contents matches the expected
2163 * size or if the contents can be read. */
2165 if(hash_mode
== TNG_USE_HASH
)
2167 tng_md5_hash_match_verify(block
, &same_hash
);
2168 if(same_hash
!= TNG_TRUE
)
2170 fprintf(stderr
, "TNG library: Molecules block contents corrupt. Hashes do not match. "
2172 __FILE__
, __LINE__
);
2176 if(tng_data
->molecules
)
2178 for(i
=tng_data
->n_molecules
; i
--;)
2180 tng_molecule_destroy(tng_data
, &tng_data
->molecules
[i
]);
2182 free(tng_data
->molecules
);
2183 tng_data
->molecules
= 0;
2184 tng_data
->n_molecules
= 0;
2187 memcpy(&tng_data
->n_molecules
, block
->block_contents
,
2188 sizeof(tng_data
->n_molecules
));
2189 if(tng_data
->input_endianness_swap_func_64
)
2191 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2192 &tng_data
->n_molecules
)
2195 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2196 __FILE__
, __LINE__
);
2199 offset
+= sizeof(tng_data
->n_molecules
);
2201 if(tng_data
->molecules
)
2203 free(tng_data
->molecules
);
2206 tng_data
->n_particles
= 0;
2208 tng_data
->molecules
= malloc(tng_data
->n_molecules
*
2209 sizeof(struct tng_molecule
));
2210 if(!tng_data
->molecules
)
2212 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
2213 tng_data
->n_molecules
* sizeof(struct tng_molecule
),
2214 __FILE__
, __LINE__
);
2215 return(TNG_CRITICAL
);
2218 if(!tng_data
->var_num_atoms_flag
)
2220 if(tng_data
->molecule_cnt_list
)
2222 free(tng_data
->molecule_cnt_list
);
2224 tng_data
->molecule_cnt_list
= malloc(sizeof(int64_t) *
2225 tng_data
->n_molecules
);
2226 if(!tng_data
->molecule_cnt_list
)
2228 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
2229 tng_data
->n_molecules
* sizeof(struct tng_molecule
),
2230 __FILE__
, __LINE__
);
2231 return(TNG_CRITICAL
);
2235 /* Read each molecule from file */
2236 for(i
=0; i
< tng_data
->n_molecules
; i
++)
2238 molecule
= &tng_data
->molecules
[i
];
2240 memcpy(&molecule
->id
, block
->block_contents
+offset
,
2241 sizeof(molecule
->id
));
2242 if(tng_data
->input_endianness_swap_func_64
)
2244 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2248 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2249 __FILE__
, __LINE__
);
2252 offset
+= sizeof(molecule
->id
);
2254 /* fprintf(stderr, "TNG library: Read id: %"PRId64" offset: %d\n", molecule->id, offset);*/
2255 len
= tng_min_i((int)strlen(block
->block_contents
+offset
) + 1, TNG_MAX_STR_LEN
);
2256 molecule
->name
= malloc(len
);
2257 strncpy(molecule
->name
, block
->block_contents
+offset
, len
);
2260 memcpy(&molecule
->quaternary_str
, block
->block_contents
+offset
,
2261 sizeof(molecule
->quaternary_str
));
2262 if(tng_data
->input_endianness_swap_func_64
)
2264 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2265 &molecule
->quaternary_str
)
2268 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2269 __FILE__
, __LINE__
);
2272 offset
+= sizeof(molecule
->quaternary_str
);
2274 if(!tng_data
->var_num_atoms_flag
)
2276 memcpy(&tng_data
->molecule_cnt_list
[i
],
2277 block
->block_contents
+offset
,
2279 if(tng_data
->input_endianness_swap_func_64
)
2281 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2282 &tng_data
->molecule_cnt_list
[i
])
2285 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2286 __FILE__
, __LINE__
);
2289 offset
+= sizeof(int64_t);
2293 memcpy(&molecule
->n_chains
, block
->block_contents
+offset
,
2294 sizeof(molecule
->n_chains
));
2295 if(tng_data
->input_endianness_swap_func_64
)
2297 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2298 &molecule
->n_chains
)
2301 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2302 __FILE__
, __LINE__
);
2305 offset
+= sizeof(molecule
->n_chains
);
2307 memcpy(&molecule
->n_residues
, block
->block_contents
+offset
,
2308 sizeof(molecule
->n_residues
));
2309 if(tng_data
->input_endianness_swap_func_64
)
2311 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2312 &molecule
->n_residues
)
2315 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2316 __FILE__
, __LINE__
);
2319 offset
+= sizeof(molecule
->n_residues
);
2321 memcpy(&molecule
->n_atoms
, block
->block_contents
+offset
,
2322 sizeof(molecule
->n_atoms
));
2323 if(tng_data
->input_endianness_swap_func_64
)
2325 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2329 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2330 __FILE__
, __LINE__
);
2333 offset
+= sizeof(molecule
->n_atoms
);
2335 tng_data
->n_particles
+= molecule
->n_atoms
*
2336 tng_data
->molecule_cnt_list
[i
];
2338 if(molecule
->n_chains
> 0)
2340 molecule
->chains
= malloc(molecule
->n_chains
*
2341 sizeof(struct tng_chain
));
2342 if(!molecule
->chains
)
2344 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
2345 molecule
->n_chains
* sizeof(struct tng_chain
),
2346 __FILE__
, __LINE__
);
2347 return(TNG_CRITICAL
);
2350 chain
= molecule
->chains
;
2357 if(molecule
->n_residues
> 0)
2359 molecule
->residues
= malloc(molecule
->n_residues
*
2360 sizeof(struct tng_residue
));
2361 if(!molecule
->residues
)
2363 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
2364 molecule
->n_residues
* sizeof(struct tng_residue
),
2365 __FILE__
, __LINE__
);
2366 if(molecule
->chains
)
2368 free(molecule
->chains
);
2369 molecule
->chains
= 0;
2371 return(TNG_CRITICAL
);
2374 residue
= molecule
->residues
;
2381 molecule
->atoms
= malloc(molecule
->n_atoms
*
2382 sizeof(struct tng_atom
));
2383 if(!molecule
->atoms
)
2385 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
2386 molecule
->n_atoms
* sizeof(struct tng_atom
),
2387 __FILE__
, __LINE__
);
2388 if(molecule
->chains
)
2390 free(molecule
->chains
);
2391 molecule
->chains
= 0;
2393 if(molecule
->residues
)
2395 free(molecule
->residues
);
2396 molecule
->residues
= 0;
2398 return(TNG_CRITICAL
);
2401 atom
= molecule
->atoms
;
2403 if(molecule
->n_chains
> 0)
2405 /* Read the chains of the molecule */
2406 for(j
=molecule
->n_chains
; j
--;)
2408 chain
->molecule
= molecule
;
2410 tng_chain_data_read(tng_data
, block
, chain
, &offset
);
2412 chain
->residues
= molecule
->residues
;
2413 residue
= chain
->residues
;
2415 /* Read the residues of the chain */
2416 for(k
=chain
->n_residues
; k
--;)
2418 residue
->chain
= chain
;
2420 tng_residue_data_read(tng_data
, block
, residue
, &offset
);
2422 residue
->atoms_offset
= atom
- molecule
->atoms
;
2423 /* Read the atoms of the residue */
2424 for(l
=residue
->n_atoms
; l
--;)
2426 atom
->residue
= residue
;
2428 tng_atom_data_read(tng_data
, block
, atom
, &offset
);
2439 if(molecule
->n_residues
> 0)
2441 for(k
=molecule
->n_residues
; k
--;)
2445 tng_residue_data_read(tng_data
, block
, residue
, &offset
);
2447 residue
->atoms_offset
= atom
- molecule
->atoms
;
2448 /* Read the atoms of the residue */
2449 for(l
=residue
->n_atoms
; l
--;)
2451 atom
->residue
= residue
;
2453 tng_atom_data_read(tng_data
, block
, atom
, &offset
);
2462 for(l
=molecule
->n_atoms
; l
--;)
2466 tng_atom_data_read(tng_data
, block
, atom
, &offset
);
2473 memcpy(&molecule
->n_bonds
, block
->block_contents
+offset
,
2474 sizeof(molecule
->n_bonds
));
2475 if(tng_data
->input_endianness_swap_func_64
)
2477 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2481 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2482 __FILE__
, __LINE__
);
2485 offset
+= sizeof(molecule
->n_bonds
);
2487 if(molecule
->n_bonds
> 0)
2489 tng_data
->molecules
[i
].bonds
= malloc(molecule
->n_bonds
*
2490 sizeof(struct tng_bond
));
2491 if(!molecule
->bonds
)
2493 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
2494 molecule
->n_bonds
* sizeof(struct tng_bond
),
2495 __FILE__
, __LINE__
);
2496 if(molecule
->chains
)
2498 free(molecule
->chains
);
2499 molecule
->chains
= 0;
2501 if(molecule
->residues
)
2503 free(molecule
->residues
);
2504 molecule
->residues
= 0;
2508 free(molecule
->atoms
);
2509 molecule
->atoms
= 0;
2511 return(TNG_CRITICAL
);
2514 bond
= molecule
->bonds
;
2516 for(j
=molecule
->n_bonds
; j
--;)
2518 memcpy(&bond
->from_atom_id
, block
->block_contents
+offset
,
2519 sizeof(bond
->from_atom_id
));
2520 if(tng_data
->input_endianness_swap_func_64
)
2522 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2523 &bond
->from_atom_id
)
2526 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2527 __FILE__
, __LINE__
);
2530 offset
+= sizeof(bond
->from_atom_id
);
2532 memcpy(&bond
->to_atom_id
, block
->block_contents
+offset
,
2533 sizeof(bond
->to_atom_id
));
2534 if(tng_data
->input_endianness_swap_func_64
)
2536 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2540 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2541 __FILE__
, __LINE__
);
2544 offset
+= sizeof(bond
->to_atom_id
);
2551 molecule
->bonds
= 0;
2555 return(TNG_SUCCESS
);
2558 /** Write a molecules block.
2559 * @param tng_data is a trajectory data container.
2560 * @param hash_mode is an option to decide whether to use the md5 hash or not.
2561 * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
2562 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
2563 * error has occured.
2565 static tng_function_status tng_molecules_block_write
2566 (tng_trajectory_t tng_data
,
2567 const char hash_mode
)
2569 int len
= 0, name_len
, offset
= 0;
2571 tng_molecule_t molecule
;
2573 tng_residue_t residue
;
2576 tng_gen_block_t block
;
2578 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
2580 return(TNG_CRITICAL
);
2583 /* First predict the size of the block */
2584 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
2586 molecule
= &tng_data
->molecules
[i
];
2589 molecule
->name
= malloc(1);
2592 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
2593 __FILE__
, __LINE__
);
2594 return(TNG_CRITICAL
);
2596 molecule
->name
[0] = 0;
2598 len
+= tng_min_i((int)strlen(molecule
->name
) + 1, TNG_MAX_STR_LEN
);
2600 chain
= molecule
->chains
;
2601 for(j
= molecule
->n_chains
; j
--;)
2603 len
+= sizeof(chain
->id
);
2607 chain
->name
= malloc(1);
2610 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
2611 __FILE__
, __LINE__
);
2612 return(TNG_CRITICAL
);
2616 len
+= tng_min_i((int)strlen(chain
->name
) + 1, TNG_MAX_STR_LEN
);
2618 len
+= sizeof(chain
->n_residues
);
2623 residue
= molecule
->residues
;
2624 for(j
= molecule
->n_residues
; j
--;)
2626 len
+= sizeof(residue
->id
);
2630 residue
->name
= malloc(1);
2633 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
2634 __FILE__
, __LINE__
);
2635 return(TNG_CRITICAL
);
2637 residue
->name
[0] = 0;
2639 len
+= tng_min_i((int)strlen(residue
->name
) + 1, TNG_MAX_STR_LEN
);
2641 len
+= sizeof(residue
->n_atoms
);
2646 atom
= molecule
->atoms
;
2647 for(j
= molecule
->n_atoms
; j
--;)
2649 len
+= sizeof(atom
->id
);
2652 atom
->name
= malloc(1);
2655 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
2656 __FILE__
, __LINE__
);
2657 return(TNG_CRITICAL
);
2661 len
+= tng_min_i((int)strlen(atom
->name
) + 1, TNG_MAX_STR_LEN
);
2663 if(!atom
->atom_type
)
2665 atom
->atom_type
= malloc(1);
2666 if(!atom
->atom_type
)
2668 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
2669 __FILE__
, __LINE__
);
2670 return(TNG_CRITICAL
);
2672 atom
->atom_type
[0] = 0;
2674 len
+= tng_min_i((int)strlen(atom
->atom_type
) + 1, TNG_MAX_STR_LEN
);
2679 for(j
= molecule
->n_bonds
; j
--;)
2681 len
+= sizeof(bond
->from_atom_id
) + sizeof(bond
->to_atom_id
);
2685 tng_block_init(&block
);
2687 name_len
= (int)strlen("MOLECULES");
2689 block
->name
= malloc(name_len
+ 1);
2692 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
2693 name_len
+1, __FILE__
, __LINE__
);
2694 tng_block_destroy(&block
);
2695 return(TNG_CRITICAL
);
2698 strcpy(block
->name
, "MOLECULES");
2699 block
->id
= TNG_MOLECULES
;
2701 block
->block_contents_size
= sizeof(tng_data
->n_molecules
) +
2702 (sizeof(molecule
->id
) +
2703 sizeof(molecule
->quaternary_str
) +
2704 sizeof(molecule
->n_chains
) +
2705 sizeof(molecule
->n_residues
) +
2706 sizeof(molecule
->n_atoms
) +
2707 sizeof(molecule
->n_bonds
)) *
2708 tng_data
->n_molecules
+
2711 if(!tng_data
->var_num_atoms_flag
)
2713 block
->block_contents_size
+= tng_data
->n_molecules
* sizeof(int64_t);
2716 block
->block_contents
= malloc(block
->block_contents_size
);
2717 if(!block
->block_contents
)
2719 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
2720 block
->block_contents_size
, __FILE__
, __LINE__
);
2721 tng_block_destroy(&block
);
2722 return(TNG_CRITICAL
);
2725 memcpy(block
->block_contents
+offset
, &tng_data
->n_molecules
,
2726 sizeof(tng_data
->n_molecules
));
2727 if(tng_data
->output_endianness_swap_func_64
)
2729 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2730 (int64_t *)block
->header_contents
+offset
)
2733 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2734 __FILE__
, __LINE__
);
2737 offset
+= sizeof(tng_data
->n_molecules
);
2739 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
2741 molecule
= &tng_data
->molecules
[i
];
2742 memcpy(block
->block_contents
+offset
, &molecule
->id
,
2743 sizeof(molecule
->id
));
2744 if(tng_data
->output_endianness_swap_func_64
)
2746 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2747 (int64_t *)block
->header_contents
+offset
)
2750 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2751 __FILE__
, __LINE__
);
2754 offset
+= sizeof(molecule
->id
);
2756 /* fprintf(stderr, "TNG library: Wrote id: %"PRId64" offset: %d\n", molecule->id, offset); */
2757 len
= tng_min_i((int)strlen(molecule
->name
) + 1, TNG_MAX_STR_LEN
);
2758 strncpy(block
->block_contents
+ offset
, molecule
->name
, len
);
2761 memcpy(block
->block_contents
+offset
, &molecule
->quaternary_str
,
2762 sizeof(molecule
->quaternary_str
));
2763 if(tng_data
->output_endianness_swap_func_64
)
2765 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2766 (int64_t *)block
->header_contents
+offset
)
2769 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2770 __FILE__
, __LINE__
);
2773 offset
+= sizeof(molecule
->quaternary_str
);
2775 if(!tng_data
->var_num_atoms_flag
)
2777 memcpy(block
->block_contents
+offset
,
2778 &tng_data
->molecule_cnt_list
[i
], sizeof(int64_t));
2779 if(tng_data
->output_endianness_swap_func_64
)
2781 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2782 (int64_t *)block
->header_contents
+offset
)
2785 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2786 __FILE__
, __LINE__
);
2789 offset
+= sizeof(int64_t);
2792 memcpy(block
->block_contents
+offset
, &molecule
->n_chains
,
2793 sizeof(molecule
->n_chains
));
2794 if(tng_data
->output_endianness_swap_func_64
)
2796 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2797 (int64_t *)block
->header_contents
+offset
)
2800 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2801 __FILE__
, __LINE__
);
2804 offset
+= sizeof(molecule
->n_chains
);
2806 memcpy(block
->block_contents
+offset
, &molecule
->n_residues
,
2807 sizeof(molecule
->n_residues
));
2808 if(tng_data
->output_endianness_swap_func_64
)
2810 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2811 (int64_t *)block
->header_contents
+offset
)
2814 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2815 __FILE__
, __LINE__
);
2818 offset
+= sizeof(molecule
->n_residues
);
2820 memcpy(block
->block_contents
+offset
, &molecule
->n_atoms
,
2821 sizeof(molecule
->n_atoms
));
2822 if(tng_data
->output_endianness_swap_func_64
)
2824 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2825 (int64_t *)block
->header_contents
+offset
)
2828 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2829 __FILE__
, __LINE__
);
2832 offset
+= sizeof(molecule
->n_atoms
);
2834 if(molecule
->n_chains
> 0)
2836 chain
= molecule
->chains
;
2837 for(j
= molecule
->n_chains
; j
--;)
2839 tng_chain_data_write(tng_data
, block
, chain
, &offset
);
2841 residue
= chain
->residues
;
2842 for(k
= chain
->n_residues
; k
--;)
2844 tng_residue_data_write(tng_data
, block
, residue
, &offset
);
2846 atom
= molecule
->atoms
+ residue
->atoms_offset
;
2847 for(l
= residue
->n_atoms
; l
--;)
2849 tng_atom_data_write(tng_data
, block
, atom
, &offset
);
2860 if(molecule
->n_residues
> 0)
2862 residue
= molecule
->residues
;
2863 for(k
= molecule
->n_residues
; k
--;)
2865 tng_residue_data_write(tng_data
, block
, residue
, &offset
);
2867 atom
= molecule
->atoms
+ residue
->atoms_offset
;
2868 for(l
= residue
->n_atoms
; l
--;)
2870 tng_atom_data_write(tng_data
, block
, atom
, &offset
);
2879 atom
= molecule
->atoms
;
2880 for(l
= molecule
->n_atoms
; l
--;)
2882 tng_atom_data_write(tng_data
, block
, atom
, &offset
);
2889 memcpy(block
->block_contents
+offset
, &molecule
->n_bonds
,
2890 sizeof(molecule
->n_bonds
));
2891 if(tng_data
->output_endianness_swap_func_64
)
2893 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2894 (int64_t *)block
->header_contents
+offset
)
2897 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2898 __FILE__
, __LINE__
);
2901 offset
+= sizeof(molecule
->n_bonds
);
2903 bond
= molecule
->bonds
;
2904 for(j
= molecule
->n_bonds
; j
--;)
2906 memcpy(block
->block_contents
+offset
, &bond
->from_atom_id
,
2907 sizeof(bond
->from_atom_id
));
2908 if(tng_data
->output_endianness_swap_func_64
)
2910 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2911 (int64_t *)block
->header_contents
+offset
)
2914 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2915 __FILE__
, __LINE__
);
2918 offset
+= sizeof(bond
->from_atom_id
);
2920 memcpy(block
->block_contents
+offset
, &bond
->to_atom_id
,
2921 sizeof(bond
->to_atom_id
));
2922 if(tng_data
->output_endianness_swap_func_64
)
2924 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2925 (int64_t *)block
->header_contents
+offset
)
2928 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2929 __FILE__
, __LINE__
);
2932 offset
+= sizeof(bond
->to_atom_id
);
2938 if(tng_block_header_write(tng_data
, block
, hash_mode
) != TNG_SUCCESS
)
2940 fprintf(stderr
, "TNG library: Cannot write header of file %s. %s: %d\n",
2941 tng_data
->output_file_path
, __FILE__
, __LINE__
);
2942 tng_block_destroy(&block
);
2943 return(TNG_CRITICAL
);
2946 if(fwrite(block
->block_contents
, block
->block_contents_size
, 1,
2947 tng_data
->output_file
) != 1)
2949 fprintf(stderr
, "TNG library: Could not write all block data. %s: %d\n",
2950 __FILE__
, __LINE__
);
2951 tng_block_destroy(&block
);
2952 return(TNG_CRITICAL
);
2955 tng_block_destroy(&block
);
2957 return(TNG_SUCCESS
);
2960 /** Read a frame set block. Update tng_data->current_trajectory_frame_set
2961 * @param tng_data is a trajectory data container.
2962 * @param block is a general block container.
2963 * @param hash_mode is an option to decide whether to use the md5 hash or not.
2964 * If hash_mode == TNG_USE_HASH the written md5 hash in the file will be
2965 * compared to the md5 hash of the read contents to ensure valid data.
2966 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
2967 * error has occured.
2969 static tng_function_status tng_frame_set_block_read
2970 (tng_trajectory_t tng_data
,
2971 tng_gen_block_t block
,
2972 const char hash_mode
)
2976 int64_t i
, prev_n_particles
;
2978 tng_trajectory_frame_set_t frame_set
=
2979 &tng_data
->current_trajectory_frame_set
;
2981 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
2983 return(TNG_CRITICAL
);
2986 if(block
->block_contents
)
2988 free(block
->block_contents
);
2991 block
->block_contents
= malloc(block
->block_contents_size
);
2992 if(!block
->block_contents
)
2994 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
2995 block
->block_contents_size
, __FILE__
, __LINE__
);
2996 return(TNG_CRITICAL
);
2999 /* Read the whole block into block_contents to be able to write it to
3000 * disk even if it cannot be interpreted. */
3001 if(fread(block
->block_contents
, block
->block_contents_size
, 1,
3002 tng_data
->input_file
) == 0)
3004 fprintf(stderr
, "TNG library: Cannot read block. %s: %d\n", __FILE__
, __LINE__
);
3005 return(TNG_CRITICAL
);
3008 /* FIXME: Does not check if the size of the contents matches the expected
3009 * size or if the contents can be read. */
3011 file_pos
= (int64_t)ftell(tng_data
->input_file
) -
3012 (long)(block
->block_contents_size
+ block
->header_contents_size
);
3014 if(hash_mode
== TNG_USE_HASH
)
3016 tng_md5_hash_match_verify(block
, &same_hash
);
3017 if(same_hash
!= TNG_TRUE
)
3019 fprintf(stderr
, "TNG library: Frame set block contents corrupt. File pos %ld Hashes do not match. "
3021 file_pos
, __FILE__
, __LINE__
);
3022 /* return(TNG_FAILURE); */
3026 tng_data
->current_trajectory_frame_set_input_file_pos
= file_pos
;
3028 tng_frame_set_particle_mapping_free(tng_data
);
3030 if(tng_data
->first_trajectory_frame_set_input_file_pos
<= 0)
3032 tng_data
->first_trajectory_frame_set_input_file_pos
= file_pos
;
3034 /* FIXME: Should check the frame number instead of the file_pos, in case
3035 * frame sets are not in order */
3036 if(tng_data
->last_trajectory_frame_set_input_file_pos
< file_pos
)
3038 tng_data
->last_trajectory_frame_set_input_file_pos
= file_pos
;
3041 memcpy(&frame_set
->first_frame
, block
->block_contents
,
3042 sizeof(frame_set
->first_frame
));
3043 if(tng_data
->input_endianness_swap_func_64
)
3045 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3046 &frame_set
->first_frame
)
3049 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3050 __FILE__
, __LINE__
);
3053 offset
+= sizeof(frame_set
->first_frame
);
3055 memcpy(&frame_set
->n_frames
, block
->block_contents
+ offset
,
3056 sizeof(frame_set
->n_frames
));
3057 if(tng_data
->input_endianness_swap_func_64
)
3059 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3060 &frame_set
->n_frames
)
3063 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3064 __FILE__
, __LINE__
);
3067 offset
+= sizeof(frame_set
->n_frames
);
3069 if(tng_data
->var_num_atoms_flag
)
3071 prev_n_particles
= frame_set
->n_particles
;
3072 frame_set
->n_particles
= 0;
3073 /* If the list of molecule counts has already been created assume that
3074 * it is of correct size. */
3075 if(!frame_set
->molecule_cnt_list
)
3077 frame_set
->molecule_cnt_list
=
3078 malloc(sizeof(int64_t) * tng_data
->n_molecules
);
3080 if(!frame_set
->molecule_cnt_list
)
3082 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
3083 sizeof(int64_t) * tng_data
->n_molecules
,
3084 __FILE__
, __LINE__
);
3085 return(TNG_CRITICAL
);
3088 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
3090 memcpy(&frame_set
->molecule_cnt_list
[i
],
3091 block
->block_contents
+ offset
,
3093 if(tng_data
->input_endianness_swap_func_64
)
3095 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3096 &frame_set
->molecule_cnt_list
[i
])
3099 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3100 __FILE__
, __LINE__
);
3103 offset
+= sizeof(int64_t);
3104 frame_set
->n_particles
+= tng_data
->molecules
[i
].n_atoms
*
3105 frame_set
->molecule_cnt_list
[i
];
3107 if(prev_n_particles
&& frame_set
->n_particles
!= prev_n_particles
)
3109 /* FIXME: Particle dependent data memory management */
3113 memcpy(&frame_set
->next_frame_set_file_pos
,
3114 block
->block_contents
+ offset
,
3115 sizeof(frame_set
->next_frame_set_file_pos
));
3116 if(tng_data
->input_endianness_swap_func_64
)
3118 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3119 &frame_set
->next_frame_set_file_pos
)
3122 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3123 __FILE__
, __LINE__
);
3126 offset
+= sizeof(frame_set
->next_frame_set_file_pos
);
3128 memcpy(&frame_set
->prev_frame_set_file_pos
,
3129 block
->block_contents
+ offset
,
3130 sizeof(frame_set
->prev_frame_set_file_pos
));
3131 if(tng_data
->input_endianness_swap_func_64
)
3133 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3134 &frame_set
->prev_frame_set_file_pos
)
3137 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3138 __FILE__
, __LINE__
);
3141 offset
+= sizeof(frame_set
->prev_frame_set_file_pos
);
3143 memcpy(&frame_set
->medium_stride_next_frame_set_file_pos
,
3144 block
->block_contents
+ offset
,
3145 sizeof(frame_set
->medium_stride_next_frame_set_file_pos
));
3146 if(tng_data
->input_endianness_swap_func_64
)
3148 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3149 &frame_set
->medium_stride_next_frame_set_file_pos
)
3152 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3153 __FILE__
, __LINE__
);
3156 offset
+= sizeof(frame_set
->medium_stride_next_frame_set_file_pos
);
3158 memcpy(&frame_set
->medium_stride_prev_frame_set_file_pos
,
3159 block
->block_contents
+ offset
,
3160 sizeof(frame_set
->medium_stride_prev_frame_set_file_pos
));
3161 if(tng_data
->input_endianness_swap_func_64
)
3163 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3164 &frame_set
->medium_stride_prev_frame_set_file_pos
)
3167 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3168 __FILE__
, __LINE__
);
3171 offset
+= sizeof(frame_set
->medium_stride_prev_frame_set_file_pos
);
3173 memcpy(&frame_set
->long_stride_next_frame_set_file_pos
,
3174 block
->block_contents
+ offset
,
3175 sizeof(frame_set
->long_stride_next_frame_set_file_pos
));
3176 if(tng_data
->input_endianness_swap_func_64
)
3178 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3179 &frame_set
->long_stride_next_frame_set_file_pos
)
3182 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3183 __FILE__
, __LINE__
);
3186 offset
+= sizeof(frame_set
->long_stride_next_frame_set_file_pos
);
3188 memcpy(&frame_set
->long_stride_prev_frame_set_file_pos
,
3189 block
->block_contents
+ offset
,
3190 sizeof(frame_set
->long_stride_prev_frame_set_file_pos
));
3191 if(tng_data
->input_endianness_swap_func_64
)
3193 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3194 &frame_set
->long_stride_prev_frame_set_file_pos
)
3197 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3198 __FILE__
, __LINE__
);
3201 offset
+= sizeof(frame_set
->long_stride_prev_frame_set_file_pos
);
3203 if(block
->block_version
>= 3)
3205 memcpy(&frame_set
->first_frame_time
,
3206 block
->block_contents
+ offset
,
3207 sizeof(frame_set
->first_frame_time
));
3208 if(tng_data
->input_endianness_swap_func_64
)
3210 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3211 (int64_t *)&frame_set
->first_frame_time
)
3214 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3215 __FILE__
, __LINE__
);
3218 offset
+= sizeof(frame_set
->first_frame_time
);
3220 memcpy(&tng_data
->time_per_frame
,
3221 block
->block_contents
+ offset
,
3222 sizeof(tng_data
->time_per_frame
));
3223 if(tng_data
->input_endianness_swap_func_64
)
3225 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3226 (int64_t *)&tng_data
->time_per_frame
)
3229 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3230 __FILE__
, __LINE__
);
3236 frame_set
->first_frame_time
= -1;
3237 tng_data
->time_per_frame
= -1;
3240 frame_set
->n_written_frames
= frame_set
->n_frames
;
3242 return(TNG_SUCCESS
);
3245 /** Write tng_data->current_trajectory_frame_set to file
3246 * @param tng_data is a trajectory data container.
3247 * @param block is a general block container.
3248 * @param hash_mode is an option to decide whether to use the md5 hash or not.
3249 * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
3250 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
3251 * error has occured.
3253 static tng_function_status tng_frame_set_block_write
3254 (tng_trajectory_t tng_data
,
3255 tng_gen_block_t block
,
3256 const char hash_mode
)
3261 unsigned int name_len
;
3262 tng_trajectory_frame_set_t frame_set
=
3263 &tng_data
->current_trajectory_frame_set
;
3265 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
3267 return(TNG_CRITICAL
);
3270 name_len
= (int)strlen("TRAJECTORY FRAME SET");
3272 if(!block
->name
|| strlen(block
->name
) < name_len
)
3274 temp_name
= realloc(block
->name
, name_len
+ 1);
3277 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
3278 name_len
+1, __FILE__
, __LINE__
);
3281 return(TNG_CRITICAL
);
3283 block
->name
= temp_name
;
3285 strcpy(block
->name
, "TRAJECTORY FRAME SET");
3286 block
->id
= TNG_TRAJECTORY_FRAME_SET
;
3288 block
->block_contents_size
= sizeof(int64_t) * 8;
3289 block
->block_contents_size
+= sizeof(double) * 2;
3291 if(tng_data
->var_num_atoms_flag
)
3293 block
->block_contents_size
+= sizeof(int64_t) * tng_data
->n_molecules
;
3296 if(block
->block_contents
)
3298 free(block
->block_contents
);
3300 block
->block_contents
= malloc(block
->block_contents_size
);
3301 if(!block
->block_contents
)
3303 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
3304 block
->block_contents_size
, __FILE__
, __LINE__
);
3305 return(TNG_CRITICAL
);
3308 memcpy(block
->block_contents
, &frame_set
->first_frame
,
3309 sizeof(frame_set
->first_frame
));
3310 if(tng_data
->output_endianness_swap_func_64
)
3312 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3313 (int64_t *)block
->header_contents
+offset
)
3316 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3317 __FILE__
, __LINE__
);
3320 offset
+= sizeof(frame_set
->first_frame
);
3322 memcpy(block
->block_contents
+offset
, &frame_set
->n_frames
,
3323 sizeof(frame_set
->n_frames
));
3324 if(tng_data
->output_endianness_swap_func_64
)
3326 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3327 (int64_t *)block
->header_contents
+offset
)
3330 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3331 __FILE__
, __LINE__
);
3334 offset
+= sizeof(frame_set
->n_frames
);
3336 if(tng_data
->var_num_atoms_flag
)
3338 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
3340 memcpy(block
->block_contents
+offset
,
3341 &frame_set
->molecule_cnt_list
[i
],
3343 if(tng_data
->output_endianness_swap_func_64
)
3345 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3346 (int64_t *)block
->header_contents
+offset
)
3349 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3350 __FILE__
, __LINE__
);
3353 offset
+= sizeof(int64_t);
3358 memcpy(block
->block_contents
+offset
, &frame_set
->next_frame_set_file_pos
,
3359 sizeof(frame_set
->next_frame_set_file_pos
));
3360 if(tng_data
->output_endianness_swap_func_64
)
3362 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3363 (int64_t *)block
->header_contents
+offset
)
3366 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3367 __FILE__
, __LINE__
);
3370 offset
+= sizeof(frame_set
->next_frame_set_file_pos
);
3372 memcpy(block
->block_contents
+offset
, &frame_set
->prev_frame_set_file_pos
,
3373 sizeof(frame_set
->prev_frame_set_file_pos
));
3374 if(tng_data
->output_endianness_swap_func_64
)
3376 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3377 (int64_t *)block
->header_contents
+offset
)
3380 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3381 __FILE__
, __LINE__
);
3384 offset
+= sizeof(frame_set
->prev_frame_set_file_pos
);
3386 memcpy(block
->block_contents
+offset
,
3387 &frame_set
->medium_stride_next_frame_set_file_pos
,
3388 sizeof(frame_set
->medium_stride_next_frame_set_file_pos
));
3389 if(tng_data
->output_endianness_swap_func_64
)
3391 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3392 (int64_t *)block
->header_contents
+offset
)
3395 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3396 __FILE__
, __LINE__
);
3399 offset
+= sizeof(frame_set
->medium_stride_next_frame_set_file_pos
);
3401 memcpy(block
->block_contents
+offset
,
3402 &frame_set
->medium_stride_prev_frame_set_file_pos
,
3403 sizeof(frame_set
->medium_stride_prev_frame_set_file_pos
));
3404 if(tng_data
->output_endianness_swap_func_64
)
3406 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3407 (int64_t *)block
->header_contents
+offset
)
3410 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3411 __FILE__
, __LINE__
);
3414 offset
+= sizeof(frame_set
->medium_stride_prev_frame_set_file_pos
);
3416 memcpy(block
->block_contents
+offset
,
3417 &frame_set
->long_stride_next_frame_set_file_pos
,
3418 sizeof(frame_set
->long_stride_next_frame_set_file_pos
));
3419 if(tng_data
->output_endianness_swap_func_64
)
3421 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3422 (int64_t *)block
->header_contents
+offset
)
3425 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3426 __FILE__
, __LINE__
);
3429 offset
+= sizeof(frame_set
->long_stride_next_frame_set_file_pos
);
3431 memcpy(block
->block_contents
+offset
,
3432 &frame_set
->long_stride_prev_frame_set_file_pos
,
3433 sizeof(frame_set
->long_stride_prev_frame_set_file_pos
));
3434 if(tng_data
->output_endianness_swap_func_64
)
3436 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3437 (int64_t *)block
->header_contents
+offset
)
3440 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3441 __FILE__
, __LINE__
);
3444 offset
+= sizeof(frame_set
->long_stride_prev_frame_set_file_pos
);
3446 memcpy(block
->block_contents
+offset
,
3447 &frame_set
->first_frame_time
,
3448 sizeof(frame_set
->first_frame_time
));
3449 if(tng_data
->output_endianness_swap_func_64
)
3451 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3452 (int64_t *)block
->header_contents
+offset
)
3455 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3456 __FILE__
, __LINE__
);
3459 offset
+= sizeof(frame_set
->first_frame_time
);
3461 memcpy(block
->block_contents
+offset
,
3462 &tng_data
->time_per_frame
,
3463 sizeof(tng_data
->time_per_frame
));
3464 if(tng_data
->output_endianness_swap_func_64
)
3466 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3467 (int64_t *)block
->header_contents
+offset
)
3470 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3471 __FILE__
, __LINE__
);
3475 if(tng_block_header_write(tng_data
, block
, hash_mode
) != TNG_SUCCESS
)
3477 fprintf(stderr
, "TNG library: Cannot write header of file %s. %s: %d\n",
3478 tng_data
->output_file_path
, __FILE__
, __LINE__
);
3479 return(TNG_CRITICAL
);
3482 if(fwrite(block
->block_contents
, block
->block_contents_size
, 1,
3483 tng_data
->output_file
) != 1)
3485 fprintf(stderr
, "TNG library: Could not write all block data. %s: %d\n", __FILE__
, __LINE__
);
3486 return(TNG_CRITICAL
);
3489 return(TNG_SUCCESS
);
3493 /** Read an atom mappings block (translating between real atom indexes and how
3494 * the atom info is written in this frame set).
3495 * @param tng_data is a trajectory data container.
3496 * @param block is a general block container.
3497 * @param hash_mode is an option to decide whether to use the md5 hash or not.
3498 * If hash_mode == TNG_USE_HASH the written md5 hash in the file will be
3499 * compared to the md5 hash of the read contents to ensure valid data.
3500 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
3501 * error has occured.
3503 static tng_function_status tng_trajectory_mapping_block_read
3504 (tng_trajectory_t tng_data
,
3505 tng_gen_block_t block
,
3506 const char hash_mode
)
3511 tng_trajectory_frame_set_t frame_set
=
3512 &tng_data
->current_trajectory_frame_set
;
3514 tng_particle_mapping_t mapping
, mappings
;
3516 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
3518 return(TNG_CRITICAL
);
3521 if(block
->block_contents
)
3523 free(block
->block_contents
);
3526 block
->block_contents
= malloc(block
->block_contents_size
);
3527 if(!block
->block_contents
)
3529 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
3530 block
->block_contents_size
, __FILE__
, __LINE__
);
3531 return(TNG_CRITICAL
);
3534 /* Read the whole block into block_contents to be able to write it to disk
3535 * even if it cannot be interpreted. */
3536 if(fread(block
->block_contents
, block
->block_contents_size
, 1,
3537 tng_data
->input_file
) == 0)
3539 fprintf(stderr
, "TNG library: Cannot read block. %s: %d\n", __FILE__
, __LINE__
);
3540 return(TNG_CRITICAL
);
3543 /* FIXME: Does not check if the size of the contents matches the expected
3544 * size or if the contents can be read. */
3546 if(hash_mode
== TNG_USE_HASH
)
3548 tng_md5_hash_match_verify(block
, &same_hash
);
3549 if(same_hash
!= TNG_TRUE
)
3551 fprintf(stderr
, "TNG library: Particle mapping block contents corrupt. Hashes do not match. "
3553 __FILE__
, __LINE__
);
3554 /* return(TNG_FAILURE); */
3558 frame_set
->n_mapping_blocks
++;
3559 mappings
= realloc(frame_set
->mappings
,
3560 sizeof(struct tng_particle_mapping
) *
3561 frame_set
->n_mapping_blocks
);
3564 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
3565 block
->block_contents_size
, __FILE__
, __LINE__
);
3566 free(frame_set
->mappings
);
3567 frame_set
->mappings
= 0;
3568 return(TNG_CRITICAL
);
3570 frame_set
->mappings
= mappings
;
3571 mapping
= &mappings
[frame_set
->n_mapping_blocks
- 1];
3574 memcpy(&mapping
->num_first_particle
, block
->block_contents
+offset
,
3575 sizeof(mapping
->num_first_particle
));
3576 if(tng_data
->input_endianness_swap_func_64
)
3578 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3579 &mapping
->num_first_particle
)
3582 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3583 __FILE__
, __LINE__
);
3586 offset
+= sizeof(mapping
->num_first_particle
);
3588 memcpy(&mapping
->n_particles
, block
->block_contents
+offset
,
3589 sizeof(mapping
->n_particles
));
3590 if(tng_data
->input_endianness_swap_func_64
)
3592 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3593 &mapping
->n_particles
)
3596 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3597 __FILE__
, __LINE__
);
3600 offset
+= sizeof(mapping
->n_particles
);
3602 mapping
->real_particle_numbers
= malloc(mapping
->n_particles
*
3604 if(!mapping
->real_particle_numbers
)
3606 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
3607 mapping
->n_particles
* sizeof(int64_t), __FILE__
, __LINE__
);
3608 return(TNG_CRITICAL
);
3611 /* If the byte order needs to be swapped the data must be read one value at
3612 * a time and swapped */
3613 if(tng_data
->input_endianness_swap_func_64
)
3615 for(i
= 0; i
< mapping
->n_particles
; i
++)
3617 memcpy(&mapping
->real_particle_numbers
[i
],
3618 block
->block_contents
+ offset
,
3620 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3621 &mapping
->real_particle_numbers
[i
])
3624 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3625 __FILE__
, __LINE__
);
3627 offset
+= sizeof(int64_t);
3630 /* Otherwise the data can be read all at once */
3633 memcpy(mapping
->real_particle_numbers
, block
->block_contents
+ offset
,
3634 mapping
->n_particles
* sizeof(int64_t));
3638 return(TNG_SUCCESS
);
3641 /** Write the atom mappings of the current trajectory frame set
3642 * @param tng_data is a trajectory data container.
3643 * @param block is a general block container.
3644 * @param mapping_block_nr is the index of the mapping block to write.
3645 * @param hash_mode is an option to decide whether to use the md5 hash or not.
3646 * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
3647 * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if a minor error
3648 * has occurred or TNG_CRITICAL (2) if a major error has occured.
3650 static tng_function_status tng_trajectory_mapping_block_write
3651 (tng_trajectory_t tng_data
,
3652 tng_gen_block_t block
,
3653 int mapping_block_nr
,
3654 const char hash_mode
)
3658 unsigned int name_len
;
3659 tng_particle_mapping_t mapping
=
3660 &tng_data
->current_trajectory_frame_set
.mappings
[mapping_block_nr
];
3662 if(mapping_block_nr
>=
3663 tng_data
->current_trajectory_frame_set
.n_mapping_blocks
)
3665 fprintf(stderr
, "TNG library: Mapping block index out of bounds. %s: %d\n",
3666 __FILE__
, __LINE__
);
3667 return(TNG_FAILURE
);
3670 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
3672 return(TNG_CRITICAL
);
3675 name_len
= (int)strlen("PARTICLE MAPPING");
3677 if(!block
->name
|| strlen(block
->name
) < name_len
)
3679 temp_name
= realloc(block
->name
, name_len
+ 1);
3682 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
3683 name_len
+1, __FILE__
, __LINE__
);
3686 return(TNG_CRITICAL
);
3688 block
->name
= temp_name
;
3690 strcpy(block
->name
, "PARTICLE MAPPING");
3691 block
->id
= TNG_PARTICLE_MAPPING
;
3693 block
->block_contents_size
= sizeof(int64_t) * (2 + mapping
->n_particles
);
3695 if(block
->block_contents
)
3697 free(block
->block_contents
);
3699 block
->block_contents
= malloc(block
->block_contents_size
);
3700 if(!block
->block_contents
)
3702 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
3703 block
->block_contents_size
, __FILE__
, __LINE__
);
3704 return(TNG_CRITICAL
);
3707 memcpy(block
->block_contents
, &mapping
->num_first_particle
,
3708 sizeof(mapping
->num_first_particle
));
3709 if(tng_data
->output_endianness_swap_func_64
)
3711 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3712 (int64_t *)block
->header_contents
+offset
)
3715 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3716 __FILE__
, __LINE__
);
3719 offset
+= sizeof(mapping
->num_first_particle
);
3721 memcpy(block
->block_contents
+offset
, &mapping
->n_particles
,
3722 sizeof(mapping
->n_particles
));
3723 if(tng_data
->output_endianness_swap_func_64
)
3725 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3726 (int64_t *)block
->header_contents
+offset
)
3729 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3730 __FILE__
, __LINE__
);
3733 offset
+= sizeof(mapping
->n_particles
);
3735 if(tng_data
->output_endianness_swap_func_64
)
3737 for(i
= 0; i
< mapping
->n_particles
; i
++)
3739 memcpy(block
->block_contents
+offset
, &mapping
->real_particle_numbers
[i
],
3741 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3742 (int64_t *)block
->header_contents
+offset
)
3745 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3746 __FILE__
, __LINE__
);
3748 offset
+= sizeof(int64_t);
3753 memcpy(block
->block_contents
+offset
, mapping
->real_particle_numbers
,
3754 mapping
->n_particles
* sizeof(int64_t));
3758 if(tng_block_header_write(tng_data
, block
, hash_mode
) != TNG_SUCCESS
)
3760 fprintf(stderr
, "TNG library: Cannot write header of file %s. %s: %d\n",
3761 tng_data
->output_file_path
, __FILE__
, __LINE__
);
3762 return(TNG_CRITICAL
);
3765 if(fwrite(block
->block_contents
, block
->block_contents_size
, 1,
3766 tng_data
->output_file
) != 1)
3768 fprintf(stderr
, "TNG library: Could not write all block data. %s: %d\n", __FILE__
, __LINE__
);
3769 return(TNG_CRITICAL
);
3772 return(TNG_SUCCESS
);
3775 /** Prepare a block for storing particle data
3776 * @param tng_data is a trajectory data container.
3777 * @param block_type_flag specifies if this is a trajectory block or a
3778 * non-trajectory block. (TNG_TRAJECTORY_BLOCK or TNG_NON_TRAJECTORY_BLOCK)
3779 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
3780 * error has occured.
3782 static tng_function_status tng_particle_data_block_create
3783 (tng_trajectory_t tng_data
,
3784 const char block_type_flag
)
3786 tng_trajectory_frame_set_t frame_set
=
3787 &tng_data
->current_trajectory_frame_set
;
3789 tng_particle_data_t data
;
3791 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
3793 frame_set
->n_particle_data_blocks
++;
3794 data
= realloc(frame_set
->tr_particle_data
,
3795 sizeof(struct tng_particle_data
) *
3796 frame_set
->n_particle_data_blocks
);
3799 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
3800 sizeof(struct tng_particle_data
) *
3801 frame_set
->n_particle_data_blocks
,
3802 __FILE__
, __LINE__
);
3803 free(frame_set
->tr_particle_data
);
3804 frame_set
->tr_particle_data
= 0;
3805 return(TNG_CRITICAL
);
3807 frame_set
->tr_particle_data
= data
;
3811 tng_data
->n_particle_data_blocks
++;
3812 data
= realloc(tng_data
->non_tr_particle_data
,
3813 sizeof(struct tng_particle_data
) *
3814 tng_data
->n_particle_data_blocks
);
3817 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
3818 sizeof(struct tng_particle_data
) *
3819 tng_data
->n_particle_data_blocks
,
3820 __FILE__
, __LINE__
);
3821 free(tng_data
->non_tr_particle_data
);
3822 tng_data
->non_tr_particle_data
= 0;
3823 return(TNG_CRITICAL
);
3825 tng_data
->non_tr_particle_data
= data
;
3828 return(TNG_SUCCESS
);
3831 static tng_function_status
tng_compress(tng_trajectory_t tng_data
,
3832 tng_gen_block_t block
,
3833 const int64_t n_frames
,
3834 const int64_t n_particles
,
3842 int64_t algo_find_n_frames
;
3843 unsigned long offset
;
3847 if(block
->id
!= TNG_TRAJ_POSITIONS
&&
3848 block
->id
!= TNG_TRAJ_VELOCITIES
)
3850 fprintf(stderr
, "TNG library: Can only compress positions and velocities with the "
3851 "TNG method. %s: %d\n", __FILE__
, __LINE__
);
3852 return(TNG_FAILURE
);
3854 if(type
!= TNG_FLOAT_DATA
&& type
!= TNG_DOUBLE_DATA
)
3856 fprintf(stderr
, "TNG library: Data type not supported. %s: %d\n", __FILE__
, __LINE__
);
3857 return(TNG_FAILURE
);
3860 if(n_frames
<= 0 || n_particles
<= 0)
3862 fprintf(stderr
, "TNG library: Missing frames or particles. Cannot compress data "
3863 "with the TNG method. %s: %d\n", __FILE__
, __LINE__
);
3864 return(TNG_FAILURE
);
3867 f_precision
= 1/(float)tng_data
->compression_precision
;
3868 d_precision
= 1/tng_data
->compression_precision
;
3870 if(block
->id
== TNG_TRAJ_POSITIONS
)
3872 /* If there is only one frame in this frame set and there might be more
3873 * do not store the algorithm as the compression algorithm, but find
3874 * the best one without storing it */
3875 if(n_frames
== 1 && tng_data
->frame_set_n_frames
> 1)
3877 nalgo
= tng_compress_nalgo();
3878 alt_algo
=malloc(nalgo
* sizeof *tng_data
->compress_algo_pos
);
3879 if(type
== TNG_FLOAT_DATA
)
3881 dest
= tng_compress_pos_float_find_algo(start_pos
, (int)n_particles
,
3890 dest
= tng_compress_pos_find_algo(start_pos
, (int)n_particles
,
3897 else if(!tng_data
->compress_algo_pos
)
3901 algo_find_n_frames
= 5;
3905 algo_find_n_frames
= n_frames
;
3908 nalgo
= tng_compress_nalgo();
3909 tng_data
->compress_algo_pos
=malloc(nalgo
*
3910 sizeof *tng_data
->compress_algo_pos
);
3911 if(type
== TNG_FLOAT_DATA
)
3913 dest
= tng_compress_pos_float_find_algo(start_pos
, (int)n_particles
,
3914 (int)algo_find_n_frames
,
3920 if(algo_find_n_frames
< n_frames
)
3922 dest
= tng_compress_pos_float(start_pos
, (int)n_particles
,
3925 0, tng_data
->compress_algo_pos
,
3931 dest
= tng_compress_pos_find_algo(start_pos
, (int)n_particles
,
3932 (int)algo_find_n_frames
,
3938 if(algo_find_n_frames
< n_frames
)
3940 dest
= tng_compress_pos(start_pos
, (int)n_particles
,
3943 tng_data
->compress_algo_pos
,
3950 if(type
== TNG_FLOAT_DATA
)
3952 dest
= tng_compress_pos_float(start_pos
, (int)n_particles
,
3955 tng_data
->compress_algo_pos
, &new_len
);
3959 dest
= tng_compress_pos(start_pos
, (int)n_particles
,
3962 tng_data
->compress_algo_pos
,
3967 else if(block
->id
== TNG_TRAJ_VELOCITIES
)
3969 /* If there is only one frame in this frame set and there might be more
3970 * do not store the algorithm as the compression algorithm, but find
3971 * the best one without storing it */
3972 if(n_frames
== 1 && tng_data
->frame_set_n_frames
> 1)
3974 nalgo
= tng_compress_nalgo();
3975 alt_algo
=malloc(nalgo
* sizeof *tng_data
->compress_algo_pos
);
3976 if(type
== TNG_FLOAT_DATA
)
3978 dest
= tng_compress_vel_float_find_algo(start_pos
, (int)n_particles
,
3987 dest
= tng_compress_vel_find_algo(start_pos
, (int)n_particles
,
3994 else if(!tng_data
->compress_algo_vel
)
3998 algo_find_n_frames
= 5;
4002 algo_find_n_frames
= n_frames
;
4005 nalgo
= tng_compress_nalgo();
4006 tng_data
->compress_algo_vel
=malloc(nalgo
*
4007 sizeof *tng_data
->compress_algo_vel
);
4009 if(type
== TNG_FLOAT_DATA
)
4011 dest
= tng_compress_vel_float_find_algo(start_pos
, (int)n_particles
,
4012 (int)algo_find_n_frames
,
4017 if(algo_find_n_frames
< n_frames
)
4019 dest
= tng_compress_vel_float(start_pos
, (int)n_particles
,
4022 0, tng_data
->compress_algo_vel
,
4028 dest
= tng_compress_vel_find_algo(start_pos
, (int)n_particles
,
4029 (int)algo_find_n_frames
,
4034 if(algo_find_n_frames
< n_frames
)
4036 dest
= tng_compress_vel(start_pos
, (int)n_particles
,
4039 0, tng_data
->compress_algo_vel
,
4046 if(type
== TNG_FLOAT_DATA
)
4048 dest
= tng_compress_vel_float(start_pos
, (int)n_particles
,
4057 dest
= tng_compress_vel(start_pos
, (int)n_particles
,
4068 fprintf(stderr
, "TNG library: Can only compress positions and velocities using TNG-MF1 algorithms.\n");
4069 return(TNG_FAILURE
);
4072 offset
= (unsigned long)((char *)start_pos
- block
->block_contents
);
4079 block
->block_contents_size
= new_len
+ offset
;
4081 temp
= realloc(block
->block_contents
, block
->block_contents_size
);
4084 free(block
->block_contents
);
4085 block
->block_contents
= 0;
4086 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
4087 block
->block_contents_size
, __FILE__
, __LINE__
);
4088 return(TNG_CRITICAL
);
4090 block
->block_contents
= temp
;
4093 memcpy(temp
+ offset
, dest
, new_len
);
4098 fprintf(stderr
, "TNG library: Error during TNG compression. %s: %d\n", __FILE__
, __LINE__
);
4099 return(TNG_FAILURE
);
4102 return(TNG_SUCCESS
);
4105 static tng_function_status
tng_uncompress(tng_trajectory_t tng_data
,
4106 tng_gen_block_t block
,
4109 const unsigned long uncompressed_len
)
4114 unsigned long offset
;
4118 TNG_ASSERT(uncompressed_len
, "TNG library: The full length of the uncompressed data must be > 0.");
4120 if(block
->id
!= TNG_TRAJ_POSITIONS
&&
4121 block
->id
!= TNG_TRAJ_VELOCITIES
)
4123 fprintf(stderr
, "TNG library: Can only uncompress positions and velocities with the"
4125 return(TNG_FAILURE
);
4127 if(type
!= TNG_FLOAT_DATA
&& type
!= TNG_DOUBLE_DATA
)
4129 fprintf(stderr
, "TNG library: Data type not supported.\n");
4130 return(TNG_FAILURE
);
4133 if(type
== TNG_FLOAT_DATA
)
4135 f_dest
= malloc(uncompressed_len
);
4138 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
4139 uncompressed_len
, __FILE__
, __LINE__
);
4140 return(TNG_CRITICAL
);
4142 result
= tng_compress_uncompress_float(start_pos
, f_dest
);
4146 d_dest
= malloc(uncompressed_len
);
4149 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
4150 uncompressed_len
, __FILE__
, __LINE__
);
4151 return(TNG_CRITICAL
);
4153 result
= tng_compress_uncompress(start_pos
, d_dest
);
4158 fprintf(stderr
, "TNG library: Cannot uncompress TNG compressed block.\n");
4159 return(TNG_FAILURE
);
4162 offset
= (unsigned long)((char *)start_pos
- (char *)block
->block_contents
);
4164 block
->block_contents_size
= (int64_t)(uncompressed_len
+ offset
);
4166 temp
= realloc(block
->block_contents
, uncompressed_len
+ offset
);
4169 free(block
->block_contents
);
4170 block
->block_contents
= 0;
4179 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
4180 block
->block_contents_size
, __FILE__
, __LINE__
);
4181 return(TNG_CRITICAL
);
4184 if(type
== TNG_FLOAT_DATA
)
4186 memcpy(temp
+ offset
, f_dest
, uncompressed_len
);
4190 memcpy(temp
+ offset
, d_dest
, uncompressed_len
);
4193 block
->block_contents
= temp
;
4203 return(TNG_SUCCESS
);
4207 static tng_function_status
tng_gzip_compress(tng_trajectory_t tng_data
,
4208 tng_gen_block_t block
,
4209 void *start_pos
, const int len
)
4213 unsigned long max_len
, stat
, offset
;
4216 max_len
= compressBound(len
);
4217 dest
= malloc(max_len
);
4220 fprintf(stderr
, "TNG library: Cannot allocate memory (%ld bytes). %s: %d\n",
4221 max_len
, __FILE__
, __LINE__
);
4222 return(TNG_CRITICAL
);
4225 stat
= compress(dest
, &max_len
, start_pos
, len
);
4226 if(stat
!= (unsigned long)Z_OK
)
4229 if(stat
== (unsigned long)Z_MEM_ERROR
)
4231 fprintf(stderr
, "TNG library: Not enough memory. ");
4233 else if(stat
== (unsigned long)Z_BUF_ERROR
)
4235 fprintf(stderr
, "TNG library: Destination buffer too small. ");
4237 fprintf(stderr
, "TNG library: Error gzipping data. %s: %d\n", __FILE__
, __LINE__
);
4238 return(TNG_FAILURE
);
4241 offset
= (char *)start_pos
- block
->block_contents
;
4243 block
->block_contents_size
= max_len
+ offset
;
4245 temp
= realloc(block
->block_contents
, block
->block_contents_size
);
4248 free(block
->block_contents
);
4250 block
->block_contents
= 0;
4251 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
4252 block
->block_contents_size
, __FILE__
, __LINE__
);
4253 return(TNG_CRITICAL
);
4256 block
->block_contents
= temp
;
4258 memcpy(temp
+ offset
, dest
, max_len
);
4262 return(TNG_SUCCESS
);
4265 static tng_function_status
tng_gzip_uncompress(tng_trajectory_t tng_data
,
4266 tng_gen_block_t block
,
4268 unsigned long uncompressed_len
)
4276 offset
= (char *)start_pos
- (char *)block
->block_contents
;
4278 dest
= malloc(uncompressed_len
);
4281 fprintf(stderr
, "TNG library: Cannot allocate memory (%lud bytes). %s: %d\n",
4282 uncompressed_len
, __FILE__
, __LINE__
);
4283 return(TNG_CRITICAL
);
4286 stat
= uncompress(dest
, &uncompressed_len
, (Bytef
*) start_pos
,
4287 block
->block_contents_size
- offset
);
4292 if(stat
== (unsigned long)Z_MEM_ERROR
)
4294 fprintf(stderr
, "TNG library: Not enough memory. ");
4296 else if(stat
== (unsigned long)Z_BUF_ERROR
)
4298 fprintf(stderr
, "TNG library: Destination buffer too small. ");
4300 else if(stat
== (unsigned long)Z_DATA_ERROR
)
4302 fprintf(stderr
, "TNG library: Data corrupt. ");
4304 fprintf(stderr
, "TNG library: Error uncompressing gzipped data. %s: %d\n", __FILE__
,
4306 return(TNG_FAILURE
);
4310 block
->block_contents_size
= uncompressed_len
+ offset
;
4312 temp
= realloc(block
->block_contents
, uncompressed_len
+ offset
);
4315 free(block
->block_contents
);
4316 block
->block_contents
= 0;
4318 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
4319 block
->block_contents_size
, __FILE__
, __LINE__
);
4320 return(TNG_CRITICAL
);
4323 memcpy(temp
+ offset
, dest
, uncompressed_len
);
4325 block
->block_contents
= temp
;
4328 return(TNG_SUCCESS
);
4332 /** Allocate memory for storing particle data.
4333 * The allocated block will be refered to by data->values.
4334 * @param tng_data is a trajectory data container.
4335 * @param data is the data struct, which will contain the allocated memory in
4337 * @param n_frames is the number of frames of data to store.
4338 * @param n_particles is the number of particles with data.
4339 * @param n_values_per_frame is the number of data values per particle and
4341 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
4342 * error has occured.
4344 static tng_function_status tng_allocate_particle_data_mem
4345 (tng_trajectory_t tng_data
,
4346 tng_particle_data_t data
,
4348 int64_t stride_length
,
4349 const int64_t n_particles
,
4350 const int64_t n_values_per_frame
)
4353 int64_t i
, j
, k
, size
, frame_alloc
;
4356 if(n_particles
== 0 || n_values_per_frame
== 0)
4358 return(TNG_FAILURE
);
4361 if(data
->strings
&& data
->datatype
== TNG_CHAR_DATA
)
4363 for(i
= data
->n_frames
; i
--;)
4365 for(j
= n_particles
; j
--;)
4367 for(k
= data
->n_values_per_frame
; k
--;)
4369 if(data
->strings
[i
][j
][k
])
4371 free(data
->strings
[i
][j
][k
]);
4374 free(data
->strings
[i
][j
]);
4376 free(data
->strings
[i
]);
4378 free(data
->strings
);
4380 data
->n_frames
= n_frames
;
4381 n_frames
= tng_max_i64(1, n_frames
);
4382 data
->stride_length
= tng_max_i64(1, stride_length
);
4383 data
->n_values_per_frame
= n_values_per_frame
;
4384 frame_alloc
= (n_frames
% stride_length
) ? n_frames
/ stride_length
+ 1 : n_frames
/ stride_length
;
4386 if(data
->datatype
== TNG_CHAR_DATA
)
4388 data
->strings
= malloc(sizeof(char ***) * frame_alloc
);
4389 for(i
= frame_alloc
; i
-- ;)
4391 data
->strings
[i
] = malloc(sizeof(char **) *
4393 if(!data
->strings
[i
])
4395 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
4396 sizeof(union data_values
*) * n_particles
,
4397 __FILE__
, __LINE__
);
4398 return(TNG_CRITICAL
);
4400 for(j
= n_particles
; j
--;)
4402 data
->strings
[i
][j
] = malloc(sizeof(char *) *
4403 n_values_per_frame
);
4404 if(!data
->strings
[i
][j
])
4406 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
4407 sizeof(union data_values
) * n_values_per_frame
,
4408 __FILE__
, __LINE__
);
4409 return(TNG_CRITICAL
);
4411 for(k
= n_values_per_frame
; k
--;)
4413 data
->strings
[i
][j
][k
] = 0;
4420 switch(data
->datatype
)
4423 size
= sizeof(int64_t);
4425 case TNG_FLOAT_DATA
:
4426 size
= sizeof(float);
4428 case TNG_DOUBLE_DATA
:
4430 size
= sizeof(double);
4433 values
= realloc(data
->values
,
4434 size
* frame_alloc
*
4435 n_particles
* n_values_per_frame
);
4438 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
4439 size
* frame_alloc
*
4440 n_particles
* n_values_per_frame
,
4441 __FILE__
, __LINE__
);
4444 return(TNG_CRITICAL
);
4446 data
->values
= values
;
4448 return(TNG_SUCCESS
);
4451 static tng_function_status tng_particle_data_find
4452 (tng_trajectory_t tng_data
,
4454 tng_particle_data_t
*data
)
4456 int64_t block_index
, i
;
4457 tng_trajectory_frame_set_t frame_set
= &tng_data
->
4458 current_trajectory_frame_set
;
4459 char block_type_flag
;
4461 if(tng_data
->current_trajectory_frame_set_input_file_pos
> 0 ||
4462 tng_data
->current_trajectory_frame_set_output_file_pos
> 0)
4464 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
4468 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
4472 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
4474 for(i
= frame_set
->n_particle_data_blocks
; i
-- ;)
4476 *data
= &frame_set
->tr_particle_data
[i
];
4477 if((*data
)->block_id
== id
)
4486 for(i
= tng_data
->n_particle_data_blocks
; i
-- ;)
4488 *data
= &tng_data
->non_tr_particle_data
[i
];
4489 if((*data
)->block_id
== id
)
4496 if(block_index
== -1)
4498 return(TNG_FAILURE
);
4500 return(TNG_SUCCESS
);
4503 static tng_function_status tng_data_find
4504 (tng_trajectory_t tng_data
,
4506 tng_non_particle_data_t
*data
)
4508 int64_t block_index
, i
;
4509 tng_trajectory_frame_set_t frame_set
= &tng_data
->
4510 current_trajectory_frame_set
;
4511 char block_type_flag
;
4513 if(tng_data
->current_trajectory_frame_set_input_file_pos
> 0 ||
4514 tng_data
->current_trajectory_frame_set_output_file_pos
> 0)
4516 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
4520 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
4524 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
4526 for(i
= frame_set
->n_data_blocks
; i
-- ;)
4528 *data
= &frame_set
->tr_data
[i
];
4529 if((*data
)->block_id
== id
)
4535 if(block_index
== -1)
4537 for(i
= tng_data
->n_data_blocks
; i
-- ;)
4539 *data
= &tng_data
->non_tr_data
[i
];
4540 if((*data
)->block_id
== id
)
4550 for(i
= tng_data
->n_data_blocks
; i
-- ;)
4552 *data
= &tng_data
->non_tr_data
[i
];
4553 if((*data
)->block_id
== id
)
4560 if(block_index
== -1)
4562 return(TNG_FAILURE
);
4564 return(TNG_SUCCESS
);
4567 /** Read the values of a particle data block
4568 * @param tng_data is a trajectory data container.
4569 * @param block is the block to store the data (should already contain
4570 * the block headers and the block contents).
4571 * @param offset is the reading offset to point at the place where the actual
4572 * values are stored, starting from the beginning of the block_contents. The
4573 * offset is changed during the reading.
4574 * @param datatype is the type of data of the data block (char, int, float or
4576 * @param num_first_particle is the number of the first particle in the data
4577 * block. This should be the same as in the corresponding particle mapping
4579 * @param n_particles is the number of particles in the data block. This should
4580 * be the same as in the corresponding particle mapping block.
4581 * @param first_frame_with_data is the frame number of the first frame with data
4582 * in this data block.
4583 * @param stride_length is the number of frames between each data entry.
4584 * @param n_frames is the number of frames in this data block.
4585 * @param n_values is the number of values per particle and frame stored in this
4587 * @param codec_id is the ID of the codec to compress the data.
4588 * @param multiplier is the multiplication factor applied to each data value
4589 * before compression. This factor is applied since some compression algorithms
4590 * work only on integers.
4591 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
4592 * error has occured.
4594 static tng_function_status tng_particle_data_read
4595 (tng_trajectory_t tng_data
,
4596 tng_gen_block_t block
,
4598 const char datatype
,
4599 const int64_t num_first_particle
,
4600 const int64_t n_particles
,
4601 const int64_t first_frame_with_data
,
4602 const int64_t stride_length
,
4604 const int64_t n_values
,
4605 const int64_t codec_id
,
4606 const double multiplier
)
4608 int64_t i
, j
, k
, tot_n_particles
, n_frames_div
;
4610 unsigned long data_size
;
4611 char ***first_dim_values
, **second_dim_values
;
4612 tng_particle_data_t data
;
4613 tng_trajectory_frame_set_t frame_set
=
4614 &tng_data
->current_trajectory_frame_set
;
4615 char block_type_flag
;
4617 TNG_ASSERT(offset
!= 0, "TNG library: offset must not be a NULL pointer.");
4625 size
= sizeof(int64_t);
4627 case TNG_FLOAT_DATA
:
4628 size
= sizeof(float);
4630 case TNG_DOUBLE_DATA
:
4632 size
= sizeof(double);
4635 /* If the block does not exist, create it */
4636 if(tng_particle_data_find(tng_data
, block
->id
, &data
) != TNG_SUCCESS
)
4638 if(tng_data
->current_trajectory_frame_set_input_file_pos
> 0)
4640 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
4644 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
4647 if(tng_particle_data_block_create(tng_data
, block_type_flag
) !=
4650 fprintf(stderr
, "TNG library: Cannot create particle data block. %s: %d\n",
4651 __FILE__
, __LINE__
);
4652 return(TNG_CRITICAL
);
4654 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
4656 data
= &frame_set
->tr_particle_data
[frame_set
->
4657 n_particle_data_blocks
- 1];
4661 data
= &tng_data
->non_tr_particle_data
[tng_data
->
4662 n_particle_data_blocks
- 1];
4664 data
->block_id
= block
->id
;
4666 data
->block_name
= malloc(strlen(block
->name
) + 1);
4667 if(!data
->block_name
)
4669 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
4670 (int)strlen(block
->name
)+1, __FILE__
, __LINE__
);
4671 return(TNG_CRITICAL
);
4673 strcpy(data
->block_name
, block
->name
);
4675 data
->datatype
= datatype
;
4678 /* FIXME: Memory leak from strings. */
4681 data
->codec_id
= codec_id
;
4682 data
->compression_multiplier
= multiplier
;
4683 data
->last_retrieved_frame
= -1;
4686 if(/*block_type_flag == TNG_TRAJECTORY_BLOCK &&*/
4687 tng_data
->current_trajectory_frame_set_input_file_pos
> 0 &&
4688 tng_data
->var_num_atoms_flag
)
4690 tot_n_particles
= frame_set
->n_particles
;
4694 tot_n_particles
= tng_data
->n_particles
;
4697 n_frames_div
= (n_frames
% stride_length
) ? n_frames
/ stride_length
+ 1 : n_frames
/ stride_length
;
4699 if(codec_id
!= TNG_UNCOMPRESSED
)
4701 data_size
= (unsigned long)(n_frames_div
* size
* n_particles
* n_values
);
4704 case TNG_XTC_COMPRESSION
:
4705 fprintf(stderr
, "TNG library: XTC compression not implemented yet.\n");
4707 case TNG_TNG_COMPRESSION
:
4708 /* fprintf(stderr, "TNG library: Before TNG uncompression: %"PRId64"\n", block->block_contents_size);*/
4709 if(tng_uncompress(tng_data
, block
, datatype
,
4710 block
->block_contents
+ *offset
,
4711 data_size
) != TNG_SUCCESS
)
4713 fprintf(stderr
, "TNG library: Could not read tng compressed block data. %s: %d\n",
4714 __FILE__
, __LINE__
);
4715 return(TNG_CRITICAL
);
4717 /* fprintf(stderr, "TNG library: After TNG uncompression: %"PRId64"\n", block->block_contents_size);*/
4720 case TNG_GZIP_COMPRESSION
:
4721 /* fprintf(stderr, "TNG library: Before GZIP uncompression: %"PRId64"\n", block->block_contents_size);*/
4722 if(tng_gzip_uncompress(tng_data
, block
,
4723 block
->block_contents
+ *offset
,
4724 data_size
) != TNG_SUCCESS
)
4726 fprintf(stderr
, "TNG library: Could not read gzipped block data. %s: %d\n", __FILE__
,
4728 return(TNG_CRITICAL
);
4730 /* fprintf(stderr, "TNG library: After GZIP uncompression: %"PRId64"\n", block->block_contents_size);*/
4735 /* Allocate memory */
4736 if(!data
->values
|| data
->n_frames
!= n_frames
||
4737 data
->n_values_per_frame
!= n_values
)
4739 if(tng_allocate_particle_data_mem(tng_data
, data
, n_frames
,
4741 tot_n_particles
, n_values
) !=
4744 fprintf(stderr
, "TNG library: Cannot allocate memory for particle data. %s: %d\n",
4745 __FILE__
, __LINE__
);
4746 return(TNG_CRITICAL
);
4750 data
->first_frame_with_data
= first_frame_with_data
;
4752 if(datatype
== TNG_CHAR_DATA
)
4754 for(i
= 0; i
< n_frames_div
; i
++)
4756 first_dim_values
= data
->strings
[i
];
4757 for(j
= num_first_particle
; j
< num_first_particle
+ n_particles
;
4760 second_dim_values
= first_dim_values
[j
];
4761 for(k
= 0; k
< n_values
; k
++)
4763 len
= tng_min_i((int)strlen(block
->block_contents
+*offset
) + 1,
4765 if(second_dim_values
[k
])
4767 free(second_dim_values
[k
]);
4769 second_dim_values
[k
] = malloc(len
);
4770 if(!second_dim_values
[k
])
4772 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
4773 len
, __FILE__
, __LINE__
);
4774 return(TNG_CRITICAL
);
4776 strncpy(second_dim_values
[k
],
4777 block
->block_contents
+*offset
, len
);
4785 memcpy((char *)data
->values
+ n_frames_div
* size
* n_values
*
4787 block
->block_contents
+ *offset
,
4788 block
->block_contents_size
- *offset
);
4791 case TNG_FLOAT_DATA
:
4792 if(tng_data
->input_endianness_swap_func_32
)
4794 for(i
= 0; i
< (block
->block_contents_size
- *offset
); i
+=size
)
4796 if(tng_data
->input_endianness_swap_func_32(tng_data
,
4797 (int32_t *)((char *)data
->values
+ i
))
4800 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
4801 __FILE__
, __LINE__
);
4807 case TNG_DOUBLE_DATA
:
4808 if(tng_data
->input_endianness_swap_func_64
)
4810 for(i
= 0; i
< (block
->block_contents_size
- *offset
); i
+=size
)
4812 if(tng_data
->input_endianness_swap_func_64(tng_data
,
4813 (int64_t *)((char *)data
->values
+ i
))
4816 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
4817 __FILE__
, __LINE__
);
4826 return(TNG_SUCCESS
);
4829 /** Write a particle data block
4830 * @param tng_data is a trajectory data container.
4831 * @param block is the block to store the data (should already contain
4832 * the block headers and the block contents).
4833 * @param block_index is the index number of the data block in the frame set.
4834 * @param mapping is the particle mapping that is relevant for the data block.
4835 * @param hash_mode is an option to decide whether to use the md5 hash or not.
4836 * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
4837 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
4838 * error has occured.
4840 static tng_function_status tng_particle_data_block_write
4841 (tng_trajectory_t tng_data
,
4842 tng_gen_block_t block
,
4843 const int64_t block_index
,
4844 const tng_particle_mapping_t mapping
,
4845 const char hash_mode
)
4847 int64_t n_particles
, num_first_particle
, n_frames
, stride_length
;
4848 int64_t frame_step
, data_start_pos
;
4851 size_t len
, offset
= 0;
4852 char dependency
, temp
, *temp_name
;
4854 char ***first_dim_values
, **second_dim_values
;
4855 tng_trajectory_frame_set_t frame_set
;
4856 tng_function_status stat
;
4858 tng_particle_data_t data
;
4859 char block_type_flag
;
4861 frame_set
= &tng_data
->current_trajectory_frame_set
;
4863 /* If we have already started writing frame sets it is too late to write
4864 * non-trajectory data blocks */
4865 if(tng_data
->current_trajectory_frame_set_output_file_pos
> 0)
4867 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
4871 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
4874 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
4876 return(TNG_CRITICAL
);
4879 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
4881 data
= &frame_set
->tr_particle_data
[block_index
];
4883 /* If this data block has not had any data added in this frame set
4884 * do not write it. */
4885 if(data
->first_frame_with_data
< frame_set
->first_frame
)
4887 return(TNG_SUCCESS
);
4890 stride_length
= tng_max_i64(1, data
->stride_length
);
4894 data
= &tng_data
->non_tr_particle_data
[block_index
];
4898 switch(data
->datatype
)
4904 size
= sizeof(int64_t);
4906 case TNG_FLOAT_DATA
:
4907 size
= sizeof(float);
4909 case TNG_DOUBLE_DATA
:
4911 size
= sizeof(double);
4914 len
= strlen(data
->block_name
) + 1;
4916 if(!block
->name
|| strlen(block
->name
) < len
)
4918 temp_name
= realloc(block
->name
, len
);
4921 fprintf(stderr
, "TNG library: Cannot allocate memory (%lud bytes). %s: %d\n", len
,
4922 __FILE__
, __LINE__
);
4925 return(TNG_CRITICAL
);
4927 block
->name
= temp_name
;
4929 strncpy(block
->name
, data
->block_name
, len
);
4930 block
->id
= data
->block_id
;
4932 /* If writing frame independent data data->n_frames is 0, but n_frames
4933 is used for the loop writing the data (and reserving memory) and needs
4935 n_frames
= tng_max_i64(1, data
->n_frames
);
4937 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
4939 /* If the frame set is finished before writing the full number of frames
4940 make sure the data block is not longer than the frame set. */
4941 n_frames
= tng_min_i64(n_frames
, frame_set
->n_frames
);
4943 n_frames
-= (data
->first_frame_with_data
- frame_set
->first_frame
);
4946 frame_step
= (n_frames
% stride_length
) ? n_frames
/ stride_length
+ 1:
4947 n_frames
/ stride_length
;
4949 /* TNG compression will use compression precision to get integers from
4950 * floating point data. The compression multiplier stores that information
4951 * to be able to return the precision of the compressed data. */
4952 if(data
->codec_id
== TNG_TNG_COMPRESSION
)
4954 data
->compression_multiplier
= tng_data
->compression_precision
;
4956 /* Uncompressed data blocks do not use compression multipliers at all.
4957 * GZip compression does not need it either. */
4958 else if(data
->codec_id
== TNG_UNCOMPRESSED
|| data
->codec_id
== TNG_GZIP_COMPRESSION
)
4960 data
->compression_multiplier
= 1.0;
4963 if(mapping
&& mapping
->n_particles
!= 0)
4965 n_particles
= mapping
->n_particles
;
4966 num_first_particle
= mapping
->num_first_particle
;
4970 num_first_particle
= 0;
4971 if(tng_data
->var_num_atoms_flag
)
4973 n_particles
= frame_set
->n_particles
;
4977 n_particles
= tng_data
->n_particles
;
4981 block
->block_contents_size
= sizeof(char) * 2 +
4982 sizeof(data
->n_values_per_frame
) +
4983 sizeof(data
->codec_id
) +
4984 sizeof(num_first_particle
) +
4985 sizeof(n_particles
);
4987 if(stride_length
> 1)
4989 block
->block_contents_size
+= sizeof(data
->first_frame_with_data
) +
4990 sizeof(data
->stride_length
);
4993 if(data
->codec_id
!= TNG_UNCOMPRESSED
)
4995 block
->block_contents_size
+= sizeof(data
->compression_multiplier
);
4998 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
&& data
->n_frames
> 0)
5000 dependency
= TNG_FRAME_DEPENDENT
+ TNG_PARTICLE_DEPENDENT
;
5004 dependency
= TNG_PARTICLE_DEPENDENT
;
5006 if(dependency
& TNG_FRAME_DEPENDENT
)
5008 block
->block_contents_size
+= sizeof(char);
5011 data_start_pos
= block
->block_contents_size
;
5013 if(data
->datatype
== TNG_CHAR_DATA
)
5015 for(i
= n_frames
; i
--;)
5017 first_dim_values
= data
->strings
[i
];
5018 for(j
= num_first_particle
; j
< num_first_particle
+ n_particles
;
5021 second_dim_values
= first_dim_values
[j
];
5022 for(k
= data
->n_values_per_frame
; k
--;)
5024 block
->block_contents_size
+=
5025 strlen(second_dim_values
[k
]) + 1;
5032 block
->block_contents_size
+= size
* frame_step
*
5033 n_particles
* data
->n_values_per_frame
;
5036 if(block
->block_contents
)
5038 free(block
->block_contents
);
5040 block
->block_contents
= malloc(block
->block_contents_size
);
5041 if(!block
->block_contents
)
5043 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
5044 block
->block_contents_size
, __FILE__
, __LINE__
);
5045 return(TNG_CRITICAL
);
5049 memcpy(block
->block_contents
, &data
->datatype
, sizeof(char));
5050 offset
+= sizeof(char);
5052 memcpy(block
->block_contents
+offset
, &dependency
, sizeof(char));
5053 offset
+= sizeof(char);
5055 if(dependency
& TNG_FRAME_DEPENDENT
)
5057 if(stride_length
> 1)
5065 memcpy(block
->block_contents
+offset
, &temp
, sizeof(char));
5066 offset
+= sizeof(char);
5069 memcpy(block
->block_contents
+offset
, &data
->n_values_per_frame
,
5070 sizeof(data
->n_values_per_frame
));
5071 if(tng_data
->output_endianness_swap_func_64
)
5073 if(tng_data
->output_endianness_swap_func_64(tng_data
,
5074 (int64_t *)block
->header_contents
+offset
)
5077 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5078 __FILE__
, __LINE__
);
5081 offset
+= sizeof(data
->n_values_per_frame
);
5083 memcpy(block
->block_contents
+offset
, &data
->codec_id
,
5084 sizeof(data
->codec_id
));
5085 if(tng_data
->output_endianness_swap_func_64
)
5087 if(tng_data
->output_endianness_swap_func_64(tng_data
,
5088 (int64_t *)block
->header_contents
+offset
)
5091 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5092 __FILE__
, __LINE__
);
5095 offset
+= sizeof(data
->codec_id
);
5097 if(data
->codec_id
!= TNG_UNCOMPRESSED
)
5099 memcpy(block
->block_contents
+offset
, &data
->compression_multiplier
,
5100 sizeof(data
->compression_multiplier
));
5101 if(tng_data
->output_endianness_swap_func_64
)
5103 if(tng_data
->output_endianness_swap_func_64(tng_data
,
5104 (int64_t *)block
->header_contents
+offset
)
5107 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5108 __FILE__
, __LINE__
);
5111 offset
+= sizeof(data
->compression_multiplier
);
5114 if(data
->n_frames
> 0 && stride_length
> 1)
5116 /* FIXME: first_frame_with_data is not reliably set */
5117 if(data
->first_frame_with_data
== 0)
5119 data
->first_frame_with_data
= frame_set
->first_frame
;
5121 memcpy(block
->block_contents
+offset
, &data
->first_frame_with_data
,
5122 sizeof(data
->first_frame_with_data
));
5123 if(tng_data
->output_endianness_swap_func_64
)
5125 if(tng_data
->output_endianness_swap_func_64(tng_data
,
5126 (int64_t *)block
->header_contents
+offset
)
5129 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5130 __FILE__
, __LINE__
);
5133 offset
+= sizeof(data
->first_frame_with_data
);
5135 memcpy(block
->block_contents
+offset
, &stride_length
,
5136 sizeof(stride_length
));
5137 if(tng_data
->output_endianness_swap_func_64
)
5139 if(tng_data
->output_endianness_swap_func_64(tng_data
,
5140 (int64_t *)block
->header_contents
+offset
)
5143 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5144 __FILE__
, __LINE__
);
5147 offset
+= sizeof(stride_length
);
5151 memcpy(block
->block_contents
+offset
, &num_first_particle
,
5152 sizeof(num_first_particle
));
5153 if(tng_data
->output_endianness_swap_func_64
)
5155 if(tng_data
->output_endianness_swap_func_64(tng_data
,
5156 (int64_t *)block
->header_contents
+offset
)
5159 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5160 __FILE__
, __LINE__
);
5163 offset
+= sizeof(num_first_particle
);
5165 memcpy(block
->block_contents
+offset
, &n_particles
, sizeof(n_particles
));
5166 if(tng_data
->output_endianness_swap_func_64
)
5168 if(tng_data
->output_endianness_swap_func_64(tng_data
,
5169 (int64_t *)block
->header_contents
+offset
)
5172 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5173 __FILE__
, __LINE__
);
5176 offset
+= sizeof(n_particles
);
5178 if(data
->datatype
== TNG_CHAR_DATA
)
5182 for(i
= 0; i
< frame_step
; i
++)
5184 first_dim_values
= data
->strings
[i
];
5185 for(j
= num_first_particle
; j
< num_first_particle
+ n_particles
;
5188 second_dim_values
= first_dim_values
[j
];
5189 for(k
= 0; k
< data
->n_values_per_frame
; k
++)
5191 len
= (unsigned int)strlen(second_dim_values
[k
]) + 1;
5192 strncpy(block
->block_contents
+offset
,
5193 second_dim_values
[k
], len
);
5200 else if(data
->values
)
5202 memcpy(block
->block_contents
+ offset
, data
->values
,
5203 block
->block_contents_size
- offset
);
5205 switch(data
->datatype
)
5207 case TNG_FLOAT_DATA
:
5208 if(data
->codec_id
== TNG_UNCOMPRESSED
|| data
-> codec_id
== TNG_GZIP_COMPRESSION
||
5209 data
->codec_id
== TNG_TNG_COMPRESSION
)
5211 if(tng_data
->input_endianness_swap_func_32
)
5213 for(i
= offset
; i
< block
->block_contents_size
; i
+=size
)
5215 if(tng_data
->input_endianness_swap_func_32(tng_data
,
5216 (int32_t *)(block
->block_contents
+ i
))
5219 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5220 __FILE__
, __LINE__
);
5227 multiplier
= data
->compression_multiplier
;
5228 if(fabs(multiplier
- 1.0) > 0.00001 ||
5229 tng_data
->input_endianness_swap_func_32
)
5231 for(i
= offset
; i
< block
->block_contents_size
; i
+=size
)
5233 *(float *)(block
->block_contents
+ i
) *= (float)multiplier
;
5234 if(tng_data
->input_endianness_swap_func_32
&&
5235 tng_data
->input_endianness_swap_func_32(tng_data
,
5236 (int32_t *)(block
->block_contents
+ i
))
5239 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5240 __FILE__
, __LINE__
);
5247 if(tng_data
->input_endianness_swap_func_64
)
5249 for(i
= offset
; i
< block
->block_contents_size
; i
+=size
)
5251 if(tng_data
->input_endianness_swap_func_64(tng_data
,
5252 (int64_t *)(block
->block_contents
+ i
))
5255 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5256 __FILE__
, __LINE__
);
5261 case TNG_DOUBLE_DATA
:
5262 if(data
->codec_id
== TNG_UNCOMPRESSED
|| data
-> codec_id
== TNG_GZIP_COMPRESSION
||
5263 data
->codec_id
== TNG_TNG_COMPRESSION
)
5265 if(tng_data
->input_endianness_swap_func_64
)
5267 for(i
= offset
; i
< block
->block_contents_size
; i
+=size
)
5269 if(tng_data
->input_endianness_swap_func_64(tng_data
,
5270 (int64_t *)(block
->block_contents
+ i
))
5273 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5274 __FILE__
, __LINE__
);
5281 multiplier
= data
->compression_multiplier
;
5282 if(fabs(multiplier
- 1.0) > 0.00001 ||
5283 tng_data
->input_endianness_swap_func_64
)
5285 for(i
= offset
; i
< block
->block_contents_size
; i
+=size
)
5287 *(double *)(block
->block_contents
+ i
) *= multiplier
;
5288 if(tng_data
->input_endianness_swap_func_64
&&
5289 tng_data
->input_endianness_swap_func_64(tng_data
,
5290 (int64_t *)(block
->block_contents
+ i
))
5293 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5294 __FILE__
, __LINE__
);
5306 memset(block
->block_contents
+offset
, 0, block
->block_contents_size
- offset
);
5309 frame_set
->n_written_frames
+= frame_set
->n_unwritten_frames
;
5310 frame_set
->n_unwritten_frames
= 0;
5312 if(block_type_flag
== TNG_NON_TRAJECTORY_BLOCK
|| frame_set
->n_written_frames
> 0)
5314 switch(data
->codec_id
)
5316 case TNG_XTC_COMPRESSION
:
5317 fprintf(stderr
, "TNG library: XTC compression not implemented yet.\n");
5318 data
->codec_id
= TNG_UNCOMPRESSED
;
5320 case TNG_TNG_COMPRESSION
:
5321 stat
= tng_compress(tng_data
, block
, frame_step
,
5322 n_particles
, data
->datatype
,
5323 block
->block_contents
+ data_start_pos
);
5324 if(stat
!= TNG_SUCCESS
)
5326 fprintf(stderr
, "TNG library: Could not write tng compressed block data. %s: %d\n",
5327 __FILE__
, __LINE__
);
5328 if(stat
== TNG_CRITICAL
)
5330 return(TNG_CRITICAL
);
5332 /* Set the data again, but with no compression (to write only
5333 * the relevant data) */
5334 data
->codec_id
= TNG_UNCOMPRESSED
;
5335 stat
= tng_particle_data_block_write(tng_data
, block
,
5336 block_index
, mapping
,
5342 case TNG_GZIP_COMPRESSION
:
5343 /* fprintf(stderr, "TNG library: Before compression: %"PRId64"\n", block->block_contents_size);*/
5344 stat
= tng_gzip_compress(tng_data
, block
,
5345 block
->block_contents
+ data_start_pos
,
5346 block
->block_contents_size
- data_start_pos
);
5347 if(stat
!= TNG_SUCCESS
)
5349 fprintf(stderr
, "TNG library: Could not write gzipped block data. %s: %d\n", __FILE__
,
5351 if(stat
== TNG_CRITICAL
)
5353 return(TNG_CRITICAL
);
5355 /* Set the data again, but with no compression (to write only
5356 * the relevant data) */
5357 data
->codec_id
= TNG_UNCOMPRESSED
;
5358 stat
= tng_particle_data_block_write(tng_data
, block
,
5359 block_index
, mapping
,
5363 /* fprintf(stderr, "TNG library: After compression: %"PRId64"\n", block->block_contents_size);*/
5369 if(tng_block_header_write(tng_data
, block
, hash_mode
) != TNG_SUCCESS
)
5371 fprintf(stderr
, "TNG library: Cannot write header of file %s. %s: %d\n",
5372 tng_data
->output_file_path
, __FILE__
, __LINE__
);
5373 return(TNG_CRITICAL
);
5376 if(fwrite(block
->block_contents
, block
->block_contents_size
, 1,
5377 tng_data
->output_file
) != 1)
5379 fprintf(stderr
, "TNG library: Could not write all block data. %s: %d\n", __FILE__
,
5381 return(TNG_CRITICAL
);
5384 return(TNG_SUCCESS
);
5388 /** Create a non-particle data block
5389 * @param tng_data is a trajectory data container.
5390 * @param block_type_flag specifies if this is a trajectory block or a
5391 * non-trajectory block. (TNG_TRAJECTORY_BLOCK or TNG_NON_TRAJECTORY_BLOCK)
5392 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
5393 * error has occured.
5395 static tng_function_status tng_data_block_create
5396 (tng_trajectory_t tng_data
,
5397 const char block_type_flag
)
5399 tng_trajectory_frame_set_t frame_set
=
5400 &tng_data
->current_trajectory_frame_set
;
5402 tng_non_particle_data_t data
;
5404 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
5406 frame_set
->n_data_blocks
++;
5407 data
= realloc(frame_set
->tr_data
, sizeof(struct tng_non_particle_data
) *
5408 frame_set
->n_data_blocks
);
5411 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
5412 sizeof(struct tng_non_particle_data
) * frame_set
->n_data_blocks
,
5413 __FILE__
, __LINE__
);
5414 free(frame_set
->tr_data
);
5415 frame_set
->tr_data
= 0;
5416 return(TNG_CRITICAL
);
5418 frame_set
->tr_data
= data
;
5422 tng_data
->n_data_blocks
++;
5423 data
= realloc(tng_data
->non_tr_data
, sizeof(struct tng_non_particle_data
) *
5424 tng_data
->n_data_blocks
);
5427 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
5428 sizeof(struct tng_non_particle_data
) * tng_data
->n_data_blocks
,
5429 __FILE__
, __LINE__
);
5430 free(tng_data
->non_tr_data
);
5431 tng_data
->non_tr_data
= 0;
5432 return(TNG_CRITICAL
);
5434 tng_data
->non_tr_data
= data
;
5437 return(TNG_SUCCESS
);
5441 /** Allocate memory for storing non-particle data.
5442 * The allocated block will be refered to by data->values.
5443 * @param tng_data is a trajectory data container.
5444 * @param data is the data struct, which will contain the allocated memory in
5446 * @param n_frames is the number of frames of data to store.
5447 * @param n_values_per_frame is the number of data values per frame.
5448 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
5449 * error has occured.
5451 static tng_function_status tng_allocate_data_mem
5452 (tng_trajectory_t tng_data
,
5453 tng_non_particle_data_t data
,
5455 int64_t stride_length
,
5456 const int64_t n_values_per_frame
)
5459 int64_t i
, j
, size
, frame_alloc
;
5462 if(n_values_per_frame
== 0)
5464 return(TNG_FAILURE
);
5467 if(data
->strings
&& data
->datatype
== TNG_CHAR_DATA
)
5469 for(i
= data
->n_frames
; i
--;)
5471 for(j
= data
->n_values_per_frame
; j
--;)
5473 if(data
->strings
[i
][j
])
5475 free(data
->strings
[i
][j
]);
5476 data
->strings
[i
][j
] = 0;
5479 free(data
->strings
[i
]);
5480 data
->strings
[i
] = 0;
5482 free(data
->strings
);
5484 data
->n_frames
= n_frames
;
5485 data
->stride_length
= tng_max_i64(1, stride_length
);
5486 n_frames
= tng_max_i64(1, n_frames
);
5487 data
->n_values_per_frame
= n_values_per_frame
;
5488 frame_alloc
= (n_frames
% stride_length
) ? n_frames
/ stride_length
+ 1 : n_frames
/ stride_length
;
5490 if(data
->datatype
== TNG_CHAR_DATA
)
5492 data
->strings
= malloc(sizeof(char **) * frame_alloc
);
5493 for(i
= frame_alloc
; i
-- ;)
5495 data
->strings
[i
] = malloc(sizeof(char *) * n_values_per_frame
);
5496 if(!data
->strings
[i
])
5498 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
5500 __FILE__
, __LINE__
);
5501 return(TNG_CRITICAL
);
5503 for(j
= n_values_per_frame
; j
--;)
5505 data
->strings
[i
][j
] = 0;
5511 switch(data
->datatype
)
5514 size
= sizeof(int64_t);
5516 case TNG_FLOAT_DATA
:
5517 size
= sizeof(float);
5519 case TNG_DOUBLE_DATA
:
5521 size
= sizeof(double);
5524 values
= realloc(data
->values
,
5525 size
* frame_alloc
*
5526 n_values_per_frame
);
5529 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
5530 size
* frame_alloc
*
5532 __FILE__
, __LINE__
);
5535 return(TNG_CRITICAL
);
5537 data
->values
= values
;
5540 return(TNG_SUCCESS
);
5543 /** Read the values of a non-particle data block
5544 * @param tng_data is a trajectory data container.
5545 * @param block is the block to store the data (should already contain
5546 * the block headers and the block contents).
5547 * @param offset is the reading offset to point at the place where the actual
5548 * values are stored, starting from the beginning of the block_contents. The
5549 * offset is changed during the reading.
5550 * @param datatype is the type of data of the data block (char, int, float or
5552 * @param first_frame_with_data is the frame number of the first frame with data
5553 * in this data block.
5554 * @param stride_length is the number of frames between each data entry.
5555 * @param n_frames is the number of frames in this data block.
5556 * @param n_values is the number of values per frame stored in this data block.
5557 * @param codec_id is the ID of the codec to compress the data.
5558 * @param multiplier is the multiplication factor applied to each data value
5559 * before compression. This factor is applied since some compression algorithms
5560 * work only on integers.
5561 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
5562 * error has occured.
5564 static tng_function_status
tng_data_read(tng_trajectory_t tng_data
,
5565 tng_gen_block_t block
,
5567 const char datatype
,
5568 const int64_t first_frame_with_data
,
5569 const int64_t stride_length
,
5571 const int64_t n_values
,
5572 const int64_t codec_id
,
5573 const double multiplier
)
5575 int64_t i
, j
, n_frames_div
;
5578 unsigned long data_size
;
5580 tng_non_particle_data_t data
;
5581 tng_trajectory_frame_set_t frame_set
=
5582 &tng_data
->current_trajectory_frame_set
;
5583 char block_type_flag
;
5585 TNG_ASSERT(offset
!= 0, "TNG library: offset must not be a NULL pointer.");
5587 /* fprintf(stderr, "TNG library: %s\n", block->name);*/
5595 size
= sizeof(int64_t);
5597 case TNG_FLOAT_DATA
:
5598 size
= sizeof(float);
5600 case TNG_DOUBLE_DATA
:
5602 size
= sizeof(double);
5605 /* If the block does not exist, create it */
5606 if(tng_data_find(tng_data
, block
->id
, &data
) != TNG_SUCCESS
)
5608 if(tng_data
->current_trajectory_frame_set_input_file_pos
> 0)
5610 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
5614 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
5617 if(tng_data_block_create(tng_data
, block_type_flag
) !=
5620 fprintf(stderr
, "TNG library: Cannot create particle data block. %s: %d\n",
5621 __FILE__
, __LINE__
);
5622 return(TNG_CRITICAL
);
5624 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
5626 data
= &frame_set
->tr_data
[frame_set
->n_data_blocks
- 1];
5630 data
= &tng_data
->non_tr_data
[tng_data
->n_data_blocks
- 1];
5632 data
->block_id
= block
->id
;
5634 data
->block_name
= malloc(strlen(block
->name
) + 1);
5635 if(!data
->block_name
)
5637 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
5638 (int)strlen(block
->name
)+1, __FILE__
, __LINE__
);
5639 return(TNG_CRITICAL
);
5641 strcpy(data
->block_name
, block
->name
);
5643 data
->datatype
= datatype
;
5646 /* FIXME: Memory leak from strings. */
5649 data
->codec_id
= codec_id
;
5650 data
->compression_multiplier
= multiplier
;
5651 data
->last_retrieved_frame
= -1;
5654 n_frames_div
= (n_frames
% stride_length
) ? n_frames
/ stride_length
+ 1 : n_frames
/ stride_length
;
5656 if(codec_id
!= TNG_UNCOMPRESSED
)
5661 case TNG_GZIP_COMPRESSION
:
5662 data_size
= n_frames_div
* size
* n_values
;
5663 /* fprintf(stderr, "TNG library: Before compression: %"PRId64"\n", block->block_contents_size); */
5664 if(tng_gzip_uncompress(tng_data
, block
,
5665 block
->block_contents
+ *offset
,
5666 data_size
) != TNG_SUCCESS
)
5668 fprintf(stderr
, "TNG library: Could not read gzipped block data. %s: %d\n", __FILE__
,
5670 return(TNG_CRITICAL
);
5672 /* fprintf(stderr, "TNG library: After compression: %"PRId64"\n", block->block_contents_size); */
5678 /* Allocate memory */
5679 if(!data
->values
|| data
->n_frames
!= n_frames
||
5680 data
->n_values_per_frame
!= n_values
)
5682 if(tng_allocate_data_mem(tng_data
, data
, n_frames
, stride_length
,
5686 fprintf(stderr
, "TNG library: Cannot allocate memory for data. %s: %d\n",
5687 __FILE__
, __LINE__
);
5688 return(TNG_CRITICAL
);
5692 data
->first_frame_with_data
= first_frame_with_data
;
5694 if(datatype
== TNG_CHAR_DATA
)
5696 for(i
= 0; i
< n_frames_div
; i
++)
5698 for(j
= 0; j
< n_values
; j
++)
5700 len
= tng_min_i((int)strlen(block
->block_contents
+*offset
) + 1,
5702 if(data
->strings
[i
][j
])
5704 free(data
->strings
[i
][j
]);
5706 data
->strings
[i
][j
] = malloc(len
);
5707 if(!data
->strings
[i
][j
])
5709 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
5710 len
, __FILE__
, __LINE__
);
5711 return(TNG_CRITICAL
);
5713 strncpy(data
->strings
[i
][j
], block
->block_contents
+*offset
,
5721 memcpy(data
->values
, block
->block_contents
+ *offset
,
5722 block
->block_contents_size
- *offset
);
5725 case TNG_FLOAT_DATA
:
5726 if(tng_data
->input_endianness_swap_func_32
)
5728 for(i
= 0; i
< (block
->block_contents_size
- *offset
); i
+=size
)
5730 if(tng_data
->input_endianness_swap_func_32(tng_data
,
5731 (int32_t *)((char *)data
->values
+ i
))
5734 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5735 __FILE__
, __LINE__
);
5741 case TNG_DOUBLE_DATA
:
5742 if(tng_data
->input_endianness_swap_func_64
)
5744 for(i
= 0; i
< (block
->block_contents_size
- *offset
); i
+=size
)
5746 if(tng_data
->input_endianness_swap_func_64(tng_data
,
5747 (int64_t *)((char *)data
->values
+ i
))
5750 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5751 __FILE__
, __LINE__
);
5760 return(TNG_SUCCESS
);
5763 /** Write a non-particle data block
5764 * @param tng_data is a trajectory data container.
5765 * @param block is the block to store the data (should already contain
5766 * the block headers and the block contents).
5767 * @param block_index is the index number of the data block in the frame set.
5768 * @param hash_mode is an option to decide whether to use the md5 hash or not.
5769 * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
5770 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
5771 * error has occured.
5773 static tng_function_status
tng_data_block_write(tng_trajectory_t tng_data
,
5774 tng_gen_block_t block
,
5775 const int64_t block_index
,
5776 const char hash_mode
)
5778 int64_t n_frames
, stride_length
, frame_step
;
5780 int offset
= 0, size
;
5784 tng_function_status stat
;
5786 char temp
, dependency
, *temp_name
;
5788 tng_trajectory_frame_set_t frame_set
=
5789 &tng_data
->current_trajectory_frame_set
;
5791 tng_non_particle_data_t data
;
5792 char block_type_flag
;
5794 /* If we have already started writing frame sets it is too late to write
5795 * non-trajectory data blocks */
5796 if(tng_data
->current_trajectory_frame_set_output_file_pos
> 0)
5798 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
5802 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
5805 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
5807 return(TNG_CRITICAL
);
5810 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
5812 data
= &frame_set
->tr_data
[block_index
];
5814 /* If this data block has not had any data added in this frame set
5815 * do not write it. */
5816 if(data
->first_frame_with_data
< frame_set
->first_frame
)
5818 return(TNG_SUCCESS
);
5821 stride_length
= tng_max_i64(1, data
->stride_length
);
5825 data
= &tng_data
->non_tr_data
[block_index
];
5829 switch(data
->datatype
)
5835 size
= sizeof(int64_t);
5837 case TNG_FLOAT_DATA
:
5838 size
= sizeof(float);
5840 case TNG_DOUBLE_DATA
:
5842 size
= sizeof(double);
5845 len
= (unsigned int)strlen(data
->block_name
) + 1;
5847 if(!block
->name
|| strlen(block
->name
) < len
)
5849 temp_name
= realloc(block
->name
, len
);
5852 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
+1,
5853 __FILE__
, __LINE__
);
5856 return(TNG_CRITICAL
);
5858 block
->name
= temp_name
;
5860 strncpy(block
->name
, data
->block_name
, len
);
5861 block
->id
= data
->block_id
;
5863 /* If writing frame independent data data->n_frames is 0, but n_frames
5864 is used for the loop writing the data (and reserving memory) and needs
5866 n_frames
= tng_max_i64(1, data
->n_frames
);
5868 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
5870 /* If the frame set is finished before writing the full number of frames
5871 make sure the data block is not longer than the frame set. */
5872 n_frames
= tng_min_i64(n_frames
, frame_set
->n_frames
);
5874 n_frames
-= (data
->first_frame_with_data
- frame_set
->first_frame
);
5877 frame_step
= (n_frames
% stride_length
) ? n_frames
/ stride_length
+ 1:
5878 n_frames
/ stride_length
;
5880 /* TNG compression will use compression precision to get integers from
5881 * floating point data. The compression multiplier stores that information
5882 * to be able to return the precision of the compressed data. */
5883 if(data
->codec_id
== TNG_TNG_COMPRESSION
)
5885 data
->compression_multiplier
= tng_data
->compression_precision
;
5887 /* Uncompressed data blocks do not use compression multipliers at all.
5888 * GZip compression does not need it either. */
5889 else if(data
->codec_id
== TNG_UNCOMPRESSED
|| data
->codec_id
== TNG_GZIP_COMPRESSION
)
5891 data
->compression_multiplier
= 1.0;
5894 block
->block_contents_size
= sizeof(char) * 2 +
5895 sizeof(data
->n_values_per_frame
) +
5896 sizeof(data
->codec_id
);
5898 if(stride_length
> 1)
5900 block
->block_contents_size
+= sizeof(data
->first_frame_with_data
) +
5901 sizeof(data
->stride_length
);
5904 if(data
->codec_id
!= TNG_UNCOMPRESSED
)
5906 block
->block_contents_size
+= sizeof(data
->compression_multiplier
);
5909 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
&& data
->n_frames
> 0)
5911 dependency
= TNG_FRAME_DEPENDENT
;
5917 if(dependency
& TNG_FRAME_DEPENDENT
)
5919 block
->block_contents_size
+= sizeof(char);
5923 data_start_pos
= block
->block_contents_size
;
5926 if(data
->datatype
== TNG_CHAR_DATA
)
5928 for(i
= n_frames
; i
--;)
5930 for(j
= data
->n_values_per_frame
; j
--;)
5932 block
->block_contents_size
+= strlen(data
->strings
[i
][j
]) + 1;
5938 block
->block_contents_size
+= size
* frame_step
*
5939 data
->n_values_per_frame
;
5942 if(block
->block_contents
)
5944 free(block
->block_contents
);
5946 block
->block_contents
= malloc(block
->block_contents_size
);
5947 if(!block
->block_contents
)
5949 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
5950 block
->block_contents_size
, __FILE__
, __LINE__
);
5951 return(TNG_CRITICAL
);
5955 memcpy(block
->block_contents
, &data
->datatype
, sizeof(char));
5956 offset
+= sizeof(char);
5958 memcpy(block
->block_contents
+offset
, &dependency
, sizeof(char));
5959 offset
+= sizeof(char);
5961 if(dependency
& TNG_FRAME_DEPENDENT
)
5963 if(stride_length
> 1)
5971 memcpy(block
->block_contents
+offset
, &temp
, sizeof(char));
5972 offset
+= sizeof(char);
5975 memcpy(block
->block_contents
+offset
, &data
->n_values_per_frame
,
5976 sizeof(data
->n_values_per_frame
));
5977 if(tng_data
->output_endianness_swap_func_64
)
5979 if(tng_data
->output_endianness_swap_func_64(tng_data
,
5980 (int64_t *)block
->header_contents
+offset
)
5983 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5984 __FILE__
, __LINE__
);
5987 offset
+= sizeof(data
->n_values_per_frame
);
5989 memcpy(block
->block_contents
+offset
, &data
->codec_id
,
5990 sizeof(data
->codec_id
));
5991 if(tng_data
->output_endianness_swap_func_64
)
5993 if(tng_data
->output_endianness_swap_func_64(tng_data
,
5994 (int64_t *)block
->header_contents
+offset
)
5997 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5998 __FILE__
, __LINE__
);
6001 offset
+= sizeof(data
->codec_id
);
6003 if(data
->codec_id
!= TNG_UNCOMPRESSED
)
6005 memcpy(block
->block_contents
+offset
, &data
->compression_multiplier
,
6006 sizeof(data
->compression_multiplier
));
6007 if(tng_data
->output_endianness_swap_func_64
)
6009 if(tng_data
->output_endianness_swap_func_64(tng_data
,
6010 (int64_t *)block
->header_contents
+offset
)
6013 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6014 __FILE__
, __LINE__
);
6017 offset
+= sizeof(data
->compression_multiplier
);
6020 if(data
->n_frames
> 0 && stride_length
> 1)
6022 /* FIXME: first_frame_with_data is not reliably set */
6023 if(data
->first_frame_with_data
== 0)
6025 data
->first_frame_with_data
= frame_set
->first_frame
;
6027 memcpy(block
->block_contents
+offset
, &data
->first_frame_with_data
,
6028 sizeof(data
->first_frame_with_data
));
6029 if(tng_data
->output_endianness_swap_func_64
)
6031 if(tng_data
->output_endianness_swap_func_64(tng_data
,
6032 (int64_t *)block
->header_contents
+offset
)
6035 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6036 __FILE__
, __LINE__
);
6039 offset
+= sizeof(data
->first_frame_with_data
);
6041 memcpy(block
->block_contents
+offset
, &stride_length
,
6042 sizeof(data
->stride_length
));
6043 if(tng_data
->output_endianness_swap_func_64
)
6045 if(tng_data
->output_endianness_swap_func_64(tng_data
,
6046 (int64_t *)block
->header_contents
+offset
)
6049 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6050 __FILE__
, __LINE__
);
6053 offset
+= sizeof(data
->stride_length
);
6056 if(data
->datatype
== TNG_CHAR_DATA
)
6060 for(i
= 0; i
< frame_step
; i
++)
6062 for(j
= 0; j
< data
->n_values_per_frame
; j
++)
6064 len
= (unsigned int)strlen(data
->strings
[i
][j
]) + 1;
6065 strncpy(block
->block_contents
+offset
, data
->strings
[i
][j
],
6072 else if(data
->values
)
6074 memcpy(block
->block_contents
+ offset
, data
->values
,
6075 block
->block_contents_size
- offset
);
6076 switch(data
->datatype
)
6078 case TNG_FLOAT_DATA
:
6079 if(data
->codec_id
== TNG_UNCOMPRESSED
|| data
-> codec_id
== TNG_GZIP_COMPRESSION
||
6080 data
->codec_id
== TNG_TNG_COMPRESSION
)
6082 if(tng_data
->input_endianness_swap_func_32
)
6084 for(i
= offset
; i
< block
->block_contents_size
; i
+=size
)
6086 if(tng_data
->input_endianness_swap_func_32(tng_data
,
6087 (int32_t *)(block
->block_contents
+ i
))
6090 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6091 __FILE__
, __LINE__
);
6098 multiplier
= data
->compression_multiplier
;
6099 if(fabs(multiplier
- 1.0) > 0.00001 ||
6100 tng_data
->input_endianness_swap_func_32
)
6102 for(i
= offset
; block
->block_contents_size
; i
+=size
)
6104 *(float *)(block
->block_contents
+ i
) *= (float)multiplier
;
6105 if(tng_data
->input_endianness_swap_func_32
&&
6106 tng_data
->input_endianness_swap_func_32(tng_data
,
6107 (int32_t *)(block
->block_contents
+ i
))
6110 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6111 __FILE__
, __LINE__
);
6118 if(tng_data
->input_endianness_swap_func_64
)
6120 for(i
= offset
; i
< block
->block_contents_size
; i
+=size
)
6122 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6123 (int64_t *)(block
->block_contents
+ i
))
6126 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6127 __FILE__
, __LINE__
);
6132 case TNG_DOUBLE_DATA
:
6133 if(data
->codec_id
== TNG_UNCOMPRESSED
|| data
-> codec_id
== TNG_GZIP_COMPRESSION
||
6134 data
->codec_id
== TNG_TNG_COMPRESSION
)
6136 if(tng_data
->input_endianness_swap_func_64
)
6138 for(i
= offset
; i
< block
->block_contents_size
; i
+=size
)
6140 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6141 (int64_t *)(block
->block_contents
+ i
))
6144 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6145 __FILE__
, __LINE__
);
6152 multiplier
= data
->compression_multiplier
;
6153 if(fabs(multiplier
- 1.0) > 0.00001 ||
6154 tng_data
->input_endianness_swap_func_64
)
6156 for(i
= offset
; i
< block
->block_contents_size
; i
+=size
)
6158 *(double *)(block
->block_contents
+ i
) *= multiplier
;
6159 if(tng_data
->input_endianness_swap_func_64
&&
6160 tng_data
->input_endianness_swap_func_64(tng_data
,
6161 (int64_t *)(block
->block_contents
+ i
))
6164 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6165 __FILE__
, __LINE__
);
6177 memset(block
->block_contents
+offset
, 0, block
->block_contents_size
- offset
);
6180 frame_set
->n_written_frames
+= frame_set
->n_unwritten_frames
;
6181 frame_set
->n_unwritten_frames
= 0;
6183 if(block_type_flag
== TNG_NON_TRAJECTORY_BLOCK
|| frame_set
->n_written_frames
> 0)
6185 switch(data
->codec_id
)
6188 case TNG_GZIP_COMPRESSION
:
6189 /* fprintf(stderr, "TNG library: Before compression: %"PRId64"\n", block->block_contents_size); */
6190 stat
= tng_gzip_compress(tng_data
, block
,
6191 block
->block_contents
+ data_start_pos
,
6192 block
->block_contents_size
- data_start_pos
);
6193 if(stat
!= TNG_SUCCESS
)
6195 fprintf(stderr
, "TNG library: Could not write gzipped block data. %s: %d\n", __FILE__
,
6197 if(stat
== TNG_CRITICAL
)
6199 return(TNG_CRITICAL
);
6201 data
->codec_id
= TNG_UNCOMPRESSED
;
6203 /* fprintf(stderr, "TNG library: After compression: %"PRId64"\n", block->block_contents_size); */
6209 if(tng_block_header_write(tng_data
, block
, hash_mode
) != TNG_SUCCESS
)
6211 fprintf(stderr
, "TNG library: Cannot write header of file %s. %s: %d\n",
6212 tng_data
->output_file_path
, __FILE__
, __LINE__
);
6213 return(TNG_CRITICAL
);
6216 if(fwrite(block
->block_contents
, block
->block_contents_size
, 1,
6217 tng_data
->output_file
) != 1)
6219 fprintf(stderr
, "TNG library: Could not write all block data. %s: %d\n",
6220 __FILE__
, __LINE__
);
6221 return(TNG_CRITICAL
);
6224 return(TNG_SUCCESS
);
6227 /** Read the meta information of a data block (particle or non-particle data).
6228 * @param tng_data is a trajectory data container.
6229 * @param block is the block to store the data (should already contain
6230 * the block headers).
6231 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
6232 * error has occured.
6234 static tng_function_status tng_data_block_meta_information_read
6235 (tng_trajectory_t tng_data
,
6236 tng_gen_block_t block
,
6243 int64_t *first_frame_with_data
,
6244 int64_t *stride_length
,
6246 int64_t *num_first_particle
,
6247 int64_t *block_n_particles
,
6253 if(block
->block_contents
)
6255 contents
= block
->block_contents
;
6259 meta_size
= 3 * sizeof(char) + sizeof(double) + 6 * sizeof(int64_t);
6260 contents
= malloc(meta_size
);
6263 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
6264 meta_size
, __FILE__
, __LINE__
);
6267 if(fread(contents
, meta_size
, 1, tng_data
->input_file
) == 0)
6269 fprintf(stderr
, "TNG library: Cannot read data block meta information. %s: %d\n", __FILE__
, __LINE__
);
6271 return(TNG_CRITICAL
);
6275 memcpy(datatype
, contents
+*offset
,
6277 *offset
+= sizeof(*datatype
);
6279 memcpy(dependency
, contents
+*offset
,
6280 sizeof(*dependency
));
6281 *offset
+= sizeof(*dependency
);
6283 if(*dependency
& TNG_FRAME_DEPENDENT
)
6285 memcpy(sparse_data
, contents
+*offset
,
6286 sizeof(*sparse_data
));
6287 *offset
+= sizeof(*sparse_data
);
6290 memcpy(n_values
, contents
+*offset
,
6292 if(tng_data
->input_endianness_swap_func_64
)
6294 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6298 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6299 __FILE__
, __LINE__
);
6302 *offset
+= sizeof(*n_values
);
6304 memcpy(codec_id
, contents
+*offset
,
6306 if(tng_data
->input_endianness_swap_func_64
)
6308 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6312 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6313 __FILE__
, __LINE__
);
6316 *offset
+= sizeof(*codec_id
);
6318 if(*codec_id
!= TNG_UNCOMPRESSED
)
6320 memcpy(multiplier
, contents
+*offset
,
6321 sizeof(*multiplier
));
6322 if(tng_data
->input_endianness_swap_func_64
)
6324 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6325 (int64_t *) multiplier
)
6328 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6329 __FILE__
, __LINE__
);
6332 *offset
+= sizeof(*multiplier
);
6339 if(*dependency
& TNG_FRAME_DEPENDENT
)
6343 memcpy(first_frame_with_data
, contents
+*offset
,
6344 sizeof(*first_frame_with_data
));
6345 if(tng_data
->input_endianness_swap_func_64
)
6347 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6348 first_frame_with_data
)
6351 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6352 __FILE__
, __LINE__
);
6355 *offset
+= sizeof(*first_frame_with_data
);
6357 memcpy(stride_length
, contents
+*offset
,
6358 sizeof(*stride_length
));
6359 if(tng_data
->input_endianness_swap_func_64
)
6361 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6365 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6366 __FILE__
, __LINE__
);
6369 *offset
+= sizeof(*stride_length
);
6370 *n_frames
= tng_data
->current_trajectory_frame_set
.n_frames
-
6371 (*first_frame_with_data
-
6372 tng_data
->current_trajectory_frame_set
.first_frame
);
6376 *first_frame_with_data
= 0;
6378 *n_frames
= tng_data
->current_trajectory_frame_set
.n_frames
;
6383 *first_frame_with_data
= 0;
6388 if (*dependency
& TNG_PARTICLE_DEPENDENT
)
6390 memcpy(num_first_particle
, contents
+*offset
,
6391 sizeof(*num_first_particle
));
6392 if(tng_data
->input_endianness_swap_func_64
)
6394 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6398 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6399 __FILE__
, __LINE__
);
6402 *offset
+= sizeof(*num_first_particle
);
6404 memcpy(block_n_particles
, contents
+*offset
,
6405 sizeof(*block_n_particles
));
6406 if(tng_data
->input_endianness_swap_func_64
)
6408 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6412 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6413 __FILE__
, __LINE__
);
6416 *offset
+= sizeof(*block_n_particles
);
6419 if(!block
->block_contents
)
6423 return(TNG_SUCCESS
);
6426 /** Read the contents of a data block (particle or non-particle data).
6427 * @param tng_data is a trajectory data container.
6428 * @param block is the block to store the data (should already contain
6429 * the block headers).
6430 * @param hash_mode is an option to decide whether to use the md5 hash or not.
6431 * If hash_mode == TNG_USE_HASH the written md5 hash in the file will be
6432 * compared to the md5 hash of the read contents to ensure valid data.
6433 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
6434 * error has occured.
6436 static tng_function_status tng_data_block_contents_read
6437 (tng_trajectory_t tng_data
,
6438 tng_gen_block_t block
,
6439 const char hash_mode
)
6441 int64_t n_values
, codec_id
, n_frames
, first_frame_with_data
;
6442 int64_t stride_length
, block_n_particles
, num_first_particle
;
6444 char datatype
, dependency
, sparse_data
;
6448 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
6450 return(TNG_CRITICAL
);
6453 if(block
->block_contents
)
6455 free(block
->block_contents
);
6458 block
->block_contents
= malloc(block
->block_contents_size
);
6459 if(!block
->block_contents
)
6461 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
6462 block
->block_contents_size
, __FILE__
, __LINE__
);
6463 return(TNG_CRITICAL
);
6466 /* Read the whole block into block_contents to be able to write it to
6467 * disk even if it cannot be interpreted. */
6468 if(fread(block
->block_contents
, block
->block_contents_size
, 1,
6469 tng_data
->input_file
) == 0)
6471 fprintf(stderr
, "TNG library: Cannot read block. %s: %d\n", __FILE__
, __LINE__
);
6472 return(TNG_CRITICAL
);
6475 /* FIXME: Does not check if the size of the contents matches the expected
6476 * size or if the contents can be read. */
6478 if(hash_mode
== TNG_USE_HASH
)
6480 tng_md5_hash_match_verify(block
, &same_hash
);
6481 if(same_hash
!= TNG_TRUE
)
6483 fprintf(stderr
, "TNG library: '%s' data block contents corrupt. Hashes do not match. %s: %d\n",
6484 block
->name
, __FILE__
, __LINE__
);
6485 /* return(TNG_FAILURE); */
6489 if(tng_data_block_meta_information_read(tng_data
, block
,
6491 &dependency
, &sparse_data
,
6492 &n_values
, &codec_id
,
6493 &first_frame_with_data
,
6494 &stride_length
, &n_frames
,
6495 &num_first_particle
,
6497 &multiplier
) == TNG_CRITICAL
)
6499 fprintf(stderr
, "TNG library: Cannot read data block (%s) meta information. %s: %d\n",
6500 block
->name
, __FILE__
, __LINE__
);
6501 return(TNG_CRITICAL
);
6504 if (dependency
& TNG_PARTICLE_DEPENDENT
)
6506 return(tng_particle_data_read(tng_data
, block
,
6510 first_frame_with_data
,
6513 codec_id
, multiplier
));
6517 return(tng_data_read(tng_data
, block
,
6519 first_frame_with_data
,
6522 codec_id
, multiplier
));
6526 /** Update the md5 hash of a block already written to the file
6527 * @param tng_data is a trajectory data container.
6528 * @param block is the block, of which to update the md5 hash.
6529 * @param header_start_pos is the file position where the block header starts.
6530 * @param contents_start_pos is the file position where the block contents
6532 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
6533 * error has occured.
6535 static tng_function_status
tng_md5_hash_update(tng_trajectory_t tng_data
,
6536 tng_gen_block_t block
,
6537 const int64_t header_start_pos
,
6538 const int64_t contents_start_pos
)
6540 if(block
->block_contents
)
6542 free(block
->block_contents
);
6545 block
->block_contents
= malloc(block
->block_contents_size
);
6546 if(!block
->block_contents
)
6548 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
6549 block
->block_contents_size
, __FILE__
, __LINE__
);
6550 return(TNG_CRITICAL
);
6553 fseek(tng_data
->output_file
, (long)contents_start_pos
, SEEK_SET
);
6554 if(fread(block
->block_contents
, block
->block_contents_size
, 1,
6555 tng_data
->output_file
) == 0)
6557 fprintf(stderr
, "TNG library: Cannot read block. %s: %d\n", __FILE__
, __LINE__
);
6558 return(TNG_CRITICAL
);
6561 tng_block_md5_hash_generate(block
);
6563 fseek(tng_data
->output_file
, (long)header_start_pos
+ 3 * sizeof(int64_t),
6565 fwrite(block
->md5_hash
, TNG_MD5_HASH_LEN
, 1, tng_data
->output_file
);
6567 return(TNG_SUCCESS
);
6570 /** Update the frame set pointers in the file header (general info block),
6571 * already written to disk
6572 * @param tng_data is a trajectory data container.
6573 * @param hash_mode specifies whether to update the block md5 hash when
6574 * updating the pointers.
6575 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
6576 * error has occured.
6578 static tng_function_status tng_header_pointers_update
6579 (tng_trajectory_t tng_data
, const char hash_mode
)
6581 tng_gen_block_t block
;
6582 FILE *temp
= tng_data
->input_file
;
6583 int64_t output_file_pos
, pos
, contents_start_pos
;
6585 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
6587 fprintf(stderr
, "TNG library: Cannot initialise destination file. %s: %d\n",
6588 __FILE__
, __LINE__
);
6589 return(TNG_CRITICAL
);
6592 tng_data
->input_file
= tng_data
->output_file
;
6594 tng_block_init(&block
);
6596 output_file_pos
= ftell(tng_data
->output_file
);
6597 fseek(tng_data
->output_file
, 0, SEEK_SET
);
6599 if(tng_block_header_read(tng_data
, block
) != TNG_SUCCESS
)
6601 fprintf(stderr
, "TNG library: Cannot read general info header. %s: %d\n",
6602 __FILE__
, __LINE__
);
6603 tng_data
->input_file
= temp
;
6604 tng_block_destroy(&block
);
6605 return(TNG_CRITICAL
);
6608 contents_start_pos
= ftell(tng_data
->output_file
);
6610 fseek(tng_data
->output_file
, (long)block
->block_contents_size
- 5 *
6611 sizeof(int64_t), SEEK_CUR
);
6613 tng_data
->input_file
= temp
;
6615 pos
= tng_data
->first_trajectory_frame_set_output_file_pos
;
6617 if(tng_data
->input_endianness_swap_func_64
)
6619 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6623 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6624 __FILE__
, __LINE__
);
6628 if(fwrite(&pos
, sizeof(int64_t), 1, tng_data
->output_file
) != 1)
6630 tng_block_destroy(&block
);
6631 return(TNG_CRITICAL
);
6634 pos
= tng_data
->last_trajectory_frame_set_output_file_pos
;
6636 if(tng_data
->input_endianness_swap_func_64
)
6638 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6642 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6643 __FILE__
, __LINE__
);
6648 sizeof(int64_t), 1, tng_data
->output_file
) != 1)
6650 tng_block_destroy(&block
);
6651 return(TNG_CRITICAL
);
6654 if(hash_mode
== TNG_USE_HASH
)
6656 tng_md5_hash_update(tng_data
, block
, 0, contents_start_pos
);
6659 tng_block_destroy(&block
);
6661 fseek(tng_data
->output_file
, (long)output_file_pos
, SEEK_SET
);
6663 return(TNG_SUCCESS
);
6666 /** Update the frame set pointers in the current frame set block, already
6667 * written to disk. It also updates the pointers of the blocks pointing to
6668 * the current frame set block.
6669 * @param tng_data is a trajectory data container.
6670 * @param hash_mode specifies whether to update the block md5 hash when
6671 * updating the pointers.
6672 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
6673 * error has occured.
6675 static tng_function_status tng_frame_set_pointers_update
6676 (tng_trajectory_t tng_data
, const char hash_mode
)
6678 tng_gen_block_t block
;
6679 tng_trajectory_frame_set_t frame_set
;
6680 FILE *temp
= tng_data
->input_file
;
6681 int64_t pos
, output_file_pos
, header_start_pos
, contents_start_pos
;
6683 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
6685 fprintf(stderr
, "TNG library: Cannot initialise destination file. %s: %d\n",
6686 __FILE__
, __LINE__
);
6687 return(TNG_CRITICAL
);
6690 tng_block_init(&block
);
6691 output_file_pos
= ftell(tng_data
->output_file
);
6693 tng_data
->input_file
= tng_data
->output_file
;
6695 frame_set
= &tng_data
->current_trajectory_frame_set
;
6697 /* Update previous frame set */
6698 if(frame_set
->prev_frame_set_file_pos
!= -1 &&
6699 frame_set
->prev_frame_set_file_pos
!= 0)
6701 fseek(tng_data
->output_file
, (long)frame_set
->prev_frame_set_file_pos
,
6704 header_start_pos
= frame_set
->prev_frame_set_file_pos
;
6706 if(tng_block_header_read(tng_data
, block
) != TNG_SUCCESS
)
6708 fprintf(stderr
, "TNG library: Cannot read frame header. %s: %d\n",
6709 __FILE__
, __LINE__
);
6710 tng_data
->input_file
= temp
;
6711 tng_block_destroy(&block
);
6712 return(TNG_CRITICAL
);
6715 contents_start_pos
= ftell(tng_data
->output_file
);
6717 fseek(tng_data
->output_file
, (long)block
->block_contents_size
- (6 *
6718 sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR
);
6720 pos
= tng_data
->current_trajectory_frame_set_output_file_pos
;
6722 if(tng_data
->input_endianness_swap_func_64
)
6724 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6728 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6729 __FILE__
, __LINE__
);
6733 if(fwrite(&pos
, sizeof(int64_t), 1, tng_data
->output_file
) != 1)
6735 tng_data
->input_file
= temp
;
6736 tng_block_destroy(&block
);
6737 return(TNG_CRITICAL
);
6740 if(hash_mode
== TNG_USE_HASH
)
6742 tng_md5_hash_update(tng_data
, block
, header_start_pos
,
6743 contents_start_pos
);
6745 fseek(tng_data
->output_file
, (long)output_file_pos
, SEEK_SET
);
6748 /* Update the frame set one medium stride step before */
6749 if(frame_set
->medium_stride_prev_frame_set_file_pos
!= -1 &&
6750 frame_set
->medium_stride_prev_frame_set_file_pos
!= 0)
6752 fseek(tng_data
->output_file
,
6753 (long)frame_set
->medium_stride_prev_frame_set_file_pos
,
6756 if(tng_block_header_read(tng_data
, block
) != TNG_SUCCESS
)
6758 fprintf(stderr
, "TNG library: Cannot read frame set header. %s: %d\n",
6759 __FILE__
, __LINE__
);
6760 tng_data
->input_file
= temp
;
6761 tng_block_destroy(&block
);
6762 return(TNG_CRITICAL
);
6765 contents_start_pos
= ftell(tng_data
->output_file
);
6767 fseek(tng_data
->output_file
, (long)block
->block_contents_size
- (4 *
6768 sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR
);
6770 pos
= tng_data
->current_trajectory_frame_set_output_file_pos
;
6772 if(tng_data
->input_endianness_swap_func_64
)
6774 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6778 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6779 __FILE__
, __LINE__
);
6783 if(fwrite(&pos
, sizeof(int64_t), 1, tng_data
->output_file
) != 1)
6785 tng_data
->input_file
= temp
;
6786 tng_block_destroy(&block
);
6787 return(TNG_CRITICAL
);
6790 if(hash_mode
== TNG_USE_HASH
)
6792 tng_md5_hash_update(tng_data
, block
,
6793 frame_set
->medium_stride_prev_frame_set_file_pos
,
6794 contents_start_pos
);
6798 /* Update the frame set one long stride step before */
6799 if(frame_set
->long_stride_prev_frame_set_file_pos
!= -1 &&
6800 frame_set
->long_stride_prev_frame_set_file_pos
!= 0)
6802 fseek(tng_data
->output_file
,
6803 (long)frame_set
->long_stride_prev_frame_set_file_pos
,
6806 if(tng_block_header_read(tng_data
, block
) != TNG_SUCCESS
)
6808 fprintf(stderr
, "TNG library: Cannot read frame set header. %s: %d\n",
6809 __FILE__
, __LINE__
);
6810 tng_data
->input_file
= temp
;
6811 tng_block_destroy(&block
);
6812 return(TNG_CRITICAL
);
6815 contents_start_pos
= ftell(tng_data
->output_file
);
6817 fseek(tng_data
->output_file
, (long)block
->block_contents_size
- (2 *
6818 sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR
);
6820 pos
= tng_data
->current_trajectory_frame_set_output_file_pos
;
6822 if(tng_data
->input_endianness_swap_func_64
)
6824 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6828 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6829 __FILE__
, __LINE__
);
6833 if(fwrite(&pos
, sizeof(int64_t), 1, tng_data
->output_file
) != 1)
6835 tng_data
->input_file
= temp
;
6836 tng_block_destroy(&block
);
6837 return(TNG_CRITICAL
);
6840 if(hash_mode
== TNG_USE_HASH
)
6842 tng_md5_hash_update(tng_data
, block
,
6843 frame_set
->long_stride_prev_frame_set_file_pos
,
6844 contents_start_pos
);
6848 fseek(tng_data
->output_file
, (long)output_file_pos
, SEEK_SET
);
6850 tng_data
->input_file
= temp
;
6852 tng_block_destroy(&block
);
6854 return(TNG_SUCCESS
);
6857 // ** Move the blocks in a frame set so that there is no unused space between
6858 // * them. This can only be done on the last frame set in the file and should
6859 // * be done e.g. if the last frame set in the file has fewer frames than
6860 // * default or after compressing data blocks in a frame set.
6861 // * @param tng_data is a trajectory data container.
6862 // * @details the current_trajectory_frame_set is the one that will be modified.
6863 // * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the frame set
6864 // * cannot be aligned or TNG_CRITICAL (2) if a major error has occured.
6865 // * FIXME: This function is not finished!!!
6867 // static tng_function_status tng_frame_set_align(tng_trajectory_t tng_data)
6869 // tng_gen_block_t block;
6870 // tng_trajectory_frame_set_t frame_set;
6871 // FILE *temp = tng_data->input_file;
6872 // int64_t pos, contents_start_pos, output_file_len;
6874 // frame_set = &tng_data->current_trajectory_frame_set;
6876 // if(frame_set->n_written_frames == frame_set->n_frames)
6878 // return(TNG_SUCCESS);
6881 // if(tng_data->current_trajectory_frame_set_output_file_pos !=
6882 // tng_data->last_trajectory_frame_set_output_file_pos)
6886 // if(tng_output_file_init(tng_data) != TNG_SUCCESS)
6888 // fprintf(stderr, "TNG library: Cannot initialise destination file. %s: %d\n",
6889 // __FILE__, __LINE__);
6890 // return(TNG_CRITICAL);
6893 // tng_block_init(&block);
6894 // // output_file_pos = ftell(tng_data->output_file);
6896 // tng_data->input_file = tng_data->output_file;
6898 // pos = tng_data->current_trajectory_frame_set_output_file_pos;
6900 // fseek(tng_data->output_file, pos, SEEK_SET);
6901 // if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
6903 // fprintf(stderr, "TNG library: Cannot read frame set header. %s: %d\n",
6904 // __FILE__, __LINE__);
6905 // tng_data->input_file = temp;
6906 // tng_block_destroy(&block);
6907 // return(TNG_CRITICAL);
6910 // contents_start_pos = ftell(tng_data->output_file);
6912 // fseek(tng_data->output_file, 0, SEEK_END);
6913 // output_file_len = ftell(tng_data->output_file);
6914 // pos = contents_start_pos + block->block_contents_size;
6915 // fseek(tng_data->output_file, pos,
6918 // while(pos < output_file_len)
6920 // if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
6922 // fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", pos,
6923 // __FILE__, __LINE__);
6924 // tng_data->input_file = temp;
6925 // tng_block_destroy(&block);
6926 // return(TNG_CRITICAL);
6928 // pos += block->header_contents_size + block->block_contents_size;
6929 // fseek(tng_data->output_file, pos, SEEK_SET);
6932 // return(TNG_SUCCESS);
6935 /** Finish writing the current frame set. Update the number of frames
6936 * and the hashes of the frame set and all its data blocks (if hash_mode
6938 * @param tng_data is a trajectory data container.
6939 * @param hash_mode specifies whether to update the block md5 hash when
6940 * updating the pointers.
6941 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
6942 * error has occured.
6944 static tng_function_status tng_frame_set_finalize
6945 (tng_trajectory_t tng_data
, const char hash_mode
)
6947 tng_gen_block_t block
;
6948 tng_trajectory_frame_set_t frame_set
;
6949 FILE *temp
= tng_data
->input_file
;
6950 int64_t pos
, contents_start_pos
, output_file_len
;
6952 frame_set
= &tng_data
->current_trajectory_frame_set
;
6954 if(frame_set
->n_written_frames
== frame_set
->n_frames
)
6956 return(TNG_SUCCESS
);
6959 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
6961 fprintf(stderr
, "TNG library: Cannot initialise destination file. %s: %d\n",
6962 __FILE__
, __LINE__
);
6963 return(TNG_CRITICAL
);
6966 tng_block_init(&block
);
6967 /* output_file_pos = ftell(tng_data->output_file); */
6969 tng_data
->input_file
= tng_data
->output_file
;
6971 pos
= tng_data
->current_trajectory_frame_set_output_file_pos
;
6973 fseek(tng_data
->output_file
, (long)pos
, SEEK_SET
);
6975 if(tng_block_header_read(tng_data
, block
) != TNG_SUCCESS
)
6977 fprintf(stderr
, "TNG library: Cannot read frame set header. %s: %d\n",
6978 __FILE__
, __LINE__
);
6979 tng_data
->input_file
= temp
;
6980 tng_block_destroy(&block
);
6981 return(TNG_CRITICAL
);
6984 contents_start_pos
= ftell(tng_data
->output_file
);
6986 fseek(tng_data
->output_file
, sizeof(frame_set
->first_frame
), SEEK_CUR
);
6987 if(fwrite(&frame_set
->n_written_frames
, sizeof(frame_set
->n_frames
),
6988 1, tng_data
->output_file
) != 1)
6990 tng_data
->input_file
= temp
;
6991 tng_block_destroy(&block
);
6992 return(TNG_CRITICAL
);
6996 if(hash_mode
== TNG_USE_HASH
)
6998 tng_md5_hash_update(tng_data
, block
, pos
,
6999 pos
+ block
->header_contents_size
);
7002 fseek(tng_data
->output_file
, 0, SEEK_END
);
7003 output_file_len
= ftell(tng_data
->output_file
);
7004 pos
= contents_start_pos
+ block
->block_contents_size
;
7005 fseek(tng_data
->output_file
, (long)pos
, SEEK_SET
);
7007 while(pos
< output_file_len
)
7009 if(tng_block_header_read(tng_data
, block
) != TNG_SUCCESS
)
7011 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n", pos
,
7012 __FILE__
, __LINE__
);
7013 tng_data
->input_file
= temp
;
7014 tng_block_destroy(&block
);
7015 return(TNG_CRITICAL
);
7018 if(hash_mode
== TNG_USE_HASH
)
7020 tng_md5_hash_update(tng_data
, block
, pos
,
7021 pos
+ block
->header_contents_size
);
7023 pos
+= block
->header_contents_size
+ block
->block_contents_size
;
7024 fseek(tng_data
->output_file
, (long)pos
, SEEK_SET
);
7027 tng_data
->input_file
= temp
;
7028 tng_block_destroy(&block
);
7029 return(TNG_SUCCESS
);
7033 // ** Sets the name of a file contents block
7034 // * @param tng_data is a trajectory data container.
7035 // * @param block is the block, of which to change names.
7036 // * @param new_name is the new name of the block.
7037 // * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
7038 // * error has occured.
7040 // static tng_function_status tng_block_name_set(tng_trajectory_t tng_data,
7041 // tng_gen_block_t block,
7042 // const char *new_name)
7046 // len = tng_min_i((int)strlen(new_name) + 1, TNG_MAX_STR_LEN);
7048 // * If the currently stored string length is not enough to store the new
7049 // * string it is freed and reallocated. *
7050 // if(block->name && strlen(block->name) < len)
7052 // free(block->name);
7057 // block->name = malloc(len);
7060 // fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
7061 // __FILE__, __LINE__);
7062 // return(TNG_CRITICAL);
7066 // strncpy(block->name, new_name, len);
7068 // return(TNG_SUCCESS);
7072 tng_function_status
tng_atom_residue_get(const tng_trajectory_t tng_data
,
7073 const tng_atom_t atom
,
7074 tng_residue_t
*residue
)
7078 TNG_ASSERT(atom
, "TNG library: atom must not be NULL");
7080 *residue
= atom
->residue
;
7082 return(TNG_SUCCESS
);
7085 tng_function_status
tng_atom_name_get(const tng_trajectory_t tng_data
,
7086 const tng_atom_t atom
,
7091 TNG_ASSERT(atom
, "TNG library: atom must not be NULL");
7092 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
7094 strncpy(name
, atom
->name
, max_len
- 1);
7095 name
[max_len
- 1] = 0;
7097 if(strlen(atom
->name
) > (unsigned int)max_len
- 1)
7099 return(TNG_FAILURE
);
7101 return(TNG_SUCCESS
);
7104 tng_function_status
tng_atom_name_set(tng_trajectory_t tng_data
,
7106 const char *new_name
)
7111 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7112 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer.");
7114 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
7116 /* If the currently stored string length is not enough to store the new
7117 * string it is freed and reallocated. */
7118 if(atom
->name
&& strlen(atom
->name
) < len
)
7125 atom
->name
= malloc(len
);
7128 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
7129 __FILE__
, __LINE__
);
7130 return(TNG_CRITICAL
);
7134 strncpy(atom
->name
, new_name
, len
);
7136 return(TNG_SUCCESS
);
7139 tng_function_status
tng_atom_type_get(const tng_trajectory_t tng_data
,
7140 const tng_atom_t atom
,
7145 TNG_ASSERT(atom
, "TNG library: atom must not be NULL");
7146 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer");
7148 strncpy(type
, atom
->atom_type
, max_len
- 1);
7149 type
[max_len
- 1] = 0;
7151 if(strlen(atom
->atom_type
) > (unsigned int)max_len
- 1)
7153 return(TNG_FAILURE
);
7155 return(TNG_SUCCESS
);
7158 tng_function_status
tng_atom_type_set(tng_trajectory_t tng_data
,
7160 const char *new_type
)
7165 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7166 TNG_ASSERT(new_type
, "TNG library: new_type must not be a NULL pointer.");
7168 len
= tng_min_i((int)strlen(new_type
) + 1, TNG_MAX_STR_LEN
);
7170 /* If the currently stored string length is not enough to store the new
7171 * string it is freed and reallocated. */
7172 if(atom
->atom_type
&& strlen(atom
->atom_type
) < len
)
7174 free(atom
->atom_type
);
7175 atom
->atom_type
= 0;
7177 if(!atom
->atom_type
)
7179 atom
->atom_type
= malloc(len
);
7180 if(!atom
->atom_type
)
7182 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
7183 __FILE__
, __LINE__
);
7184 return(TNG_CRITICAL
);
7188 strncpy(atom
->atom_type
, new_type
, len
);
7190 return(TNG_SUCCESS
);
7193 /** Initialise an atom struct
7194 * @param atom is the atom to initialise.
7195 * @return TNG_SUCCESS (0) if successful.
7197 static tng_function_status
tng_atom_init(tng_atom_t atom
)
7200 atom
->atom_type
= 0;
7202 return(TNG_SUCCESS
);
7205 /** Free the memory in an atom struct
7206 * @param atom is the atom to destroy.
7207 * @return TNG_SUCCESS (0) if successful.
7209 static tng_function_status
tng_atom_destroy(tng_atom_t atom
)
7218 free(atom
->atom_type
);
7219 atom
->atom_type
= 0;
7222 return(TNG_SUCCESS
);
7225 tng_function_status DECLSPECDLLEXPORT tng_molecule_add
7226 (tng_trajectory_t tng_data
,
7228 tng_molecule_t
*molecule
)
7231 tng_bool found_id
= TNG_TRUE
;
7233 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7234 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
7236 /* Find an unused ID */
7240 found_id
= TNG_FALSE
;
7241 for(i
= tng_data
->n_molecules
; i
--;)
7243 if(tng_data
->molecules
[i
].id
== id
)
7245 found_id
= TNG_TRUE
;
7255 return(tng_molecule_w_id_add(tng_data
, name
, id
, molecule
));
7258 tng_function_status DECLSPECDLLEXPORT tng_molecule_w_id_add
7259 (tng_trajectory_t tng_data
,
7262 tng_molecule_t
*molecule
)
7264 tng_molecule_t new_molecules
;
7265 int64_t *new_molecule_cnt_list
, i
;
7266 tng_function_status stat
= TNG_SUCCESS
;
7268 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7269 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
7271 new_molecules
= realloc(tng_data
->molecules
,
7272 sizeof(struct tng_molecule
) *
7273 (tng_data
->n_molecules
+ 1));
7277 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
7278 sizeof(struct tng_molecule
) * (tng_data
->n_molecules
+ 1),
7279 __FILE__
, __LINE__
);
7280 free(tng_data
->molecules
);
7281 tng_data
->molecules
= 0;
7282 return(TNG_CRITICAL
);
7285 new_molecule_cnt_list
= realloc(tng_data
->molecule_cnt_list
,
7287 (tng_data
->n_molecules
+ 1));
7289 if(!new_molecule_cnt_list
)
7291 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
7292 sizeof(int64_t) * (tng_data
->n_molecules
+ 1),
7293 __FILE__
, __LINE__
);
7294 free(tng_data
->molecule_cnt_list
);
7295 tng_data
->molecule_cnt_list
= 0;
7296 free(new_molecules
);
7297 return(TNG_CRITICAL
);
7300 tng_data
->molecules
= new_molecules
;
7301 tng_data
->molecule_cnt_list
= new_molecule_cnt_list
;
7303 *molecule
= &new_molecules
[tng_data
->n_molecules
];
7305 tng_molecule_init(tng_data
, *molecule
);
7306 tng_molecule_name_set(tng_data
, *molecule
, name
);
7308 /* FIXME: Should this be a function argument instead? */
7309 tng_data
->molecule_cnt_list
[tng_data
->n_molecules
] = 0;
7311 for(i
= tng_data
->n_molecules
; i
--;)
7313 if(tng_data
->molecules
[i
].id
== id
)
7316 fprintf(stderr
, "TNG library: Molecule ID %"PRId64
" already in use. %s: %d\n", id
,
7317 __FILE__
, __LINE__
);
7322 (*molecule
)->id
= id
;
7324 tng_data
->n_molecules
++;
7329 tng_function_status DECLSPECDLLEXPORT tng_molecule_existing_add
7330 (tng_trajectory_t tng_data
,
7331 tng_molecule_t
*molecule_p
)
7333 tng_bool found_id
= TNG_TRUE
;
7334 tng_molecule_t new_molecules
, molecule
;
7335 int64_t *new_molecule_cnt_list
, i
, id
;
7337 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7339 /* Find an unused ID */
7343 found_id
= TNG_FALSE
;
7344 for(i
= tng_data
->n_molecules
; i
--;)
7346 if(tng_data
->molecules
[i
].id
== id
)
7348 found_id
= TNG_TRUE
;
7358 new_molecules
= realloc(tng_data
->molecules
,
7359 sizeof(struct tng_molecule
) *
7360 (tng_data
->n_molecules
+ 1));
7364 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
7365 sizeof(struct tng_molecule
) * (tng_data
->n_molecules
+ 1),
7366 __FILE__
, __LINE__
);
7367 free(tng_data
->molecules
);
7368 tng_data
->molecules
= 0;
7369 return(TNG_CRITICAL
);
7372 new_molecule_cnt_list
= realloc(tng_data
->molecule_cnt_list
,
7374 (tng_data
->n_molecules
+ 1));
7376 if(!new_molecule_cnt_list
)
7378 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
7379 sizeof(int64_t) * (tng_data
->n_molecules
+ 1),
7380 __FILE__
, __LINE__
);
7381 free(tng_data
->molecule_cnt_list
);
7382 tng_data
->molecule_cnt_list
= 0;
7383 free(new_molecules
);
7384 return(TNG_CRITICAL
);
7387 molecule
= *molecule_p
;
7389 tng_data
->molecules
= new_molecules
;
7390 tng_data
->molecule_cnt_list
= new_molecule_cnt_list
;
7392 new_molecules
[tng_data
->n_molecules
] = *molecule
;
7394 tng_data
->molecule_cnt_list
[tng_data
->n_molecules
] = 0;
7398 molecule
= &new_molecules
[tng_data
->n_molecules
];
7400 *molecule_p
= molecule
;
7404 tng_data
->n_molecules
++;
7406 return(TNG_SUCCESS
);
7409 tng_function_status
tng_molecule_name_get(const tng_trajectory_t tng_data
,
7410 const tng_molecule_t molecule
,
7415 TNG_ASSERT(molecule
, "TNG library: molecule must not be NULL");
7416 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
7418 strncpy(name
, molecule
->name
, max_len
- 1);
7419 name
[max_len
- 1] = 0;
7421 if(strlen(molecule
->name
) > (unsigned int)max_len
- 1)
7423 return(TNG_FAILURE
);
7425 return(TNG_SUCCESS
);
7428 tng_function_status DECLSPECDLLEXPORT tng_molecule_name_set
7429 (tng_trajectory_t tng_data
,
7430 tng_molecule_t molecule
,
7431 const char *new_name
)
7436 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7437 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer.");
7439 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
7441 /* If the currently stored string length is not enough to store the new
7442 * string it is freed and reallocated. */
7443 if(molecule
->name
&& strlen(molecule
->name
) < len
)
7445 free(molecule
->name
);
7450 molecule
->name
= malloc(len
);
7453 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
7454 __FILE__
, __LINE__
);
7455 return(TNG_CRITICAL
);
7459 strncpy(molecule
->name
, new_name
, len
);
7461 return(TNG_SUCCESS
);
7464 tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_get
7465 (const tng_trajectory_t tng_data
,
7466 const tng_molecule_t molecule
,
7469 int64_t i
, index
= -1;
7471 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7472 TNG_ASSERT(cnt
, "TNG library: cnt must not be a NULL pointer.");
7474 for(i
= tng_data
->n_molecules
; i
--;)
7476 if(&tng_data
->molecules
[i
] == molecule
)
7484 return(TNG_FAILURE
);
7486 *cnt
= tng_data
->molecule_cnt_list
[index
];
7488 return(TNG_SUCCESS
);
7491 tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_set
7492 (tng_trajectory_t tng_data
,
7493 tng_molecule_t molecule
,
7496 int64_t i
, old_cnt
, index
= -1;
7498 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7500 for(i
= tng_data
->n_molecules
; i
--;)
7502 if(&tng_data
->molecules
[i
] == molecule
)
7510 fprintf(stderr
, "TNG library: Could not find molecule in TNG trajectory. %s: %d\n",
7511 __FILE__
, __LINE__
);
7512 return(TNG_FAILURE
);
7514 if(tng_data
->var_num_atoms_flag
== TNG_CONSTANT_N_ATOMS
)
7516 old_cnt
= tng_data
->molecule_cnt_list
[index
];
7517 tng_data
->molecule_cnt_list
[index
] = cnt
;
7519 tng_data
->n_particles
+= (cnt
-old_cnt
) *
7520 tng_data
->molecules
[index
].n_atoms
;
7524 old_cnt
= tng_data
->current_trajectory_frame_set
.molecule_cnt_list
[index
];
7525 tng_data
->current_trajectory_frame_set
.molecule_cnt_list
[index
] = cnt
;
7527 tng_data
->current_trajectory_frame_set
.n_particles
+= (cnt
-old_cnt
) *
7528 tng_data
->molecules
[index
].n_atoms
;
7531 return(TNG_SUCCESS
);
7534 tng_function_status DECLSPECDLLEXPORT tng_molecule_find
7535 (tng_trajectory_t tng_data
,
7538 tng_molecule_t
*molecule
)
7540 int64_t i
, n_molecules
;
7542 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7543 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
7544 TNG_ASSERT(molecule
, "TNG library: molecule must not be a NULL pointer.");
7546 n_molecules
= tng_data
->n_molecules
;
7548 for(i
= 0; i
< n_molecules
; i
++)
7550 *molecule
= &tng_data
->molecules
[i
];
7551 if(name
[0] == 0 || strcmp(name
, (*molecule
)->name
) == 0)
7553 if(nr
== -1 || nr
== (*molecule
)->id
)
7555 return(TNG_SUCCESS
);
7562 return(TNG_FAILURE
);
7565 tng_function_status DECLSPECDLLEXPORT tng_molecule_of_index_get
7566 (tng_trajectory_t tng_data
,
7568 tng_molecule_t
*molecule
)
7570 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7571 TNG_ASSERT(molecule
, "TNG library: molecule must not be a NULL pointer.");
7573 if(index
>= tng_data
->n_molecules
)
7576 return(TNG_FAILURE
);
7578 *molecule
= &tng_data
->molecules
[index
];
7579 return(TNG_SUCCESS
);
7582 tng_function_status DECLSPECDLLEXPORT
tng_molecule_system_copy(tng_trajectory_t tng_data_src
,
7583 tng_trajectory_t tng_data_dest
)
7585 tng_molecule_t molecule
, molecule_temp
;
7586 tng_chain_t chain
, chain_temp
;
7587 tng_residue_t residue
, residue_temp
;
7588 tng_atom_t atom
, atom_temp
;
7589 tng_bond_t bond_temp
;
7590 tng_function_status stat
;
7591 int64_t i
, j
, k
, l
, *list_temp
;
7593 TNG_ASSERT(tng_data_src
, "TNG library: Trajectory container not properly setup.");
7594 TNG_ASSERT(tng_data_dest
, "TNG library: Trajectory container not properly setup.");
7596 for(i
= 0; i
< tng_data_dest
->n_molecules
; i
++)
7598 molecule
= &tng_data_dest
->molecules
[i
];
7599 tng_molecule_destroy(tng_data_dest
, molecule
);
7602 tng_data_dest
->n_molecules
= 0;
7603 tng_data_dest
->n_particles
= 0;
7605 molecule_temp
= realloc(tng_data_dest
->molecules
,
7606 sizeof(struct tng_molecule
) * tng_data_src
->n_molecules
);
7609 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
7610 sizeof(struct tng_molecule
) * tng_data_src
->n_molecules
,
7611 __FILE__
, __LINE__
);
7612 free(tng_data_dest
->molecules
);
7613 tng_data_dest
->molecules
= 0;
7614 return(TNG_CRITICAL
);
7616 list_temp
= realloc(tng_data_dest
->molecule_cnt_list
,
7617 sizeof(int64_t) * tng_data_src
->n_molecules
);
7620 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
7621 sizeof(int64_t) * tng_data_src
->n_molecules
,
7622 __FILE__
, __LINE__
);
7623 free(tng_data_dest
->molecule_cnt_list
);
7624 tng_data_dest
->molecule_cnt_list
= 0;
7625 free(molecule_temp
);
7626 return(TNG_CRITICAL
);
7629 tng_data_dest
->molecules
= molecule_temp
;
7630 tng_data_dest
->molecule_cnt_list
= list_temp
;
7632 for(i
= 0; i
< tng_data_src
->n_molecules
; i
++)
7634 molecule
= &tng_data_src
->molecules
[i
];
7635 stat
= tng_molecule_w_id_add(tng_data_dest
, molecule
->name
, molecule
->id
,
7637 if(stat
!= TNG_SUCCESS
)
7639 fprintf(stderr
, "TNG library: Cannot create new molecule to make a copy. %s: %d\n",
7640 __FILE__
, __LINE__
);
7643 molecule_temp
->quaternary_str
= molecule
->quaternary_str
;
7644 for(j
= 0; j
< molecule
->n_chains
; j
++)
7646 chain
= &molecule
->chains
[j
];
7647 stat
= tng_molecule_chain_w_id_add(tng_data_dest
, molecule_temp
,
7648 chain
->name
, chain
->id
,
7650 if(stat
!= TNG_SUCCESS
)
7652 fprintf(stderr
, "TNG library: Cannot create new chain to make a copy. %s: %d\n",
7653 __FILE__
, __LINE__
);
7656 for(k
= 0; k
< chain
->n_residues
; k
++)
7658 residue
= &chain
->residues
[k
];
7659 stat
= tng_chain_residue_w_id_add(tng_data_dest
, chain_temp
,
7660 residue
->name
, residue
->id
,
7662 if(stat
!= TNG_SUCCESS
)
7664 fprintf(stderr
, "TNG library: Cannot create new residue to make a copy. %s: %d\n",
7665 __FILE__
, __LINE__
);
7668 for(l
= 0; l
< residue
->n_atoms
; l
++)
7670 atom
= &molecule
->atoms
[residue
->atoms_offset
+ l
];
7671 stat
= tng_residue_atom_w_id_add(tng_data_dest
, residue_temp
,
7672 atom
->name
, atom
->atom_type
,
7673 atom
->id
, &atom_temp
);
7674 if(stat
!= TNG_SUCCESS
)
7676 fprintf(stderr
, "TNG library: Cannot create new atom to make a copy. %s: %d\n",
7677 __FILE__
, __LINE__
);
7683 molecule_temp
->n_bonds
= molecule
->n_bonds
;
7684 bond_temp
= realloc(molecule_temp
->bonds
, sizeof(struct tng_bond
) *
7688 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
7689 sizeof(struct tng_bond
) * molecule
->n_bonds
,
7690 __FILE__
, __LINE__
);
7691 free(molecule_temp
->bonds
);
7692 molecule_temp
->n_bonds
= 0;
7693 return(TNG_CRITICAL
);
7695 molecule_temp
->bonds
= bond_temp
;
7696 for(j
= 0; j
< molecule
->n_bonds
; j
++)
7698 molecule_temp
->bonds
[j
] = molecule
->bonds
[j
];
7700 stat
= tng_molecule_cnt_set(tng_data_dest
, molecule_temp
,
7701 tng_data_src
->molecule_cnt_list
[i
]);
7702 if(stat
!= TNG_SUCCESS
)
7704 fprintf(stderr
, "TNG library: Cannot set molecule count. %s: %d.\n",
7705 __FILE__
, __LINE__
);
7709 return(TNG_SUCCESS
);
7712 tng_function_status DECLSPECDLLEXPORT tng_molecule_num_chains_get
7713 (const tng_trajectory_t tng_data
,
7714 const tng_molecule_t molecule
,
7718 TNG_ASSERT(molecule
, "TNG library: molecule must not be NULL");
7719 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
7721 *n
= molecule
->n_chains
;
7723 return(TNG_SUCCESS
);
7726 tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_of_index_get
7727 (tng_trajectory_t tng_data
,
7728 tng_molecule_t molecule
,
7733 TNG_ASSERT(molecule
, "TNG library: molecule must not be a NULL pointer.");
7734 TNG_ASSERT(chain
, "TNG library: chain must not be a NULL pointer.");
7736 if(index
>= molecule
->n_chains
)
7739 return(TNG_FAILURE
);
7741 *chain
= &molecule
->chains
[index
];
7742 return(TNG_SUCCESS
);
7745 tng_function_status DECLSPECDLLEXPORT tng_molecule_num_residues_get
7746 (const tng_trajectory_t tng_data
,
7747 const tng_molecule_t molecule
,
7751 TNG_ASSERT(molecule
, "TNG library: molecule must not be NULL");
7752 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
7754 *n
= molecule
->n_residues
;
7756 return(TNG_SUCCESS
);
7759 tng_function_status DECLSPECDLLEXPORT tng_molecule_residue_of_index_get
7760 (const tng_trajectory_t tng_data
,
7761 const tng_molecule_t molecule
,
7762 const int64_t index
,
7763 tng_residue_t
*residue
)
7766 TNG_ASSERT(molecule
, "TNG library: molecule must not be a NULL pointer.");
7767 TNG_ASSERT(residue
, "TNG library: residue must not be a NULL pointer.");
7769 if(index
>= molecule
->n_residues
)
7772 return(TNG_FAILURE
);
7774 *residue
= &molecule
->residues
[index
];
7775 return(TNG_SUCCESS
);
7778 tng_function_status DECLSPECDLLEXPORT tng_molecule_num_atoms_get
7779 (const tng_trajectory_t tng_data
,
7780 const tng_molecule_t molecule
,
7784 TNG_ASSERT(molecule
, "TNG library: molecule must not be NULL");
7785 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
7787 *n
= molecule
->n_atoms
;
7789 return(TNG_SUCCESS
);
7792 tng_function_status DECLSPECDLLEXPORT tng_molecule_atom_of_index_get
7793 (const tng_trajectory_t tng_data
,
7794 const tng_molecule_t molecule
,
7795 const int64_t index
,
7799 TNG_ASSERT(molecule
, "TNG library: molecule must not be a NULL pointer.");
7800 TNG_ASSERT(atom
, "TNG library: atom must not be a NULL pointer.");
7802 if(index
>= molecule
->n_atoms
)
7805 return(TNG_FAILURE
);
7807 *atom
= &molecule
->atoms
[index
];
7808 return(TNG_SUCCESS
);
7811 tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_find
7812 (tng_trajectory_t tng_data
,
7813 tng_molecule_t molecule
,
7818 int64_t i
, n_chains
;
7821 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7822 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
7824 n_chains
= molecule
->n_chains
;
7826 for(i
= 0; i
< n_chains
; i
++)
7828 *chain
= &molecule
->chains
[i
];
7829 if(name
[0] == 0 || strcmp(name
, (*chain
)->name
) == 0)
7831 if(nr
== -1 || nr
== (*chain
)->id
)
7833 return(TNG_SUCCESS
);
7840 return(TNG_FAILURE
);
7843 tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_add
7844 (tng_trajectory_t tng_data
,
7845 tng_molecule_t molecule
,
7849 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7850 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
7852 return(tng_molecule_chain_w_id_add(tng_data
, molecule
, name
,
7853 molecule
->n_chains
+ 1, chain
));
7856 tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_w_id_add
7857 (tng_trajectory_t tng_data
,
7858 tng_molecule_t molecule
,
7864 tng_chain_t new_chains
;
7865 tng_function_status stat
= TNG_SUCCESS
;
7867 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7868 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
7870 new_chains
= realloc(molecule
->chains
,
7871 sizeof(struct tng_chain
) *
7872 (molecule
->n_chains
+ 1));
7876 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
7877 sizeof(struct tng_chain
) * (molecule
->n_chains
+ 1),
7878 __FILE__
, __LINE__
);
7879 free(molecule
->chains
);
7880 molecule
->chains
= 0;
7881 return(TNG_CRITICAL
);
7884 molecule
->chains
= new_chains
;
7886 *chain
= &new_chains
[molecule
->n_chains
];
7889 tng_chain_name_set(tng_data
, *chain
, name
);
7891 (*chain
)->molecule
= molecule
;
7892 (*chain
)->n_residues
= 0;
7894 for(i
= molecule
->n_chains
; i
--;)
7896 if(molecule
->chains
[i
].id
== id
)
7899 fprintf(stderr
, "TNG library: Chain ID already in use. %s: %d\n", __FILE__
, __LINE__
);
7904 molecule
->n_chains
++;
7911 tng_function_status DECLSPECDLLEXPORT tng_molecule_bond_add
7912 (const tng_trajectory_t tng_data
,
7913 tng_molecule_t molecule
,
7914 const int64_t from_atom_id
,
7915 const int64_t to_atom_id
,
7919 tng_bond_t new_bonds
;
7922 for(i
= 0; i
< molecule
->n_bonds
; i
++)
7924 *bond
= &molecule
->bonds
[i
];
7925 /* Check if the bond already exists */
7926 if(((*bond
)->from_atom_id
== from_atom_id
&& (*bond
)->to_atom_id
== to_atom_id
) ||
7927 ((*bond
)->to_atom_id
== from_atom_id
&& (*bond
)->from_atom_id
== to_atom_id
))
7929 return(TNG_SUCCESS
);
7933 new_bonds
= realloc(molecule
->bonds
,
7934 sizeof(struct tng_bond
) *
7935 (molecule
->n_bonds
+ 1));
7939 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
7940 sizeof(struct tng_bond
) * (molecule
->n_bonds
+ 1),
7941 __FILE__
, __LINE__
);
7943 free(molecule
->bonds
);
7944 molecule
->bonds
= 0;
7945 return(TNG_CRITICAL
);
7948 molecule
->bonds
= new_bonds
;
7950 *bond
= &new_bonds
[molecule
->n_bonds
];
7952 (*bond
)->from_atom_id
= from_atom_id
;
7953 (*bond
)->to_atom_id
= to_atom_id
;
7955 molecule
->n_bonds
++;
7957 return(TNG_SUCCESS
);
7960 tng_function_status DECLSPECDLLEXPORT tng_molecule_atom_find
7961 (tng_trajectory_t tng_data
,
7962 tng_molecule_t molecule
,
7970 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
7972 n_atoms
= molecule
->n_atoms
;
7974 for(i
= 0; i
< n_atoms
; i
++)
7976 *atom
= &molecule
->atoms
[i
];
7977 if(name
[0] == 0 || strcmp(name
, (*atom
)->name
) == 0)
7979 if(id
== -1 || id
== (*atom
)->id
)
7981 return(TNG_SUCCESS
);
7988 return(TNG_FAILURE
);
7991 tng_function_status
tng_chain_name_get(const tng_trajectory_t tng_data
,
7992 const tng_chain_t chain
,
7997 TNG_ASSERT(chain
, "TNG library: chain must not be NULL");
7998 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
8000 strncpy(name
, chain
->name
, max_len
- 1);
8001 name
[max_len
- 1] = 0;
8003 if(strlen(chain
->name
) > (unsigned int)max_len
- 1)
8005 return(TNG_FAILURE
);
8007 return(TNG_SUCCESS
);
8010 tng_function_status DECLSPECDLLEXPORT tng_chain_name_set
8011 (tng_trajectory_t tng_data
,
8013 const char *new_name
)
8018 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer.");
8020 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
8022 /* If the currently stored string length is not enough to store the new
8023 * string it is freed and reallocated. */
8024 if(chain
->name
&& strlen(chain
->name
) < len
)
8031 chain
->name
= malloc(len
);
8034 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
8035 __FILE__
, __LINE__
);
8036 return(TNG_CRITICAL
);
8040 strncpy(chain
->name
, new_name
, len
);
8042 return(TNG_SUCCESS
);
8045 tng_function_status DECLSPECDLLEXPORT tng_chain_num_residues_get
8046 (const tng_trajectory_t tng_data
,
8047 const tng_chain_t chain
,
8051 TNG_ASSERT(chain
, "TNG library: chain must not be NULL");
8052 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
8054 *n
= chain
->n_residues
;
8056 return(TNG_SUCCESS
);
8059 tng_function_status DECLSPECDLLEXPORT tng_chain_residue_of_index_get
8060 (const tng_trajectory_t tng_data
,
8061 const tng_chain_t chain
,
8062 const int64_t index
,
8063 tng_residue_t
*residue
)
8066 TNG_ASSERT(chain
, "TNG library: chain must not be a NULL pointer.");
8067 TNG_ASSERT(residue
, "TNG library: residue must not be a NULL pointer.");
8069 if(index
>= chain
->n_residues
)
8072 return(TNG_FAILURE
);
8074 *residue
= &chain
->residues
[index
];
8075 return(TNG_SUCCESS
);
8078 tng_function_status DECLSPECDLLEXPORT tng_chain_residue_find
8079 (tng_trajectory_t tng_data
,
8083 tng_residue_t
*residue
)
8085 int64_t i
, n_residues
;
8088 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
8090 n_residues
= chain
->n_residues
;
8092 for(i
= 0; i
< n_residues
; i
++)
8094 *residue
= &chain
->residues
[i
];
8095 if(name
[0] == 0 || strcmp(name
, (*residue
)->name
) == 0)
8097 if(id
== -1 || id
== (*residue
)->id
)
8099 return(TNG_SUCCESS
);
8106 return(TNG_FAILURE
);
8109 tng_function_status DECLSPECDLLEXPORT tng_chain_residue_add
8110 (tng_trajectory_t tng_data
,
8113 tng_residue_t
*residue
)
8115 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8116 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
8118 return(tng_chain_residue_w_id_add(tng_data
, chain
, name
,
8119 chain
->n_residues
+ 1, residue
));
8122 tng_function_status DECLSPECDLLEXPORT tng_chain_residue_w_id_add
8123 (tng_trajectory_t tng_data
,
8127 tng_residue_t
*residue
)
8129 int64_t i
, curr_index
;
8130 tng_residue_t new_residues
, temp_residue
, last_residue
;
8131 tng_molecule_t molecule
= chain
->molecule
;
8132 tng_function_status stat
= TNG_SUCCESS
;
8134 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8135 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
8137 if(chain
->n_residues
)
8139 curr_index
= chain
->residues
- molecule
->residues
;
8146 new_residues
= realloc(molecule
->residues
,
8147 sizeof(struct tng_residue
) *
8148 (molecule
->n_residues
+ 1));
8152 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
8153 sizeof(struct tng_residue
) * (molecule
->n_residues
+ 1),
8154 __FILE__
, __LINE__
);
8155 free(molecule
->residues
);
8156 molecule
->residues
= 0;
8157 return(TNG_CRITICAL
);
8160 molecule
->residues
= new_residues
;
8162 if(curr_index
!= -1)
8164 chain
->residues
= new_residues
+ curr_index
;
8165 if(molecule
->n_residues
)
8167 last_residue
= &new_residues
[molecule
->n_residues
- 1];
8169 temp_residue
= chain
->residues
+ (chain
->n_residues
- 1);
8170 /* Make space in list of residues to add the new residues together with the other
8171 * residues of this chain */
8172 if(temp_residue
!= last_residue
)
8175 memmove(temp_residue
+ 1, temp_residue
,
8176 last_residue
- temp_residue
);
8182 curr_index
= molecule
->n_residues
;
8185 *residue
= &molecule
->residues
[curr_index
+ chain
->n_residues
];
8187 if(!chain
->n_residues
)
8189 chain
->residues
= *residue
;
8192 (*residue
)->name
= 0;
8193 tng_residue_name_set(tng_data
, *residue
, name
);
8195 (*residue
)->chain
= chain
;
8196 (*residue
)->n_atoms
= 0;
8197 (*residue
)->atoms_offset
= 0;
8199 for(i
= chain
->n_residues
; i
--;)
8201 if(chain
->residues
[i
].id
== id
)
8204 fprintf(stderr
, "TNG library: Residue ID already in use. %s: %d\n", __FILE__
, __LINE__
);
8209 chain
->n_residues
++;
8210 molecule
->n_residues
++;
8212 (*residue
)->id
= id
;
8217 tng_function_status
tng_residue_name_get(const tng_trajectory_t tng_data
,
8218 const tng_residue_t residue
,
8223 TNG_ASSERT(residue
, "TNG library: residue must not be NULL");
8224 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
8226 strncpy(name
, residue
->name
, max_len
- 1);
8227 name
[max_len
- 1] = 0;
8229 if(strlen(residue
->name
) > (unsigned int)max_len
- 1)
8231 return(TNG_FAILURE
);
8233 return(TNG_SUCCESS
);
8236 tng_function_status DECLSPECDLLEXPORT
tng_residue_name_set(tng_trajectory_t tng_data
,
8237 tng_residue_t residue
,
8238 const char *new_name
)
8243 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8244 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer");
8246 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
8248 /* If the currently stored string length is not enough to store the new
8249 * string it is freed and reallocated. */
8250 if(residue
->name
&& strlen(residue
->name
) < len
)
8252 free(residue
->name
);
8257 residue
->name
= malloc(len
);
8260 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
8261 __FILE__
, __LINE__
);
8262 return(TNG_CRITICAL
);
8266 strncpy(residue
->name
, new_name
, len
);
8268 return(TNG_SUCCESS
);
8271 tng_function_status DECLSPECDLLEXPORT tng_residue_num_atoms_get
8272 (const tng_trajectory_t tng_data
,
8273 const tng_residue_t residue
,
8277 TNG_ASSERT(residue
, "TNG library: residue must not be NULL");
8278 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
8280 *n
= residue
->n_atoms
;
8282 return(TNG_SUCCESS
);
8285 tng_function_status DECLSPECDLLEXPORT tng_residue_atom_of_index_get
8286 (const tng_trajectory_t tng_data
,
8287 const tng_residue_t residue
,
8288 const int64_t index
,
8292 tng_molecule_t molecule
;
8295 TNG_ASSERT(residue
, "TNG library: residue must not be a NULL pointer.");
8296 TNG_ASSERT(atom
, "TNG library: atom must not be a NULL pointer.");
8298 if(index
>= residue
->n_atoms
)
8301 return(TNG_FAILURE
);
8303 chain
= residue
->chain
;
8304 molecule
= chain
->molecule
;
8306 if(index
+ residue
->atoms_offset
>= molecule
->n_atoms
)
8309 return(TNG_FAILURE
);
8312 *atom
= &molecule
->atoms
[residue
->atoms_offset
+ index
];
8313 return(TNG_SUCCESS
);
8316 tng_function_status DECLSPECDLLEXPORT tng_residue_atom_add
8317 (tng_trajectory_t tng_data
,
8318 tng_residue_t residue
,
8319 const char *atom_name
,
8320 const char *atom_type
,
8323 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8324 TNG_ASSERT(atom_name
, "TNG library: atom_name must not be a NULL pointer.");
8325 TNG_ASSERT(atom_type
, "TNG library: atom_type must not be a NULL pointer.");
8327 return(tng_residue_atom_w_id_add(tng_data
, residue
, atom_name
, atom_type
,
8328 residue
->chain
->molecule
->n_atoms
+ 1,
8332 tng_function_status DECLSPECDLLEXPORT tng_residue_atom_w_id_add
8333 (tng_trajectory_t tng_data
,
8334 tng_residue_t residue
,
8335 const char *atom_name
,
8336 const char *atom_type
,
8341 tng_atom_t new_atoms
;
8342 tng_molecule_t molecule
= residue
->chain
->molecule
;
8343 tng_function_status stat
= TNG_SUCCESS
;
8345 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8346 TNG_ASSERT(atom_name
, "TNG library: atom_name must not be a NULL pointer.");
8347 TNG_ASSERT(atom_type
, "TNG library: atom_type must not be a NULL pointer.");
8349 if(!residue
->n_atoms
)
8351 residue
->atoms_offset
= molecule
->n_atoms
;
8354 new_atoms
= realloc(molecule
->atoms
,
8355 sizeof(struct tng_atom
) *
8356 (molecule
->n_atoms
+ 1));
8360 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
8361 sizeof(struct tng_atom
) * (molecule
->n_atoms
+ 1),
8362 __FILE__
, __LINE__
);
8363 free(molecule
->atoms
);
8364 molecule
->atoms
= 0;
8365 return(TNG_CRITICAL
);
8368 molecule
->atoms
= new_atoms
;
8370 *atom
= &new_atoms
[molecule
->n_atoms
];
8372 tng_atom_init(*atom
);
8373 tng_atom_name_set(tng_data
, *atom
, atom_name
);
8374 tng_atom_type_set(tng_data
, *atom
, atom_type
);
8376 (*atom
)->residue
= residue
;
8378 for(i
= molecule
->n_atoms
; i
--;)
8380 if(molecule
->atoms
[i
].id
== id
)
8383 fprintf(stderr
, "TNG library: Atom ID %"PRId64
" already in use. %s: %d\n", id
, __FILE__
, __LINE__
);
8389 molecule
->n_atoms
++;
8396 tng_function_status DECLSPECDLLEXPORT
tng_molecule_alloc(const tng_trajectory_t tng_data
,
8397 tng_molecule_t
*molecule_p
)
8399 *molecule_p
= malloc(sizeof(struct tng_molecule
));
8402 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
8403 sizeof(struct tng_molecule
), __FILE__
, __LINE__
);
8404 return(TNG_CRITICAL
);
8407 tng_molecule_init(tng_data
, *molecule_p
);
8409 return(TNG_SUCCESS
);
8412 tng_function_status DECLSPECDLLEXPORT
tng_molecule_free(const tng_trajectory_t tng_data
,
8413 tng_molecule_t
*molecule_p
)
8417 return(TNG_SUCCESS
);
8420 tng_molecule_destroy(tng_data
, *molecule_p
);
8425 return(TNG_SUCCESS
);
8428 tng_function_status DECLSPECDLLEXPORT
tng_molecule_init(const tng_trajectory_t tng_data
,
8429 tng_molecule_t molecule
)
8432 molecule
->quaternary_str
= 1;
8434 molecule
->n_chains
= 0;
8435 molecule
->chains
= 0;
8436 molecule
->n_residues
= 0;
8437 molecule
->residues
= 0;
8438 molecule
->n_atoms
= 0;
8439 molecule
->atoms
= 0;
8440 molecule
->n_bonds
= 0;
8441 molecule
->bonds
= 0;
8443 return(TNG_SUCCESS
);
8446 tng_function_status DECLSPECDLLEXPORT
tng_molecule_destroy(const tng_trajectory_t tng_data
,
8447 tng_molecule_t molecule
)
8454 free(molecule
->name
);
8458 if(molecule
->chains
)
8460 for(i
= molecule
->n_chains
; i
--;)
8462 if(molecule
->chains
[i
].name
)
8464 free(molecule
->chains
[i
].name
);
8465 molecule
->chains
[i
].name
= 0;
8468 free(molecule
->chains
);
8469 molecule
->chains
= 0;
8471 molecule
->n_chains
= 0;
8473 if(molecule
->residues
)
8475 for(i
= molecule
->n_residues
; i
--;)
8477 if(molecule
->residues
[i
].name
)
8479 free(molecule
->residues
[i
].name
);
8480 molecule
->residues
[i
].name
= 0;
8483 free(molecule
->residues
);
8484 molecule
->residues
= 0;
8486 molecule
->n_residues
= 0;
8490 for(i
= molecule
->n_atoms
; i
--;)
8492 tng_atom_destroy(&molecule
->atoms
[i
]);
8494 free(molecule
->atoms
);
8495 molecule
->atoms
= 0;
8497 molecule
->n_atoms
= 0;
8501 free(molecule
->bonds
);
8502 molecule
->bonds
= 0;
8504 molecule
->n_bonds
= 0;
8506 return(TNG_SUCCESS
);
8509 tng_function_status DECLSPECDLLEXPORT tng_molecule_name_of_particle_nr_get
8510 (const tng_trajectory_t tng_data
,
8515 int64_t cnt
= 0, i
, *molecule_cnt_list
= 0;
8517 tng_bool found
= TNG_FALSE
;
8519 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8520 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
8522 tng_molecule_cnt_list_get(tng_data
, &molecule_cnt_list
);
8524 if(!molecule_cnt_list
)
8526 return(TNG_FAILURE
);
8529 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8531 mol
= &tng_data
->molecules
[i
];
8532 if(cnt
+ mol
->n_atoms
* molecule_cnt_list
[i
] - 1 < nr
)
8534 cnt
+= mol
->n_atoms
* molecule_cnt_list
[i
];
8542 return(TNG_FAILURE
);
8545 strncpy(name
, mol
->name
, max_len
- 1);
8546 name
[max_len
- 1] = 0;
8548 if(strlen(mol
->name
) > (unsigned int)max_len
- 1)
8550 return(TNG_FAILURE
);
8552 return(TNG_SUCCESS
);
8555 tng_function_status DECLSPECDLLEXPORT tng_molecule_id_of_particle_nr_get
8556 (const tng_trajectory_t tng_data
,
8560 int64_t cnt
= 0, i
, *molecule_cnt_list
= 0;
8562 tng_bool found
= TNG_FALSE
;
8564 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8565 TNG_ASSERT(id
, "TNG library: id must not be a NULL pointer.");
8567 tng_molecule_cnt_list_get(tng_data
, &molecule_cnt_list
);
8569 if(!molecule_cnt_list
)
8571 return(TNG_FAILURE
);
8574 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8576 mol
= &tng_data
->molecules
[i
];
8577 if(cnt
+ mol
->n_atoms
* molecule_cnt_list
[i
] - 1 < nr
)
8579 cnt
+= mol
->n_atoms
* molecule_cnt_list
[i
];
8587 return(TNG_FAILURE
);
8592 return(TNG_SUCCESS
);
8595 tng_function_status DECLSPECDLLEXPORT tng_molsystem_bonds_get
8596 (const tng_trajectory_t tng_data
,
8598 int64_t **from_atoms
,
8601 int64_t atom_cnt
= 0, cnt
, mol_cnt
, i
, j
, k
;
8602 int64_t from_atom
, to_atom
, *molecule_cnt_list
= 0;
8606 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8607 TNG_ASSERT(n_bonds
, "TNG library: n_bonds must not be a NULL pointer.");
8608 TNG_ASSERT(from_atoms
, "TNG library: from_atoms must not be a NULL pointer.");
8609 TNG_ASSERT(to_atoms
, "TNG library: to_atoms must not be a NULL pointer.");
8611 tng_molecule_cnt_list_get(tng_data
, &molecule_cnt_list
);
8613 if(!molecule_cnt_list
)
8615 return(TNG_FAILURE
);
8619 /* First count the total number of bonds to allocate memory */
8620 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8622 mol
= &tng_data
->molecules
[i
];
8623 mol_cnt
= molecule_cnt_list
[i
];
8624 *n_bonds
+= mol_cnt
* mol
->n_bonds
;
8628 return(TNG_SUCCESS
);
8631 *from_atoms
= malloc(sizeof(int64_t) * (*n_bonds
));
8634 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
8635 sizeof(int64_t) * (*n_bonds
), __FILE__
, __LINE__
);
8636 return(TNG_CRITICAL
);
8638 *to_atoms
= malloc(sizeof(int64_t) * (*n_bonds
));
8641 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
8642 sizeof(int64_t) * (*n_bonds
), __FILE__
, __LINE__
);
8645 return(TNG_CRITICAL
);
8649 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8651 mol
= &tng_data
->molecules
[i
];
8652 mol_cnt
= molecule_cnt_list
[i
];
8653 for(j
= 0; j
< mol_cnt
; j
++)
8655 for(k
= 0; k
< mol
->n_bonds
; k
++)
8657 bond
= &mol
->bonds
[k
];
8658 from_atom
= atom_cnt
+ bond
->from_atom_id
;
8659 to_atom
= atom_cnt
+ bond
->to_atom_id
;
8660 (*from_atoms
)[cnt
] = from_atom
;
8661 (*to_atoms
)[cnt
++] = to_atom
;
8663 atom_cnt
+= mol
->n_atoms
;
8667 return(TNG_SUCCESS
);
8670 tng_function_status DECLSPECDLLEXPORT tng_chain_name_of_particle_nr_get
8671 (const tng_trajectory_t tng_data
,
8676 int64_t cnt
= 0, i
, *molecule_cnt_list
= 0;
8679 tng_bool found
= TNG_FALSE
;
8681 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8682 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
8684 tng_molecule_cnt_list_get(tng_data
, &molecule_cnt_list
);
8686 if(!molecule_cnt_list
)
8688 return(TNG_FAILURE
);
8691 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8693 mol
= &tng_data
->molecules
[i
];
8694 if(cnt
+ mol
->n_atoms
* molecule_cnt_list
[i
] - 1 < nr
)
8696 cnt
+= mol
->n_atoms
* molecule_cnt_list
[i
];
8699 atom
= &mol
->atoms
[nr
% mol
->n_atoms
];
8705 return(TNG_FAILURE
);
8707 if(!atom
->residue
|| !atom
->residue
->chain
)
8709 return(TNG_FAILURE
);
8712 strncpy(name
, atom
->residue
->chain
->name
, max_len
- 1);
8713 name
[max_len
- 1] = 0;
8715 if(strlen(atom
->residue
->chain
->name
) > (unsigned int)max_len
- 1)
8717 return(TNG_FAILURE
);
8719 return(TNG_SUCCESS
);
8722 tng_function_status DECLSPECDLLEXPORT tng_residue_name_of_particle_nr_get
8723 (const tng_trajectory_t tng_data
,
8728 int64_t cnt
= 0, i
, *molecule_cnt_list
= 0;
8731 tng_bool found
= TNG_FALSE
;
8733 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8734 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
8736 tng_molecule_cnt_list_get(tng_data
, &molecule_cnt_list
);
8738 if(!molecule_cnt_list
)
8740 return(TNG_FAILURE
);
8743 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8745 mol
= &tng_data
->molecules
[i
];
8746 if(cnt
+ mol
->n_atoms
* molecule_cnt_list
[i
] - 1 < nr
)
8748 cnt
+= mol
->n_atoms
* molecule_cnt_list
[i
];
8751 atom
= &mol
->atoms
[nr
% mol
->n_atoms
];
8757 return(TNG_FAILURE
);
8761 return(TNG_FAILURE
);
8764 strncpy(name
, atom
->residue
->name
, max_len
- 1);
8765 name
[max_len
- 1] = 0;
8767 if(strlen(atom
->residue
->name
) > (unsigned int)max_len
- 1)
8769 return(TNG_FAILURE
);
8771 return(TNG_SUCCESS
);
8774 tng_function_status DECLSPECDLLEXPORT tng_residue_id_of_particle_nr_get
8775 (const tng_trajectory_t tng_data
,
8779 int64_t cnt
= 0, i
, *molecule_cnt_list
= 0;
8782 tng_bool found
= TNG_FALSE
;
8784 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8785 TNG_ASSERT(id
, "TNG library: id must not be a NULL pointer.");
8787 tng_molecule_cnt_list_get(tng_data
, &molecule_cnt_list
);
8789 if(!molecule_cnt_list
)
8791 return(TNG_FAILURE
);
8794 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8796 mol
= &tng_data
->molecules
[i
];
8797 if(cnt
+ mol
->n_atoms
* molecule_cnt_list
[i
] - 1 < nr
)
8799 cnt
+= mol
->n_atoms
* molecule_cnt_list
[i
];
8802 atom
= &mol
->atoms
[nr
% mol
->n_atoms
];
8808 return(TNG_FAILURE
);
8812 return(TNG_FAILURE
);
8815 *id
= atom
->residue
->id
;
8817 return(TNG_SUCCESS
);
8820 tng_function_status DECLSPECDLLEXPORT tng_global_residue_id_of_particle_nr_get
8821 (const tng_trajectory_t tng_data
,
8825 int64_t cnt
= 0, i
, offset
= 0, *molecule_cnt_list
= 0;
8828 tng_bool found
= TNG_FALSE
;
8830 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8831 TNG_ASSERT(id
, "TNG library: id must not be a NULL pointer.");
8833 tng_molecule_cnt_list_get(tng_data
, &molecule_cnt_list
);
8835 if(!molecule_cnt_list
)
8837 return(TNG_FAILURE
);
8840 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8842 mol
= &tng_data
->molecules
[i
];
8843 if(cnt
+ mol
->n_atoms
* molecule_cnt_list
[i
] - 1 < nr
)
8845 cnt
+= mol
->n_atoms
* molecule_cnt_list
[i
];
8846 offset
+= mol
->n_residues
* molecule_cnt_list
[i
];
8849 atom
= &mol
->atoms
[nr
% mol
->n_atoms
];
8855 return(TNG_FAILURE
);
8859 return(TNG_FAILURE
);
8862 offset
+= mol
->n_residues
* ((nr
- cnt
) / mol
->n_atoms
);
8864 *id
= atom
->residue
->id
+ offset
;
8866 return(TNG_SUCCESS
);
8869 tng_function_status DECLSPECDLLEXPORT tng_atom_name_of_particle_nr_get
8870 (const tng_trajectory_t tng_data
,
8875 int64_t cnt
= 0, i
, *molecule_cnt_list
= 0;
8878 tng_bool found
= TNG_FALSE
;
8880 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8881 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
8883 tng_molecule_cnt_list_get(tng_data
, &molecule_cnt_list
);
8885 if(!molecule_cnt_list
)
8887 return(TNG_FAILURE
);
8890 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8892 mol
= &tng_data
->molecules
[i
];
8893 if(cnt
+ mol
->n_atoms
* molecule_cnt_list
[i
] - 1 < nr
)
8895 cnt
+= mol
->n_atoms
* molecule_cnt_list
[i
];
8898 atom
= &mol
->atoms
[nr
% mol
->n_atoms
];
8904 return(TNG_FAILURE
);
8907 strncpy(name
, atom
->name
, max_len
- 1);
8908 name
[max_len
- 1] = 0;
8910 if(strlen(atom
->name
) > (unsigned int)max_len
- 1)
8912 return(TNG_FAILURE
);
8914 return(TNG_SUCCESS
);
8917 tng_function_status tng_atom_type_of_particle_nr_get
8918 (const tng_trajectory_t tng_data
,
8923 int64_t cnt
= 0, i
, *molecule_cnt_list
= 0;
8926 tng_bool found
= TNG_FALSE
;
8928 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8929 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer.");
8931 tng_molecule_cnt_list_get(tng_data
, &molecule_cnt_list
);
8933 if(!molecule_cnt_list
)
8935 return(TNG_FAILURE
);
8938 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8940 mol
= &tng_data
->molecules
[i
];
8941 if(cnt
+ mol
->n_atoms
* molecule_cnt_list
[i
] - 1 < nr
)
8943 cnt
+= mol
->n_atoms
* molecule_cnt_list
[i
];
8946 atom
= &mol
->atoms
[nr
% mol
->n_atoms
];
8952 return(TNG_FAILURE
);
8955 strncpy(type
, atom
->atom_type
, max_len
- 1);
8956 type
[max_len
- 1] = 0;
8958 if(strlen(atom
->atom_type
) > (unsigned int)max_len
- 1)
8960 return(TNG_FAILURE
);
8962 return(TNG_SUCCESS
);
8965 tng_function_status DECLSPECDLLEXPORT tng_particle_mapping_add
8966 (tng_trajectory_t tng_data
,
8967 const int64_t num_first_particle
,
8968 const int64_t n_particles
,
8969 const int64_t *mapping_table
)
8972 tng_particle_mapping_t mapping
;
8973 tng_trajectory_frame_set_t frame_set
;
8975 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8977 frame_set
= &tng_data
->current_trajectory_frame_set
;
8979 /* Sanity check of the particle ranges. Split into multiple if
8980 * statements for improved readability */
8981 for(i
= 0; i
< frame_set
->n_mapping_blocks
; i
++)
8983 mapping
= &frame_set
->mappings
[i
];
8984 if(num_first_particle
>= mapping
->num_first_particle
&&
8985 num_first_particle
< mapping
->num_first_particle
+
8986 mapping
->n_particles
)
8988 fprintf(stderr
, "TNG library: Particle mapping overlap. %s: %d\n", __FILE__
, __LINE__
);
8989 return(TNG_FAILURE
);
8991 if(num_first_particle
+ n_particles
>=
8992 mapping
->num_first_particle
&&
8993 num_first_particle
+ n_particles
<
8994 mapping
->num_first_particle
+ mapping
->n_particles
)
8996 fprintf(stderr
, "TNG library: Particle mapping overlap. %s: %d\n", __FILE__
, __LINE__
);
8997 return(TNG_FAILURE
);
8999 if(mapping
->num_first_particle
>= num_first_particle
&&
9000 mapping
->num_first_particle
< num_first_particle
+
9003 fprintf(stderr
, "TNG library: Particle mapping overlap. %s: %d\n", __FILE__
, __LINE__
);
9004 return(TNG_FAILURE
);
9006 if(mapping
->num_first_particle
+ mapping
->n_particles
>
9007 num_first_particle
&&
9008 mapping
->num_first_particle
+ mapping
->n_particles
<
9009 num_first_particle
+ n_particles
)
9011 fprintf(stderr
, "TNG library: Particle mapping overlap. %s: %d\n", __FILE__
, __LINE__
);
9012 return(TNG_FAILURE
);
9016 frame_set
->n_mapping_blocks
++;
9018 mapping
= realloc(frame_set
->mappings
, sizeof(struct tng_particle_mapping
) *
9019 frame_set
->n_mapping_blocks
);
9023 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
9024 sizeof(struct tng_particle_mapping
)*frame_set
->n_mapping_blocks
,
9025 __FILE__
, __LINE__
);
9026 free(frame_set
->mappings
);
9027 frame_set
->mappings
= 0;
9028 return(TNG_CRITICAL
);
9030 frame_set
->mappings
= mapping
;
9032 frame_set
->mappings
[frame_set
->n_mapping_blocks
- 1].num_first_particle
= num_first_particle
;
9033 frame_set
->mappings
[frame_set
->n_mapping_blocks
- 1].n_particles
= n_particles
;
9035 frame_set
->mappings
[frame_set
->n_mapping_blocks
- 1].real_particle_numbers
= malloc(sizeof(int64_t) * n_particles
);
9036 if(!frame_set
->mappings
[frame_set
->n_mapping_blocks
- 1].real_particle_numbers
)
9038 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
9039 sizeof(int64_t) * n_particles
, __FILE__
, __LINE__
);
9040 return(TNG_CRITICAL
);
9043 for(i
=0; i
<n_particles
; i
++)
9045 frame_set
->mappings
[frame_set
->n_mapping_blocks
- 1].real_particle_numbers
[i
] = mapping_table
[i
];
9048 return(TNG_SUCCESS
);
9051 tng_function_status DECLSPECDLLEXPORT
tng_frame_set_particle_mapping_free(tng_trajectory_t tng_data
)
9053 tng_trajectory_frame_set_t frame_set
;
9054 tng_particle_mapping_t mapping
;
9057 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
9059 frame_set
= &tng_data
->current_trajectory_frame_set
;
9061 if(frame_set
->n_mapping_blocks
&& frame_set
->mappings
)
9063 for(i
= frame_set
->n_mapping_blocks
; i
--;)
9065 mapping
= &frame_set
->mappings
[i
];
9066 if(mapping
->real_particle_numbers
)
9068 free(mapping
->real_particle_numbers
);
9069 mapping
->real_particle_numbers
= 0;
9072 free(frame_set
->mappings
);
9073 frame_set
->mappings
= 0;
9074 frame_set
->n_mapping_blocks
= 0;
9077 return(TNG_SUCCESS
);
9080 tng_function_status DECLSPECDLLEXPORT
tng_trajectory_init(tng_trajectory_t
*tng_data_p
)
9083 tng_trajectory_frame_set_t frame_set
;
9084 tng_trajectory_t tng_data
;
9086 *tng_data_p
= malloc(sizeof(struct tng_trajectory
));
9089 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
9090 sizeof(struct tng_trajectory
), __FILE__
, __LINE__
);
9091 return(TNG_CRITICAL
);
9094 tng_data
= *tng_data_p
;
9096 frame_set
= &tng_data
->current_trajectory_frame_set
;
9098 tng_data
->input_file_path
= 0;
9099 tng_data
->input_file
= 0;
9100 tng_data
->input_file_len
= 0;
9101 tng_data
->output_file_path
= 0;
9102 tng_data
->output_file
= 0;
9104 tng_data
->first_program_name
= 0;
9105 tng_data
->first_user_name
= 0;
9106 tng_data
->first_computer_name
= 0;
9107 tng_data
->first_pgp_signature
= 0;
9108 tng_data
->last_program_name
= 0;
9109 tng_data
->last_user_name
= 0;
9110 tng_data
->last_computer_name
= 0;
9111 tng_data
->last_pgp_signature
= 0;
9112 tng_data
->forcefield_name
= 0;
9117 fprintf(stderr
, "TNG library: Cannot get time. %s: %d\n", __FILE__
, __LINE__
);
9121 tng_data
->time
= seconds
;
9124 tng_data
->var_num_atoms_flag
= TNG_CONSTANT_N_ATOMS
;
9125 tng_data
->first_trajectory_frame_set_input_file_pos
= -1;
9126 tng_data
->last_trajectory_frame_set_input_file_pos
= -1;
9127 tng_data
->current_trajectory_frame_set_input_file_pos
= -1;
9128 tng_data
->first_trajectory_frame_set_output_file_pos
= -1;
9129 tng_data
->last_trajectory_frame_set_output_file_pos
= -1;
9130 tng_data
->current_trajectory_frame_set_output_file_pos
= -1;
9131 tng_data
->frame_set_n_frames
= 100;
9132 tng_data
->n_trajectory_frame_sets
= 0;
9133 tng_data
->n_trajectory_blocks
= 0;
9134 tng_data
->medium_stride_length
= 100;
9135 tng_data
->long_stride_length
= 10000;
9137 tng_data
->time_per_frame
= -1;
9139 tng_data
->n_particle_data_blocks
= 0;
9140 tng_data
->n_data_blocks
= 0;
9142 tng_data
->non_tr_particle_data
= 0;
9143 tng_data
->non_tr_data
= 0;
9145 tng_data
->compress_algo_pos
= 0;
9146 tng_data
->compress_algo_vel
= 0;
9147 tng_data
->compression_precision
= 1000;
9148 tng_data
->distance_unit_exponential
= -9;
9150 frame_set
->first_frame
= -1;
9151 frame_set
->n_mapping_blocks
= 0;
9152 frame_set
->mappings
= 0;
9153 frame_set
->molecule_cnt_list
= 0;
9155 frame_set
->n_particle_data_blocks
= 0;
9156 frame_set
->n_data_blocks
= 0;
9158 frame_set
->tr_particle_data
= 0;
9159 frame_set
->tr_data
= 0;
9161 frame_set
->n_written_frames
= 0;
9162 frame_set
->n_unwritten_frames
= 0;
9164 frame_set
->next_frame_set_file_pos
= -1;
9165 frame_set
->prev_frame_set_file_pos
= -1;
9166 frame_set
->medium_stride_next_frame_set_file_pos
= -1;
9167 frame_set
->medium_stride_prev_frame_set_file_pos
= -1;
9168 frame_set
->long_stride_next_frame_set_file_pos
= -1;
9169 frame_set
->long_stride_prev_frame_set_file_pos
= -1;
9171 frame_set
->first_frame_time
= -1;
9173 tng_data
->n_molecules
= 0;
9174 tng_data
->molecules
= 0;
9175 tng_data
->molecule_cnt_list
= 0;
9176 tng_data
->n_particles
= 0;
9179 /* Check the endianness of the computer */
9180 static int32_t endianness_32
= 0x01234567;
9182 if ( *(const unsigned char*)&endianness_32
== 0x01 )
9184 tng_data
->endianness_32
= TNG_BIG_ENDIAN_32
;
9188 else if( *(const unsigned char*)&endianness_32
== 0x67 )
9190 tng_data
->endianness_32
= TNG_LITTLE_ENDIAN_32
;
9195 else if ( *(const unsigned char*)&endianness_32
== 0x45 )
9197 tng_data
->endianness_32
= TNG_BYTE_PAIR_SWAP_32
;
9201 static int64_t endianness_64
= 0x0123456789ABCDEFLL
;
9202 /* 0x0123456789ABCDEF */
9203 if ( *(const unsigned char*)&endianness_64
== 0x01 )
9205 tng_data
->endianness_64
= TNG_BIG_ENDIAN_64
;
9208 /* 0xEFCDAB8967452301 */
9209 else if ( *(const unsigned char*)&endianness_64
== 0xEF )
9211 tng_data
->endianness_64
= TNG_LITTLE_ENDIAN_64
;
9214 /* 0x89ABCDEF01234567 */
9215 else if ( *(const unsigned char*)&endianness_64
== 0x89 )
9217 tng_data
->endianness_64
= TNG_QUAD_SWAP_64
;
9220 /* 0x45670123CDEF89AB */
9221 else if ( *(const unsigned char*)&endianness_64
== 0x45 )
9223 tng_data
->endianness_64
= TNG_BYTE_PAIR_SWAP_64
;
9226 /* 0x23016745AB89EFCD */
9227 else if ( *(const unsigned char*)&endianness_64
== 0x23 )
9229 tng_data
->endianness_64
= TNG_BYTE_SWAP_64
;
9233 /* By default do not swap the byte order, i.e. keep the byte order of the
9234 * architecture. The input file endianness will be set when reading the
9235 * header. The output endianness can be changed - before the file is
9237 tng_data
->input_endianness_swap_func_32
= 0;
9238 tng_data
->input_endianness_swap_func_64
= 0;
9239 tng_data
->output_endianness_swap_func_32
= 0;
9240 tng_data
->output_endianness_swap_func_64
= 0;
9242 tng_data
->current_trajectory_frame_set
.next_frame_set_file_pos
= -1;
9243 tng_data
->current_trajectory_frame_set
.prev_frame_set_file_pos
= -1;
9244 tng_data
->current_trajectory_frame_set
.n_frames
= 0;
9246 return(TNG_SUCCESS
);
9249 tng_function_status DECLSPECDLLEXPORT
tng_trajectory_destroy(tng_trajectory_t
*tng_data_p
)
9252 int64_t n_particles
, n_values_per_frame
;
9253 tng_trajectory_t tng_data
= *tng_data_p
;
9254 tng_trajectory_frame_set_t frame_set
;
9258 return(TNG_SUCCESS
);
9261 frame_set
= &tng_data
->current_trajectory_frame_set
;
9263 if(tng_data
->input_file_path
)
9265 free(tng_data
->input_file_path
);
9266 tng_data
->input_file_path
= 0;
9269 if(tng_data
->input_file
)
9271 fclose(tng_data
->input_file
);
9272 tng_data
->input_file
= 0;
9275 if(tng_data
->output_file_path
)
9277 free(tng_data
->output_file_path
);
9278 tng_data
->output_file_path
= 0;
9281 if(tng_data
->output_file
)
9283 /* FIXME: Do not always write the hash */
9284 tng_frame_set_finalize(tng_data
, TNG_USE_HASH
);
9285 fclose(tng_data
->output_file
);
9286 tng_data
->output_file
= 0;
9289 if(tng_data
->first_program_name
)
9291 free(tng_data
->first_program_name
);
9292 tng_data
->first_program_name
= 0;
9295 if(tng_data
->last_program_name
)
9297 free(tng_data
->last_program_name
);
9298 tng_data
->last_program_name
= 0;
9301 if(tng_data
->first_user_name
)
9303 free(tng_data
->first_user_name
);
9304 tng_data
->first_user_name
= 0;
9307 if(tng_data
->last_user_name
)
9309 free(tng_data
->last_user_name
);
9310 tng_data
->last_user_name
= 0;
9313 if(tng_data
->first_computer_name
)
9315 free(tng_data
->first_computer_name
);
9316 tng_data
->first_computer_name
= 0;
9319 if(tng_data
->last_computer_name
)
9321 free(tng_data
->last_computer_name
);
9322 tng_data
->last_computer_name
= 0;
9325 if(tng_data
->first_pgp_signature
)
9327 free(tng_data
->first_pgp_signature
);
9328 tng_data
->first_pgp_signature
= 0;
9331 if(tng_data
->last_pgp_signature
)
9333 free(tng_data
->last_pgp_signature
);
9334 tng_data
->last_pgp_signature
= 0;
9337 if(tng_data
->forcefield_name
)
9339 free(tng_data
->forcefield_name
);
9340 tng_data
->forcefield_name
= 0;
9343 tng_frame_set_particle_mapping_free(tng_data
);
9345 if(frame_set
->molecule_cnt_list
)
9347 free(frame_set
->molecule_cnt_list
);
9348 frame_set
->molecule_cnt_list
= 0;
9351 if(tng_data
->var_num_atoms_flag
)
9353 n_particles
= frame_set
->n_particles
;
9357 n_particles
= tng_data
->n_particles
;
9360 if(tng_data
->non_tr_particle_data
)
9362 for(i
= tng_data
->n_particle_data_blocks
; i
--; )
9364 if(tng_data
->non_tr_particle_data
[i
].values
)
9366 free(tng_data
->non_tr_particle_data
[i
].values
);
9367 tng_data
->non_tr_particle_data
[i
].values
= 0;
9370 if(tng_data
->non_tr_particle_data
[i
].strings
)
9372 n_values_per_frame
= tng_data
->non_tr_particle_data
[i
].
9374 if(tng_data
->non_tr_particle_data
[i
].strings
[0])
9376 for(j
= n_particles
; j
--;)
9378 if(tng_data
->non_tr_particle_data
[i
].strings
[0][j
])
9380 for(k
= n_values_per_frame
; k
--;)
9382 if(tng_data
->non_tr_particle_data
[i
].
9385 free(tng_data
->non_tr_particle_data
[i
].
9387 tng_data
->non_tr_particle_data
[i
].
9388 strings
[0][j
][k
] = 0;
9391 free(tng_data
->non_tr_particle_data
[i
].
9393 tng_data
->non_tr_particle_data
[i
].strings
[0][j
] = 0;
9396 free(tng_data
->non_tr_particle_data
[i
].strings
[0]);
9397 tng_data
->non_tr_particle_data
[i
].strings
[0] = 0;
9399 free(tng_data
->non_tr_particle_data
[i
].strings
);
9400 tng_data
->non_tr_particle_data
[i
].strings
= 0;
9403 if(tng_data
->non_tr_particle_data
[i
].block_name
)
9405 free(tng_data
->non_tr_particle_data
[i
].block_name
);
9406 tng_data
->non_tr_particle_data
[i
].block_name
= 0;
9409 free(tng_data
->non_tr_particle_data
);
9410 tng_data
->non_tr_particle_data
= 0;
9413 if(tng_data
->non_tr_data
)
9415 for(i
= tng_data
->n_data_blocks
; i
--;)
9417 if(tng_data
->non_tr_data
[i
].values
)
9419 free(tng_data
->non_tr_data
[i
].values
);
9420 tng_data
->non_tr_data
[i
].values
= 0;
9423 if(tng_data
->non_tr_data
[i
].strings
)
9425 n_values_per_frame
= tng_data
->non_tr_data
[i
].
9427 if(tng_data
->non_tr_data
[i
].strings
[0])
9429 for(j
= n_values_per_frame
; j
--;)
9431 if(tng_data
->non_tr_data
[i
].strings
[0][j
])
9433 free(tng_data
->non_tr_data
[i
].strings
[0][j
]);
9434 tng_data
->non_tr_data
[i
].strings
[0][j
] = 0;
9437 free(tng_data
->non_tr_data
[i
].strings
[0]);
9438 tng_data
->non_tr_data
[i
].strings
[0] = 0;
9440 free(tng_data
->non_tr_data
[i
].strings
);
9441 tng_data
->non_tr_data
[i
].strings
= 0;
9444 if(tng_data
->non_tr_data
[i
].block_name
)
9446 free(tng_data
->non_tr_data
[i
].block_name
);
9447 tng_data
->non_tr_data
[i
].block_name
= 0;
9450 free(tng_data
->non_tr_data
);
9451 tng_data
->non_tr_data
= 0;
9454 tng_data
->n_particle_data_blocks
= 0;
9455 tng_data
->n_data_blocks
= 0;
9457 if(tng_data
->compress_algo_pos
)
9459 free(tng_data
->compress_algo_pos
);
9460 tng_data
->compress_algo_pos
= 0;
9462 if(tng_data
->compress_algo_vel
)
9464 free(tng_data
->compress_algo_vel
);
9465 tng_data
->compress_algo_vel
= 0;
9468 if(frame_set
->tr_particle_data
)
9470 for(i
= frame_set
->n_particle_data_blocks
; i
--; )
9472 if(frame_set
->tr_particle_data
[i
].values
)
9474 free(frame_set
->tr_particle_data
[i
].values
);
9475 frame_set
->tr_particle_data
[i
].values
= 0;
9478 if(frame_set
->tr_particle_data
[i
].strings
)
9480 n_values_per_frame
= frame_set
->tr_particle_data
[i
].
9482 for(j
= frame_set
->tr_particle_data
[i
].n_frames
; j
--;)
9484 if(frame_set
->tr_particle_data
[i
].strings
[j
])
9486 for(k
= n_particles
; k
--;)
9488 if(frame_set
->tr_particle_data
[i
].
9491 for(l
= n_values_per_frame
; l
--;)
9493 if(frame_set
->tr_particle_data
[i
].
9496 free(frame_set
->tr_particle_data
[i
].
9498 frame_set
->tr_particle_data
[i
].
9499 strings
[j
][k
][l
] = 0;
9502 free(frame_set
->tr_particle_data
[i
].
9504 frame_set
->tr_particle_data
[i
].
9508 free(frame_set
->tr_particle_data
[i
].strings
[j
]);
9509 frame_set
->tr_particle_data
[i
].strings
[j
] = 0;
9512 free(frame_set
->tr_particle_data
[i
].strings
);
9513 frame_set
->tr_particle_data
[i
].strings
= 0;
9516 if(frame_set
->tr_particle_data
[i
].block_name
)
9518 free(frame_set
->tr_particle_data
[i
].block_name
);
9519 frame_set
->tr_particle_data
[i
].block_name
= 0;
9522 free(frame_set
->tr_particle_data
);
9523 frame_set
->tr_particle_data
= 0;
9526 if(frame_set
->tr_data
)
9528 for(i
= frame_set
->n_data_blocks
; i
--;)
9530 if(frame_set
->tr_data
[i
].values
)
9532 free(frame_set
->tr_data
[i
].values
);
9533 frame_set
->tr_data
[i
].values
= 0;
9536 if(frame_set
->tr_data
[i
].strings
)
9538 n_values_per_frame
= frame_set
->tr_data
[i
].
9540 for(j
= frame_set
->tr_data
[i
].n_frames
; j
--;)
9542 if(frame_set
->tr_data
[i
].strings
[j
])
9544 for(k
= n_values_per_frame
; k
--;)
9546 if(frame_set
->tr_data
[i
].strings
[j
][k
])
9548 free(frame_set
->tr_data
[i
].strings
[j
][k
]);
9549 frame_set
->tr_data
[i
].strings
[j
][k
] = 0;
9552 free(frame_set
->tr_data
[i
].strings
[j
]);
9553 frame_set
->tr_data
[i
].strings
[j
] = 0;
9556 free(frame_set
->tr_data
[i
].strings
);
9557 frame_set
->tr_data
[i
].strings
= 0;
9560 if(frame_set
->tr_data
[i
].block_name
)
9562 free(frame_set
->tr_data
[i
].block_name
);
9563 frame_set
->tr_data
[i
].block_name
= 0;
9566 free(frame_set
->tr_data
);
9567 frame_set
->tr_data
= 0;
9570 frame_set
->n_particle_data_blocks
= 0;
9571 frame_set
->n_data_blocks
= 0;
9573 if(tng_data
->molecules
)
9575 for(i
=tng_data
->n_molecules
; i
--;)
9577 tng_molecule_destroy(tng_data
, &tng_data
->molecules
[i
]);
9579 free(tng_data
->molecules
);
9580 tng_data
->molecules
= 0;
9581 tng_data
->n_molecules
= 0;
9583 if(tng_data
->molecule_cnt_list
)
9585 free(tng_data
->molecule_cnt_list
);
9586 tng_data
->molecule_cnt_list
= 0;
9592 return(TNG_SUCCESS
);
9595 tng_function_status DECLSPECDLLEXPORT
tng_trajectory_init_from_src(tng_trajectory_t src
,
9596 tng_trajectory_t
*dest_p
)
9598 tng_trajectory_frame_set_t frame_set
;
9599 tng_trajectory_t dest
;
9601 TNG_ASSERT(src
!= 0, "TNG library: Source trajectory must not be NULL.");
9603 *dest_p
= malloc(sizeof(struct tng_trajectory
));
9606 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
9607 sizeof(struct tng_trajectory
), __FILE__
, __LINE__
);
9608 return(TNG_CRITICAL
);
9613 frame_set
= &dest
->current_trajectory_frame_set
;
9615 dest
->input_file_path
= malloc(strlen(src
->input_file_path
) + 1);
9616 if(!dest
->input_file_path
)
9618 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
9619 (int)strlen(src
->input_file_path
) + 1, __FILE__
, __LINE__
);
9620 return(TNG_CRITICAL
);
9622 strcpy(dest
->input_file_path
, src
->input_file_path
);
9623 dest
->input_file
= 0;
9624 dest
->input_file_len
= src
->input_file_len
;
9625 dest
->output_file_path
= malloc(strlen(src
->output_file_path
) + 1);
9626 if(!dest
->output_file_path
)
9628 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
9629 (int)strlen(src
->output_file_path
) + 1, __FILE__
, __LINE__
);
9630 return(TNG_CRITICAL
);
9632 strcpy(dest
->output_file_path
, src
->output_file_path
);
9633 dest
->output_file
= 0;
9635 dest
->first_program_name
= 0;
9636 dest
->first_user_name
= 0;
9637 dest
->first_computer_name
= 0;
9638 dest
->first_pgp_signature
= 0;
9639 dest
->last_program_name
= 0;
9640 dest
->last_user_name
= 0;
9641 dest
->last_computer_name
= 0;
9642 dest
->last_pgp_signature
= 0;
9643 dest
->forcefield_name
= 0;
9645 dest
->var_num_atoms_flag
= src
->var_num_atoms_flag
;
9646 dest
->first_trajectory_frame_set_input_file_pos
=
9647 src
->first_trajectory_frame_set_input_file_pos
;
9648 dest
->last_trajectory_frame_set_input_file_pos
=
9649 src
->last_trajectory_frame_set_input_file_pos
;
9650 dest
->current_trajectory_frame_set_input_file_pos
=
9651 src
->current_trajectory_frame_set_input_file_pos
;
9652 dest
->first_trajectory_frame_set_output_file_pos
=
9653 src
->first_trajectory_frame_set_output_file_pos
;
9654 dest
->last_trajectory_frame_set_output_file_pos
=
9655 src
->last_trajectory_frame_set_output_file_pos
;
9656 dest
->current_trajectory_frame_set_output_file_pos
=
9657 src
->current_trajectory_frame_set_output_file_pos
;
9658 dest
->frame_set_n_frames
= src
->frame_set_n_frames
;
9659 dest
->n_trajectory_frame_sets
= src
->n_trajectory_frame_sets
;
9660 dest
->n_trajectory_blocks
= src
->n_trajectory_blocks
;
9661 dest
->medium_stride_length
= src
->medium_stride_length
;
9662 dest
->long_stride_length
= src
->long_stride_length
;
9664 dest
->time_per_frame
= src
->time_per_frame
;
9666 /* Currently the non trajectory data blocks are not copied since it
9667 * can lead to problems when freeing memory in a parallel block. */
9668 dest
->n_particle_data_blocks
= 0;
9669 dest
->n_data_blocks
= 0;
9670 dest
->non_tr_particle_data
= 0;
9671 dest
->non_tr_data
= 0;
9673 dest
->compress_algo_pos
= 0;
9674 dest
->compress_algo_vel
= 0;
9675 dest
->distance_unit_exponential
= -9;
9676 dest
->compression_precision
= 1000;
9678 frame_set
->n_mapping_blocks
= 0;
9679 frame_set
->mappings
= 0;
9680 frame_set
->molecule_cnt_list
= 0;
9682 frame_set
->n_particle_data_blocks
= 0;
9683 frame_set
->n_data_blocks
= 0;
9685 frame_set
->tr_particle_data
= 0;
9686 frame_set
->tr_data
= 0;
9688 frame_set
->next_frame_set_file_pos
= -1;
9689 frame_set
->prev_frame_set_file_pos
= -1;
9690 frame_set
->medium_stride_next_frame_set_file_pos
= -1;
9691 frame_set
->medium_stride_prev_frame_set_file_pos
= -1;
9692 frame_set
->long_stride_next_frame_set_file_pos
= -1;
9693 frame_set
->long_stride_prev_frame_set_file_pos
= -1;
9694 frame_set
->first_frame
= -1;
9696 dest
->n_molecules
= 0;
9697 dest
->molecules
= 0;
9698 dest
->molecule_cnt_list
= 0;
9699 dest
->n_particles
= src
->n_particles
;
9701 dest
->endianness_32
= src
->endianness_32
;
9702 dest
->endianness_64
= src
->endianness_64
;
9703 dest
->input_endianness_swap_func_32
= src
->input_endianness_swap_func_32
;
9704 dest
->input_endianness_swap_func_64
= src
->input_endianness_swap_func_64
;
9705 dest
->output_endianness_swap_func_32
= src
->output_endianness_swap_func_32
;
9706 dest
->output_endianness_swap_func_64
= src
->output_endianness_swap_func_64
;
9708 dest
->current_trajectory_frame_set
.next_frame_set_file_pos
= -1;
9709 dest
->current_trajectory_frame_set
.prev_frame_set_file_pos
= -1;
9710 dest
->current_trajectory_frame_set
.n_frames
= 0;
9712 return(TNG_SUCCESS
);
9715 tng_function_status DECLSPECDLLEXPORT
tng_input_file_get(const tng_trajectory_t tng_data
,
9716 char *file_name
, const int max_len
)
9718 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
9719 TNG_ASSERT(file_name
, "TNG library: file_name must not be a NULL pointer");
9721 strncpy(file_name
, tng_data
->input_file_path
, max_len
- 1);
9722 file_name
[max_len
- 1] = 0;
9724 if(strlen(tng_data
->input_file_path
) > (unsigned int)max_len
- 1)
9726 return(TNG_FAILURE
);
9728 return(TNG_SUCCESS
);
9731 tng_function_status DECLSPECDLLEXPORT
tng_input_file_set(tng_trajectory_t tng_data
,
9732 const char *file_name
)
9737 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
9738 TNG_ASSERT(file_name
, "TNG library: file_name must not be a NULL pointer");
9741 if(tng_data
->input_file_path
&& strcmp(tng_data
->input_file_path
,
9744 return(TNG_SUCCESS
);
9747 if(tng_data
->input_file
)
9749 fclose(tng_data
->input_file
);
9752 len
= tng_min_i((int)strlen(file_name
) + 1, TNG_MAX_STR_LEN
);
9753 temp
= realloc(tng_data
->input_file_path
, len
);
9756 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
9757 __FILE__
, __LINE__
);
9758 free(tng_data
->input_file_path
);
9759 tng_data
->input_file_path
= 0;
9760 return(TNG_CRITICAL
);
9762 tng_data
->input_file_path
= temp
;
9764 strncpy(tng_data
->input_file_path
, file_name
, len
);
9766 return(tng_input_file_init(tng_data
));
9769 tng_function_status
tng_output_file_get(const tng_trajectory_t tng_data
,
9770 char *file_name
, const int max_len
)
9772 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
9773 TNG_ASSERT(file_name
, "TNG library: file_name must not be a NULL pointer");
9775 strncpy(file_name
, tng_data
->output_file_path
, max_len
- 1);
9776 file_name
[max_len
- 1] = 0;
9778 if(strlen(tng_data
->output_file_path
) > (unsigned int)max_len
- 1)
9780 return(TNG_FAILURE
);
9782 return(TNG_SUCCESS
);
9785 tng_function_status DECLSPECDLLEXPORT
tng_output_file_set(tng_trajectory_t tng_data
,
9786 const char *file_name
)
9791 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
9792 TNG_ASSERT(file_name
, "TNG library: file_name must not be a NULL pointer");
9794 if(tng_data
->output_file_path
&&
9795 strcmp(tng_data
->output_file_path
, file_name
) == 0)
9797 return(TNG_SUCCESS
);
9800 if(tng_data
->output_file
)
9802 fclose(tng_data
->output_file
);
9805 len
= tng_min_i((int)strlen(file_name
) + 1, TNG_MAX_STR_LEN
);
9806 temp
= realloc(tng_data
->output_file_path
, len
);
9809 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
9810 __FILE__
, __LINE__
);
9811 free(tng_data
->output_file_path
);
9812 tng_data
->output_file_path
= 0;
9813 return(TNG_CRITICAL
);
9815 tng_data
->output_file_path
= temp
;
9817 strncpy(tng_data
->output_file_path
, file_name
, len
);
9819 return(tng_output_file_init(tng_data
));
9822 tng_function_status DECLSPECDLLEXPORT tng_output_append_file_set
9823 (tng_trajectory_t tng_data
,
9824 const char *file_name
)
9829 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
9830 TNG_ASSERT(file_name
, "TNG library: file_name must not be a NULL pointer");
9832 if(tng_data
->output_file_path
&&
9833 strcmp(tng_data
->output_file_path
, file_name
) == 0)
9835 return(TNG_SUCCESS
);
9838 if(tng_data
->output_file
)
9840 fclose(tng_data
->output_file
);
9843 len
= tng_min_i((int)strlen(file_name
) + 1, TNG_MAX_STR_LEN
);
9844 temp
= realloc(tng_data
->output_file_path
, len
);
9847 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
9848 __FILE__
, __LINE__
);
9849 free(tng_data
->output_file_path
);
9850 tng_data
->output_file_path
= 0;
9851 return(TNG_CRITICAL
);
9853 tng_data
->output_file_path
= temp
;
9855 strncpy(tng_data
->output_file_path
, file_name
, len
);
9857 tng_data
->output_file
= fopen(tng_data
->output_file_path
, "rb+");
9858 if(!tng_data
->output_file
)
9860 fprintf(stderr
, "TNG library: Cannot open file %s. %s: %d\n",
9861 tng_data
->output_file_path
, __FILE__
, __LINE__
);
9862 return(TNG_CRITICAL
);
9865 return(TNG_SUCCESS
);
9868 tng_function_status DECLSPECDLLEXPORT tng_output_file_endianness_get
9869 (const tng_trajectory_t tng_data
, tng_file_endianness
*endianness
)
9871 tng_endianness_32 end_32
;
9872 tng_endianness_64 end_64
;
9874 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
9875 TNG_ASSERT(endianness
, "TNG library: endianness must not be a NULL pointer");
9877 if(tng_data
->output_endianness_swap_func_32
)
9879 /* If other endianness variants are added they must be added here as well */
9880 if(tng_data
->output_endianness_swap_func_32
==
9881 &tng_swap_byte_order_big_endian_32
)
9883 end_32
= TNG_BIG_ENDIAN_32
;
9885 else if(tng_data
->output_endianness_swap_func_32
==
9886 &tng_swap_byte_order_little_endian_32
)
9888 end_32
= TNG_LITTLE_ENDIAN_32
;
9892 return(TNG_FAILURE
);
9897 end_32
= (tng_endianness_32
)tng_data
->endianness_32
;
9900 if(tng_data
->output_endianness_swap_func_64
)
9902 /* If other endianness variants are added they must be added here as well */
9903 if(tng_data
->output_endianness_swap_func_64
==
9904 &tng_swap_byte_order_big_endian_64
)
9906 end_64
= TNG_BIG_ENDIAN_64
;
9908 else if(tng_data
->output_endianness_swap_func_64
==
9909 &tng_swap_byte_order_little_endian_64
)
9911 end_64
= TNG_LITTLE_ENDIAN_64
;
9915 return(TNG_FAILURE
);
9920 end_64
= (tng_endianness_64
)tng_data
->endianness_64
;
9923 if((int)end_32
!= (int)end_64
)
9925 return(TNG_FAILURE
);
9928 if(end_32
== TNG_LITTLE_ENDIAN_32
)
9930 *endianness
= TNG_LITTLE_ENDIAN
;
9933 else if(end_32
== TNG_BIG_ENDIAN_32
)
9935 *endianness
= TNG_BIG_ENDIAN
;
9939 return(TNG_FAILURE
);
9942 return(TNG_SUCCESS
);
9945 tng_function_status DECLSPECDLLEXPORT tng_output_file_endianness_set
9946 (tng_trajectory_t tng_data
,
9947 const tng_file_endianness endianness
)
9949 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
9951 /* Tne endianness cannot be changed if the data has already been written
9952 * to the output file. */
9953 if(ftell(tng_data
->output_file
) > 0)
9955 return(TNG_FAILURE
);
9958 if(endianness
== TNG_BIG_ENDIAN
)
9960 if(tng_data
->endianness_32
== TNG_BIG_ENDIAN_32
)
9962 tng_data
->output_endianness_swap_func_32
= 0;
9966 tng_data
->output_endianness_swap_func_32
=
9967 &tng_swap_byte_order_big_endian_32
;
9969 if(tng_data
->endianness_64
== TNG_BIG_ENDIAN_64
)
9971 tng_data
->output_endianness_swap_func_64
= 0;
9975 tng_data
->output_endianness_swap_func_64
=
9976 &tng_swap_byte_order_big_endian_64
;
9978 return(TNG_SUCCESS
);
9980 else if(endianness
== TNG_LITTLE_ENDIAN
)
9982 if(tng_data
->endianness_32
== TNG_LITTLE_ENDIAN_32
)
9984 tng_data
->output_endianness_swap_func_32
= 0;
9988 tng_data
->output_endianness_swap_func_32
=
9989 &tng_swap_byte_order_little_endian_32
;
9991 if(tng_data
->endianness_64
== TNG_LITTLE_ENDIAN_64
)
9993 tng_data
->output_endianness_swap_func_64
= 0;
9997 tng_data
->output_endianness_swap_func_64
=
9998 &tng_swap_byte_order_little_endian_64
;
10000 return(TNG_SUCCESS
);
10003 /* If the specified endianness is neither big nor little endian return a
10005 return(TNG_FAILURE
);
10008 tng_function_status DECLSPECDLLEXPORT tng_first_program_name_get
10009 (const tng_trajectory_t tng_data
,
10010 char *name
, const int max_len
)
10012 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10013 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
10015 strncpy(name
, tng_data
->first_program_name
, max_len
- 1);
10016 name
[max_len
- 1] = 0;
10018 if(strlen(tng_data
->first_program_name
) > (unsigned int)max_len
- 1)
10020 return(TNG_FAILURE
);
10022 return(TNG_SUCCESS
);
10025 tng_function_status DECLSPECDLLEXPORT
tng_first_program_name_set(tng_trajectory_t tng_data
,
10026 const char *new_name
)
10030 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10031 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer");
10033 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
10035 if(tng_data
->first_program_name
&& strlen(tng_data
->first_program_name
) < len
)
10037 free(tng_data
->first_program_name
);
10038 tng_data
->first_program_name
= 0;
10040 if(!tng_data
->first_program_name
)
10042 tng_data
->first_program_name
= malloc(len
);
10043 if(!tng_data
->first_program_name
)
10045 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
10046 __FILE__
, __LINE__
);
10047 return(TNG_CRITICAL
);
10051 strncpy(tng_data
->first_program_name
, new_name
, len
);
10053 return(TNG_SUCCESS
);
10056 tng_function_status DECLSPECDLLEXPORT tng_last_program_name_get
10057 (const tng_trajectory_t tng_data
,
10058 char *name
, const int max_len
)
10060 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10061 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
10063 strncpy(name
, tng_data
->last_program_name
, max_len
- 1);
10064 name
[max_len
- 1] = 0;
10066 if(strlen(tng_data
->last_program_name
) > (unsigned int)max_len
- 1)
10068 return(TNG_FAILURE
);
10070 return(TNG_SUCCESS
);
10073 tng_function_status DECLSPECDLLEXPORT tng_last_program_name_set
10074 (tng_trajectory_t tng_data
,
10075 const char *new_name
)
10079 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10080 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer");
10082 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
10084 if(tng_data
->last_program_name
&& strlen(tng_data
->last_program_name
) < len
)
10086 free(tng_data
->last_program_name
);
10087 tng_data
->last_program_name
= 0;
10089 if(!tng_data
->last_program_name
)
10091 tng_data
->last_program_name
= malloc(len
);
10092 if(!tng_data
->last_program_name
)
10094 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
10095 __FILE__
, __LINE__
);
10096 return(TNG_CRITICAL
);
10100 strncpy(tng_data
->last_program_name
, new_name
, len
);
10102 return(TNG_SUCCESS
);
10105 tng_function_status DECLSPECDLLEXPORT tng_first_user_name_get
10106 (const tng_trajectory_t tng_data
,
10107 char *name
, const int max_len
)
10109 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10110 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
10112 strncpy(name
, tng_data
->first_user_name
, max_len
- 1);
10113 name
[max_len
- 1] = 0;
10115 if(strlen(tng_data
->first_user_name
) > (unsigned int)max_len
- 1)
10117 return(TNG_FAILURE
);
10119 return(TNG_SUCCESS
);
10122 tng_function_status DECLSPECDLLEXPORT tng_first_user_name_set
10123 (tng_trajectory_t tng_data
,
10124 const char *new_name
)
10128 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10129 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer");
10131 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
10133 /* If the currently stored string length is not enough to store the new
10134 * string it is freed and reallocated. */
10135 if(tng_data
->first_user_name
&& strlen(tng_data
->first_user_name
) < len
)
10137 free(tng_data
->first_user_name
);
10138 tng_data
->first_user_name
= 0;
10140 if(!tng_data
->first_user_name
)
10142 tng_data
->first_user_name
= malloc(len
);
10143 if(!tng_data
->first_user_name
)
10145 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
10146 __FILE__
, __LINE__
);
10147 return(TNG_CRITICAL
);
10151 strncpy(tng_data
->first_user_name
, new_name
, len
);
10153 return(TNG_SUCCESS
);
10156 tng_function_status DECLSPECDLLEXPORT tng_last_user_name_get
10157 (const tng_trajectory_t tng_data
,
10158 char *name
, const int max_len
)
10160 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10161 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
10163 strncpy(name
, tng_data
->last_user_name
, max_len
- 1);
10164 name
[max_len
- 1] = 0;
10166 if(strlen(tng_data
->last_user_name
) > (unsigned int)max_len
- 1)
10168 return(TNG_FAILURE
);
10170 return(TNG_SUCCESS
);
10173 tng_function_status DECLSPECDLLEXPORT tng_last_user_name_set
10174 (tng_trajectory_t tng_data
,
10175 const char *new_name
)
10179 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10180 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer");
10182 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
10184 /* If the currently stored string length is not enough to store the new
10185 * string it is freed and reallocated. */
10186 if(tng_data
->last_user_name
&& strlen(tng_data
->last_user_name
) < len
)
10188 free(tng_data
->last_user_name
);
10189 tng_data
->last_user_name
= 0;
10191 if(!tng_data
->last_user_name
)
10193 tng_data
->last_user_name
= malloc(len
);
10194 if(!tng_data
->last_user_name
)
10196 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
10197 __FILE__
, __LINE__
);
10198 return(TNG_CRITICAL
);
10202 strncpy(tng_data
->last_user_name
, new_name
, len
);
10204 return(TNG_SUCCESS
);
10207 tng_function_status DECLSPECDLLEXPORT tng_first_computer_name_get
10208 (const tng_trajectory_t tng_data
,
10209 char *name
, const int max_len
)
10211 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10212 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
10214 strncpy(name
, tng_data
->first_computer_name
, max_len
- 1);
10215 name
[max_len
- 1] = 0;
10217 if(strlen(tng_data
->first_computer_name
) > (unsigned int)max_len
- 1)
10219 return(TNG_FAILURE
);
10221 return(TNG_SUCCESS
);
10224 tng_function_status DECLSPECDLLEXPORT tng_first_computer_name_set
10225 (tng_trajectory_t tng_data
,
10226 const char *new_name
)
10230 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10231 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer");
10233 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
10235 /* If the currently stored string length is not enough to store the new
10236 * string it is freed and reallocated. */
10237 if(tng_data
->first_computer_name
&& strlen(tng_data
->first_computer_name
) < len
)
10239 free(tng_data
->first_computer_name
);
10240 tng_data
->first_computer_name
= 0;
10242 if(!tng_data
->first_computer_name
)
10244 tng_data
->first_computer_name
= malloc(len
);
10245 if(!tng_data
->first_computer_name
)
10247 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
10248 __FILE__
, __LINE__
);
10249 return(TNG_CRITICAL
);
10253 strncpy(tng_data
->first_computer_name
, new_name
, len
);
10255 return(TNG_SUCCESS
);
10258 tng_function_status DECLSPECDLLEXPORT tng_last_computer_name_get
10259 (const tng_trajectory_t tng_data
,
10260 char *name
, const int max_len
)
10262 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10263 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
10265 strncpy(name
, tng_data
->last_computer_name
, max_len
- 1);
10266 name
[max_len
- 1] = 0;
10268 if(strlen(tng_data
->last_computer_name
) > (unsigned int)max_len
- 1)
10270 return(TNG_FAILURE
);
10272 return(TNG_SUCCESS
);
10275 tng_function_status DECLSPECDLLEXPORT tng_last_computer_name_set
10276 (tng_trajectory_t tng_data
,
10277 const char *new_name
)
10281 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10282 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer");
10284 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
10286 /* If the currently stored string length is not enough to store the new
10287 * string it is freed and reallocated. */
10288 if(tng_data
->last_computer_name
&& strlen(tng_data
->last_computer_name
) <
10291 free(tng_data
->last_computer_name
);
10292 tng_data
->last_computer_name
= 0;
10294 if(!tng_data
->last_computer_name
)
10296 tng_data
->last_computer_name
= malloc(len
);
10297 if(!tng_data
->last_computer_name
)
10299 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
10300 __FILE__
, __LINE__
);
10301 return(TNG_CRITICAL
);
10305 strncpy(tng_data
->last_computer_name
, new_name
, len
);
10307 return(TNG_SUCCESS
);
10310 tng_function_status DECLSPECDLLEXPORT tng_first_signature_get
10311 (const tng_trajectory_t tng_data
,
10312 char *signature
, const int max_len
)
10314 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10315 TNG_ASSERT(signature
, "TNG library: signature must not be a NULL pointer");
10317 strncpy(signature
, tng_data
->first_pgp_signature
, max_len
- 1);
10318 signature
[max_len
- 1] = 0;
10320 if(strlen(tng_data
->first_pgp_signature
) > (unsigned int)max_len
- 1)
10322 return(TNG_FAILURE
);
10324 return(TNG_SUCCESS
);
10327 tng_function_status DECLSPECDLLEXPORT tng_first_signature_set
10328 (tng_trajectory_t tng_data
,
10329 const char *signature
)
10333 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10334 TNG_ASSERT(signature
, "TNG library: signature must not be a NULL pointer");
10336 len
= tng_min_i((int)strlen(signature
) + 1, TNG_MAX_STR_LEN
);
10338 /* If the currently stored string length is not enough to store the new
10339 * string it is freed and reallocated. */
10340 if(tng_data
->first_pgp_signature
&& strlen(tng_data
->first_pgp_signature
) <
10343 free(tng_data
->first_pgp_signature
);
10344 tng_data
->first_pgp_signature
= 0;
10346 if(!tng_data
->first_pgp_signature
)
10348 tng_data
->first_pgp_signature
= malloc(len
);
10349 if(!tng_data
->first_pgp_signature
)
10351 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
10352 __FILE__
, __LINE__
);
10353 return(TNG_CRITICAL
);
10357 strncpy(tng_data
->first_pgp_signature
, signature
, len
);
10359 return(TNG_SUCCESS
);
10362 tng_function_status DECLSPECDLLEXPORT tng_last_signature_get
10363 (const tng_trajectory_t tng_data
,
10364 char *signature
, const int max_len
)
10366 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10367 TNG_ASSERT(signature
, "TNG library: signature must not be a NULL pointer");
10369 strncpy(signature
, tng_data
->last_pgp_signature
, max_len
- 1);
10370 signature
[max_len
- 1] = 0;
10372 if(strlen(tng_data
->last_pgp_signature
) > (unsigned int)max_len
- 1)
10374 return(TNG_FAILURE
);
10376 return(TNG_SUCCESS
);
10379 tng_function_status DECLSPECDLLEXPORT tng_last_signature_set
10380 (tng_trajectory_t tng_data
,
10381 const char *signature
)
10385 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10386 TNG_ASSERT(signature
, "TNG library: signature must not be a NULL pointer");
10388 len
= tng_min_i((int)strlen(signature
) + 1, TNG_MAX_STR_LEN
);
10390 /* If the currently stored string length is not enough to store the new
10391 * string it is freed and reallocated. */
10392 if(tng_data
->last_pgp_signature
&& strlen(tng_data
->last_pgp_signature
) <
10395 free(tng_data
->last_pgp_signature
);
10396 tng_data
->last_pgp_signature
= 0;
10398 if(!tng_data
->last_pgp_signature
)
10400 tng_data
->last_pgp_signature
= malloc(len
);
10401 if(!tng_data
->last_pgp_signature
)
10403 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
10404 __FILE__
, __LINE__
);
10405 return(TNG_CRITICAL
);
10409 strncpy(tng_data
->last_pgp_signature
, signature
, len
);
10411 return(TNG_SUCCESS
);
10414 tng_function_status DECLSPECDLLEXPORT tng_forcefield_name_get
10415 (const tng_trajectory_t tng_data
,
10416 char *name
, const int max_len
)
10418 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10419 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
10421 strncpy(name
, tng_data
->forcefield_name
, max_len
- 1);
10422 name
[max_len
- 1] = 0;
10424 if(strlen(tng_data
->forcefield_name
) > (unsigned int)max_len
- 1)
10426 return(TNG_FAILURE
);
10428 return(TNG_SUCCESS
);
10431 tng_function_status DECLSPECDLLEXPORT tng_forcefield_name_set
10432 (tng_trajectory_t tng_data
,
10433 const char *new_name
)
10437 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10438 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer");
10440 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
10442 /* If the currently stored string length is not enough to store the new
10443 * string it is freed and reallocated. */
10444 if(tng_data
->forcefield_name
&& strlen(tng_data
->forcefield_name
) < len
)
10446 free(tng_data
->forcefield_name
);
10447 tng_data
->forcefield_name
= 0;
10449 if(!tng_data
->forcefield_name
)
10451 tng_data
->forcefield_name
= malloc(len
);
10452 if(!tng_data
->forcefield_name
)
10454 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
10455 __FILE__
, __LINE__
);
10456 return(TNG_CRITICAL
);
10460 strncpy(tng_data
->forcefield_name
, new_name
, len
);
10462 return(TNG_SUCCESS
);
10465 tng_function_status DECLSPECDLLEXPORT tng_medium_stride_length_get
10466 (const tng_trajectory_t tng_data
,
10469 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10470 TNG_ASSERT(len
, "TNG library: len must not be a NULL pointer");
10472 *len
= tng_data
->medium_stride_length
;
10474 return(TNG_SUCCESS
);
10477 tng_function_status DECLSPECDLLEXPORT tng_medium_stride_length_set
10478 (tng_trajectory_t tng_data
,
10481 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10483 if(len
>= tng_data
->long_stride_length
)
10485 return(TNG_FAILURE
);
10487 tng_data
->medium_stride_length
= len
;
10489 return(TNG_SUCCESS
);
10492 tng_function_status DECLSPECDLLEXPORT tng_long_stride_length_get
10493 (const tng_trajectory_t tng_data
,
10496 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10497 TNG_ASSERT(len
, "TNG library: len must not be a NULL pointer");
10499 *len
= tng_data
->long_stride_length
;
10501 return(TNG_SUCCESS
);
10504 tng_function_status DECLSPECDLLEXPORT tng_long_stride_length_set
10505 (tng_trajectory_t tng_data
,
10508 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10510 if(len
<= tng_data
->medium_stride_length
)
10512 return(TNG_FAILURE
);
10514 tng_data
->long_stride_length
= len
;
10516 return(TNG_SUCCESS
);
10519 tng_function_status DECLSPECDLLEXPORT tng_time_per_frame_get
10520 (const tng_trajectory_t tng_data
,
10523 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10524 TNG_ASSERT(time
, "TNG library: time must not be a NULL pointer");
10526 *time
= tng_data
->time_per_frame
;
10528 return(TNG_SUCCESS
);
10531 tng_function_status DECLSPECDLLEXPORT tng_time_per_frame_set
10532 (tng_trajectory_t tng_data
,
10535 tng_trajectory_frame_set_t frame_set
;
10537 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10538 TNG_ASSERT(time
>= 0, "TNG library: The time per frame must be >= 0.");
10540 if(fabs(time
- tng_data
->time_per_frame
) < 0.00001)
10542 return(TNG_SUCCESS
);
10545 frame_set
= &tng_data
->current_trajectory_frame_set
;
10547 /* If the current frame set is not finished write it to disk before
10548 changing time per frame. */
10549 if(tng_data
->time_per_frame
> 0 && frame_set
->n_unwritten_frames
> 0)
10551 frame_set
->n_frames
= frame_set
->n_unwritten_frames
;
10552 tng_frame_set_write(tng_data
, TNG_USE_HASH
);
10554 tng_data
->time_per_frame
= time
;
10556 return(TNG_SUCCESS
);
10559 tng_function_status DECLSPECDLLEXPORT tng_input_file_len_get
10560 (const tng_trajectory_t tng_data
,
10563 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10564 TNG_ASSERT(len
, "TNG library: len must not be a NULL pointer");
10566 *len
= tng_data
->input_file_len
;
10568 return(TNG_SUCCESS
);
10571 tng_function_status DECLSPECDLLEXPORT tng_num_frames_get
10572 (const tng_trajectory_t tng_data
,
10575 tng_gen_block_t block
;
10576 tng_function_status stat
;
10578 int64_t last_file_pos
, first_frame
, n_frames
;
10580 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10581 TNG_ASSERT(tng_data
->input_file
, "TNG library: An input file must be open to find the next frame set");
10582 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
10584 file_pos
= ftell(tng_data
->input_file
);
10585 last_file_pos
= tng_data
->last_trajectory_frame_set_input_file_pos
;
10587 if(last_file_pos
<= 0)
10589 return(TNG_FAILURE
);
10592 tng_block_init(&block
);
10593 fseek(tng_data
->input_file
,
10594 (long)last_file_pos
,
10596 /* Read block headers first to see that a frame set block is found. */
10597 stat
= tng_block_header_read(tng_data
, block
);
10598 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
10600 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n", last_file_pos
,
10601 __FILE__
, __LINE__
);
10602 tng_block_destroy(&block
);
10603 return(TNG_FAILURE
);
10605 tng_block_destroy(&block
);
10607 if(fread(&first_frame
, sizeof(int64_t), 1, tng_data
->input_file
) == 0)
10609 fprintf(stderr
, "TNG library: Cannot read first frame of frame set. %s: %d\n",
10610 __FILE__
, __LINE__
);
10611 return(TNG_CRITICAL
);
10613 if(fread(&n_frames
, sizeof(int64_t), 1, tng_data
->input_file
) == 0)
10615 fprintf(stderr
, "TNG library: Cannot read n frames of frame set. %s: %d\n",
10616 __FILE__
, __LINE__
);
10617 return(TNG_CRITICAL
);
10619 fseek(tng_data
->input_file
, file_pos
, SEEK_SET
);
10621 *n
= first_frame
+ n_frames
;
10623 return(TNG_SUCCESS
);
10626 tng_function_status DECLSPECDLLEXPORT tng_compression_precision_get
10627 (const tng_trajectory_t tng_data
,
10630 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10632 *precision
= tng_data
->compression_precision
;
10634 return(TNG_SUCCESS
);
10637 tng_function_status DECLSPECDLLEXPORT tng_compression_precision_set
10638 (tng_trajectory_t tng_data
,
10639 const double precision
)
10641 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10643 tng_data
->compression_precision
= precision
;
10645 return(TNG_SUCCESS
);
10648 tng_function_status DECLSPECDLLEXPORT tng_implicit_num_particles_set
10649 (tng_trajectory_t tng_data
,
10652 tng_molecule_t mol
;
10656 tng_function_status stat
;
10657 int64_t diff
, n_mod
, n_impl
;
10659 TNG_ASSERT(n
>= 0, "TNG library: The number of molecules must be >= 0");
10661 diff
= n
- tng_data
->n_particles
;
10663 stat
= tng_molecule_find(tng_data
, "TNG_IMPLICIT_MOL", -1, &mol
);
10664 if(stat
== TNG_SUCCESS
)
10666 if(tng_molecule_cnt_get(tng_data
, mol
, &n_impl
) != TNG_SUCCESS
)
10668 fprintf(stderr
, "TNG library: Cannot get the number of implicit molecules. %s: %d\n",
10669 __FILE__
, __LINE__
);
10670 return(TNG_FAILURE
);
10672 diff
-= n_impl
* mol
->n_atoms
;
10677 if(stat
== TNG_SUCCESS
)
10679 stat
= tng_molecule_cnt_set(tng_data
, mol
, 0);
10682 return(TNG_SUCCESS
);
10686 fprintf(stderr
, "TNG library: Already more actual particles than requested implicit ");
10687 fprintf(stderr
, "particle count.\n");
10688 fprintf(stderr
, "TNG library: Cannot set implicit particle count. %s: %d\n",
10689 __FILE__
, __LINE__
);
10690 /* FIXME: Should we set the count of all other molecules to 0 and add
10691 * implicit molecules? */
10692 return(TNG_FAILURE
);
10694 if(stat
!= TNG_SUCCESS
)
10696 stat
= tng_molecule_add(tng_data
,
10697 "TNG_IMPLICIT_MOL",
10699 if(stat
!= TNG_SUCCESS
)
10703 stat
= tng_molecule_chain_add(tng_data
, mol
, "", &chain
);
10704 if(stat
!= TNG_SUCCESS
)
10708 stat
= tng_chain_residue_add(tng_data
, chain
, "", &res
);
10709 if(stat
!= TNG_SUCCESS
)
10713 stat
= tng_residue_atom_add(tng_data
, res
, "", "", &atom
);
10714 if(stat
!= TNG_SUCCESS
)
10721 if(mol
->n_atoms
> 1)
10723 n_mod
= diff
% mol
->n_atoms
;
10726 fprintf(stderr
, "TNG library: Number of atoms in implicit molecule ");
10727 fprintf(stderr
, "not compatible with requested implicit particle cnt.\n");
10728 fprintf(stderr
, "TNG library: Cannot set implicit particle count. %s: %d\n",
10729 __FILE__
, __LINE__
);
10730 return(TNG_FAILURE
);
10732 diff
/= mol
->n_atoms
;
10735 stat
= tng_molecule_cnt_set(tng_data
, mol
, diff
);
10740 tng_function_status DECLSPECDLLEXPORT tng_num_particles_get
10741 (const tng_trajectory_t tng_data
,
10744 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10745 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
10747 if(tng_data
->var_num_atoms_flag
== TNG_CONSTANT_N_ATOMS
)
10749 *n
= tng_data
->n_particles
;
10753 *n
= tng_data
->current_trajectory_frame_set
.n_particles
;
10756 return(TNG_SUCCESS
);
10759 tng_function_status DECLSPECDLLEXPORT tng_num_particles_variable_get
10760 (const tng_trajectory_t tng_data
,
10763 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10764 TNG_ASSERT(variable
, "TNG library: variable must not be a NULL pointer");
10766 *variable
= tng_data
->var_num_atoms_flag
;
10768 return(TNG_SUCCESS
);
10771 tng_function_status DECLSPECDLLEXPORT tng_num_molecule_types_get
10772 (const tng_trajectory_t tng_data
,
10775 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10776 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
10778 *n
= tng_data
->n_molecules
;
10780 return(TNG_SUCCESS
);
10783 tng_function_status DECLSPECDLLEXPORT tng_num_molecules_get
10784 (const tng_trajectory_t tng_data
,
10787 int64_t *cnt_list
= 0, cnt
= 0, i
;
10789 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10790 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
10792 tng_molecule_cnt_list_get(tng_data
, &cnt_list
);
10796 return(TNG_FAILURE
);
10799 for(i
= tng_data
->n_molecules
; i
--;)
10801 cnt
+= cnt_list
[i
];
10806 return(TNG_SUCCESS
);
10809 tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_list_get
10810 (const tng_trajectory_t tng_data
,
10811 int64_t **mol_cnt_list
)
10813 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10815 if(tng_data
->var_num_atoms_flag
)
10817 *mol_cnt_list
= tng_data
->current_trajectory_frame_set
.
10822 *mol_cnt_list
= tng_data
->molecule_cnt_list
;
10824 if(*mol_cnt_list
== 0)
10826 return(TNG_FAILURE
);
10828 return(TNG_SUCCESS
);
10831 tng_function_status DECLSPECDLLEXPORT tng_distance_unit_exponential_get
10832 (const tng_trajectory_t tng_data
,
10835 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10836 TNG_ASSERT(exp
, "TNG library: exp must not be a NULL pointer");
10838 *exp
= tng_data
->distance_unit_exponential
;
10840 return(TNG_SUCCESS
);
10843 tng_function_status DECLSPECDLLEXPORT tng_distance_unit_exponential_set
10844 (const tng_trajectory_t tng_data
,
10847 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10849 tng_data
->distance_unit_exponential
= exp
;
10851 return(TNG_SUCCESS
);
10854 tng_function_status DECLSPECDLLEXPORT tng_num_frames_per_frame_set_get
10855 (const tng_trajectory_t tng_data
,
10858 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10859 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
10861 *n
= tng_data
->frame_set_n_frames
;
10863 return(TNG_SUCCESS
);
10866 tng_function_status DECLSPECDLLEXPORT tng_num_frames_per_frame_set_set
10867 (const tng_trajectory_t tng_data
,
10870 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10872 tng_data
->frame_set_n_frames
= n
;
10874 return(TNG_SUCCESS
);
10877 tng_function_status DECLSPECDLLEXPORT tng_num_frame_sets_get
10878 (const tng_trajectory_t tng_data
,
10881 int64_t long_stride_length
, medium_stride_length
;
10882 long file_pos
, orig_frame_set_file_pos
;
10883 tng_trajectory_frame_set_t frame_set
;
10884 struct tng_trajectory_frame_set orig_frame_set
;
10885 tng_gen_block_t block
;
10886 tng_function_status stat
;
10889 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10890 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
10892 orig_frame_set
= tng_data
->current_trajectory_frame_set
;
10894 frame_set
= &tng_data
->current_trajectory_frame_set
;
10896 orig_frame_set_file_pos
= tng_data
->current_trajectory_frame_set_input_file_pos
;
10897 file_pos
= (long)tng_data
->first_trajectory_frame_set_input_file_pos
;
10899 tng_block_init(&block
);
10900 fseek(tng_data
->input_file
,
10903 tng_data
->current_trajectory_frame_set_input_file_pos
= file_pos
;
10904 /* Read block headers first to see what block is found. */
10905 stat
= tng_block_header_read(tng_data
, block
);
10906 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
10908 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n", file_pos
,
10909 __FILE__
, __LINE__
);
10910 tng_block_destroy(&block
);
10911 return(TNG_CRITICAL
);
10914 if(tng_block_read_next(tng_data
, block
,
10915 TNG_SKIP_HASH
) != TNG_SUCCESS
)
10917 tng_block_destroy(&block
);
10918 return(TNG_CRITICAL
);
10923 long_stride_length
= tng_data
->long_stride_length
;
10924 medium_stride_length
= tng_data
->medium_stride_length
;
10926 /* Take long steps forward until a long step forward would be too long or
10927 * the last frame set is found */
10928 file_pos
= (long)frame_set
->long_stride_next_frame_set_file_pos
;
10929 while(file_pos
> 0)
10933 cnt
+= long_stride_length
;
10934 fseek(tng_data
->input_file
, file_pos
, SEEK_SET
);
10935 /* Read block headers first to see what block is found. */
10936 stat
= tng_block_header_read(tng_data
, block
);
10937 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
10939 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
10940 file_pos
, __FILE__
, __LINE__
);
10941 tng_block_destroy(&block
);
10942 return(TNG_CRITICAL
);
10945 if(tng_block_read_next(tng_data
, block
,
10946 TNG_SKIP_HASH
) != TNG_SUCCESS
)
10948 tng_block_destroy(&block
);
10949 return(TNG_CRITICAL
);
10952 file_pos
= (long)frame_set
->long_stride_next_frame_set_file_pos
;
10955 /* Take medium steps forward until a medium step forward would be too long
10956 * or the last frame set is found */
10957 file_pos
= (long)frame_set
->medium_stride_next_frame_set_file_pos
;
10958 while(file_pos
> 0)
10962 cnt
+= medium_stride_length
;
10963 fseek(tng_data
->input_file
,
10966 /* Read block headers first to see what block is found. */
10967 stat
= tng_block_header_read(tng_data
, block
);
10968 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
10970 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
10971 file_pos
, __FILE__
, __LINE__
);
10972 tng_block_destroy(&block
);
10973 return(TNG_CRITICAL
);
10976 if(tng_block_read_next(tng_data
, block
,
10977 TNG_SKIP_HASH
) != TNG_SUCCESS
)
10979 tng_block_destroy(&block
);
10980 return(TNG_CRITICAL
);
10983 file_pos
= (long)frame_set
->medium_stride_next_frame_set_file_pos
;
10986 /* Take one step forward until the last frame set is found */
10987 file_pos
= (long)frame_set
->next_frame_set_file_pos
;
10988 while(file_pos
> 0)
10993 fseek(tng_data
->input_file
,
10996 /* Read block headers first to see what block is found. */
10997 stat
= tng_block_header_read(tng_data
, block
);
10998 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11000 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
11001 file_pos
, __FILE__
, __LINE__
);
11002 tng_block_destroy(&block
);
11003 return(TNG_CRITICAL
);
11006 if(tng_block_read_next(tng_data
, block
,
11007 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11009 tng_block_destroy(&block
);
11010 return(TNG_CRITICAL
);
11013 file_pos
= (long)frame_set
->next_frame_set_file_pos
;
11016 tng_block_destroy(&block
);
11018 *n
= tng_data
->n_trajectory_frame_sets
= cnt
;
11020 *frame_set
= orig_frame_set
;
11022 fseek(tng_data
->input_file
,
11023 (long)tng_data
->first_trajectory_frame_set_input_file_pos
,
11026 tng_data
->current_trajectory_frame_set_input_file_pos
= orig_frame_set_file_pos
;
11028 return(TNG_SUCCESS
);
11031 tng_function_status DECLSPECDLLEXPORT tng_current_frame_set_get
11032 (const tng_trajectory_t tng_data
,
11033 tng_trajectory_frame_set_t
*frame_set_p
)
11035 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
11037 *frame_set_p
= &tng_data
->current_trajectory_frame_set
;
11039 return(TNG_SUCCESS
);
11042 tng_function_status DECLSPECDLLEXPORT tng_frame_set_nr_find
11043 (tng_trajectory_t tng_data
,
11046 int64_t long_stride_length
, medium_stride_length
;
11047 int64_t file_pos
, curr_nr
= 0, n_frame_sets
;
11048 tng_trajectory_frame_set_t frame_set
;
11049 tng_gen_block_t block
;
11050 tng_function_status stat
;
11052 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
11053 TNG_ASSERT(nr
>= 0, "The frame set number (nr) must be >= 0");
11055 frame_set
= &tng_data
->current_trajectory_frame_set
;
11057 stat
= tng_num_frame_sets_get(tng_data
, &n_frame_sets
);
11059 if(stat
!= TNG_SUCCESS
)
11064 if(nr
>= n_frame_sets
)
11066 return(TNG_FAILURE
);
11069 long_stride_length
= tng_data
->long_stride_length
;
11070 medium_stride_length
= tng_data
->medium_stride_length
;
11072 /* FIXME: The frame set number of the current frame set is not stored */
11074 if(nr
< n_frame_sets
- 1 - nr
)
11076 /* Start from the beginning */
11077 file_pos
= tng_data
->first_trajectory_frame_set_input_file_pos
;
11081 /* Start from the end */
11082 file_pos
= tng_data
->last_trajectory_frame_set_input_file_pos
;
11083 curr_nr
= n_frame_sets
- 1;
11087 return(TNG_FAILURE
);
11090 tng_block_init(&block
);
11091 fseek(tng_data
->input_file
,
11094 tng_data
->current_trajectory_frame_set_input_file_pos
= (long)file_pos
;
11095 /* Read block headers first to see what block is found. */
11096 stat
= tng_block_header_read(tng_data
, block
);
11097 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11099 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n", file_pos
,
11100 __FILE__
, __LINE__
);
11101 tng_block_destroy(&block
);
11102 return(TNG_CRITICAL
);
11105 if(tng_block_read_next(tng_data
, block
,
11106 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11108 tng_block_destroy(&block
);
11109 return(TNG_CRITICAL
);
11114 tng_block_destroy(&block
);
11115 return(TNG_SUCCESS
);
11118 file_pos
= tng_data
->current_trajectory_frame_set_input_file_pos
;
11120 /* Take long steps forward until a long step forward would be too long or
11121 * the right frame set is found */
11122 while(file_pos
> 0 && curr_nr
+ long_stride_length
<= nr
)
11124 file_pos
= frame_set
->long_stride_next_frame_set_file_pos
;
11127 curr_nr
+= long_stride_length
;
11128 fseek(tng_data
->input_file
, (long)file_pos
, SEEK_SET
);
11129 /* Read block headers first to see what block is found. */
11130 stat
= tng_block_header_read(tng_data
, block
);
11131 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11133 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11134 file_pos
, __FILE__
, __LINE__
);
11135 tng_block_destroy(&block
);
11136 return(TNG_CRITICAL
);
11139 if(tng_block_read_next(tng_data
, block
,
11140 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11142 tng_block_destroy(&block
);
11143 return(TNG_CRITICAL
);
11147 tng_block_destroy(&block
);
11148 return(TNG_SUCCESS
);
11153 /* Take medium steps forward until a medium step forward would be too long
11154 * or the right frame set is found */
11155 while(file_pos
> 0 && curr_nr
+ medium_stride_length
<= nr
)
11157 file_pos
= frame_set
->medium_stride_next_frame_set_file_pos
;
11160 curr_nr
+= medium_stride_length
;
11161 fseek(tng_data
->input_file
,
11164 /* Read block headers first to see what block is found. */
11165 stat
= tng_block_header_read(tng_data
, block
);
11166 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11168 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11169 file_pos
, __FILE__
, __LINE__
);
11170 tng_block_destroy(&block
);
11171 return(TNG_CRITICAL
);
11174 if(tng_block_read_next(tng_data
, block
,
11175 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11177 tng_block_destroy(&block
);
11178 return(TNG_CRITICAL
);
11182 tng_block_destroy(&block
);
11183 return(TNG_SUCCESS
);
11188 /* Take one step forward until the right frame set is found */
11189 while(file_pos
> 0 && curr_nr
< nr
)
11191 file_pos
= frame_set
->next_frame_set_file_pos
;
11196 fseek(tng_data
->input_file
,
11199 /* Read block headers first to see what block is found. */
11200 stat
= tng_block_header_read(tng_data
, block
);
11201 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11203 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11204 file_pos
, __FILE__
, __LINE__
);
11205 tng_block_destroy(&block
);
11206 return(TNG_CRITICAL
);
11209 if(tng_block_read_next(tng_data
, block
,
11210 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11212 tng_block_destroy(&block
);
11213 return(TNG_CRITICAL
);
11217 tng_block_destroy(&block
);
11218 return(TNG_SUCCESS
);
11223 /* Take long steps backward until a long step backward would be too long
11224 * or the right frame set is found */
11225 while(file_pos
> 0 && curr_nr
- long_stride_length
>= nr
)
11227 file_pos
= frame_set
->long_stride_prev_frame_set_file_pos
;
11230 curr_nr
-= long_stride_length
;
11231 fseek(tng_data
->input_file
,
11234 /* Read block headers first to see what block is found. */
11235 stat
= tng_block_header_read(tng_data
, block
);
11236 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11238 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11239 file_pos
, __FILE__
, __LINE__
);
11240 tng_block_destroy(&block
);
11241 return(TNG_CRITICAL
);
11244 if(tng_block_read_next(tng_data
, block
,
11245 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11247 tng_block_destroy(&block
);
11248 return(TNG_CRITICAL
);
11252 tng_block_destroy(&block
);
11253 return(TNG_SUCCESS
);
11258 /* Take medium steps backward until a medium step backward would be too long
11259 * or the right frame set is found */
11260 while(file_pos
> 0 && curr_nr
- medium_stride_length
>= nr
)
11262 file_pos
= frame_set
->medium_stride_prev_frame_set_file_pos
;
11265 curr_nr
-= medium_stride_length
;
11266 fseek(tng_data
->input_file
,
11269 /* Read block headers first to see what block is found. */
11270 stat
= tng_block_header_read(tng_data
, block
);
11271 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11273 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11274 file_pos
, __FILE__
, __LINE__
);
11275 tng_block_destroy(&block
);
11276 return(TNG_CRITICAL
);
11279 if(tng_block_read_next(tng_data
, block
,
11280 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11282 tng_block_destroy(&block
);
11283 return(TNG_CRITICAL
);
11287 tng_block_destroy(&block
);
11288 return(TNG_SUCCESS
);
11293 /* Take one step backward until the right frame set is found */
11294 while(file_pos
> 0 && curr_nr
> nr
)
11296 file_pos
= frame_set
->prev_frame_set_file_pos
;
11300 fseek(tng_data
->input_file
,
11303 /* Read block headers first to see what block is found. */
11304 stat
= tng_block_header_read(tng_data
, block
);
11305 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11307 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11308 file_pos
, __FILE__
, __LINE__
);
11309 tng_block_destroy(&block
);
11310 return(TNG_CRITICAL
);
11313 if(tng_block_read_next(tng_data
, block
,
11314 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11316 tng_block_destroy(&block
);
11317 return(TNG_CRITICAL
);
11321 tng_block_destroy(&block
);
11322 return(TNG_SUCCESS
);
11327 /* If for some reason the current frame set is not yet found,
11328 * take one step forward until the right frame set is found */
11329 while(file_pos
> 0 && curr_nr
< nr
)
11331 file_pos
= frame_set
->next_frame_set_file_pos
;
11335 fseek(tng_data
->input_file
,
11338 /* Read block headers first to see what block is found. */
11339 stat
= tng_block_header_read(tng_data
, block
);
11340 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11342 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11343 file_pos
, __FILE__
, __LINE__
);
11344 tng_block_destroy(&block
);
11345 return(TNG_CRITICAL
);
11348 if(tng_block_read_next(tng_data
, block
,
11349 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11351 tng_block_destroy(&block
);
11352 return(TNG_CRITICAL
);
11356 tng_block_destroy(&block
);
11357 return(TNG_SUCCESS
);
11362 tng_block_destroy(&block
);
11363 return(TNG_FAILURE
);
11366 tng_function_status DECLSPECDLLEXPORT tng_frame_set_of_frame_find
11367 (tng_trajectory_t tng_data
,
11368 const int64_t frame
)
11370 int64_t first_frame
, last_frame
, n_frames_per_frame_set
;
11371 int64_t long_stride_length
, medium_stride_length
;
11372 int64_t file_pos
, temp_frame
, n_frames
;
11373 tng_trajectory_frame_set_t frame_set
;
11374 tng_gen_block_t block
;
11375 tng_function_status stat
;
11377 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
11378 TNG_ASSERT(frame
>= 0, "TNG library: frame must be >= 0.");
11380 frame_set
= &tng_data
->current_trajectory_frame_set
;
11382 tng_block_init(&block
);
11384 if(tng_data
->current_trajectory_frame_set_input_file_pos
< 0)
11386 file_pos
= tng_data
->first_trajectory_frame_set_input_file_pos
;
11387 fseek(tng_data
->input_file
,
11390 tng_data
->current_trajectory_frame_set_input_file_pos
= (long)file_pos
;
11391 /* Read block headers first to see what block is found. */
11392 stat
= tng_block_header_read(tng_data
, block
);
11393 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11395 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11396 file_pos
, __FILE__
, __LINE__
);
11397 tng_block_destroy(&block
);
11398 return(TNG_CRITICAL
);
11401 if(tng_block_read_next(tng_data
, block
,
11402 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11404 tng_block_destroy(&block
);
11405 return(TNG_CRITICAL
);
11409 first_frame
= tng_max_i64(frame_set
->first_frame
, 0);
11410 last_frame
= first_frame
+ frame_set
->n_frames
- 1;
11411 /* Is this the right frame set? */
11412 if(first_frame
<= frame
&& frame
<= last_frame
)
11414 tng_block_destroy(&block
);
11415 return(TNG_SUCCESS
);
11418 n_frames_per_frame_set
= tng_data
->frame_set_n_frames
;
11419 long_stride_length
= tng_data
->long_stride_length
;
11420 medium_stride_length
= tng_data
->medium_stride_length
;
11422 if(tng_first_frame_nr_of_next_frame_set_get(tng_data
, &temp_frame
) ==
11425 if(temp_frame
- first_frame
> n_frames_per_frame_set
)
11427 n_frames_per_frame_set
= temp_frame
- first_frame
;
11431 tng_num_frames_get(tng_data
, &n_frames
);
11433 if(frame
>= n_frames
)
11435 tng_block_destroy(&block
);
11436 return(TNG_FAILURE
);
11439 if(first_frame
- frame
>= frame
||
11440 frame
- last_frame
>
11441 tng_data
->n_trajectory_frame_sets
* n_frames_per_frame_set
- frame
)
11443 /* Start from the beginning */
11444 if(first_frame
- frame
>= frame
)
11446 file_pos
= tng_data
->first_trajectory_frame_set_input_file_pos
;
11450 tng_block_destroy(&block
);
11451 return(TNG_FAILURE
);
11454 /* Start from the end */
11455 else if(frame
- first_frame
> (n_frames
- 1) - frame
)
11457 file_pos
= tng_data
->last_trajectory_frame_set_input_file_pos
;
11459 /* If the last frame set position is not set start from the current
11460 * frame set, since it will be closer than the first frame set. */
11462 /* Start from current */
11465 file_pos
= tng_data
->current_trajectory_frame_set_input_file_pos
;
11470 fseek(tng_data
->input_file
,
11473 tng_data
->current_trajectory_frame_set_input_file_pos
= (long)file_pos
;
11474 /* Read block headers first to see what block is found. */
11475 stat
= tng_block_header_read(tng_data
, block
);
11476 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11478 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11479 file_pos
, __FILE__
, __LINE__
);
11480 tng_block_destroy(&block
);
11481 return(TNG_CRITICAL
);
11484 if(tng_block_read_next(tng_data
, block
,
11485 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11487 tng_block_destroy(&block
);
11488 return(TNG_CRITICAL
);
11493 first_frame
= tng_max_i64(frame_set
->first_frame
, 0);
11494 last_frame
= first_frame
+ frame_set
->n_frames
- 1;
11496 if(frame
>= first_frame
&& frame
<= last_frame
)
11498 tng_block_destroy(&block
);
11499 return(TNG_SUCCESS
);
11502 file_pos
= tng_data
->current_trajectory_frame_set_input_file_pos
;
11504 /* Take long steps forward until a long step forward would be too long or
11505 * the right frame set is found */
11506 while(file_pos
> 0 && first_frame
+ long_stride_length
*
11507 n_frames_per_frame_set
<= frame
)
11509 file_pos
= frame_set
->long_stride_next_frame_set_file_pos
;
11512 fseek(tng_data
->input_file
, (long)file_pos
, SEEK_SET
);
11513 /* Read block headers first to see what block is found. */
11514 stat
= tng_block_header_read(tng_data
, block
);
11515 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11517 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11518 file_pos
, __FILE__
, __LINE__
);
11519 tng_block_destroy(&block
);
11520 return(TNG_CRITICAL
);
11523 if(tng_block_read_next(tng_data
, block
,
11524 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11526 tng_block_destroy(&block
);
11527 return(TNG_CRITICAL
);
11530 first_frame
= tng_max_i64(frame_set
->first_frame
, 0);
11531 last_frame
= first_frame
+ frame_set
->n_frames
- 1;
11532 if(frame
>= first_frame
&& frame
<= last_frame
)
11534 tng_block_destroy(&block
);
11535 return(TNG_SUCCESS
);
11539 /* Take medium steps forward until a medium step forward would be too long
11540 * or the right frame set is found */
11541 while(file_pos
> 0 && first_frame
+ medium_stride_length
*
11542 n_frames_per_frame_set
<= frame
)
11544 file_pos
= frame_set
->medium_stride_next_frame_set_file_pos
;
11547 fseek(tng_data
->input_file
,
11550 /* Read block headers first to see what block is found. */
11551 stat
= tng_block_header_read(tng_data
, block
);
11552 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11554 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11555 file_pos
, __FILE__
, __LINE__
);
11556 tng_block_destroy(&block
);
11557 return(TNG_CRITICAL
);
11560 if(tng_block_read_next(tng_data
, block
,
11561 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11563 tng_block_destroy(&block
);
11564 return(TNG_CRITICAL
);
11567 first_frame
= tng_max_i64(frame_set
->first_frame
, 0);
11568 last_frame
= first_frame
+ frame_set
->n_frames
- 1;
11569 if(frame
>= first_frame
&& frame
<= last_frame
)
11571 tng_block_destroy(&block
);
11572 return(TNG_SUCCESS
);
11576 /* Take one step forward until the right frame set is found */
11577 while(file_pos
> 0 && first_frame
< frame
&& last_frame
< frame
)
11579 file_pos
= frame_set
->next_frame_set_file_pos
;
11582 fseek(tng_data
->input_file
,
11585 /* Read block headers first to see what block is found. */
11586 stat
= tng_block_header_read(tng_data
, block
);
11587 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11589 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11590 file_pos
, __FILE__
, __LINE__
);
11591 tng_block_destroy(&block
);
11592 return(TNG_CRITICAL
);
11595 if(tng_block_read_next(tng_data
, block
,
11596 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11598 tng_block_destroy(&block
);
11599 return(TNG_CRITICAL
);
11602 first_frame
= tng_max_i64(frame_set
->first_frame
, 0);
11603 last_frame
= first_frame
+ frame_set
->n_frames
- 1;
11604 if(frame
>= first_frame
&& frame
<= last_frame
)
11606 tng_block_destroy(&block
);
11607 return(TNG_SUCCESS
);
11611 /* Take long steps backward until a long step backward would be too long
11612 * or the right frame set is found */
11613 while(file_pos
> 0 && first_frame
- long_stride_length
*
11614 n_frames_per_frame_set
>= frame
)
11616 file_pos
= frame_set
->long_stride_prev_frame_set_file_pos
;
11619 fseek(tng_data
->input_file
,
11622 /* Read block headers first to see what block is found. */
11623 stat
= tng_block_header_read(tng_data
, block
);
11624 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11626 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11627 file_pos
, __FILE__
, __LINE__
);
11628 tng_block_destroy(&block
);
11629 return(TNG_CRITICAL
);
11632 if(tng_block_read_next(tng_data
, block
,
11633 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11635 tng_block_destroy(&block
);
11636 return(TNG_CRITICAL
);
11639 first_frame
= tng_max_i64(frame_set
->first_frame
, 0);
11640 last_frame
= first_frame
+ frame_set
->n_frames
- 1;
11641 if(frame
>= first_frame
&& frame
<= last_frame
)
11643 tng_block_destroy(&block
);
11644 return(TNG_SUCCESS
);
11648 /* Take medium steps backward until a medium step backward would be too long
11649 * or the right frame set is found */
11650 while(file_pos
> 0 && first_frame
- medium_stride_length
*
11651 n_frames_per_frame_set
>= frame
)
11653 file_pos
= frame_set
->medium_stride_prev_frame_set_file_pos
;
11656 fseek(tng_data
->input_file
,
11659 /* Read block headers first to see what block is found. */
11660 stat
= tng_block_header_read(tng_data
, block
);
11661 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11663 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11664 file_pos
, __FILE__
, __LINE__
);
11665 tng_block_destroy(&block
);
11666 return(TNG_CRITICAL
);
11669 if(tng_block_read_next(tng_data
, block
,
11670 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11672 tng_block_destroy(&block
);
11673 return(TNG_CRITICAL
);
11676 first_frame
= tng_max_i64(frame_set
->first_frame
, 0);
11677 last_frame
= first_frame
+ frame_set
->n_frames
- 1;
11678 if(frame
>= first_frame
&& frame
<= last_frame
)
11680 tng_block_destroy(&block
);
11681 return(TNG_SUCCESS
);
11685 /* Take one step backward until the right frame set is found */
11686 while(file_pos
> 0 && first_frame
> frame
&& last_frame
> frame
)
11688 file_pos
= frame_set
->prev_frame_set_file_pos
;
11691 fseek(tng_data
->input_file
,
11694 /* Read block headers first to see what block is found. */
11695 stat
= tng_block_header_read(tng_data
, block
);
11696 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11698 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11699 file_pos
, __FILE__
, __LINE__
);
11700 tng_block_destroy(&block
);
11701 return(TNG_CRITICAL
);
11704 if(tng_block_read_next(tng_data
, block
,
11705 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11707 tng_block_destroy(&block
);
11708 return(TNG_CRITICAL
);
11711 first_frame
= tng_max_i64(frame_set
->first_frame
, 0);
11712 last_frame
= first_frame
+ frame_set
->n_frames
- 1;
11713 if(frame
>= first_frame
&& frame
<= last_frame
)
11715 tng_block_destroy(&block
);
11716 return(TNG_SUCCESS
);
11720 /* If for some reason the current frame set is not yet found,
11721 * take one step forward until the right frame set is found */
11722 while(file_pos
> 0 && first_frame
< frame
&& last_frame
< frame
)
11724 file_pos
= frame_set
->next_frame_set_file_pos
;
11727 fseek(tng_data
->input_file
,
11730 /* Read block headers first to see what block is found. */
11731 stat
= tng_block_header_read(tng_data
, block
);
11732 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11734 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11735 file_pos
, __FILE__
, __LINE__
);
11736 tng_block_destroy(&block
);
11737 return(TNG_CRITICAL
);
11740 if(tng_block_read_next(tng_data
, block
,
11741 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11743 tng_block_destroy(&block
);
11744 return(TNG_CRITICAL
);
11747 first_frame
= tng_max_i64(frame_set
->first_frame
, 0);
11748 last_frame
= first_frame
+ frame_set
->n_frames
- 1;
11749 if(frame
>= first_frame
&& frame
<= last_frame
)
11751 tng_block_destroy(&block
);
11752 return(TNG_SUCCESS
);
11756 tng_block_destroy(&block
);
11757 return(TNG_FAILURE
);
11760 tng_function_status DECLSPECDLLEXPORT tng_frame_set_next_frame_set_file_pos_get
11761 (const tng_trajectory_t tng_data
,
11762 const tng_trajectory_frame_set_t frame_set
,
11767 TNG_ASSERT(frame_set
, "TNG library: frame_set not initialised before accessing data.");
11768 TNG_ASSERT(pos
, "TNG library: pos must not be a NULL pointer");
11770 *pos
= frame_set
->next_frame_set_file_pos
;
11772 return(TNG_SUCCESS
);
11775 tng_function_status DECLSPECDLLEXPORT tng_frame_set_prev_frame_set_file_pos_get
11776 (const tng_trajectory_t tng_data
,
11777 const tng_trajectory_frame_set_t frame_set
,
11782 TNG_ASSERT(frame_set
, "TNG library: frame_set not initialised before accessing data.");
11783 TNG_ASSERT(pos
, "TNG library: pos must not be a NULL pointer");
11785 *pos
= frame_set
->prev_frame_set_file_pos
;
11787 return(TNG_SUCCESS
);
11790 tng_function_status DECLSPECDLLEXPORT tng_frame_set_frame_range_get
11791 (const tng_trajectory_t tng_data
,
11792 const tng_trajectory_frame_set_t frame_set
,
11793 int64_t *first_frame
,
11794 int64_t *last_frame
)
11798 TNG_ASSERT(first_frame
, "TNG library: first_frame must not be a NULL pointer");
11799 TNG_ASSERT(last_frame
, "TNG library: last_frame must not be a NULL pointer");
11800 TNG_ASSERT(frame_set
, "TNG library: frame_set must not be a NULL pointer");
11802 *first_frame
= frame_set
->first_frame
;
11803 *last_frame
= *first_frame
+ frame_set
->n_frames
- 1;
11805 return(TNG_SUCCESS
);
11808 /** Translate from the particle numbering used in a frame set to the real
11809 * particle numbering - used in the molecule description.
11810 * @param frame_set is the frame_set containing the mappings to use.
11811 * @param local is the index number of the atom in this frame set
11812 * @param real is set to the index of the atom in the molecular system.
11813 * @return TNG_SUCCESS (0) if successful or TNG_FAILURE (1) if the mapping
11816 static TNG_INLINE tng_function_status tng_particle_mapping_get_real_particle
11817 (const tng_trajectory_frame_set_t frame_set
,
11818 const int64_t local
,
11821 int64_t i
, n_blocks
= frame_set
->n_mapping_blocks
, first
;
11822 tng_particle_mapping_t mapping
;
11826 return(TNG_SUCCESS
);
11828 for(i
= 0; i
< n_blocks
; i
++)
11830 mapping
= &frame_set
->mappings
[i
];
11831 first
= mapping
->num_first_particle
;
11832 if(local
< first
||
11833 local
>= first
+ mapping
->n_particles
)
11837 *real
= mapping
->real_particle_numbers
[local
-first
];
11838 return(TNG_SUCCESS
);
11841 return(TNG_FAILURE
);
11844 /** Translate from the real particle numbering to the particle numbering
11845 * used in a frame set.
11846 * @param frame_set is the frame_set containing the mappings to use.
11847 * @param real is the index number of the atom in the molecular system.
11848 * @param local is set to the index of the atom in this frame set.
11849 * @return TNG_SUCCESS (0) if successful or TNG_FAILURE (1) if the mapping
11852 /*static TNG_INLINE tng_function_status tng_particle_mapping_get_local_particle
11853 (const tng_trajectory_frame_set_t frame_set,
11854 const int64_t real,
11857 int64_t i, j, n_blocks = frame_set->n_mapping_blocks;
11858 tng_particle_mapping_t mapping;
11862 return(TNG_SUCCESS);
11864 for(i = 0; i < n_blocks; i++)
11866 mapping = &frame_set->mappings[i];
11867 for(j = mapping->n_particles; j--;)
11869 if(mapping->real_particle_numbers[j] == real)
11872 return(TNG_SUCCESS);
11876 return(TNG_FAILURE);
11880 tng_function_status DECLSPECDLLEXPORT tng_file_headers_read
11881 (tng_trajectory_t tng_data
,
11882 const char hash_mode
)
11884 int cnt
= 0, prev_pos
= 0;
11885 tng_gen_block_t block
;
11887 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
11889 tng_data
->n_trajectory_frame_sets
= 0;
11891 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
11893 return(TNG_CRITICAL
);
11896 if(!tng_data
->input_file_len
)
11898 fseek(tng_data
->input_file
, 0, SEEK_END
);
11899 tng_data
->input_file_len
= ftell(tng_data
->input_file
);
11900 fseek(tng_data
->input_file
, 0, SEEK_SET
);
11903 tng_block_init(&block
);
11904 /* Non trajectory blocks (they come before the trajectory
11905 * blocks in the file) */
11906 while (prev_pos
< tng_data
->input_file_len
&&
11907 tng_block_header_read(tng_data
, block
) != TNG_CRITICAL
&&
11909 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11911 if(tng_block_read_next(tng_data
, block
,
11912 hash_mode
) == TNG_SUCCESS
)
11916 prev_pos
= ftell(tng_data
->input_file
);
11919 /* Go back if a trajectory block was encountered */
11920 if(block
->id
== TNG_TRAJECTORY_FRAME_SET
)
11922 fseek(tng_data
->input_file
, prev_pos
, SEEK_SET
);
11925 tng_block_destroy(&block
);
11927 return(TNG_SUCCESS
);
11930 tng_function_status DECLSPECDLLEXPORT tng_file_headers_write
11931 (tng_trajectory_t tng_data
,
11932 const char hash_mode
)
11935 tng_gen_block_t data_block
;
11937 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
11939 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
11941 return(TNG_CRITICAL
);
11944 /* TODO: If there is already frame set data written to this file (e.g. when
11945 * appending to an already existing file we might need to move frame sets to
11946 * the end of the file. */
11948 if(tng_general_info_block_write(tng_data
, hash_mode
)
11951 fprintf(stderr
, "TNG library: Error writing general info block of file %s. %s: %d\n",
11952 tng_data
->input_file_path
, __FILE__
, __LINE__
);
11953 return(TNG_CRITICAL
);
11956 if(tng_molecules_block_write(tng_data
, hash_mode
)
11959 fprintf(stderr
, "TNG library: Error writing atom names block of file %s. %s: %d\n",
11960 tng_data
->input_file_path
, __FILE__
, __LINE__
);
11961 return(TNG_CRITICAL
);
11964 /* FIXME: Currently writing non-trajectory data blocks here.
11965 * Should perhaps be moved. */
11966 tng_block_init(&data_block
);
11967 for(i
= 0; i
< tng_data
->n_data_blocks
; i
++)
11969 data_block
->id
= tng_data
->non_tr_data
[i
].block_id
;
11970 tng_data_block_write(tng_data
, data_block
,
11974 for(i
= 0; i
< tng_data
->n_particle_data_blocks
; i
++)
11976 data_block
->id
= tng_data
->non_tr_particle_data
[i
].block_id
;
11977 tng_particle_data_block_write(tng_data
, data_block
,
11981 tng_block_destroy(&data_block
);
11983 return(TNG_SUCCESS
);
11986 tng_function_status DECLSPECDLLEXPORT
tng_block_read_next(tng_trajectory_t tng_data
,
11987 tng_gen_block_t block
,
11988 const char hash_mode
)
11990 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
11991 TNG_ASSERT(block
, "TNG library: block must be initialised and must not be a NULL pointer.");
11995 case TNG_TRAJECTORY_FRAME_SET
:
11996 return(tng_frame_set_block_read(tng_data
, block
, hash_mode
));
11997 case TNG_PARTICLE_MAPPING
:
11998 return(tng_trajectory_mapping_block_read(tng_data
, block
, hash_mode
));
11999 case TNG_GENERAL_INFO
:
12000 return(tng_general_info_block_read(tng_data
, block
, hash_mode
));
12001 case TNG_MOLECULES
:
12002 return(tng_molecules_block_read(tng_data
, block
, hash_mode
));
12004 if(block
->id
>= TNG_TRAJ_BOX_SHAPE
)
12006 return(tng_data_block_contents_read(tng_data
, block
, hash_mode
));
12010 /* Skip to the next block */
12011 fseek(tng_data
->input_file
, (long)block
->block_contents_size
, SEEK_CUR
);
12012 return(TNG_FAILURE
);
12017 tng_function_status DECLSPECDLLEXPORT tng_frame_set_read
12018 (tng_trajectory_t tng_data
,
12019 const char hash_mode
)
12022 tng_gen_block_t block
;
12023 tng_function_status stat
;
12025 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12027 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
12029 return(TNG_CRITICAL
);
12032 file_pos
= ftell(tng_data
->input_file
);
12034 tng_block_init(&block
);
12036 if(!tng_data
->input_file_len
)
12038 fseek(tng_data
->input_file
, 0, SEEK_END
);
12039 tng_data
->input_file_len
= ftell(tng_data
->input_file
);
12040 fseek(tng_data
->input_file
, file_pos
, SEEK_SET
);
12043 /* Read block headers first to see what block is found. */
12044 stat
= tng_block_header_read(tng_data
, block
);
12045 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
12047 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
12048 file_pos
, __FILE__
, __LINE__
);
12049 tng_block_destroy(&block
);
12050 return(TNG_CRITICAL
);
12053 tng_data
->current_trajectory_frame_set_input_file_pos
= file_pos
;
12055 if(tng_block_read_next(tng_data
, block
,
12056 hash_mode
) == TNG_SUCCESS
)
12058 tng_data
->n_trajectory_frame_sets
++;
12059 file_pos
= ftell(tng_data
->input_file
);
12060 /* Read all blocks until next frame set block */
12061 stat
= tng_block_header_read(tng_data
, block
);
12062 while(file_pos
< tng_data
->input_file_len
&&
12063 stat
!= TNG_CRITICAL
&&
12064 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
12066 stat
= tng_block_read_next(tng_data
, block
,
12068 if(stat
!= TNG_CRITICAL
)
12070 file_pos
= ftell(tng_data
->input_file
);
12071 if(file_pos
< tng_data
->input_file_len
)
12073 stat
= tng_block_header_read(tng_data
, block
);
12077 if(stat
== TNG_CRITICAL
)
12079 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
12080 file_pos
, __FILE__
, __LINE__
);
12081 tng_block_destroy(&block
);
12085 if(block
->id
== TNG_TRAJECTORY_FRAME_SET
)
12087 fseek(tng_data
->input_file
, file_pos
, SEEK_SET
);
12091 tng_block_destroy(&block
);
12093 return(TNG_SUCCESS
);
12097 tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_current_only_data_from_block_id
12098 (tng_trajectory_t tng_data
,
12099 const char hash_mode
,
12100 const int64_t block_id
)
12103 tng_gen_block_t block
;
12104 tng_function_status stat
;
12105 int found_flag
= 1;
12107 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12109 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
12111 return(TNG_CRITICAL
);
12114 file_pos
= (long)tng_data
->current_trajectory_frame_set_input_file_pos
;
12118 /* No current frame set. This means that the first frame set must be
12121 file_pos
= (long)tng_data
->first_trajectory_frame_set_input_file_pos
;
12126 fseek(tng_data
->input_file
,
12132 return(TNG_FAILURE
);
12135 tng_block_init(&block
);
12137 if(!tng_data
->input_file_len
)
12139 fseek(tng_data
->input_file
, 0, SEEK_END
);
12140 tng_data
->input_file_len
= ftell(tng_data
->input_file
);
12141 fseek(tng_data
->input_file
, file_pos
, SEEK_SET
);
12144 /* Read block headers first to see what block is found. */
12145 stat
= tng_block_header_read(tng_data
, block
);
12146 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
12148 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
12149 file_pos
, __FILE__
, __LINE__
);
12150 tng_block_destroy(&block
);
12151 return(TNG_CRITICAL
);
12153 /* If the current frame set had already been read skip its block contents */
12156 fseek(tng_data
->input_file
, (long)block
->block_contents_size
, SEEK_CUR
);
12158 /* Otherwiese read the frame set block */
12161 stat
= tng_block_read_next(tng_data
, block
,
12163 if(stat
!= TNG_SUCCESS
)
12165 fprintf(stderr
, "TNG library: Cannot read frame set block. %s: %d\n", __FILE__
, __LINE__
);
12166 tng_block_destroy(&block
);
12170 file_pos
= ftell(tng_data
->input_file
);
12174 /* Read only blocks of the requested ID
12175 * until next frame set block */
12176 stat
= tng_block_header_read(tng_data
, block
);
12177 while(file_pos
< tng_data
->input_file_len
&&
12178 stat
!= TNG_CRITICAL
&&
12179 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
12181 if(block
->id
== block_id
)
12183 stat
= tng_block_read_next(tng_data
, block
,
12185 if(stat
!= TNG_CRITICAL
)
12187 file_pos
= ftell(tng_data
->input_file
);
12189 if(file_pos
< tng_data
->input_file_len
)
12191 stat
= tng_block_header_read(tng_data
, block
);
12197 file_pos
+= (long)(block
->block_contents_size
+ block
->header_contents_size
);
12198 fseek(tng_data
->input_file
, (long)block
->block_contents_size
, SEEK_CUR
);
12199 if(file_pos
< tng_data
->input_file_len
)
12201 stat
= tng_block_header_read(tng_data
, block
);
12205 if(stat
== TNG_CRITICAL
)
12207 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
12208 file_pos
, __FILE__
, __LINE__
);
12209 tng_block_destroy(&block
);
12213 if(block
->id
== TNG_TRAJECTORY_FRAME_SET
)
12215 fseek(tng_data
->input_file
, file_pos
, SEEK_SET
);
12218 tng_block_destroy(&block
);
12222 return(TNG_SUCCESS
);
12226 return(TNG_FAILURE
);
12230 tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_next
12231 (tng_trajectory_t tng_data
,
12232 const char hash_mode
)
12236 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12238 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
12240 return(TNG_CRITICAL
);
12243 file_pos
= (long)tng_data
->current_trajectory_frame_set
.next_frame_set_file_pos
;
12245 if(file_pos
< 0 && tng_data
->current_trajectory_frame_set_input_file_pos
<= 0)
12247 file_pos
= (long)tng_data
->first_trajectory_frame_set_input_file_pos
;
12252 fseek(tng_data
->input_file
,
12258 return(TNG_FAILURE
);
12261 return(tng_frame_set_read(tng_data
, hash_mode
));
12264 tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_next_only_data_from_block_id
12265 (tng_trajectory_t tng_data
,
12266 const char hash_mode
,
12267 const int64_t block_id
)
12270 tng_gen_block_t block
;
12271 tng_function_status stat
;
12273 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12275 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
12277 return(TNG_CRITICAL
);
12280 file_pos
= (long)tng_data
->current_trajectory_frame_set
.next_frame_set_file_pos
;
12282 if(file_pos
< 0 && tng_data
->current_trajectory_frame_set_input_file_pos
<= 0)
12284 file_pos
= (long)tng_data
->first_trajectory_frame_set_input_file_pos
;
12289 fseek(tng_data
->input_file
,
12295 return(TNG_FAILURE
);
12298 tng_block_init(&block
);
12300 if(!tng_data
->input_file_len
)
12302 fseek(tng_data
->input_file
, 0, SEEK_END
);
12303 tng_data
->input_file_len
= ftell(tng_data
->input_file
);
12304 fseek(tng_data
->input_file
, file_pos
, SEEK_SET
);
12307 /* Read block headers first to see what block is found. */
12308 stat
= tng_block_header_read(tng_data
, block
);
12309 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
12311 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
12312 file_pos
, __FILE__
, __LINE__
);
12313 tng_block_destroy(&block
);
12314 return(TNG_CRITICAL
);
12317 tng_data
->current_trajectory_frame_set_input_file_pos
= file_pos
;
12319 if(tng_block_read_next(tng_data
, block
,
12320 hash_mode
) == TNG_SUCCESS
)
12322 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, hash_mode
, block_id
);
12325 tng_block_destroy(&block
);
12330 tng_function_status
tng_frame_set_write(tng_trajectory_t tng_data
,
12331 const char hash_mode
)
12334 tng_gen_block_t block
;
12335 tng_trajectory_frame_set_t frame_set
;
12336 tng_function_status stat
;
12338 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12340 frame_set
= &tng_data
->current_trajectory_frame_set
;
12342 if(frame_set
->n_written_frames
== frame_set
->n_frames
)
12344 return(TNG_SUCCESS
);
12347 tng_data
->current_trajectory_frame_set_output_file_pos
=
12348 ftell(tng_data
->output_file
);
12349 tng_data
->last_trajectory_frame_set_output_file_pos
=
12350 tng_data
->current_trajectory_frame_set_output_file_pos
;
12352 if(tng_data
->current_trajectory_frame_set_output_file_pos
<= 0)
12354 return(TNG_FAILURE
);
12357 if(tng_data
->first_trajectory_frame_set_output_file_pos
== -1)
12359 tng_data
->first_trajectory_frame_set_output_file_pos
=
12360 tng_data
->current_trajectory_frame_set_output_file_pos
;
12363 tng_block_init(&block
);
12365 if(tng_frame_set_block_write(tng_data
, block
, hash_mode
) != TNG_SUCCESS
)
12367 tng_block_destroy(&block
);
12368 return(TNG_FAILURE
);
12371 /* Write non-particle data blocks */
12372 for(i
= 0; i
<frame_set
->n_data_blocks
; i
++)
12374 block
->id
= frame_set
->tr_data
[i
].block_id
;
12375 tng_data_block_write(tng_data
, block
, i
, hash_mode
);
12377 /* Write the mapping blocks and particle data blocks*/
12378 if(frame_set
->n_mapping_blocks
)
12380 for(i
= 0; i
< frame_set
->n_mapping_blocks
; i
++)
12382 block
->id
= TNG_PARTICLE_MAPPING
;
12383 if(frame_set
->mappings
[i
].n_particles
> 0)
12385 tng_trajectory_mapping_block_write(tng_data
, block
, i
, hash_mode
);
12386 for(j
= 0; j
<frame_set
->n_particle_data_blocks
; j
++)
12388 block
->id
= frame_set
->tr_particle_data
[j
].block_id
;
12389 tng_particle_data_block_write(tng_data
, block
,
12390 j
, &frame_set
->mappings
[i
],
12398 for(i
= 0; i
<frame_set
->n_particle_data_blocks
; i
++)
12400 block
->id
= frame_set
->tr_particle_data
[i
].block_id
;
12401 tng_particle_data_block_write(tng_data
, block
,
12407 /* Update pointers in the general info block */
12408 stat
= tng_header_pointers_update(tng_data
, hash_mode
);
12410 if(stat
== TNG_SUCCESS
)
12412 stat
= tng_frame_set_pointers_update(tng_data
, hash_mode
);
12415 tng_block_destroy(&block
);
12417 frame_set
->n_unwritten_frames
= 0;
12419 fflush(tng_data
->output_file
);
12424 tng_function_status DECLSPECDLLEXPORT tng_frame_set_premature_write
12425 (tng_trajectory_t tng_data
,
12426 const char hash_mode
)
12428 tng_trajectory_frame_set_t frame_set
;
12430 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12432 frame_set
= &tng_data
->current_trajectory_frame_set
;
12434 if(frame_set
->n_unwritten_frames
== 0)
12436 return(TNG_SUCCESS
);
12438 frame_set
->n_frames
= frame_set
->n_unwritten_frames
;
12440 return(tng_frame_set_write(tng_data
, hash_mode
));
12443 tng_function_status DECLSPECDLLEXPORT tng_frame_set_new
12444 (tng_trajectory_t tng_data
,
12445 const int64_t first_frame
,
12446 const int64_t n_frames
)
12448 tng_gen_block_t block
;
12449 tng_trajectory_frame_set_t frame_set
;
12450 FILE *temp
= tng_data
->input_file
;
12453 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12454 TNG_ASSERT(first_frame
>= 0, "TNG library: first_frame must be >= 0.");
12455 TNG_ASSERT(n_frames
>= 0, "TNG library: n_frames must be >= 0.");
12457 frame_set
= &tng_data
->current_trajectory_frame_set
;
12459 curr_pos
= ftell(tng_data
->output_file
);
12463 tng_file_headers_write(tng_data
, TNG_USE_HASH
);
12466 /* Set pointer to previous frame set to the one that was loaded
12468 * FIXME: This is a bit risky. If they are not added in order
12469 * it will be wrong. */
12470 if(tng_data
->n_trajectory_frame_sets
)
12472 frame_set
->prev_frame_set_file_pos
=
12473 tng_data
->current_trajectory_frame_set_output_file_pos
;
12476 tng_data
->current_trajectory_frame_set_output_file_pos
=
12477 ftell(tng_data
->output_file
);
12479 tng_data
->n_trajectory_frame_sets
++;
12481 /* Set the medium range pointers */
12482 if(tng_data
->n_trajectory_frame_sets
== tng_data
->medium_stride_length
+ 1)
12484 frame_set
->medium_stride_prev_frame_set_file_pos
=
12485 tng_data
->first_trajectory_frame_set_output_file_pos
;
12487 else if(tng_data
->n_trajectory_frame_sets
> tng_data
->medium_stride_length
+ 1)
12489 /* FIXME: Currently only working if the previous frame set has its
12490 * medium stride pointer already set. This might need some fixing. */
12491 if(frame_set
->medium_stride_prev_frame_set_file_pos
!= -1 &&
12492 frame_set
->medium_stride_prev_frame_set_file_pos
!= 0)
12494 tng_block_init(&block
);
12495 tng_data
->input_file
= tng_data
->output_file
;
12497 curr_pos
= ftell(tng_data
->output_file
);
12498 fseek(tng_data
->output_file
,
12499 (long)frame_set
->medium_stride_prev_frame_set_file_pos
,
12502 if(tng_block_header_read(tng_data
, block
) != TNG_SUCCESS
)
12504 fprintf(stderr
, "TNG library: Cannot read frame set header. %s: %d\n",
12505 __FILE__
, __LINE__
);
12506 tng_data
->input_file
= temp
;
12507 tng_block_destroy(&block
);
12508 return(TNG_CRITICAL
);
12511 /* Read the next frame set from the previous frame set and one
12512 * medium stride step back */
12513 fseek(tng_data
->output_file
, (long)block
->block_contents_size
- 6 *
12514 sizeof(int64_t), SEEK_CUR
);
12515 if(fread(&frame_set
->medium_stride_prev_frame_set_file_pos
,
12516 sizeof(frame_set
->medium_stride_prev_frame_set_file_pos
),
12517 1, tng_data
->output_file
) == 0)
12519 fprintf(stderr
, "TNG library: Cannot read block. %s: %d\n", __FILE__
, __LINE__
);
12520 tng_data
->input_file
= temp
;
12521 tng_block_destroy(&block
);
12522 return(TNG_CRITICAL
);
12525 if(tng_data
->input_endianness_swap_func_64
)
12527 if(tng_data
->input_endianness_swap_func_64(tng_data
,
12528 &frame_set
->medium_stride_prev_frame_set_file_pos
)
12531 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
12532 __FILE__
, __LINE__
);
12536 tng_block_destroy(&block
);
12538 /* Set the long range pointers */
12539 if(tng_data
->n_trajectory_frame_sets
== tng_data
->long_stride_length
+ 1)
12541 frame_set
->long_stride_prev_frame_set_file_pos
=
12542 tng_data
->first_trajectory_frame_set_output_file_pos
;
12544 else if(tng_data
->n_trajectory_frame_sets
> tng_data
->medium_stride_length
+ 1)
12546 /* FIXME: Currently only working if the previous frame set has its
12547 * long stride pointer already set. This might need some fixing. */
12548 if(frame_set
->long_stride_prev_frame_set_file_pos
!= -1 &&
12549 frame_set
->long_stride_prev_frame_set_file_pos
!= 0)
12551 tng_block_init(&block
);
12552 tng_data
->input_file
= tng_data
->output_file
;
12554 fseek(tng_data
->output_file
,
12555 (long)frame_set
->long_stride_prev_frame_set_file_pos
,
12558 if(tng_block_header_read(tng_data
, block
) != TNG_SUCCESS
)
12560 fprintf(stderr
, "TNG library: Cannot read frame set header. %s: %d\n",
12561 __FILE__
, __LINE__
);
12562 tng_data
->input_file
= temp
;
12563 tng_block_destroy(&block
);
12564 return(TNG_CRITICAL
);
12567 /* Read the next frame set from the previous frame set and one
12568 * long stride step back */
12569 fseek(tng_data
->output_file
, (long)block
->block_contents_size
- 6 *
12570 sizeof(int64_t), SEEK_CUR
);
12572 tng_block_destroy(&block
);
12574 if(fread(&frame_set
->long_stride_prev_frame_set_file_pos
,
12575 sizeof(frame_set
->long_stride_prev_frame_set_file_pos
),
12576 1, tng_data
->output_file
) == 0)
12578 fprintf(stderr
, "TNG library: Cannot read block. %s: %d\n", __FILE__
, __LINE__
);
12579 tng_data
->input_file
= temp
;
12580 return(TNG_CRITICAL
);
12583 if(tng_data
->input_endianness_swap_func_64
)
12585 if(tng_data
->input_endianness_swap_func_64(tng_data
,
12586 &frame_set
->long_stride_prev_frame_set_file_pos
)
12589 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
12590 __FILE__
, __LINE__
);
12597 tng_data
->input_file
= temp
;
12598 fseek(tng_data
->output_file
, (long)curr_pos
, SEEK_SET
);
12602 frame_set
->first_frame
= first_frame
;
12603 frame_set
->n_frames
= n_frames
;
12604 frame_set
->n_written_frames
= 0;
12605 frame_set
->n_unwritten_frames
= 0;
12606 frame_set
->first_frame_time
= -1;
12608 if(tng_data
->first_trajectory_frame_set_output_file_pos
== -1 ||
12609 tng_data
->first_trajectory_frame_set_output_file_pos
== 0)
12611 tng_data
->first_trajectory_frame_set_output_file_pos
=
12612 tng_data
->current_trajectory_frame_set_output_file_pos
;
12614 /* FIXME: Should check the frame number instead of the file_pos,
12615 * in case frame sets are not in order */
12616 if(tng_data
->last_trajectory_frame_set_output_file_pos
== -1 ||
12617 tng_data
->last_trajectory_frame_set_output_file_pos
== 0 ||
12618 tng_data
->last_trajectory_frame_set_output_file_pos
<
12619 tng_data
->current_trajectory_frame_set_output_file_pos
)
12621 tng_data
->last_trajectory_frame_set_output_file_pos
=
12622 tng_data
->current_trajectory_frame_set_output_file_pos
;
12625 return(TNG_SUCCESS
);
12628 tng_function_status DECLSPECDLLEXPORT tng_frame_set_with_time_new
12629 (tng_trajectory_t tng_data
,
12630 const int64_t first_frame
,
12631 const int64_t n_frames
,
12632 const double first_frame_time
)
12634 tng_function_status stat
;
12636 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12637 TNG_ASSERT(first_frame
>= 0, "TNG library: first_frame must be >= 0.");
12638 TNG_ASSERT(n_frames
>= 0, "TNG library: n_frames must be >= 0.");
12639 TNG_ASSERT(first_frame_time
>= 0, "TNG library: first_frame_time must be >= 0.");
12642 stat
= tng_frame_set_new(tng_data
, first_frame
, n_frames
);
12643 if(stat
!= TNG_SUCCESS
)
12647 stat
= tng_frame_set_first_frame_time_set(tng_data
, first_frame_time
);
12652 tng_function_status DECLSPECDLLEXPORT tng_frame_set_first_frame_time_set
12653 (tng_trajectory_t tng_data
,
12654 const double first_frame_time
)
12656 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12657 TNG_ASSERT(first_frame_time
>= 0, "TNG library: first_frame_time must be >= 0.");
12659 tng_data
->current_trajectory_frame_set
.first_frame_time
= first_frame_time
;
12661 return(TNG_SUCCESS
);
12664 tng_function_status DECLSPECDLLEXPORT tng_first_frame_nr_of_next_frame_set_get
12665 (const tng_trajectory_t tng_data
,
12668 long file_pos
, next_frame_set_file_pos
;
12669 tng_gen_block_t block
;
12670 tng_function_status stat
;
12672 tng_trajectory_frame_set_t frame_set
;
12674 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12675 TNG_ASSERT(tng_data
->input_file
, "TNG library: An input file must be open to find the next frame set");
12676 TNG_ASSERT(frame
, "TNG library: frame must not be a NULL pointer");
12678 file_pos
= ftell(tng_data
->input_file
);
12680 if(tng_data
->current_trajectory_frame_set_input_file_pos
<= 0)
12682 next_frame_set_file_pos
= (long)tng_data
->first_trajectory_frame_set_input_file_pos
;
12686 frame_set
= &tng_data
->current_trajectory_frame_set
;
12687 next_frame_set_file_pos
= (long)frame_set
->next_frame_set_file_pos
;
12690 if(next_frame_set_file_pos
<= 0)
12692 return(TNG_FAILURE
);
12695 fseek(tng_data
->input_file
, (long)next_frame_set_file_pos
, SEEK_SET
);
12696 /* Read block headers first to see that a frame set block is found. */
12697 tng_block_init(&block
);
12698 stat
= tng_block_header_read(tng_data
, block
);
12699 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
12701 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
12702 file_pos
, __FILE__
, __LINE__
);
12703 return(TNG_CRITICAL
);
12705 /* if(tng_data->current_trajectory_frame_set_input_file_pos <= 0)
12707 tng_block_read_next(tng_data, block, TNG_USE_HASH);
12709 tng_block_destroy(&block
);
12711 if(fread(frame
, sizeof(int64_t), 1, tng_data
->input_file
) == 0)
12713 fprintf(stderr
, "TNG library: Cannot read first frame of next frame set. %s: %d\n",
12714 __FILE__
, __LINE__
);
12715 return(TNG_CRITICAL
);
12717 fseek(tng_data
->input_file
, file_pos
, SEEK_SET
);
12719 return(TNG_SUCCESS
);
12722 tng_function_status DECLSPECDLLEXPORT tng_data_block_add
12723 (tng_trajectory_t tng_data
,
12725 const char *block_name
,
12726 const char datatype
,
12727 const char block_type_flag
,
12729 const int64_t n_values_per_frame
,
12730 int64_t stride_length
,
12731 const int64_t codec_id
,
12734 int i
, j
, size
, len
;
12735 tng_trajectory_frame_set_t frame_set
;
12736 tng_non_particle_data_t data
;
12737 char **first_dim_values
;
12738 char *new_data_c
=new_data
;
12739 int64_t n_frames_div
;
12741 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12742 TNG_ASSERT(block_name
, "TNG library: block_name must not be a NULL pointer.");
12743 TNG_ASSERT(n_values_per_frame
> 0, "TNG library: n_values_per_frame must be a positive integer.");
12745 frame_set
= &tng_data
->current_trajectory_frame_set
;
12747 if(stride_length
<= 0)
12752 /* If the block does not exist, create it */
12753 if(tng_data_find(tng_data
, id
, &data
) != TNG_SUCCESS
)
12755 if(tng_data_block_create(tng_data
, block_type_flag
) !=
12758 fprintf(stderr
, "TNG library: Cannot create data block. %s: %d\n",
12759 __FILE__
, __LINE__
);
12760 return(TNG_CRITICAL
);
12762 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
12764 data
= &frame_set
->tr_data
[frame_set
->n_data_blocks
- 1];
12768 data
= &tng_data
->non_tr_data
[tng_data
->n_data_blocks
- 1];
12770 data
->block_id
= id
;
12772 data
->block_name
= malloc(strlen(block_name
) + 1);
12773 if(!data
->block_name
)
12775 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
12776 (int)strlen(block_name
)+1, __FILE__
, __LINE__
);
12777 return(TNG_CRITICAL
);
12779 strncpy(data
->block_name
, block_name
, strlen(block_name
) + 1);
12782 /* FIXME: Memory leak from strings. */
12784 data
->last_retrieved_frame
= -1;
12787 data
->datatype
= datatype
;
12788 data
->stride_length
= tng_max_i64(stride_length
, 1);
12789 data
->n_values_per_frame
= n_values_per_frame
;
12790 data
->n_frames
= n_frames
;
12791 data
->codec_id
= codec_id
;
12792 data
->compression_multiplier
= 1.0;
12793 /* FIXME: This can cause problems. */
12794 data
->first_frame_with_data
= frame_set
->first_frame
;
12798 case TNG_FLOAT_DATA
:
12799 size
= sizeof(float);
12802 size
= sizeof(int64_t);
12804 case TNG_DOUBLE_DATA
:
12806 size
= sizeof(double);
12812 /* Allocate memory */
12813 if(tng_allocate_data_mem(tng_data
, data
, n_frames
, stride_length
,
12814 n_values_per_frame
) !=
12817 fprintf(stderr
, "TNG library: Cannot allocate data memory. %s: %d\n",
12818 __FILE__
, __LINE__
);
12819 return(TNG_CRITICAL
);
12822 if(n_frames
> frame_set
->n_unwritten_frames
)
12824 frame_set
->n_unwritten_frames
= n_frames
;
12827 n_frames_div
= (n_frames
% stride_length
) ?
12828 n_frames
/ stride_length
+ 1:
12829 n_frames
/ stride_length
;
12831 if(datatype
== TNG_CHAR_DATA
)
12833 for(i
= 0; i
< n_frames_div
; i
++)
12835 first_dim_values
= data
->strings
[i
];
12836 for(j
= 0; j
< n_values_per_frame
; j
++)
12838 len
= tng_min_i((int)strlen(new_data_c
) + 1,
12840 if(first_dim_values
[j
])
12842 free(first_dim_values
[j
]);
12844 first_dim_values
[j
] = malloc(len
);
12845 if(!first_dim_values
[j
])
12847 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
12848 len
, __FILE__
, __LINE__
);
12849 return(TNG_CRITICAL
);
12851 strncpy(first_dim_values
[j
],
12859 memcpy(data
->values
, new_data
, size
* n_frames_div
*
12860 n_values_per_frame
);
12864 return(TNG_SUCCESS
);
12867 tng_function_status DECLSPECDLLEXPORT tng_particle_data_block_add
12868 (tng_trajectory_t tng_data
,
12870 const char *block_name
,
12871 const char datatype
,
12872 const char block_type_flag
,
12874 const int64_t n_values_per_frame
,
12875 int64_t stride_length
,
12876 const int64_t num_first_particle
,
12877 const int64_t n_particles
,
12878 const int64_t codec_id
,
12883 int64_t tot_n_particles
, n_frames_div
;
12884 char ***first_dim_values
, **second_dim_values
;
12885 tng_trajectory_frame_set_t frame_set
;
12886 tng_particle_data_t data
;
12887 char *new_data_c
=new_data
;
12889 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12890 TNG_ASSERT(block_name
, "TNG library: block_name mustnot be a NULL pointer.");
12891 TNG_ASSERT(n_values_per_frame
> 0, "TNG library: n_values_per_frame must be a positive integer.");
12892 TNG_ASSERT(num_first_particle
>= 0, "TNG library: num_first_particle must be >= 0.");
12893 TNG_ASSERT(n_particles
>= 0, "TNG library: n_particles must be >= 0.");
12896 frame_set
= &tng_data
->current_trajectory_frame_set
;
12898 if(stride_length
<= 0)
12903 /* If the block does not exist, create it */
12904 if(tng_particle_data_find(tng_data
, id
, &data
) != TNG_SUCCESS
)
12906 if(tng_particle_data_block_create(tng_data
, block_type_flag
) !=
12909 fprintf(stderr
, "TNG library: Cannot create particle data block. %s: %d\n",
12910 __FILE__
, __LINE__
);
12911 return(TNG_CRITICAL
);
12913 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
12915 data
= &frame_set
->tr_particle_data
[frame_set
->
12916 n_particle_data_blocks
- 1];
12920 data
= &tng_data
->non_tr_particle_data
[tng_data
->
12921 n_particle_data_blocks
- 1];
12923 data
->block_id
= id
;
12925 data
->block_name
= malloc(strlen(block_name
) + 1);
12926 if(!data
->block_name
)
12928 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
12929 (int)strlen(block_name
)+1, __FILE__
, __LINE__
);
12930 return(TNG_CRITICAL
);
12932 strncpy(data
->block_name
, block_name
, strlen(block_name
) + 1);
12934 data
->datatype
= datatype
;
12937 /* FIXME: Memory leak from strings. */
12939 data
->last_retrieved_frame
= -1;
12942 data
->stride_length
= tng_max_i64(stride_length
, 1);
12943 data
->n_values_per_frame
= n_values_per_frame
;
12944 data
->n_frames
= n_frames
;
12945 data
->codec_id
= codec_id
;
12946 data
->compression_multiplier
= 1.0;
12947 /* FIXME: This can cause problems. */
12948 data
->first_frame_with_data
= frame_set
->first_frame
;
12950 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
&& tng_data
->var_num_atoms_flag
)
12952 tot_n_particles
= frame_set
->n_particles
;
12956 tot_n_particles
= tng_data
->n_particles
;
12959 /* If data values are supplied add that data to the data block. */
12962 /* Allocate memory */
12963 if(tng_allocate_particle_data_mem(tng_data
, data
, n_frames
,
12964 stride_length
, tot_n_particles
,
12965 n_values_per_frame
) !=
12968 fprintf(stderr
, "TNG library: Cannot allocate particle data memory. %s: %d\n",
12969 __FILE__
, __LINE__
);
12970 return(TNG_CRITICAL
);
12973 if(n_frames
> frame_set
->n_unwritten_frames
)
12975 frame_set
->n_unwritten_frames
= n_frames
;
12978 n_frames_div
= (n_frames
% stride_length
) ?
12979 n_frames
/ stride_length
+ 1:
12980 n_frames
/ stride_length
;
12982 if(datatype
== TNG_CHAR_DATA
)
12984 for(i
= 0; i
< n_frames_div
; i
++)
12986 first_dim_values
= data
->strings
[i
];
12987 for(j
= num_first_particle
; j
< num_first_particle
+ n_particles
;
12990 second_dim_values
= first_dim_values
[j
];
12991 for(k
= 0; k
< n_values_per_frame
; k
++)
12993 len
= tng_min_i((int)strlen(new_data_c
) + 1,
12995 if(second_dim_values
[k
])
12997 free(second_dim_values
[k
]);
12999 second_dim_values
[k
] = malloc(len
);
13000 if(!second_dim_values
[k
])
13002 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
13003 len
, __FILE__
, __LINE__
);
13004 return(TNG_CRITICAL
);
13006 strncpy(second_dim_values
[k
],
13018 size
= sizeof(int64_t);
13020 case TNG_FLOAT_DATA
:
13021 size
= sizeof(float);
13023 case TNG_DOUBLE_DATA
:
13025 size
= sizeof(double);
13028 memcpy(data
->values
, new_data
, size
* n_frames_div
*
13029 n_particles
* n_values_per_frame
);
13033 return(TNG_SUCCESS
);
13036 tng_function_status DECLSPECDLLEXPORT tng_data_block_name_get
13037 (tng_trajectory_t tng_data
,
13043 tng_trajectory_frame_set_t frame_set
;
13044 tng_function_status stat
;
13045 tng_particle_data_t p_data
;
13046 tng_non_particle_data_t np_data
;
13047 int block_type
= -1;
13049 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
13050 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
13052 for(i
= 0; i
< tng_data
->n_particle_data_blocks
; i
++)
13054 p_data
= &tng_data
->non_tr_particle_data
[i
];
13055 if(p_data
->block_id
== block_id
)
13057 strncpy(name
, p_data
->block_name
, max_len
);
13058 name
[max_len
- 1] = '\0';
13059 return(TNG_SUCCESS
);
13062 for(i
= 0; i
< tng_data
->n_data_blocks
; i
++)
13064 np_data
= &tng_data
->non_tr_data
[i
];
13065 if(np_data
->block_id
== block_id
)
13067 strncpy(name
, np_data
->block_name
, max_len
);
13068 name
[max_len
- 1] = '\0';
13069 return(TNG_SUCCESS
);
13073 frame_set
= &tng_data
->current_trajectory_frame_set
;
13075 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
13076 if(stat
== TNG_SUCCESS
)
13078 block_type
= TNG_PARTICLE_BLOCK_DATA
;
13082 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
13083 if(stat
== TNG_SUCCESS
)
13085 block_type
= TNG_NON_PARTICLE_BLOCK_DATA
;
13089 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
13090 if(stat
!= TNG_SUCCESS
)
13094 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
13095 if(stat
== TNG_SUCCESS
)
13097 block_type
= TNG_PARTICLE_BLOCK_DATA
;
13101 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
13102 if(stat
== TNG_SUCCESS
)
13104 block_type
= TNG_NON_PARTICLE_BLOCK_DATA
;
13109 if(block_type
== TNG_PARTICLE_BLOCK_DATA
)
13111 for(i
= 0; i
< frame_set
->n_particle_data_blocks
; i
++)
13113 p_data
= &frame_set
->tr_particle_data
[i
];
13114 if(p_data
->block_id
== block_id
)
13116 strncpy(name
, p_data
->block_name
, max_len
);
13117 name
[max_len
- 1] = '\0';
13118 return(TNG_SUCCESS
);
13122 else if(block_type
== TNG_NON_PARTICLE_BLOCK_DATA
)
13124 for(i
= 0; i
< frame_set
->n_data_blocks
; i
++)
13126 np_data
= &frame_set
->tr_data
[i
];
13127 if(np_data
->block_id
== block_id
)
13129 strncpy(name
, np_data
->block_name
, max_len
);
13130 name
[max_len
- 1] = '\0';
13131 return(TNG_SUCCESS
);
13136 return(TNG_FAILURE
);
13139 tng_function_status DECLSPECDLLEXPORT tng_data_block_dependency_get
13140 (const tng_trajectory_t tng_data
,
13142 int *block_dependency
)
13145 tng_function_status stat
;
13146 tng_particle_data_t p_data
;
13147 tng_non_particle_data_t np_data
;
13149 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
13150 TNG_ASSERT(block_dependency
, "TNG library: block_dependency must not be a NULL pointer.");
13152 for(i
= 0; i
< tng_data
->n_particle_data_blocks
; i
++)
13154 p_data
= &tng_data
->non_tr_particle_data
[i
];
13155 if(p_data
->block_id
== block_id
)
13157 *block_dependency
= TNG_PARTICLE_DEPENDENT
;
13158 return(TNG_SUCCESS
);
13161 for(i
= 0; i
< tng_data
->n_data_blocks
; i
++)
13163 np_data
= &tng_data
->non_tr_data
[i
];
13164 if(np_data
->block_id
== block_id
)
13166 *block_dependency
= 0;
13167 return(TNG_SUCCESS
);
13171 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
13172 if(stat
== TNG_SUCCESS
)
13174 *block_dependency
= TNG_PARTICLE_DEPENDENT
+ TNG_FRAME_DEPENDENT
;
13175 return(TNG_SUCCESS
);
13179 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
13180 if(stat
== TNG_SUCCESS
)
13182 *block_dependency
= TNG_FRAME_DEPENDENT
;
13183 return(TNG_SUCCESS
);
13187 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
13188 if(stat
!= TNG_SUCCESS
)
13192 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
13193 if(stat
== TNG_SUCCESS
)
13195 *block_dependency
= TNG_PARTICLE_DEPENDENT
+ TNG_FRAME_DEPENDENT
;
13196 return(TNG_SUCCESS
);
13200 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
13201 if(stat
== TNG_SUCCESS
)
13203 *block_dependency
= TNG_FRAME_DEPENDENT
;
13204 return(TNG_SUCCESS
);
13210 return(TNG_FAILURE
);
13213 tng_function_status DECLSPECDLLEXPORT tng_data_block_num_values_per_frame_get
13214 (const tng_trajectory_t tng_data
,
13216 int64_t *n_values_per_frame
)
13219 tng_function_status stat
;
13220 tng_particle_data_t p_data
;
13221 tng_non_particle_data_t np_data
;
13223 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
13224 TNG_ASSERT(n_values_per_frame
, "TNG library: n_values_per_frame must not be a NULL pointer.");
13226 for(i
= 0; i
< tng_data
->n_particle_data_blocks
; i
++)
13228 p_data
= &tng_data
->non_tr_particle_data
[i
];
13229 if(p_data
->block_id
== block_id
)
13231 *n_values_per_frame
= p_data
->n_values_per_frame
;
13232 return(TNG_SUCCESS
);
13235 for(i
= 0; i
< tng_data
->n_data_blocks
; i
++)
13237 np_data
= &tng_data
->non_tr_data
[i
];
13238 if(np_data
->block_id
== block_id
)
13240 *n_values_per_frame
= np_data
->n_values_per_frame
;
13241 return(TNG_SUCCESS
);
13245 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
13246 if(stat
== TNG_SUCCESS
)
13248 *n_values_per_frame
= p_data
->n_values_per_frame
;
13249 return(TNG_SUCCESS
);
13253 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
13254 if(stat
== TNG_SUCCESS
)
13256 *n_values_per_frame
= np_data
->n_values_per_frame
;
13257 return(TNG_SUCCESS
);
13261 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
13262 if(stat
!= TNG_SUCCESS
)
13266 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
13267 if(stat
== TNG_SUCCESS
)
13269 *n_values_per_frame
= p_data
->n_values_per_frame
;
13270 return(TNG_SUCCESS
);
13274 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
13275 if(stat
== TNG_SUCCESS
)
13277 *n_values_per_frame
= np_data
->n_values_per_frame
;
13278 return(TNG_SUCCESS
);
13284 return(TNG_FAILURE
);
13287 tng_function_status DECLSPECDLLEXPORT tng_frame_data_write
13288 (tng_trajectory_t tng_data
,
13289 const int64_t frame_nr
,
13290 const int64_t block_id
,
13291 const void *values
,
13292 const char hash_mode
)
13294 int64_t header_pos
, file_pos
;
13295 int64_t output_file_len
, n_values_per_frame
, size
, contents_size
;
13296 int64_t header_size
, temp_first
, temp_last
;
13297 int64_t i
, last_frame
;
13299 tng_gen_block_t block
;
13300 tng_trajectory_frame_set_t frame_set
;
13301 FILE *temp
= tng_data
->input_file
;
13302 struct tng_non_particle_data data
;
13303 tng_function_status stat
;
13304 char dependency
, sparse_data
, datatype
;
13307 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
13308 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
13309 TNG_ASSERT(values
, "TNG library: values must not be a NULL pointer.");
13311 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
13313 fprintf(stderr
, "TNG library: Cannot initialise destination file. %s: %d\n",
13314 __FILE__
, __LINE__
);
13315 return(TNG_CRITICAL
);
13318 temp_first
= tng_data
->first_trajectory_frame_set_input_file_pos
;
13319 temp_last
= tng_data
->last_trajectory_frame_set_input_file_pos
;
13320 temp_current
= tng_data
->current_trajectory_frame_set_input_file_pos
;
13321 tng_data
->first_trajectory_frame_set_input_file_pos
=
13322 tng_data
->first_trajectory_frame_set_output_file_pos
;
13323 tng_data
->last_trajectory_frame_set_input_file_pos
=
13324 tng_data
->last_trajectory_frame_set_output_file_pos
;
13325 tng_data
->current_trajectory_frame_set_input_file_pos
=
13326 tng_data
->current_trajectory_frame_set_output_file_pos
;
13328 tng_data
->input_file
= tng_data
->output_file
;
13330 stat
= tng_frame_set_of_frame_find(tng_data
, frame_nr
);
13332 frame_set
= &tng_data
->current_trajectory_frame_set
;
13334 if(stat
!= TNG_SUCCESS
)
13336 last_frame
= frame_set
->first_frame
+
13337 frame_set
->n_frames
- 1;
13338 /* If the wanted frame would be in the frame set after the last
13339 * frame set create a new frame set. */
13340 if(stat
== TNG_FAILURE
&&
13341 last_frame
< frame_nr
)
13342 /* (last_frame < frame_nr &&
13343 tng_data->current_trajectory_frame_set.first_frame +
13344 tng_data->frame_set_n_frames >= frame_nr))*/
13346 if(last_frame
+ tng_data
->frame_set_n_frames
< frame_nr
)
13348 last_frame
= frame_nr
- 1;
13350 tng_frame_set_new(tng_data
,
13352 tng_data
->frame_set_n_frames
);
13353 file_pos
= ftell(tng_data
->output_file
);
13354 fseek(tng_data
->output_file
, 0, SEEK_END
);
13355 output_file_len
= ftell(tng_data
->output_file
);
13356 fseek(tng_data
->output_file
, (long)file_pos
, SEEK_SET
);
13358 /* Read mapping blocks from the last frame set */
13359 tng_block_init(&block
);
13361 stat
= tng_block_header_read(tng_data
, block
);
13362 while(file_pos
< output_file_len
&&
13363 stat
!= TNG_CRITICAL
&&
13364 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
13366 if(block
->id
== TNG_PARTICLE_MAPPING
)
13368 tng_trajectory_mapping_block_read(tng_data
, block
,
13373 fseek(tng_data
->output_file
, (long)block
->block_contents_size
,
13376 file_pos
= ftell(tng_data
->output_file
);
13377 if(file_pos
< output_file_len
)
13379 stat
= tng_block_header_read(tng_data
, block
);
13383 tng_block_destroy(&block
);
13384 /* Write the frame set to disk */
13385 if(tng_frame_set_write(tng_data
, hash_mode
) != TNG_SUCCESS
)
13387 fprintf(stderr
, "TNG library: Error writing frame set. %s: %d\n", __FILE__
, __LINE__
);
13388 return(TNG_CRITICAL
);
13393 tng_data
->input_file
= temp
;
13394 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13395 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13396 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13401 tng_block_init(&block
);
13403 file_pos
= tng_data
->current_trajectory_frame_set_output_file_pos
;
13405 fseek(tng_data
->output_file
, 0, SEEK_END
);
13406 output_file_len
= ftell(tng_data
->output_file
);
13407 fseek(tng_data
->output_file
, (long)file_pos
, SEEK_SET
);
13409 /* Read past the frame set block first */
13410 stat
= tng_block_header_read(tng_data
, block
);
13411 if(stat
== TNG_CRITICAL
)
13413 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
13414 file_pos
, __FILE__
, __LINE__
);
13415 tng_block_destroy(&block
);
13416 tng_data
->input_file
= temp
;
13418 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13419 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13420 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13423 fseek(tng_data
->output_file
, (long)block
->block_contents_size
,
13426 /* Read all block headers until next frame set block or
13427 * until the wanted block id is found */
13428 stat
= tng_block_header_read(tng_data
, block
);
13429 while(file_pos
< output_file_len
&&
13430 stat
!= TNG_CRITICAL
&&
13431 block
->id
!= block_id
&&
13432 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
13434 fseek(tng_data
->output_file
, (long)block
->block_contents_size
, SEEK_CUR
);
13435 file_pos
= ftell(tng_data
->output_file
);
13436 if(file_pos
< output_file_len
)
13438 stat
= tng_block_header_read(tng_data
, block
);
13441 if(stat
== TNG_CRITICAL
)
13443 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
13444 file_pos
, __FILE__
, __LINE__
);
13445 tng_block_destroy(&block
);
13446 tng_data
->input_file
= temp
;
13447 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13448 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13449 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13453 contents_size
= block
->block_contents_size
;
13454 header_size
= block
->header_contents_size
;
13456 header_pos
= ftell(tng_data
->output_file
) - header_size
;
13457 frame_set
= &tng_data
->current_trajectory_frame_set
;
13459 if(fread(&datatype
, sizeof(datatype
), 1, tng_data
->input_file
) == 0)
13461 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13462 tng_block_destroy(&block
);
13463 return(TNG_CRITICAL
);
13465 if(fread(&dependency
, sizeof(dependency
), 1, tng_data
->input_file
) == 0)
13467 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13468 tng_block_destroy(&block
);
13469 return(TNG_CRITICAL
);
13471 data
.datatype
= datatype
;
13473 if(!(dependency
& TNG_FRAME_DEPENDENT
) ||
13474 (dependency
& TNG_PARTICLE_DEPENDENT
))
13476 tng_block_destroy(&block
);
13477 tng_data
->input_file
= temp
;
13479 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13480 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13481 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13482 return(TNG_FAILURE
);
13485 if(fread(&sparse_data
, sizeof(sparse_data
), 1, tng_data
->input_file
) == 0)
13487 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13488 tng_block_destroy(&block
);
13489 return(TNG_CRITICAL
);
13492 if(fread(&data
.n_values_per_frame
, sizeof(data
.n_values_per_frame
), 1,
13493 tng_data
->input_file
) == 0)
13495 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13496 tng_block_destroy(&block
);
13497 return(TNG_CRITICAL
);
13499 if(tng_data
->output_endianness_swap_func_64
)
13501 if(tng_data
->output_endianness_swap_func_64(tng_data
,
13502 &data
.n_values_per_frame
)
13505 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
13506 __FILE__
, __LINE__
);
13510 if(fread(&data
.codec_id
, sizeof(data
.codec_id
), 1,
13511 tng_data
->input_file
) == 0)
13513 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13514 tng_block_destroy(&block
);
13515 return(TNG_CRITICAL
);
13517 if(tng_data
->output_endianness_swap_func_64
)
13519 if(tng_data
->output_endianness_swap_func_64(tng_data
,
13523 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
13524 __FILE__
, __LINE__
);
13528 if(data
.codec_id
!= TNG_UNCOMPRESSED
)
13530 if(fread(&data
.compression_multiplier
,
13531 sizeof(data
.compression_multiplier
), 1, tng_data
->input_file
)
13534 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13535 tng_block_destroy(&block
);
13536 return(TNG_CRITICAL
);
13538 if(tng_data
->output_endianness_swap_func_64
)
13540 if(tng_data
->output_endianness_swap_func_64(tng_data
,
13541 (int64_t *)&data
.compression_multiplier
)
13544 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
13545 __FILE__
, __LINE__
);
13551 data
.compression_multiplier
= 1;
13556 if(fread(&data
.first_frame_with_data
, sizeof(data
.first_frame_with_data
),
13557 1, tng_data
->input_file
) == 0)
13559 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13560 tng_block_destroy(&block
);
13561 return(TNG_CRITICAL
);
13563 if(tng_data
->output_endianness_swap_func_64
)
13565 if(tng_data
->output_endianness_swap_func_64(tng_data
,
13566 &data
.first_frame_with_data
)
13569 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
13570 __FILE__
, __LINE__
);
13574 if(fread(&data
.stride_length
, sizeof(data
.stride_length
),
13575 1, tng_data
->input_file
) == 0)
13577 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13578 tng_block_destroy(&block
);
13579 return(TNG_CRITICAL
);
13581 if(tng_data
->output_endianness_swap_func_64
)
13583 if(tng_data
->output_endianness_swap_func_64(tng_data
,
13584 &data
.stride_length
)
13587 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
13588 __FILE__
, __LINE__
);
13594 data
.first_frame_with_data
= 0;
13595 data
.stride_length
= 1;
13597 data
.n_frames
= tng_data
->current_trajectory_frame_set
.n_frames
;
13599 tng_data
->input_file
= temp
;
13601 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13602 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13603 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13605 switch(data
.datatype
)
13607 case(TNG_INT_DATA
):
13608 size
= sizeof(int64_t);
13610 case(TNG_FLOAT_DATA
):
13611 size
= sizeof(float);
13613 case(TNG_DOUBLE_DATA
):
13614 size
= sizeof(double);
13617 fprintf(stderr
, "TNG library: Cannot calculate writing locations. %s: %d.\n", __FILE__
,
13619 tng_block_destroy(&block
);
13620 return(TNG_FAILURE
);
13623 n_values_per_frame
= data
.n_values_per_frame
;
13625 file_pos
= (frame_nr
- tng_max_i64(frame_set
->first_frame
,
13626 data
.first_frame_with_data
)) /
13627 data
.stride_length
;
13628 file_pos
*= size
* n_values_per_frame
;
13630 if(file_pos
> contents_size
)
13632 fprintf(stderr
, "TNG library: Attempting to write outside the block. %s: %d\n", __FILE__
,
13634 tng_block_destroy(&block
);
13635 return(TNG_FAILURE
);
13638 fseek(tng_data
->output_file
, (long)file_pos
, SEEK_CUR
);
13640 /* If the endianness is not big endian the data needs to be swapped */
13641 if((data
.datatype
== TNG_INT_DATA
||
13642 data
.datatype
== TNG_DOUBLE_DATA
) &&
13643 tng_data
->output_endianness_swap_func_64
)
13645 copy
= malloc(n_values_per_frame
* size
);
13646 memcpy(copy
, values
, n_values_per_frame
* size
);
13647 for(i
= 0; i
< n_values_per_frame
; i
++)
13649 if(tng_data
->output_endianness_swap_func_64(tng_data
,
13653 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
13654 __FILE__
, __LINE__
);
13657 fwrite(copy
, n_values_per_frame
, size
,
13658 tng_data
->output_file
);
13661 else if(data
.datatype
== TNG_FLOAT_DATA
&&
13662 tng_data
->output_endianness_swap_func_32
)
13664 copy
= malloc(n_values_per_frame
* size
);
13665 memcpy(copy
, values
, n_values_per_frame
* size
);
13666 for(i
= 0; i
< n_values_per_frame
; i
++)
13668 if(tng_data
->output_endianness_swap_func_32(tng_data
,
13672 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
13673 __FILE__
, __LINE__
);
13676 fwrite(copy
, n_values_per_frame
, size
,
13677 tng_data
->output_file
);
13683 fwrite(values
, n_values_per_frame
, size
, tng_data
->output_file
);
13686 fflush(tng_data
->output_file
);
13688 /* Update the number of written frames in the frame set. */
13689 if(frame_nr
- frame_set
->first_frame
+ 1 > frame_set
->n_written_frames
)
13691 frame_set
->n_written_frames
= frame_nr
- frame_set
->first_frame
+ 1;
13694 /* If the last frame has been written update the hash */
13695 if(hash_mode
== TNG_USE_HASH
&& (frame_nr
+ data
.stride_length
-
13696 data
.first_frame_with_data
) >=
13697 frame_set
->n_frames
)
13699 tng_md5_hash_update(tng_data
, block
, header_pos
, header_pos
+
13703 tng_block_destroy(&block
);
13705 return(TNG_SUCCESS
);
13708 tng_function_status DECLSPECDLLEXPORT tng_frame_particle_data_write
13709 (tng_trajectory_t tng_data
,
13710 const int64_t frame_nr
,
13711 const int64_t block_id
,
13712 const int64_t val_first_particle
,
13713 const int64_t val_n_particles
,
13714 const void *values
,
13715 const char hash_mode
)
13717 int64_t header_pos
, file_pos
, tot_n_particles
;
13718 int64_t output_file_len
, n_values_per_frame
, size
, contents_size
;
13719 int64_t header_size
, temp_first
, temp_last
;
13720 int64_t mapping_block_end_pos
, num_first_particle
, block_n_particles
;
13721 int64_t i
, last_frame
;
13723 tng_gen_block_t block
;
13724 tng_trajectory_frame_set_t frame_set
;
13725 FILE *temp
= tng_data
->input_file
;
13726 struct tng_particle_data data
;
13727 tng_function_status stat
;
13728 tng_particle_mapping_t mapping
;
13729 char dependency
, sparse_data
, datatype
;
13732 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
13733 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
13734 TNG_ASSERT(values
, "TNG library: values must not be a NULL pointer.");
13735 TNG_ASSERT(val_first_particle
>= 0, "TNG library: val_first_particle must be >= 0.");
13736 TNG_ASSERT(val_n_particles
>= 0, "TNG library: val_n_particles must be >= 0.");
13738 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
13740 fprintf(stderr
, "TNG library: Cannot initialise destination file. %s: %d\n",
13741 __FILE__
, __LINE__
);
13742 return(TNG_CRITICAL
);
13745 temp_first
= tng_data
->first_trajectory_frame_set_input_file_pos
;
13746 temp_last
= tng_data
->last_trajectory_frame_set_input_file_pos
;
13747 temp_current
= tng_data
->current_trajectory_frame_set_input_file_pos
;
13748 tng_data
->first_trajectory_frame_set_input_file_pos
=
13749 tng_data
->first_trajectory_frame_set_output_file_pos
;
13750 tng_data
->last_trajectory_frame_set_input_file_pos
=
13751 tng_data
->last_trajectory_frame_set_output_file_pos
;
13752 tng_data
->current_trajectory_frame_set_input_file_pos
=
13753 tng_data
->current_trajectory_frame_set_output_file_pos
;
13755 tng_data
->input_file
= tng_data
->output_file
;
13757 stat
= tng_frame_set_of_frame_find(tng_data
, frame_nr
);
13759 frame_set
= &tng_data
->current_trajectory_frame_set
;
13761 if(stat
!= TNG_SUCCESS
)
13763 last_frame
= frame_set
->first_frame
+
13764 frame_set
->n_frames
- 1;
13765 /* fprintf(stderr, "TNG library: Frame %"PRId64" not found. Last frame: %"PRId64"\n", frame_nr,
13767 /* If the wanted frame would be in the frame set after the last
13768 * frame set create a new frame set. */
13769 if(stat
== TNG_FAILURE
&&
13770 (last_frame
< frame_nr
&&
13771 last_frame
+ tng_data
->frame_set_n_frames
>= frame_nr
))
13773 if(last_frame
+ tng_data
->frame_set_n_frames
< frame_nr
)
13775 last_frame
= frame_nr
- 1;
13777 tng_frame_set_new(tng_data
,
13779 tng_data
->frame_set_n_frames
);
13781 file_pos
= ftell(tng_data
->output_file
);
13782 fseek(tng_data
->output_file
, 0, SEEK_END
);
13783 output_file_len
= ftell(tng_data
->output_file
);
13784 fseek(tng_data
->output_file
, (long)file_pos
, SEEK_SET
);
13786 /* Read mapping blocks from the last frame set */
13787 tng_block_init(&block
);
13789 stat
= tng_block_header_read(tng_data
, block
);
13790 while(file_pos
< output_file_len
&&
13791 stat
!= TNG_CRITICAL
&&
13792 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
13794 if(block
->id
== TNG_PARTICLE_MAPPING
)
13796 tng_trajectory_mapping_block_read(tng_data
, block
,
13801 fseek(tng_data
->output_file
, (long)block
->block_contents_size
,
13804 file_pos
= ftell(tng_data
->output_file
);
13805 if(file_pos
< output_file_len
)
13807 stat
= tng_block_header_read(tng_data
, block
);
13811 tng_block_destroy(&block
);
13812 /* Write the frame set to disk */
13813 if(tng_frame_set_write(tng_data
, hash_mode
) != TNG_SUCCESS
)
13815 fprintf(stderr
, "TNG library: Error writing frame set. %s: %d\n", __FILE__
, __LINE__
);
13821 tng_data
->input_file
= temp
;
13822 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13823 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13824 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13830 tng_block_init(&block
);
13832 file_pos
= tng_data
->current_trajectory_frame_set_output_file_pos
;
13834 fseek(tng_data
->output_file
, 0, SEEK_END
);
13835 output_file_len
= ftell(tng_data
->output_file
);
13836 fseek(tng_data
->output_file
, (long)file_pos
, SEEK_SET
);
13838 /* Read past the frame set block first */
13839 stat
= tng_block_header_read(tng_data
, block
);
13840 if(stat
== TNG_CRITICAL
)
13842 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
13843 file_pos
, __FILE__
, __LINE__
);
13844 tng_block_destroy(&block
);
13845 tng_data
->input_file
= temp
;
13847 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13848 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13849 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13852 fseek(tng_data
->output_file
, (long)block
->block_contents_size
,
13855 if(tng_data
->var_num_atoms_flag
)
13857 tot_n_particles
= frame_set
->n_particles
;
13861 tot_n_particles
= tng_data
->n_particles
;
13864 if(val_n_particles
< tot_n_particles
)
13866 mapping_block_end_pos
= -1;
13867 /* Read all mapping blocks to find the right place to put the data */
13868 stat
= tng_block_header_read(tng_data
, block
);
13869 while(file_pos
< output_file_len
&&
13870 stat
!= TNG_CRITICAL
&&
13871 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
13873 if(block
->id
== TNG_PARTICLE_MAPPING
)
13875 tng_trajectory_mapping_block_read(tng_data
, block
, hash_mode
);
13879 fseek(tng_data
->output_file
, (long)block
->block_contents_size
,
13882 file_pos
= ftell(tng_data
->output_file
);
13883 if(block
->id
== TNG_PARTICLE_MAPPING
)
13885 mapping
= &frame_set
->mappings
[frame_set
->n_mapping_blocks
- 1];
13886 if(val_first_particle
>= mapping
->num_first_particle
&&
13887 val_first_particle
< mapping
->num_first_particle
+
13888 mapping
->n_particles
&&
13889 val_first_particle
+ val_n_particles
<=
13890 mapping
->num_first_particle
+ mapping
->n_particles
)
13892 mapping_block_end_pos
= file_pos
;
13895 if(file_pos
< output_file_len
)
13897 stat
= tng_block_header_read(tng_data
, block
);
13900 if(stat
== TNG_CRITICAL
)
13902 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
13903 file_pos
, __FILE__
, __LINE__
);
13904 tng_block_destroy(&block
);
13905 tng_data
->input_file
= temp
;
13907 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13908 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13909 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13912 if(mapping_block_end_pos
< 0)
13914 tng_block_destroy(&block
);
13915 tng_data
->input_file
= temp
;
13917 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13918 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13919 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13920 return(TNG_FAILURE
);
13922 fseek(tng_data
->output_file
, (long)mapping_block_end_pos
, SEEK_SET
);
13925 /* Read all block headers until next frame set block or
13926 * until the wanted block id is found */
13927 stat
= tng_block_header_read(tng_data
, block
);
13928 while(file_pos
< output_file_len
&&
13929 stat
!= TNG_CRITICAL
&&
13930 block
->id
!= block_id
&&
13931 block
->id
!= TNG_PARTICLE_MAPPING
&&
13932 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
13934 fseek(tng_data
->output_file
, (long)block
->block_contents_size
, SEEK_CUR
);
13935 file_pos
= ftell(tng_data
->output_file
);
13936 if(file_pos
< output_file_len
)
13938 stat
= tng_block_header_read(tng_data
, block
);
13941 if(stat
== TNG_CRITICAL
)
13943 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
13944 file_pos
, __FILE__
, __LINE__
);
13945 tng_block_destroy(&block
);
13946 tng_data
->input_file
= temp
;
13948 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13949 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13950 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13954 contents_size
= block
->block_contents_size
;
13955 header_size
= block
->header_contents_size
;
13957 header_pos
= ftell(tng_data
->output_file
) - header_size
;
13958 frame_set
= &tng_data
->current_trajectory_frame_set
;
13960 if(fread(&datatype
, sizeof(datatype
), 1, tng_data
->input_file
) == 0)
13962 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13963 tng_block_destroy(&block
);
13964 return(TNG_CRITICAL
);
13967 data
.datatype
= datatype
;
13969 if(fread(&dependency
, sizeof(dependency
), 1, tng_data
->input_file
) == 0)
13971 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13972 tng_block_destroy(&block
);
13973 return(TNG_CRITICAL
);
13976 if(!(dependency
& TNG_FRAME_DEPENDENT
) ||
13977 !(dependency
& TNG_PARTICLE_DEPENDENT
))
13979 tng_block_destroy(&block
);
13980 tng_data
->input_file
= temp
;
13982 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13983 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13984 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13985 return(TNG_FAILURE
);
13988 if(fread(&sparse_data
, sizeof(sparse_data
), 1, tng_data
->input_file
) == 0)
13990 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13991 tng_block_destroy(&block
);
13992 return(TNG_CRITICAL
);
13995 if(fread(&data
.n_values_per_frame
, sizeof(data
.n_values_per_frame
), 1,
13996 tng_data
->input_file
) == 0)
13998 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13999 tng_block_destroy(&block
);
14000 return(TNG_CRITICAL
);
14002 if(tng_data
->output_endianness_swap_func_64
)
14004 if(tng_data
->output_endianness_swap_func_64(tng_data
,
14005 &data
.n_values_per_frame
)
14008 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
14009 __FILE__
, __LINE__
);
14013 if(fread(&data
.codec_id
, sizeof(data
.codec_id
), 1,
14014 tng_data
->input_file
) == 0)
14016 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
14017 tng_block_destroy(&block
);
14018 return(TNG_CRITICAL
);
14020 if(tng_data
->output_endianness_swap_func_64
)
14022 if(tng_data
->output_endianness_swap_func_64(tng_data
,
14026 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
14027 __FILE__
, __LINE__
);
14031 if(data
.codec_id
!= TNG_UNCOMPRESSED
)
14033 if(fread(&data
.compression_multiplier
,
14034 sizeof(data
.compression_multiplier
), 1, tng_data
->input_file
)
14037 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
14038 tng_block_destroy(&block
);
14039 return(TNG_CRITICAL
);
14042 if(tng_data
->output_endianness_swap_func_64
)
14044 if(tng_data
->output_endianness_swap_func_64(tng_data
,
14045 (int64_t *)&data
.compression_multiplier
)
14048 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
14049 __FILE__
, __LINE__
);
14055 data
.compression_multiplier
= 1;
14060 if(fread(&data
.first_frame_with_data
,
14061 sizeof(data
.first_frame_with_data
),
14062 1, tng_data
->input_file
) == 0)
14064 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
14065 tng_block_destroy(&block
);
14066 return(TNG_CRITICAL
);
14068 if(tng_data
->output_endianness_swap_func_64
)
14070 if(tng_data
->output_endianness_swap_func_64(tng_data
,
14071 &data
.first_frame_with_data
)
14074 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
14075 __FILE__
, __LINE__
);
14079 if(fread(&data
.stride_length
, sizeof(data
.stride_length
),
14080 1, tng_data
->input_file
) == 0)
14082 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
14083 tng_block_destroy(&block
);
14084 return(TNG_CRITICAL
);
14086 if(tng_data
->output_endianness_swap_func_64
)
14088 if(tng_data
->output_endianness_swap_func_64(tng_data
,
14089 &data
.stride_length
)
14092 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
14093 __FILE__
, __LINE__
);
14099 data
.first_frame_with_data
= 0;
14100 data
.stride_length
= 1;
14102 data
.n_frames
= tng_data
->current_trajectory_frame_set
.n_frames
;
14104 if(fread(&num_first_particle
, sizeof(num_first_particle
), 1,
14105 tng_data
->input_file
) == 0)
14107 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
14108 tng_block_destroy(&block
);
14109 return(TNG_CRITICAL
);
14111 if(tng_data
->output_endianness_swap_func_64
)
14113 if(tng_data
->output_endianness_swap_func_64(tng_data
,
14114 &num_first_particle
)
14117 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
14118 __FILE__
, __LINE__
);
14122 if(fread(&block_n_particles
, sizeof(block_n_particles
), 1,
14123 tng_data
->input_file
) == 0)
14125 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
14126 tng_block_destroy(&block
);
14127 return(TNG_CRITICAL
);
14129 if(tng_data
->output_endianness_swap_func_64
)
14131 if(tng_data
->output_endianness_swap_func_64(tng_data
,
14132 &block_n_particles
)
14135 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
14136 __FILE__
, __LINE__
);
14141 tng_data
->input_file
= temp
;
14143 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
14144 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
14145 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
14148 switch(data
.datatype
)
14150 case(TNG_INT_DATA
):
14151 size
= sizeof(int64_t);
14153 case(TNG_FLOAT_DATA
):
14154 size
= sizeof(float);
14156 case(TNG_DOUBLE_DATA
):
14157 size
= sizeof(double);
14160 fprintf(stderr
, "TNG library: Cannot calculate writing locations. %s: %d.\n", __FILE__
,
14162 tng_block_destroy(&block
);
14163 return(TNG_FAILURE
);
14166 n_values_per_frame
= data
.n_values_per_frame
;
14168 file_pos
= (frame_nr
- tng_max_i64(frame_set
->first_frame
,
14169 data
.first_frame_with_data
)) /
14170 data
.stride_length
;
14171 file_pos
*= block_n_particles
* size
* n_values_per_frame
;
14173 if(file_pos
> contents_size
)
14175 fprintf(stderr
, "TNG library: Attempting to write outside the block. %s: %d\n", __FILE__
,
14177 tng_block_destroy(&block
);
14178 return(TNG_FAILURE
);
14181 fseek(tng_data
->output_file
, (long)file_pos
, SEEK_CUR
);
14183 /* If the endianness is not big endian the data needs to be swapped */
14184 if((data
.datatype
== TNG_INT_DATA
||
14185 data
.datatype
== TNG_DOUBLE_DATA
) &&
14186 tng_data
->output_endianness_swap_func_64
)
14188 copy
= malloc(val_n_particles
* n_values_per_frame
* size
);
14189 memcpy(copy
, values
, val_n_particles
* n_values_per_frame
* size
);
14190 for(i
= 0; i
< val_n_particles
* n_values_per_frame
; i
++)
14192 if(tng_data
->output_endianness_swap_func_64(tng_data
,
14193 (int64_t *) copy
+i
)
14196 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
14197 __FILE__
, __LINE__
);
14200 fwrite(copy
, val_n_particles
* n_values_per_frame
, size
,
14201 tng_data
->output_file
);
14204 else if(data
.datatype
== TNG_FLOAT_DATA
&&
14205 tng_data
->output_endianness_swap_func_32
)
14207 copy
= malloc(val_n_particles
* n_values_per_frame
* size
);
14208 memcpy(copy
, values
, val_n_particles
* n_values_per_frame
* size
);
14209 for(i
= 0; i
< val_n_particles
* n_values_per_frame
; i
++)
14211 if(tng_data
->output_endianness_swap_func_32(tng_data
,
14212 (int32_t *) copy
+i
)
14215 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
14216 __FILE__
, __LINE__
);
14219 fwrite(copy
, val_n_particles
* n_values_per_frame
, size
,
14220 tng_data
->output_file
);
14226 fwrite(values
, val_n_particles
* n_values_per_frame
, size
,
14227 tng_data
->output_file
);
14229 fflush(tng_data
->output_file
);
14231 /* Update the number of written frames in the frame set. */
14232 if(frame_nr
- frame_set
->first_frame
+ 1 > frame_set
->n_written_frames
)
14234 frame_set
->n_written_frames
= frame_nr
- frame_set
->first_frame
+ 1;
14237 /* If the last frame has been written update the hash */
14238 if(hash_mode
== TNG_USE_HASH
&& (frame_nr
+ data
.stride_length
-
14239 data
.first_frame_with_data
) >=
14240 frame_set
->n_frames
)
14242 tng_md5_hash_update(tng_data
, block
, header_pos
, header_pos
+
14246 tng_block_destroy(&block
);
14247 return(TNG_SUCCESS
);
14250 static tng_function_status tng_data_values_alloc
14251 (const tng_trajectory_t tng_data
,
14252 union data_values
***values
,
14253 const int64_t n_frames
,
14254 const int64_t n_values_per_frame
,
14258 tng_function_status stat
;
14260 if(n_frames
<= 0 || n_values_per_frame
<= 0)
14262 return(TNG_FAILURE
);
14267 stat
= tng_data_values_free(tng_data
, *values
, n_frames
,
14268 n_values_per_frame
,
14270 if(stat
!= TNG_SUCCESS
)
14272 fprintf(stderr
, "TNG library: Cannot free particle data values. %s: %d\n",
14273 __FILE__
, __LINE__
);
14277 *values
= malloc(sizeof(union data_values
*) * n_frames
);
14280 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
14281 sizeof(union data_values
**) * n_frames
,
14282 __FILE__
, __LINE__
);
14283 return(TNG_CRITICAL
);
14287 for(i
= n_frames
; i
--;)
14289 (*values
)[i
] = malloc(sizeof(union data_values
) *
14290 n_values_per_frame
);
14293 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
14294 sizeof(union data_values
) * n_values_per_frame
,
14295 __FILE__
, __LINE__
);
14298 return(TNG_CRITICAL
);
14301 return(TNG_SUCCESS
);
14304 /* FIXME: This needs ***values */
14305 tng_function_status DECLSPECDLLEXPORT tng_data_values_free
14306 (const tng_trajectory_t tng_data
,
14307 union data_values
**values
,
14308 const int64_t n_frames
,
14309 const int64_t n_values_per_frame
,
14317 for(i
= 0; i
< n_frames
; i
++)
14321 if(type
== TNG_CHAR_DATA
)
14323 for(j
= n_values_per_frame
; j
--;)
14327 free(values
[i
][j
].c
);
14328 values
[i
][j
].c
= 0;
14340 return(TNG_SUCCESS
);
14343 static tng_function_status tng_particle_data_values_alloc
14344 (const tng_trajectory_t tng_data
,
14345 union data_values
****values
,
14346 const int64_t n_frames
,
14347 const int64_t n_particles
,
14348 const int64_t n_values_per_frame
,
14352 tng_function_status stat
;
14354 if(n_particles
== 0 || n_values_per_frame
== 0)
14356 return(TNG_FAILURE
);
14361 stat
= tng_particle_data_values_free(tng_data
, *values
, n_frames
,
14362 n_particles
, n_values_per_frame
,
14364 if(stat
!= TNG_SUCCESS
)
14366 fprintf(stderr
, "TNG library: Cannot free particle data values. %s: %d\n",
14367 __FILE__
, __LINE__
);
14371 *values
= malloc(sizeof(union data_values
**) * n_frames
);
14374 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
14375 sizeof(union data_values
**) * n_frames
,
14376 __FILE__
, __LINE__
);
14377 return(TNG_CRITICAL
);
14381 for(i
= n_frames
; i
--;)
14383 (*values
)[i
] = malloc(sizeof(union data_values
*) *
14387 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
14388 sizeof(union data_values
*) * n_particles
,
14389 __FILE__
, __LINE__
);
14392 return(TNG_CRITICAL
);
14394 for(j
= n_particles
; j
--;)
14396 (*values
)[i
][j
] = malloc(sizeof(union data_values
) *
14397 n_values_per_frame
);
14398 if(!(*values
)[i
][j
])
14400 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
14401 sizeof(union data_values
*) * n_particles
,
14402 __FILE__
, __LINE__
);
14403 tng_particle_data_values_free(tng_data
, *values
, n_frames
,
14404 n_particles
, n_values_per_frame
,
14407 return(TNG_CRITICAL
);
14411 return(TNG_SUCCESS
);
14414 /* FIXME: This needs ****values */
14415 tng_function_status DECLSPECDLLEXPORT tng_particle_data_values_free
14416 (const tng_trajectory_t tng_data
,
14417 union data_values
***values
,
14418 const int64_t n_frames
,
14419 const int64_t n_particles
,
14420 const int64_t n_values_per_frame
,
14428 for(i
= 0; i
< n_frames
; i
++)
14432 for(j
= 0; j
< n_particles
; j
++)
14434 if(type
== TNG_CHAR_DATA
)
14436 for(k
= n_values_per_frame
; k
--;)
14438 if(values
[i
][j
][k
].c
)
14440 free(values
[i
][j
][k
].c
);
14441 values
[i
][j
][k
].c
= 0;
14445 free(values
[i
][j
]);
14456 return(TNG_SUCCESS
);
14460 tng_function_status DECLSPECDLLEXPORT tng_data_get
14461 (tng_trajectory_t tng_data
,
14462 const int64_t block_id
,
14463 union data_values
***values
,
14465 int64_t *n_values_per_frame
,
14468 int64_t i
, j
, file_pos
, block_index
;
14471 tng_non_particle_data_t data
;
14472 tng_trajectory_frame_set_t frame_set
;
14473 tng_gen_block_t block
;
14474 tng_function_status stat
;
14476 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
14477 TNG_ASSERT(n_frames
, "TNG library: n_frames must not be a NULL pointer.");
14478 TNG_ASSERT(n_values_per_frame
, "TNG library: n_values_per_frame must not be a NULL pointer.");
14479 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer.");
14481 frame_set
= &tng_data
->current_trajectory_frame_set
;
14486 if(tng_data_find(tng_data
, block_id
, &data
) != TNG_SUCCESS
)
14488 tng_block_init(&block
);
14489 file_pos
= ftell(tng_data
->input_file
);
14490 /* Read all blocks until next frame set block */
14491 stat
= tng_block_header_read(tng_data
, block
);
14492 while(file_pos
< tng_data
->input_file_len
&&
14493 stat
!= TNG_CRITICAL
&&
14494 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
14496 /* Use hash by default */
14497 stat
= tng_block_read_next(tng_data
, block
,
14499 if(stat
!= TNG_CRITICAL
)
14501 file_pos
= ftell(tng_data
->input_file
);
14502 if(file_pos
< tng_data
->input_file_len
)
14504 stat
= tng_block_header_read(tng_data
, block
);
14508 tng_block_destroy(&block
);
14509 if(stat
== TNG_CRITICAL
)
14511 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
14512 file_pos
, __FILE__
, __LINE__
);
14516 for(i
= frame_set
->n_data_blocks
; i
-- ;)
14518 data
= &frame_set
->tr_data
[i
];
14519 if(data
->block_id
== block_id
)
14525 if(block_index
< 0)
14527 return(TNG_FAILURE
);
14531 *n_frames
= tng_max_i64(1, data
->n_frames
);
14532 *n_values_per_frame
= data
->n_values_per_frame
;
14533 *type
= data
->datatype
;
14537 if(tng_data_values_alloc(tng_data
, values
, *n_frames
,
14538 *n_values_per_frame
,
14542 return(TNG_CRITICAL
);
14548 case TNG_CHAR_DATA
:
14549 for(i
=*n_frames
; i
--;)
14551 for(j
=*n_values_per_frame
; j
--;)
14553 len
= strlen(data
->strings
[i
][j
]) + 1;
14554 (*values
)[i
][j
].c
= malloc(len
);
14555 strncpy((*values
)[i
][j
].c
, data
->strings
[i
][j
], len
);
14560 size
= sizeof(int);
14561 for(i
=*n_frames
; i
--;)
14563 for(j
=*n_values_per_frame
; j
--;)
14565 (*values
)[i
][j
].i
= *(int *)((char *)data
->values
+ size
*
14566 (i
*(*n_values_per_frame
) + j
));
14570 case TNG_FLOAT_DATA
:
14571 size
= sizeof(float);
14572 for(i
=*n_frames
; i
--;)
14574 for(j
=*n_values_per_frame
; j
--;)
14576 (*values
)[i
][j
].f
= *(float *)((char *)data
->values
+ size
*
14577 (i
*(*n_values_per_frame
) + j
));
14581 case TNG_DOUBLE_DATA
:
14583 size
= sizeof(double);
14584 for(i
=*n_frames
; i
--;)
14586 for(j
=*n_values_per_frame
; j
--;)
14588 (*values
)[i
][j
].d
= *(double *)((char *)data
->values
+ size
*
14589 (i
*(*n_values_per_frame
) + j
));
14594 data
->last_retrieved_frame
= frame_set
->first_frame
+ data
->n_frames
- 1;
14596 return(TNG_SUCCESS
);
14599 tng_function_status
tng_data_vector_get(tng_trajectory_t tng_data
,
14600 const int64_t block_id
,
14603 int64_t *stride_length
,
14604 int64_t *n_values_per_frame
,
14607 int64_t file_pos
, data_size
, n_frames_div
, block_index
;
14609 tng_non_particle_data_t data
;
14610 tng_trajectory_frame_set_t frame_set
;
14611 tng_gen_block_t block
;
14613 tng_function_status stat
;
14615 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
14616 TNG_ASSERT(n_frames
, "TNG library: n_frames must not be a NULL pointer.");
14617 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer.");
14618 TNG_ASSERT(n_values_per_frame
, "TNG library: n_values_per_frame must not be a NULL pointer.");
14619 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer.");
14621 frame_set
= &tng_data
->current_trajectory_frame_set
;
14626 if(tng_data_find(tng_data
, block_id
, &data
) != TNG_SUCCESS
)
14628 tng_block_init(&block
);
14629 file_pos
= ftell(tng_data
->input_file
);
14630 /* Read all blocks until next frame set block */
14631 stat
= tng_block_header_read(tng_data
, block
);
14632 while(file_pos
< tng_data
->input_file_len
&&
14633 stat
!= TNG_CRITICAL
&&
14634 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
14636 /* Use hash by default */
14637 stat
= tng_block_read_next(tng_data
, block
,
14639 if(stat
!= TNG_CRITICAL
)
14641 file_pos
= ftell(tng_data
->input_file
);
14642 if(file_pos
< tng_data
->input_file_len
)
14644 stat
= tng_block_header_read(tng_data
, block
);
14648 tng_block_destroy(&block
);
14649 if(stat
== TNG_CRITICAL
)
14651 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
14652 file_pos
, __FILE__
, __LINE__
);
14656 for(i
= frame_set
->n_data_blocks
; i
-- ;)
14658 data
= &frame_set
->tr_data
[i
];
14659 if(data
->block_id
== block_id
)
14665 if(block_index
< 0)
14667 return(TNG_FAILURE
);
14671 *type
= data
->datatype
;
14675 case TNG_CHAR_DATA
:
14676 return(TNG_FAILURE
);
14678 size
= sizeof(int64_t);
14680 case TNG_FLOAT_DATA
:
14681 size
= sizeof(float);
14683 case TNG_DOUBLE_DATA
:
14685 size
= sizeof(double);
14688 *n_frames
= data
->n_frames
;
14689 *n_values_per_frame
= data
->n_values_per_frame
;
14690 *stride_length
= data
->stride_length
;
14691 n_frames_div
= (*n_frames
% *stride_length
) ? *n_frames
/ *stride_length
+ 1:
14692 *n_frames
/ *stride_length
;
14694 data_size
= n_frames_div
* size
*
14695 *n_values_per_frame
;
14697 temp
= realloc(*values
, data_size
);
14700 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
14701 data_size
, __FILE__
, __LINE__
);
14704 return(TNG_CRITICAL
);
14709 memcpy(*values
, data
->values
, data_size
);
14711 data
->last_retrieved_frame
= frame_set
->first_frame
+ data
->n_frames
- 1;
14713 return(TNG_SUCCESS
);
14716 tng_function_status DECLSPECDLLEXPORT tng_data_interval_get
14717 (tng_trajectory_t tng_data
,
14718 const int64_t block_id
,
14719 const int64_t start_frame_nr
,
14720 const int64_t end_frame_nr
,
14721 const char hash_mode
,
14722 union data_values
***values
,
14723 int64_t *n_values_per_frame
,
14726 int64_t i
, j
, n_frames
, file_pos
, current_frame_pos
, first_frame
;
14727 int64_t block_index
;
14730 tng_non_particle_data_t data
;
14731 tng_trajectory_frame_set_t frame_set
;
14732 tng_gen_block_t block
;
14733 tng_function_status stat
;
14735 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
14736 TNG_ASSERT(start_frame_nr
<= end_frame_nr
, "TNG library: start_frame_nr must not be higher than tne end_frame_nr.");
14737 TNG_ASSERT(n_values_per_frame
, "TNG library: n_values_per_frame must not be a NULL pointer.");
14738 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer.");
14742 frame_set
= &tng_data
->current_trajectory_frame_set
;
14743 first_frame
= frame_set
->first_frame
;
14745 stat
= tng_frame_set_of_frame_find(tng_data
, start_frame_nr
);
14746 if(stat
!= TNG_SUCCESS
)
14752 /* Do not re-read the frame set. */
14753 if(first_frame
!= frame_set
->first_frame
||
14754 frame_set
->n_data_blocks
<= 0)
14756 tng_block_init(&block
);
14757 file_pos
= ftell(tng_data
->input_file
);
14758 /* Read all blocks until next frame set block */
14759 stat
= tng_block_header_read(tng_data
, block
);
14760 while(file_pos
< tng_data
->input_file_len
&&
14761 stat
!= TNG_CRITICAL
&&
14762 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
14764 stat
= tng_block_read_next(tng_data
, block
,
14766 if(stat
!= TNG_CRITICAL
)
14768 file_pos
= ftell(tng_data
->input_file
);
14769 if(file_pos
< tng_data
->input_file_len
)
14771 stat
= tng_block_header_read(tng_data
, block
);
14775 tng_block_destroy(&block
);
14776 if(stat
== TNG_CRITICAL
)
14778 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
14779 file_pos
, __FILE__
, __LINE__
);
14785 /* See if there is a data block of this ID.
14786 * Start checking the last read frame set */
14787 for(i
= frame_set
->n_data_blocks
; i
-- ;)
14789 data
= &frame_set
->tr_data
[i
];
14790 if(data
->block_id
== block_id
)
14797 if(block_index
< 0)
14799 fprintf(stderr
, "TNG library: Could not find non-particle data block with id %"PRId64
". %s: %d\n",
14800 block_id
, __FILE__
, __LINE__
);
14801 return(TNG_FAILURE
);
14804 n_frames
= end_frame_nr
- start_frame_nr
+ 1;
14805 *n_values_per_frame
= data
->n_values_per_frame
;
14806 *type
= data
->datatype
;
14810 if(tng_data_values_alloc(tng_data
, values
, n_frames
,
14811 *n_values_per_frame
,
14812 *type
) != TNG_SUCCESS
)
14814 return(TNG_CRITICAL
);
14818 current_frame_pos
= start_frame_nr
- frame_set
->first_frame
;
14819 /* It's not very elegant to reuse so much of the code in the different case
14820 * statements, but it's unnecessarily slow to have the switch-case block
14821 * inside the for loops. */
14824 case TNG_CHAR_DATA
:
14825 for(i
=0; i
<n_frames
; i
++)
14827 if(current_frame_pos
== frame_set
->n_frames
)
14829 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
14830 if(stat
!= TNG_SUCCESS
)
14834 current_frame_pos
= 0;
14836 for(j
=*n_values_per_frame
; j
--;)
14838 len
= strlen(data
->strings
[current_frame_pos
][j
]) + 1;
14839 (*values
)[i
][j
].c
= malloc(len
);
14840 strncpy((*values
)[i
][j
].c
, data
->strings
[current_frame_pos
][j
], len
);
14842 current_frame_pos
++;
14846 size
= sizeof(int);
14847 for(i
=0; i
<n_frames
; i
++)
14849 if(current_frame_pos
== frame_set
->n_frames
)
14851 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
14852 if(stat
!= TNG_SUCCESS
)
14856 current_frame_pos
= 0;
14858 for(j
=*n_values_per_frame
; j
--;)
14860 (*values
)[i
][j
].i
= *(int *)((char *)data
->values
+ size
*
14861 (current_frame_pos
*
14862 (*n_values_per_frame
) + j
));
14864 current_frame_pos
++;
14867 case TNG_FLOAT_DATA
:
14868 size
= sizeof(float);
14869 for(i
=0; i
<n_frames
; i
++)
14871 if(current_frame_pos
== frame_set
->n_frames
)
14873 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
14874 if(stat
!= TNG_SUCCESS
)
14878 current_frame_pos
= 0;
14880 for(j
=*n_values_per_frame
; j
--;)
14882 (*values
)[i
][j
].f
= *(float *)((char *)data
->values
+ size
*
14883 (current_frame_pos
*
14884 (*n_values_per_frame
) + j
));
14886 current_frame_pos
++;
14889 case TNG_DOUBLE_DATA
:
14891 size
= sizeof(double);
14892 for(i
=0; i
<n_frames
; i
++)
14894 if(current_frame_pos
== frame_set
->n_frames
)
14896 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
14897 if(stat
!= TNG_SUCCESS
)
14901 current_frame_pos
= 0;
14903 for(j
=*n_values_per_frame
; j
--;)
14905 (*values
)[i
][j
].d
= *(double *)((char *)data
->values
+ size
*
14906 (current_frame_pos
*
14907 (*n_values_per_frame
) + j
));
14909 current_frame_pos
++;
14913 data
->last_retrieved_frame
= end_frame_nr
;
14915 return(TNG_SUCCESS
);
14918 tng_function_status DECLSPECDLLEXPORT tng_data_vector_interval_get
14919 (tng_trajectory_t tng_data
,
14920 const int64_t block_id
,
14921 const int64_t start_frame_nr
,
14922 const int64_t end_frame_nr
,
14923 const char hash_mode
,
14925 int64_t *stride_length
,
14926 int64_t *n_values_per_frame
,
14929 int64_t n_frames
, tot_n_frames
, n_frames_div
, n_frames_div_2
, first_frame
;
14930 int64_t file_pos
, current_frame_pos
, data_size
, frame_size
;
14931 int64_t last_frame_pos
;
14933 tng_trajectory_frame_set_t frame_set
;
14934 tng_non_particle_data_t np_data
;
14935 tng_gen_block_t block
;
14936 void *current_values
= 0, *temp
;
14937 tng_function_status stat
;
14939 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
14940 TNG_ASSERT(start_frame_nr
<= end_frame_nr
, "TNG library: start_frame_nr must not be higher than the end_frame_nr.");
14941 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer.");
14942 TNG_ASSERT(n_values_per_frame
, "TNG library: n_values_per_frame must not be a NULL pointer.");
14943 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer.");
14945 frame_set
= &tng_data
->current_trajectory_frame_set
;
14946 first_frame
= frame_set
->first_frame
;
14948 stat
= tng_frame_set_of_frame_find(tng_data
, start_frame_nr
);
14949 if(stat
!= TNG_SUCCESS
)
14954 /* Do not re-read the frame set and only need the requested block. */
14955 /* TODO: Test that blocks are read correctly now that not all of them are read at the same time. */
14956 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
14957 if(first_frame
!= frame_set
->first_frame
||
14958 stat
!= TNG_SUCCESS
)
14960 tng_block_init(&block
);
14961 if(stat
!= TNG_SUCCESS
)
14963 fseek(tng_data
->input_file
,
14964 (long)tng_data
->current_trajectory_frame_set_input_file_pos
,
14966 stat
= tng_block_header_read(tng_data
, block
);
14967 if(stat
!= TNG_SUCCESS
)
14969 fprintf(stderr
, "TNG library: Cannot read block header. %s: %d\n",
14970 __FILE__
, __LINE__
);
14974 fseek(tng_data
->input_file
, (long)block
->block_contents_size
, SEEK_CUR
);
14976 file_pos
= ftell(tng_data
->input_file
);
14977 /* Read until next frame set block */
14978 stat
= tng_block_header_read(tng_data
, block
);
14979 while(file_pos
< tng_data
->input_file_len
&&
14980 stat
!= TNG_CRITICAL
&&
14981 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
14983 if(block
->id
== block_id
)
14985 stat
= tng_block_read_next(tng_data
, block
,
14987 if(stat
!= TNG_CRITICAL
)
14989 file_pos
= ftell(tng_data
->input_file
);
14990 if(file_pos
< tng_data
->input_file_len
)
14992 stat
= tng_block_header_read(tng_data
, block
);
14998 file_pos
+= block
->block_contents_size
+ block
->header_contents_size
;
14999 fseek(tng_data
->input_file
, (long)block
->block_contents_size
, SEEK_CUR
);
15000 if(file_pos
< tng_data
->input_file_len
)
15002 stat
= tng_block_header_read(tng_data
, block
);
15006 tng_block_destroy(&block
);
15007 if(stat
== TNG_CRITICAL
)
15009 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
15010 file_pos
, __FILE__
, __LINE__
);
15015 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
15016 if(stat
!= TNG_SUCCESS
)
15021 stat
= tng_data_vector_get(tng_data
, block_id
, ¤t_values
,
15022 &n_frames
, stride_length
,
15023 n_values_per_frame
, type
);
15025 if(stat
!= TNG_SUCCESS
)
15029 free(current_values
);
15034 if(n_frames
== 1 && n_frames
< frame_set
->n_frames
)
15040 tot_n_frames
= end_frame_nr
- start_frame_nr
+ 1;
15045 case TNG_CHAR_DATA
:
15046 return(TNG_FAILURE
);
15048 size
= sizeof(int64_t);
15050 case TNG_FLOAT_DATA
:
15051 size
= sizeof(float);
15053 case TNG_DOUBLE_DATA
:
15055 size
= sizeof(double);
15058 n_frames_div
= (tot_n_frames
% *stride_length
) ?
15059 tot_n_frames
/ *stride_length
+ 1:
15060 tot_n_frames
/ *stride_length
;
15061 data_size
= n_frames_div
* size
* (*n_values_per_frame
);
15063 /* fprintf(stderr, "TNG library: size: %d, n_frames_div: %"PRId64", data_size: %"PRId64"\n",
15064 size, n_frames_div, data_size);
15066 temp
= realloc(*values
, data_size
);
15069 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
15070 data_size
, __FILE__
, __LINE__
);
15073 return(TNG_CRITICAL
);
15078 if( n_frames
== 1 && n_frames
< frame_set
->n_frames
)
15080 memcpy(*values
, current_values
, size
* (*n_values_per_frame
));
15084 current_frame_pos
= start_frame_nr
- frame_set
->first_frame
;
15086 frame_size
= size
* (*n_values_per_frame
);
15088 last_frame_pos
= tng_min_i64(n_frames
,
15089 end_frame_nr
- start_frame_nr
);
15091 n_frames_div
= current_frame_pos
/ *stride_length
;
15092 n_frames_div_2
= (last_frame_pos
% *stride_length
) ?
15093 last_frame_pos
/ *stride_length
+ 1:
15094 last_frame_pos
/ *stride_length
;
15095 n_frames_div_2
= tng_max_i64(1, n_frames_div_2
);
15097 memcpy(*values
, (char *)current_values
+ n_frames_div
* frame_size
,
15098 n_frames_div_2
* frame_size
);
15100 current_frame_pos
+= n_frames
- current_frame_pos
;
15102 while(current_frame_pos
<= end_frame_nr
- start_frame_nr
)
15104 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
15105 if(stat
!= TNG_SUCCESS
)
15109 free(current_values
);
15116 stat
= tng_data_vector_get(tng_data
, block_id
, ¤t_values
,
15117 &n_frames
, stride_length
,
15118 n_values_per_frame
, type
);
15120 if(stat
!= TNG_SUCCESS
)
15124 free(current_values
);
15131 last_frame_pos
= tng_min_i64(n_frames
,
15132 end_frame_nr
- current_frame_pos
);
15134 n_frames_div
= current_frame_pos
/ *stride_length
;
15135 n_frames_div_2
= (last_frame_pos
% *stride_length
) ?
15136 last_frame_pos
/ *stride_length
+ 1:
15137 last_frame_pos
/ *stride_length
;
15138 n_frames_div_2
= tng_max_i64(1, n_frames_div_2
);
15140 memcpy(((char *)*values
) + n_frames_div
* frame_size
,
15142 n_frames_div_2
* frame_size
);
15144 current_frame_pos
+= n_frames
;
15150 free(current_values
);
15153 np_data
->last_retrieved_frame
= end_frame_nr
;
15155 return(TNG_SUCCESS
);
15158 tng_function_status DECLSPECDLLEXPORT tng_particle_data_get
15159 (tng_trajectory_t tng_data
,
15160 const int64_t block_id
,
15161 union data_values
****values
,
15163 int64_t *n_particles
,
15164 int64_t *n_values_per_frame
,
15167 int64_t i
, j
, k
, mapping
, file_pos
, i_step
, block_index
;
15170 tng_particle_data_t data
;
15171 tng_trajectory_frame_set_t frame_set
;
15172 tng_gen_block_t block
;
15173 char block_type_flag
;
15174 tng_function_status stat
;
15176 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
15177 TNG_ASSERT(n_frames
, "TNG library: n_frames must not be a NULL pointer.");
15178 TNG_ASSERT(n_particles
, "TNG library: n_particles must not be a NULL pointer.");
15179 TNG_ASSERT(n_values_per_frame
, "TNG library: n_values_per_frame must not be a NULL pointer.");
15180 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer.");
15182 frame_set
= &tng_data
->current_trajectory_frame_set
;
15187 if(tng_particle_data_find(tng_data
, block_id
, &data
) != TNG_SUCCESS
)
15189 if(tng_data
->current_trajectory_frame_set_input_file_pos
> 0)
15191 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
15195 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
15198 tng_block_init(&block
);
15199 file_pos
= ftell(tng_data
->input_file
);
15200 /* Read all blocks until next frame set block */
15201 stat
= tng_block_header_read(tng_data
, block
);
15202 while(file_pos
< tng_data
->input_file_len
&&
15203 stat
!= TNG_CRITICAL
&&
15204 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
15206 /* Use hash by default */
15207 stat
= tng_block_read_next(tng_data
, block
,
15209 if(stat
!= TNG_CRITICAL
)
15211 file_pos
= ftell(tng_data
->input_file
);
15212 if(file_pos
< tng_data
->input_file_len
)
15214 stat
= tng_block_header_read(tng_data
, block
);
15218 tng_block_destroy(&block
);
15219 if(stat
== TNG_CRITICAL
)
15221 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
15222 file_pos
, __FILE__
, __LINE__
);
15226 for(i
= frame_set
->n_particle_data_blocks
; i
-- ;)
15228 data
= &frame_set
->tr_particle_data
[i
];
15229 if(data
->block_id
== block_id
)
15232 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
15236 if(block_index
< 0)
15238 return(TNG_FAILURE
);
15243 if(tng_data
->current_trajectory_frame_set_input_file_pos
> 0)
15245 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
15249 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
15253 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
&&
15254 tng_data
->var_num_atoms_flag
)
15256 *n_particles
= frame_set
->n_particles
;
15260 *n_particles
= tng_data
->n_particles
;
15263 *n_frames
= tng_max_i64(1, data
->n_frames
);
15264 *n_values_per_frame
= data
->n_values_per_frame
;
15265 *type
= data
->datatype
;
15269 if(tng_particle_data_values_alloc(tng_data
, values
, *n_frames
,
15270 *n_particles
, *n_values_per_frame
,
15274 return(TNG_CRITICAL
);
15278 /* It's not very elegant to reuse so much of the code in the different case
15279 * statements, but it's unnecessarily slow to have the switch-case block
15280 * inside the for loops. */
15283 case TNG_CHAR_DATA
:
15284 for(i
=*n_frames
; i
--;)
15286 for(j
=*n_particles
; j
--;)
15288 tng_particle_mapping_get_real_particle(frame_set
, j
, &mapping
);
15289 for(k
=*n_values_per_frame
; k
--;)
15291 len
= strlen(data
->strings
[i
][j
][k
]) + 1;
15292 (*values
)[i
][mapping
][k
].c
= malloc(len
);
15293 strncpy((*values
)[i
][mapping
][k
].c
,
15294 data
->strings
[i
][j
][k
], len
);
15300 size
= sizeof(int);
15301 i_step
= (*n_particles
) * (*n_values_per_frame
);
15302 for(i
=*n_frames
; i
--;)
15304 for(j
=*n_particles
; j
--;)
15306 tng_particle_mapping_get_real_particle(frame_set
, j
, &mapping
);
15307 for(k
=*n_values_per_frame
; k
--;)
15309 (*values
)[i
][mapping
][k
].i
= *(int *)
15310 ((char *)data
->values
+ size
*
15312 (*n_values_per_frame
) + k
));
15317 case TNG_FLOAT_DATA
:
15318 size
= sizeof(float);
15319 i_step
= (*n_particles
) * (*n_values_per_frame
);
15320 for(i
=*n_frames
; i
--;)
15322 for(j
=*n_particles
; j
--;)
15324 tng_particle_mapping_get_real_particle(frame_set
, j
, &mapping
);
15325 for(k
=*n_values_per_frame
; k
--;)
15327 (*values
)[i
][mapping
][k
].f
= *(float *)
15328 ((char *)data
->values
+ size
*
15330 (*n_values_per_frame
) + k
));
15335 case TNG_DOUBLE_DATA
:
15337 size
= sizeof(double);
15338 i_step
= (*n_particles
) * (*n_values_per_frame
);
15339 for(i
=*n_frames
; i
--;)
15341 for(j
=*n_particles
; j
--;)
15343 tng_particle_mapping_get_real_particle(frame_set
, j
, &mapping
);
15344 for(k
=*n_values_per_frame
; k
--;)
15346 (*values
)[i
][mapping
][k
].d
= *(double *)
15347 ((char *)data
->values
+ size
*
15349 (*n_values_per_frame
) + k
));
15355 data
->last_retrieved_frame
= frame_set
->first_frame
+ data
->n_frames
- 1;
15357 return(TNG_SUCCESS
);
15360 tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_get
15361 (tng_trajectory_t tng_data
,
15362 const int64_t block_id
,
15365 int64_t *stride_length
,
15366 int64_t *n_particles
,
15367 int64_t *n_values_per_frame
,
15370 int64_t i
, j
, mapping
, file_pos
, i_step
, data_size
, n_frames_div
;
15371 int64_t block_index
;
15373 tng_particle_data_t data
;
15374 tng_trajectory_frame_set_t frame_set
;
15375 tng_gen_block_t block
;
15377 char block_type_flag
;
15378 tng_function_status stat
;
15380 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
15381 TNG_ASSERT(n_particles
, "TNG library: n_particles must not be a NULL pointer.");
15382 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer.");
15383 TNG_ASSERT(n_values_per_frame
, "TNG library: n_values_per_frame must not be a NULL pointer.");
15384 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer.");
15386 frame_set
= &tng_data
->current_trajectory_frame_set
;
15391 if(tng_particle_data_find(tng_data
, block_id
, &data
) != TNG_SUCCESS
)
15393 tng_block_init(&block
);
15394 file_pos
= ftell(tng_data
->input_file
);
15395 /* Read all blocks until next frame set block */
15396 stat
= tng_block_header_read(tng_data
, block
);
15397 while(file_pos
< tng_data
->input_file_len
&&
15398 stat
!= TNG_CRITICAL
&&
15399 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
15401 /* Use hash by default */
15402 stat
= tng_block_read_next(tng_data
, block
,
15404 if(stat
!= TNG_CRITICAL
)
15406 file_pos
= ftell(tng_data
->input_file
);
15407 if(file_pos
< tng_data
->input_file_len
)
15409 stat
= tng_block_header_read(tng_data
, block
);
15413 tng_block_destroy(&block
);
15414 if(stat
== TNG_CRITICAL
)
15416 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
15417 file_pos
, __FILE__
, __LINE__
);
15421 for(i
= frame_set
->n_particle_data_blocks
; i
-- ;)
15423 data
= &frame_set
->tr_particle_data
[i
];
15424 if(data
->block_id
== block_id
)
15430 if(block_index
< 0)
15432 return(TNG_FAILURE
);
15436 if(tng_data
->current_trajectory_frame_set_input_file_pos
> 0)
15438 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
15442 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
15445 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
&&
15446 tng_data
->var_num_atoms_flag
)
15448 *n_particles
= frame_set
->n_particles
;
15452 *n_particles
= tng_data
->n_particles
;
15455 *type
= data
->datatype
;
15459 case TNG_CHAR_DATA
:
15460 return(TNG_FAILURE
);
15462 size
= sizeof(int64_t);
15464 case TNG_FLOAT_DATA
:
15465 size
= sizeof(float);
15467 case TNG_DOUBLE_DATA
:
15469 size
= sizeof(double);
15472 *n_frames
= tng_max_i64(1, data
->n_frames
);
15473 *n_values_per_frame
= data
->n_values_per_frame
;
15474 *stride_length
= data
->stride_length
;
15476 n_frames_div
= (*n_frames
% *stride_length
) ?
15477 *n_frames
/ *stride_length
+ 1:
15478 *n_frames
/ *stride_length
;
15480 data_size
= n_frames_div
* size
* (*n_particles
) *
15481 (*n_values_per_frame
);
15483 temp
= realloc(*values
, data_size
);
15486 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
15487 data_size
, __FILE__
, __LINE__
);
15490 return(TNG_CRITICAL
);
15495 if(frame_set
->n_mapping_blocks
<= 0)
15497 memcpy(*values
, data
->values
, data_size
);
15501 i_step
= (*n_particles
) * (*n_values_per_frame
);
15502 for(i
= *n_frames
; i
--;)
15504 for(j
= *n_particles
; j
--;)
15506 tng_particle_mapping_get_real_particle(frame_set
, j
, &mapping
);
15507 memcpy(((char *)*values
) + size
* (i
* i_step
+ mapping
*
15508 (*n_values_per_frame
)),
15509 (char *)data
->values
+ size
*
15510 (i
* i_step
+ j
* (*n_values_per_frame
)),
15511 size
* (*n_values_per_frame
));
15516 data
->last_retrieved_frame
= frame_set
->first_frame
+ data
->n_frames
- 1;
15518 return(TNG_SUCCESS
);
15521 tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get
15522 (tng_trajectory_t tng_data
,
15523 const int64_t block_id
,
15524 const int64_t start_frame_nr
,
15525 const int64_t end_frame_nr
,
15526 const char hash_mode
,
15527 union data_values
****values
,
15528 int64_t *n_particles
,
15529 int64_t *n_values_per_frame
,
15532 int64_t i
, j
, k
, mapping
, n_frames
, file_pos
, current_frame_pos
, i_step
;
15533 int64_t first_frame
, block_index
;
15536 tng_particle_data_t data
;
15537 tng_trajectory_frame_set_t frame_set
;
15538 tng_gen_block_t block
;
15539 char block_type_flag
;
15540 tng_function_status stat
;
15542 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
15543 TNG_ASSERT(start_frame_nr
<= end_frame_nr
, "TNG library: start_frame_nr must not be higher than tne end_frame_nr.");
15544 TNG_ASSERT(n_particles
, "TNG library: n_particles must not be a NULL pointer.");
15545 TNG_ASSERT(n_values_per_frame
, "TNG library: n_values_per_frame must not be a NULL pointer.");
15546 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer.");
15550 frame_set
= &tng_data
->current_trajectory_frame_set
;
15551 first_frame
= frame_set
->first_frame
;
15553 stat
= tng_frame_set_of_frame_find(tng_data
, start_frame_nr
);
15554 if(stat
!= TNG_SUCCESS
)
15559 /* Do not re-read the frame set. */
15560 if(first_frame
!= frame_set
->first_frame
||
15561 frame_set
->n_particle_data_blocks
<= 0)
15563 tng_block_init(&block
);
15564 file_pos
= ftell(tng_data
->input_file
);
15565 /* Read all blocks until next frame set block */
15566 stat
= tng_block_header_read(tng_data
, block
);
15567 while(file_pos
< tng_data
->input_file_len
&&
15568 stat
!= TNG_CRITICAL
&&
15569 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
15571 stat
= tng_block_read_next(tng_data
, block
,
15573 if(stat
!= TNG_CRITICAL
)
15575 file_pos
= ftell(tng_data
->input_file
);
15576 if(file_pos
< tng_data
->input_file_len
)
15578 stat
= tng_block_header_read(tng_data
, block
);
15582 tng_block_destroy(&block
);
15583 if(stat
== TNG_CRITICAL
)
15585 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
15586 file_pos
, __FILE__
, __LINE__
);
15591 /* See if there is already a data block of this ID.
15592 * Start checking the last read frame set */
15593 for(i
= frame_set
->n_particle_data_blocks
; i
-- ;)
15595 data
= &frame_set
->tr_particle_data
[i
];
15596 if(data
->block_id
== block_id
)
15599 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
15604 if(block_index
< 0)
15606 fprintf(stderr
, "TNG library: Could not find particle data block with id %"PRId64
". %s: %d\n",
15607 block_id
, __FILE__
, __LINE__
);
15608 return(TNG_FAILURE
);
15611 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
&&
15612 tng_data
->var_num_atoms_flag
)
15614 *n_particles
= frame_set
->n_particles
;
15618 *n_particles
= tng_data
->n_particles
;
15621 n_frames
= end_frame_nr
- start_frame_nr
+ 1;
15622 *n_values_per_frame
= data
->n_values_per_frame
;
15623 *type
= data
->datatype
;
15627 if(tng_particle_data_values_alloc(tng_data
, values
, n_frames
,
15628 *n_particles
, *n_values_per_frame
,
15632 return(TNG_CRITICAL
);
15636 current_frame_pos
= start_frame_nr
- frame_set
->first_frame
;
15637 /* It's not very elegant to reuse so much of the code in the different case
15638 * statements, but it's unnecessarily slow to have the switch-case block
15639 * inside the for loops. */
15642 case TNG_CHAR_DATA
:
15643 for(i
=0; i
<n_frames
; i
++)
15645 if(current_frame_pos
== frame_set
->n_frames
)
15647 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
15648 if(stat
!= TNG_SUCCESS
)
15652 current_frame_pos
= 0;
15654 for(j
=*n_particles
; j
--;)
15656 tng_particle_mapping_get_real_particle(frame_set
, j
, &mapping
);
15657 for(k
=*n_values_per_frame
; k
--;)
15659 len
= strlen(data
->strings
[current_frame_pos
][j
][k
]) + 1;
15660 (*values
)[i
][mapping
][k
].c
= malloc(len
);
15661 strncpy((*values
)[i
][mapping
][k
].c
, data
->strings
[current_frame_pos
][j
][k
], len
);
15664 current_frame_pos
++;
15668 size
= sizeof(int);
15669 i_step
= (*n_particles
) * (*n_values_per_frame
);
15670 for(i
=0; i
<n_frames
; i
++)
15672 if(current_frame_pos
== frame_set
->n_frames
)
15674 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
15675 if(stat
!= TNG_SUCCESS
)
15679 current_frame_pos
= 0;
15681 for(j
=*n_particles
; j
--;)
15683 tng_particle_mapping_get_real_particle(frame_set
, j
, &mapping
);
15684 for(k
=*n_values_per_frame
; k
--;)
15686 (*values
)[i
][mapping
][k
].i
= *(int *)
15687 ((char *)data
->values
+ size
*
15688 (current_frame_pos
*
15690 (*n_values_per_frame
) + k
));
15693 current_frame_pos
++;
15696 case TNG_FLOAT_DATA
:
15697 size
= sizeof(float);
15698 i_step
= (*n_particles
) * (*n_values_per_frame
);
15699 for(i
=0; i
<n_frames
; i
++)
15701 if(current_frame_pos
== frame_set
->n_frames
)
15703 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
15704 if(stat
!= TNG_SUCCESS
)
15708 current_frame_pos
= 0;
15710 for(j
=*n_particles
; j
--;)
15712 tng_particle_mapping_get_real_particle(frame_set
, j
, &mapping
);
15713 for(k
=*n_values_per_frame
; k
--;)
15715 (*values
)[i
][mapping
][k
].f
= *(float *)
15716 ((char *)data
->values
+ size
*
15717 (current_frame_pos
*
15719 (*n_values_per_frame
) + k
));
15722 current_frame_pos
++;
15725 case TNG_DOUBLE_DATA
:
15727 size
= sizeof(double);
15728 i_step
= (*n_particles
) * (*n_values_per_frame
);
15729 for(i
=0; i
<n_frames
; i
++)
15731 if(current_frame_pos
== frame_set
->n_frames
)
15733 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
15734 if(stat
!= TNG_SUCCESS
)
15738 current_frame_pos
= 0;
15740 for(j
=*n_particles
; j
--;)
15742 tng_particle_mapping_get_real_particle(frame_set
, j
, &mapping
);
15743 for(k
=*n_values_per_frame
; k
--;)
15745 (*values
)[i
][mapping
][k
].d
= *(double *)
15746 ((char *)data
->values
+ size
*
15747 (current_frame_pos
*
15749 (*n_values_per_frame
) + k
));
15752 current_frame_pos
++;
15756 data
->last_retrieved_frame
= end_frame_nr
;
15758 return(TNG_SUCCESS
);
15761 tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_interval_get
15762 (tng_trajectory_t tng_data
,
15763 const int64_t block_id
,
15764 const int64_t start_frame_nr
,
15765 const int64_t end_frame_nr
,
15766 const char hash_mode
,
15768 int64_t *n_particles
,
15769 int64_t *stride_length
,
15770 int64_t *n_values_per_frame
,
15773 int64_t n_frames
, tot_n_frames
, n_frames_div
, n_frames_div_2
, first_frame
;
15774 int64_t file_pos
, current_frame_pos
, last_frame_pos
, data_size
, frame_size
;
15776 tng_trajectory_frame_set_t frame_set
;
15777 tng_particle_data_t p_data
;
15778 tng_gen_block_t block
;
15779 void *current_values
= 0, *temp
;
15780 tng_function_status stat
;
15782 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
15783 TNG_ASSERT(start_frame_nr
<= end_frame_nr
, "TNG library: start_frame_nr must not be higher than tne end_frame_nr.");
15784 TNG_ASSERT(n_particles
, "TNG library: n_particles must not be a NULL pointer.");
15785 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer.");
15786 TNG_ASSERT(n_values_per_frame
, "TNG library: n_values_per_frame must not be a NULL pointer.");
15787 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer.");
15789 frame_set
= &tng_data
->current_trajectory_frame_set
;
15790 first_frame
= frame_set
->first_frame
;
15792 stat
= tng_frame_set_of_frame_find(tng_data
, start_frame_nr
);
15793 if(stat
!= TNG_SUCCESS
)
15798 /* Do not re-read the frame set and only need the requested block + particle mapping blocks. */
15799 /* TODO: Test that blocks are read correctly now that now all of them are read at the same time. */
15800 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
15801 if(first_frame
!= frame_set
->first_frame
||
15802 stat
!= TNG_SUCCESS
)
15804 tng_block_init(&block
);
15805 if(stat
!= TNG_SUCCESS
)
15807 fseek(tng_data
->input_file
,
15808 (long)tng_data
->current_trajectory_frame_set_input_file_pos
,
15810 stat
= tng_block_header_read(tng_data
, block
);
15811 if(stat
!= TNG_SUCCESS
)
15813 fprintf(stderr
, "TNG library: Cannot read block header. %s: %d\n",
15814 __FILE__
, __LINE__
);
15818 fseek(tng_data
->input_file
, (long)block
->block_contents_size
, SEEK_CUR
);
15820 file_pos
= ftell(tng_data
->input_file
);
15821 /* Read until next frame set block */
15822 stat
= tng_block_header_read(tng_data
, block
);
15823 while(file_pos
< tng_data
->input_file_len
&&
15824 stat
!= TNG_CRITICAL
&&
15825 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
15827 if(block
->id
== block_id
|| block
->id
== TNG_PARTICLE_MAPPING
)
15829 stat
= tng_block_read_next(tng_data
, block
,
15831 if(stat
!= TNG_CRITICAL
)
15833 file_pos
= ftell(tng_data
->input_file
);
15834 if(file_pos
< tng_data
->input_file_len
)
15836 stat
= tng_block_header_read(tng_data
, block
);
15842 file_pos
+= block
->block_contents_size
+ block
->header_contents_size
;
15843 fseek(tng_data
->input_file
, (long)block
->block_contents_size
, SEEK_CUR
);
15844 if(file_pos
< tng_data
->input_file_len
)
15846 stat
= tng_block_header_read(tng_data
, block
);
15850 tng_block_destroy(&block
);
15851 if(stat
== TNG_CRITICAL
)
15853 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
15854 file_pos
, __FILE__
, __LINE__
);
15858 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
15859 if(stat
!= TNG_SUCCESS
)
15864 stat
= tng_particle_data_vector_get(tng_data
, block_id
, ¤t_values
,
15865 &n_frames
, stride_length
, n_particles
,
15866 n_values_per_frame
, type
);
15868 if(stat
!= TNG_SUCCESS
|| *n_particles
== 0)
15872 free(current_values
);
15877 if(n_frames
== 1 && n_frames
< frame_set
->n_frames
)
15883 tot_n_frames
= end_frame_nr
- start_frame_nr
+ 1;
15888 case TNG_CHAR_DATA
:
15889 return(TNG_FAILURE
);
15891 size
= sizeof(int64_t);
15893 case TNG_FLOAT_DATA
:
15894 size
= sizeof(float);
15896 case TNG_DOUBLE_DATA
:
15898 size
= sizeof(double);
15901 n_frames_div
= (tot_n_frames
% *stride_length
) ?
15902 tot_n_frames
/ *stride_length
+ 1:
15903 tot_n_frames
/ *stride_length
;
15905 data_size
= n_frames_div
* size
* (*n_particles
) *
15906 (*n_values_per_frame
);
15908 temp
= realloc(*values
, data_size
);
15911 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
15912 data_size
, __FILE__
, __LINE__
);
15915 return(TNG_CRITICAL
);
15920 if( n_frames
== 1 && n_frames
< frame_set
->n_frames
)
15922 memcpy(*values
, current_values
, size
* (*n_particles
) *
15923 (*n_values_per_frame
));
15927 current_frame_pos
= start_frame_nr
- frame_set
->first_frame
;
15929 frame_size
= size
* (*n_particles
) * (*n_values_per_frame
);
15931 last_frame_pos
= tng_min_i64(n_frames
,
15932 end_frame_nr
- start_frame_nr
);
15934 n_frames_div
= current_frame_pos
/ *stride_length
;
15935 n_frames_div_2
= (last_frame_pos
% *stride_length
) ?
15936 last_frame_pos
/ *stride_length
+ 1:
15937 last_frame_pos
/ *stride_length
;
15938 n_frames_div_2
= tng_max_i64(1, n_frames_div_2
+ 1);
15940 memcpy(*values
, (char *)current_values
+ n_frames_div
* frame_size
,
15941 n_frames_div_2
* frame_size
);
15943 current_frame_pos
+= n_frames
- current_frame_pos
;
15945 while(current_frame_pos
<= end_frame_nr
- start_frame_nr
)
15947 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
15948 if(stat
!= TNG_SUCCESS
)
15952 free(current_values
);
15959 stat
= tng_particle_data_vector_get(tng_data
, block_id
, ¤t_values
,
15960 &n_frames
, stride_length
, n_particles
,
15961 n_values_per_frame
, type
);
15963 if(stat
!= TNG_SUCCESS
)
15967 free(current_values
);
15974 last_frame_pos
= tng_min_i64(n_frames
,
15975 end_frame_nr
- current_frame_pos
);
15977 n_frames_div
= current_frame_pos
/ *stride_length
;
15978 n_frames_div_2
= (last_frame_pos
% *stride_length
) ?
15979 last_frame_pos
/ *stride_length
+ 1:
15980 last_frame_pos
/ *stride_length
;
15981 n_frames_div_2
= tng_max_i64(1, n_frames_div_2
);
15983 memcpy(((char *)*values
) + n_frames_div
* frame_size
,
15985 n_frames_div_2
* frame_size
);
15987 current_frame_pos
+= n_frames
;
15993 free(current_values
);
15996 p_data
->last_retrieved_frame
= end_frame_nr
;
15998 return(TNG_SUCCESS
);
16001 tng_function_status DECLSPECDLLEXPORT tng_data_get_stride_length
16002 (const tng_trajectory_t tng_data
,
16003 const int64_t block_id
,
16005 int64_t *stride_length
)
16007 tng_function_status stat
;
16008 tng_non_particle_data_t np_data
;
16009 tng_particle_data_t p_data
;
16011 int is_particle_data
;
16013 if(tng_data
->current_trajectory_frame_set_input_file_pos
<= 0)
16020 stat
= tng_frame_set_of_frame_find(tng_data
, frame
);
16021 if(stat
!= TNG_SUCCESS
)
16026 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
16027 if(stat
!= TNG_SUCCESS
)
16029 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
16030 if(stat
!= TNG_SUCCESS
)
16032 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16033 /* If no specific frame was required read until this data block is found */
16036 file_pos
= ftell(tng_data
->input_file
);
16037 while(stat
!= TNG_SUCCESS
&& file_pos
< tng_data
->input_file_len
)
16039 stat
= tng_frame_set_read_next_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16040 file_pos
= ftell(tng_data
->input_file
);
16043 if(stat
!= TNG_SUCCESS
)
16047 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
16048 if(stat
!= TNG_SUCCESS
)
16050 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
16051 if(stat
!= TNG_SUCCESS
)
16057 is_particle_data
= 1;
16062 is_particle_data
= 0;
16067 is_particle_data
= 1;
16072 is_particle_data
= 0;
16074 if(is_particle_data
)
16076 *stride_length
= p_data
->stride_length
;
16080 *stride_length
= np_data
->stride_length
;
16082 return(TNG_SUCCESS
);
16085 tng_function_status DECLSPECDLLEXPORT tng_time_get_str
16086 (const tng_trajectory_t tng_data
,
16089 struct tm
*time_data
;
16092 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16093 TNG_ASSERT(time
, "TNG library: time must not be a NULL pointer");
16095 secs
= tng_data
->time
;
16097 time_data
= localtime(&secs
); /* Returns a statically allocated variable. */
16098 TNG_SNPRINTF(time
, TNG_MAX_DATE_STR_LEN
,
16099 "%4d-%02d-%02d %02d:%02d:%02d",
16100 time_data
->tm_year
+1900, time_data
->tm_mon
+1, time_data
->tm_mday
,
16101 time_data
->tm_hour
, time_data
->tm_min
, time_data
->tm_sec
);
16103 return(TNG_SUCCESS
);
16107 tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_open
16108 (const char *filename
,
16110 tng_trajectory_t
*tng_data_p
)
16112 tng_function_status stat
;
16114 TNG_ASSERT(filename
, "TNG library: filename must not be a NULL pointer.");
16116 if(mode
!= 'r' && mode
!= 'w' && mode
!= 'a')
16118 return(TNG_FAILURE
);
16121 if(tng_trajectory_init(tng_data_p
) != TNG_SUCCESS
)
16123 tng_trajectory_destroy(tng_data_p
);
16124 return(TNG_CRITICAL
);
16127 if(mode
== 'r' || mode
== 'a')
16129 tng_input_file_set(*tng_data_p
, filename
);
16131 /* Read the file headers */
16132 tng_file_headers_read(*tng_data_p
, TNG_USE_HASH
);
16134 tng_num_frame_sets_get(*tng_data_p
, &(*tng_data_p
)->n_trajectory_frame_sets
);
16139 tng_output_file_set(*tng_data_p
, filename
);
16141 else if(mode
== 'a')
16143 fseek((*tng_data_p
)->input_file
,
16144 (long)(*tng_data_p
)->last_trajectory_frame_set_input_file_pos
,
16147 stat
= tng_frame_set_read(*tng_data_p
, TNG_USE_HASH
);
16148 if(stat
!= TNG_SUCCESS
)
16150 fprintf(stderr
, "TNG library: Cannot read frame set and related blocks. %s: %d\n",
16151 __FILE__
, __LINE__
);
16154 (*tng_data_p
)->first_trajectory_frame_set_output_file_pos
=
16155 (*tng_data_p
)->first_trajectory_frame_set_input_file_pos
;
16156 (*tng_data_p
)->last_trajectory_frame_set_output_file_pos
=
16157 (*tng_data_p
)->last_trajectory_frame_set_input_file_pos
;
16158 (*tng_data_p
)->current_trajectory_frame_set_output_file_pos
=
16159 (*tng_data_p
)->current_trajectory_frame_set_input_file_pos
;
16160 (*tng_data_p
)->first_trajectory_frame_set_input_file_pos
= -1;
16161 (*tng_data_p
)->last_trajectory_frame_set_input_file_pos
= -1;
16162 (*tng_data_p
)->current_trajectory_frame_set_input_file_pos
= -1;
16163 if((*tng_data_p
)->input_file
)
16165 fclose((*tng_data_p
)->input_file
);
16166 (*tng_data_p
)->input_file
= 0;
16168 if((*tng_data_p
)->input_file_path
)
16170 free((*tng_data_p
)->input_file_path
);
16171 (*tng_data_p
)->input_file_path
= 0;
16173 tng_output_append_file_set(*tng_data_p
, filename
);
16175 fseek((*tng_data_p
)->output_file
, 0, SEEK_END
);
16178 return(TNG_SUCCESS
);
16181 tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_close
16182 (tng_trajectory_t
*tng_data_p
)
16184 tng_trajectory_frame_set_t frame_set
;
16186 if(tng_data_p
== 0)
16188 fprintf(stderr
, "TNG library: Empty pointer to trajectory when attempting to close. %s: %d\n",
16189 __FILE__
, __LINE__
);
16190 return(TNG_FAILURE
);
16193 if(*tng_data_p
== 0)
16195 return(TNG_SUCCESS
);
16198 frame_set
= &(*tng_data_p
)->current_trajectory_frame_set
;
16200 if(frame_set
->n_unwritten_frames
> 0)
16202 frame_set
->n_frames
= frame_set
->n_unwritten_frames
;
16203 tng_frame_set_write(*tng_data_p
, TNG_USE_HASH
);
16206 return(tng_trajectory_destroy(tng_data_p
));
16209 tng_function_status DECLSPECDLLEXPORT tng_util_time_of_frame_get
16210 (tng_trajectory_t tng_data
,
16211 const int64_t frame_nr
,
16214 int64_t first_frame
;
16215 tng_trajectory_frame_set_t frame_set
;
16216 tng_function_status stat
;
16218 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16219 TNG_ASSERT(time
, "TNG library: time must not be a NULL pointer");
16221 stat
= tng_frame_set_of_frame_find(tng_data
, frame_nr
);
16222 if(stat
!= TNG_SUCCESS
)
16224 fprintf(stderr
, "TNG library: Cannot find frame nr %"PRId64
". %s: %d\n",
16225 frame_nr
, __FILE__
, __LINE__
);
16229 frame_set
= &tng_data
->current_trajectory_frame_set
;
16230 first_frame
= frame_set
->first_frame
;
16232 if(tng_data
->time_per_frame
<= 0)
16234 return(TNG_FAILURE
);
16237 *time
= frame_set
->first_frame_time
+ (tng_data
->time_per_frame
* (frame_nr
- first_frame
));
16239 return(TNG_SUCCESS
);
16243 tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_molecules_get
16244 (tng_trajectory_t tng_data,
16246 int64_t **molecule_cnt_list,
16247 tng_molecule_t *mols)
16249 tng_trajectory_frame_set_t frame_set;
16251 TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
16252 TNG_ASSERT(n_mols, "TNG library: n_mols must not be a NULL pointer.");
16254 *n_mols = tng_data->n_molecules;
16256 frame_set = &tng_data->current_trajectory_frame_set;
16257 if(tng_data->var_num_atoms_flag && frame_set && frame_set->molecule_cnt_list)
16259 *molecule_cnt_list = frame_set->molecule_cnt_list;
16263 *molecule_cnt_list = tng_data->molecule_cnt_list;
16266 *mols = tng_data->molecules;
16268 return(TNG_SUCCESS);
16272 tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_molecule_add
16273 (tng_trajectory_t tng_data,
16276 tng_molecule_t *mol)
16278 tng_function_status stat;
16280 TNG_ASSERT(name, "TNG library: name must not be a NULL pointer");
16281 TNG_ASSERT(cnt>=0, "TNG library: cnt must be >= 0");
16283 stat = tng_molecule_add(tng_data, name, mol);
16284 if(stat != TNG_SUCCESS)
16288 stat = tng_molecule_cnt_set(tng_data, *mol, cnt);
16293 tng_function_status DECLSPECDLLEXPORT tng_util_molecule_particles_get
16294 (tng_trajectory_t tng_data
,
16295 const tng_molecule_t mol
,
16296 int64_t *n_particles
,
16301 char ***chain_names
,
16302 int64_t **chain_ids
)
16310 *n_particles
= mol
->n_atoms
;
16312 *names
= malloc(sizeof(char *) * *n_particles
);
16313 *types
= malloc(sizeof(char *) * *n_particles
);
16314 *res_names
= malloc(sizeof(char *) * *n_particles
);
16315 *chain_names
= malloc(sizeof(char *) * *n_particles
);
16316 *res_ids
= malloc(sizeof(int64_t) * *n_particles
);
16317 *chain_ids
= malloc(sizeof(int64_t) * *n_particles
);
16319 for(i
= 0; i
< *n_particles
; i
++)
16321 atom
= &mol
->atoms
[i
];
16322 res
= atom
->residue
;
16323 chain
= res
->chain
;
16324 (*names
)[i
] = malloc(strlen(atom
->name
));
16325 strcpy(*names
[i
], atom
->name
);
16326 (*types
)[i
] = malloc(strlen(atom
->atom_type
));
16327 strcpy(*types
[i
], atom
->atom_type
);
16328 (*res_names
)[i
] = malloc(strlen(res
->name
));
16329 strcpy(*res_names
[i
], res
->name
);
16330 (*chain_names
)[i
] = malloc(strlen(chain
->name
));
16331 strcpy(*chain_names
[i
], chain
->name
);
16332 (*res_ids
)[i
] = res
->id
;
16333 (*chain_ids
)[i
] = chain
->id
;
16336 return(TNG_SUCCESS
);
16339 tng_function_status DECLSPECDLLEXPORT tng_util_molecule_particles_set
16340 (tng_trajectory_t tng_data
,
16341 tng_molecule_t mol
,
16342 const int64_t n_particles
,
16343 const char **names
,
16344 const char **types
,
16345 const char **res_names
,
16346 const int64_t *res_ids
,
16347 const char **chain_names
,
16348 const int64_t *chain_ids
)
16352 tng_residue_t residue
;
16354 tng_function_status stat
;
16356 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16357 TNG_ASSERT(names
, "TNG library: names must not be a NULL pointer");
16358 TNG_ASSERT(types
, "TNG library: types must not be a NULL pointer");
16359 TNG_ASSERT(res_names
, "TNG library: res_names must not be a NULL pointer");
16360 TNG_ASSERT(res_ids
, "TNG library: res_ids must not be a NULL pointer");
16361 TNG_ASSERT(chain_names
, "TNG library: chain_names must not be a NULL pointer");
16362 TNG_ASSERT(chain_ids
, "TNG library: chain_ids must not be a NULL pointer");
16364 for(i
= 0; i
< n_particles
; i
++)
16366 if(tng_molecule_chain_find(tng_data
, mol
, chain_names
[i
], chain_ids
[i
],
16367 &chain
) == TNG_FAILURE
)
16369 stat
= tng_molecule_chain_add(tng_data
, mol
, chain_names
[i
],
16371 if(stat
!= TNG_SUCCESS
)
16376 if(tng_chain_residue_find(tng_data
, chain
, res_names
[i
], res_ids
[i
],
16377 &residue
) == TNG_FAILURE
)
16379 stat
= tng_chain_residue_add(tng_data
, chain
, res_names
[i
],
16381 if(stat
!= TNG_SUCCESS
)
16386 stat
= tng_residue_atom_add(tng_data
, residue
, names
[i
], types
[i
], &atom
);
16387 if(stat
!= TNG_SUCCESS
)
16392 return(TNG_SUCCESS
);
16395 tng_function_status DECLSPECDLLEXPORT tng_util_pos_read
16396 (tng_trajectory_t tng_data
,
16397 float **positions
, int64_t *stride_length
)
16399 int64_t n_frames
, n_particles
, n_values_per_frame
;
16401 tng_function_status stat
;
16403 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16404 TNG_ASSERT(positions
, "TNG library: positions must not be a NULL pointer");
16405 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer");
16407 stat
= tng_num_frames_get(tng_data
, &n_frames
);
16408 if(stat
!= TNG_SUCCESS
)
16413 stat
= tng_particle_data_vector_interval_get(tng_data
, TNG_TRAJ_POSITIONS
,
16414 0, n_frames
- 1, TNG_USE_HASH
,
16415 (void **)positions
,
16418 &n_values_per_frame
,
16424 tng_function_status DECLSPECDLLEXPORT tng_util_vel_read
16425 (tng_trajectory_t tng_data
,
16426 float **velocities
, int64_t *stride_length
)
16428 int64_t n_frames
, n_particles
, n_values_per_frame
;
16430 tng_function_status stat
;
16432 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16433 TNG_ASSERT(velocities
, "TNG library: velocities must not be a NULL pointer");
16434 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer");
16436 stat
= tng_num_frames_get(tng_data
, &n_frames
);
16437 if(stat
!= TNG_SUCCESS
)
16442 stat
= tng_particle_data_vector_interval_get(tng_data
, TNG_TRAJ_VELOCITIES
,
16443 0, n_frames
- 1, TNG_USE_HASH
,
16444 (void **)velocities
,
16447 &n_values_per_frame
,
16453 tng_function_status DECLSPECDLLEXPORT tng_util_force_read
16454 (tng_trajectory_t tng_data
,
16455 float **forces
, int64_t *stride_length
)
16457 int64_t n_frames
, n_particles
, n_values_per_frame
;
16459 tng_function_status stat
;
16461 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16462 TNG_ASSERT(forces
, "TNG library: forces must not be a NULL pointer");
16463 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer");
16465 stat
= tng_num_frames_get(tng_data
, &n_frames
);
16466 if(stat
!= TNG_SUCCESS
)
16471 stat
= tng_particle_data_vector_interval_get(tng_data
, TNG_TRAJ_FORCES
,
16472 0, n_frames
- 1, TNG_USE_HASH
,
16476 &n_values_per_frame
,
16482 tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_read
16483 (tng_trajectory_t tng_data
,
16485 int64_t *stride_length
)
16487 int64_t n_frames
, n_values_per_frame
;
16489 tng_function_status stat
;
16491 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16492 TNG_ASSERT(box_shape
, "TNG library: box_shape must not be a NULL pointer");
16493 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer");
16495 stat
= tng_num_frames_get(tng_data
, &n_frames
);
16496 if(stat
!= TNG_SUCCESS
)
16501 stat
= tng_data_vector_interval_get(tng_data
, TNG_TRAJ_BOX_SHAPE
,
16502 0, n_frames
- 1, TNG_USE_HASH
,
16503 (void **)box_shape
,
16505 &n_values_per_frame
,
16511 tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read
16512 (tng_trajectory_t tng_data
,
16513 const int64_t block_id
,
16516 int64_t *retrieved_frame_number
,
16517 double *retrieved_time
)
16519 tng_trajectory_frame_set_t frame_set
;
16520 tng_particle_data_t data
;
16521 tng_function_status stat
;
16523 int64_t i
, data_size
, n_particles
;
16527 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16528 TNG_ASSERT(values
, "TNG library: The pointer to the values array must not be a NULL pointer");
16529 TNG_ASSERT(data_type
, "TNG library: The pointer to the data type of the returned data must not be a NULL pointer");
16530 TNG_ASSERT(retrieved_frame_number
, "TNG library: The pointer to the frame number of the returned data must not be a NULL pointer");
16531 TNG_ASSERT(retrieved_time
, "TNG library: The pointer to the time of the returned data must not be a NULL pointer");
16533 frame_set
= &tng_data
->current_trajectory_frame_set
;
16535 stat
= tng_particle_data_find(tng_data
, block_id
, &data
);
16536 if(stat
!= TNG_SUCCESS
)
16538 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16539 file_pos
= ftell(tng_data
->input_file
);
16540 while(stat
!= TNG_SUCCESS
&& file_pos
< tng_data
->input_file_len
)
16542 stat
= tng_frame_set_read_next_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16543 file_pos
= ftell(tng_data
->input_file
);
16545 if(stat
!= TNG_SUCCESS
)
16549 stat
= tng_particle_data_find(tng_data
, block_id
, &data
);
16550 if(stat
!= TNG_SUCCESS
)
16555 if(data
->last_retrieved_frame
< 0)
16557 fseek(tng_data
->input_file
,
16558 (long)tng_data
->first_trajectory_frame_set_input_file_pos
,
16560 stat
= tng_frame_set_read(tng_data
, TNG_USE_HASH
);
16561 if(stat
!= TNG_SUCCESS
)
16565 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16566 if(stat
!= TNG_SUCCESS
)
16571 i
= data
->first_frame_with_data
;
16575 i
= data
->last_retrieved_frame
+ data
->stride_length
;
16576 if(i
< frame_set
->first_frame
|| i
>= frame_set
->first_frame
+ frame_set
->n_frames
)
16578 stat
= tng_frame_set_of_frame_find(tng_data
, i
);
16579 if(stat
!= TNG_SUCCESS
)
16581 /* If the frame set search found the frame set after the starting
16582 * frame set there is a gap in the frame sets. So, even if the frame
16583 * was not found the next frame with data is still in the found
16585 if(stat
== TNG_CRITICAL
)
16589 i
= frame_set
->first_frame
;
16592 if(data
->last_retrieved_frame
< frame_set
->first_frame
)
16594 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16595 if(stat
!= TNG_SUCCESS
)
16601 data
->last_retrieved_frame
= i
;
16602 *retrieved_frame_number
= i
;
16603 if(frame_set
->first_frame_time
>= 0 && tng_data
->time_per_frame
>= 0)
16605 *retrieved_time
= frame_set
->first_frame_time
+
16606 (i
- frame_set
->first_frame
) *
16607 tng_data
->time_per_frame
;
16611 *retrieved_time
= 0;
16614 if(data
->stride_length
> 1)
16616 i
= (i
- data
->first_frame_with_data
) / data
->stride_length
;
16620 i
= (i
- frame_set
->first_frame
);
16623 tng_num_particles_get(tng_data
, &n_particles
);
16625 *data_type
= data
->datatype
;
16629 case TNG_CHAR_DATA
:
16630 return(TNG_FAILURE
);
16632 size
= sizeof(int64_t);
16634 case TNG_FLOAT_DATA
:
16635 size
= sizeof(float);
16637 case TNG_DOUBLE_DATA
:
16639 size
= sizeof(double);
16642 data_size
= size
* n_particles
* data
->n_values_per_frame
;
16644 // fprintf(stderr, "TNG library: TEMP: i = %"PRId64", data_size = %"PRId64", size = %d, n_particles = %"PRId64", n_values_per_frame = %"PRId64"\n",
16645 // i, data_size, size, n_particles, data->n_values_per_frame);
16647 temp
= realloc(*values
, data_size
);
16650 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
16651 data_size
, __FILE__
, __LINE__
);
16654 return(TNG_CRITICAL
);
16659 memcpy(*values
, (char *)data
->values
+ i
* data_size
, data_size
);
16661 return(TNG_SUCCESS
);
16664 tng_function_status DECLSPECDLLEXPORT tng_util_non_particle_data_next_frame_read
16665 (tng_trajectory_t tng_data
,
16666 const int64_t block_id
,
16669 int64_t *retrieved_frame_number
,
16670 double *retrieved_time
)
16672 tng_trajectory_frame_set_t frame_set
;
16673 tng_non_particle_data_t data
;
16674 tng_function_status stat
;
16676 int64_t i
, data_size
;
16680 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16681 TNG_ASSERT(values
, "TNG library: The pointer to the values array must not be a NULL pointer");
16682 TNG_ASSERT(data_type
, "TNG library: The pointer to the data type of the returned data must not be a NULL pointer");
16683 TNG_ASSERT(retrieved_frame_number
, "TNG library: The pointer to the frame number of the returned data must not be a NULL pointer");
16684 TNG_ASSERT(retrieved_time
, "TNG library: The pointer to the time of the returned data must not be a NULL pointer");
16686 frame_set
= &tng_data
->current_trajectory_frame_set
;
16688 stat
= tng_data_find(tng_data
, block_id
, &data
);
16689 if(stat
!= TNG_SUCCESS
)
16691 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16692 file_pos
= ftell(tng_data
->input_file
);
16693 while(stat
!= TNG_SUCCESS
&& file_pos
< tng_data
->input_file_len
)
16695 stat
= tng_frame_set_read_next_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16696 file_pos
= ftell(tng_data
->input_file
);
16698 if(stat
!= TNG_SUCCESS
)
16702 stat
= tng_data_find(tng_data
, block_id
, &data
);
16703 if(stat
!= TNG_SUCCESS
)
16708 if(data
->last_retrieved_frame
< 0)
16710 fseek(tng_data
->input_file
,
16711 (long)tng_data
->first_trajectory_frame_set_input_file_pos
,
16713 stat
= tng_frame_set_read(tng_data
, TNG_USE_HASH
);
16714 if(stat
!= TNG_SUCCESS
)
16718 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16719 if(stat
!= TNG_SUCCESS
)
16724 i
= data
->first_frame_with_data
;
16728 i
= data
->last_retrieved_frame
+ data
->stride_length
;
16729 if(i
< frame_set
->first_frame
|| i
>= frame_set
->first_frame
+ frame_set
->n_frames
)
16731 stat
= tng_frame_set_of_frame_find(tng_data
, i
);
16732 if(stat
!= TNG_SUCCESS
)
16734 /* If the frame set search found the frame set after the starting
16735 * frame set there is a gap in the frame sets. So, even if the frame
16736 * was not found the next frame with data is still in the found
16738 if(stat
== TNG_CRITICAL
)
16742 i
= frame_set
->first_frame
;
16745 if(data
->last_retrieved_frame
< frame_set
->first_frame
)
16747 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16748 if(stat
!= TNG_SUCCESS
)
16754 data
->last_retrieved_frame
= i
;
16755 *retrieved_frame_number
= i
;
16756 if(frame_set
->first_frame_time
>= 0 && tng_data
->time_per_frame
>= 0)
16758 *retrieved_time
= frame_set
->first_frame_time
+
16759 (i
- frame_set
->first_frame
) *
16760 tng_data
->time_per_frame
;
16764 *retrieved_time
= 0;
16767 if(data
->stride_length
> 1)
16769 i
= (i
- data
->first_frame_with_data
) / data
->stride_length
;
16773 i
= (i
- frame_set
->first_frame
);
16776 *data_type
= data
->datatype
;
16780 case TNG_CHAR_DATA
:
16781 return(TNG_FAILURE
);
16783 size
= sizeof(int64_t);
16785 case TNG_FLOAT_DATA
:
16786 size
= sizeof(float);
16788 case TNG_DOUBLE_DATA
:
16790 size
= sizeof(double);
16793 data_size
= size
* data
->n_values_per_frame
;
16795 temp
= realloc(*values
, data_size
);
16798 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
16799 data_size
, __FILE__
, __LINE__
);
16802 return(TNG_CRITICAL
);
16807 memcpy(*values
, (char *)data
->values
+ i
* data_size
, data_size
);
16809 return(TNG_SUCCESS
);
16812 tng_function_status DECLSPECDLLEXPORT tng_util_pos_read_range
16813 (tng_trajectory_t tng_data
,
16814 const int64_t first_frame
,
16815 const int64_t last_frame
,
16817 int64_t *stride_length
)
16819 int64_t n_particles
, n_values_per_frame
;
16821 tng_function_status stat
;
16823 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16824 TNG_ASSERT(positions
, "TNG library: positions must not be a NULL pointer");
16825 TNG_ASSERT(first_frame
<= last_frame
, "TNG library: first_frame must be lower or equal to last_frame.");
16826 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer");
16828 stat
= tng_particle_data_vector_interval_get(tng_data
, TNG_TRAJ_POSITIONS
,
16829 first_frame
, last_frame
,
16831 (void **)positions
,
16834 &n_values_per_frame
,
16840 tng_function_status DECLSPECDLLEXPORT tng_util_vel_read_range
16841 (tng_trajectory_t tng_data
,
16842 const int64_t first_frame
,
16843 const int64_t last_frame
,
16844 float **velocities
,
16845 int64_t *stride_length
)
16847 int64_t n_particles
, n_values_per_frame
;
16849 tng_function_status stat
;
16851 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16852 TNG_ASSERT(velocities
, "TNG library: velocities must not be a NULL pointer");
16853 TNG_ASSERT(first_frame
<= last_frame
, "TNG library: first_frame must be lower or equal to last_frame.");
16854 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer");
16856 stat
= tng_particle_data_vector_interval_get(tng_data
, TNG_TRAJ_VELOCITIES
,
16857 first_frame
, last_frame
,
16859 (void **)velocities
,
16862 &n_values_per_frame
,
16868 tng_function_status DECLSPECDLLEXPORT tng_util_force_read_range
16869 (tng_trajectory_t tng_data
,
16870 const int64_t first_frame
,
16871 const int64_t last_frame
,
16873 int64_t *stride_length
)
16875 int64_t n_particles
, n_values_per_frame
;
16877 tng_function_status stat
;
16879 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16880 TNG_ASSERT(forces
, "TNG library: forces must not be a NULL pointer");
16881 TNG_ASSERT(first_frame
<= last_frame
, "TNG library: first_frame must be lower or equal to last_frame.");
16882 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer");
16884 stat
= tng_particle_data_vector_interval_get(tng_data
, TNG_TRAJ_FORCES
,
16885 first_frame
, last_frame
,
16890 &n_values_per_frame
,
16896 tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_read_range
16897 (tng_trajectory_t tng_data
,
16898 const int64_t first_frame
,
16899 const int64_t last_frame
,
16901 int64_t *stride_length
)
16903 int64_t n_values_per_frame
;
16905 tng_function_status stat
;
16907 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16908 TNG_ASSERT(box_shape
, "TNG library: box_shape must not be a NULL pointer");
16909 TNG_ASSERT(first_frame
<= last_frame
, "TNG library: first_frame must be lower or equal to last_frame.");
16910 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer");
16912 stat
= tng_data_vector_interval_get(tng_data
, TNG_TRAJ_BOX_SHAPE
,
16913 first_frame
, last_frame
,
16915 (void **)box_shape
,
16917 &n_values_per_frame
,
16923 tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_set
16924 (tng_trajectory_t tng_data
,
16926 const int64_t n_values_per_frame
,
16927 const int64_t block_id
,
16928 const char *block_name
,
16929 const char particle_dependency
,
16930 const char compression
)
16932 tng_trajectory_frame_set_t frame_set
;
16933 tng_particle_data_t p_data
;
16934 tng_non_particle_data_t np_data
;
16935 int64_t n_particles
, n_frames
;
16936 tng_function_status stat
;
16938 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16939 TNG_ASSERT(i
>= 0, "TNG library: i (writing interval) must be >= 0.");
16943 fprintf(stderr
, "TNG library: Cannot set writing frequency to %"PRId64
". %s: %d\n",
16944 i
, __FILE__
, __LINE__
);
16945 return(TNG_FAILURE
);
16948 frame_set
= &tng_data
->current_trajectory_frame_set
;
16950 if(!frame_set
|| tng_data
->n_trajectory_frame_sets
<= 0)
16952 n_frames
= tng_data
->frame_set_n_frames
;
16954 stat
= tng_frame_set_new(tng_data
, 0, n_frames
);
16955 if(stat
!= TNG_SUCCESS
)
16957 fprintf(stderr
, "TNG library: Cannot create frame set. %s: %d\n", __FILE__
,
16964 n_frames
= frame_set
->n_frames
;
16967 if(particle_dependency
== TNG_PARTICLE_BLOCK_DATA
)
16969 tng_num_particles_get(tng_data
, &n_particles
);
16970 if(n_particles
<= 0)
16972 return(TNG_FAILURE
);
16975 if(tng_particle_data_find(tng_data
, block_id
, &p_data
)
16978 stat
= tng_particle_data_block_add(tng_data
, block_id
,
16981 TNG_TRAJECTORY_BLOCK
,
16982 n_frames
, n_values_per_frame
, i
,
16985 if(stat
!= TNG_SUCCESS
)
16987 fprintf(stderr
, "TNG library: Error %s adding data block. %s: %d\n", block_name
,
16988 __FILE__
, __LINE__
);
16991 p_data
= &frame_set
->tr_particle_data
[frame_set
->
16992 n_particle_data_blocks
- 1];
16993 stat
= tng_allocate_particle_data_mem(tng_data
, p_data
, n_frames
,
16995 n_values_per_frame
);
16996 if(stat
!= TNG_SUCCESS
)
16998 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
16999 __FILE__
, __LINE__
);
17005 if(p_data
->stride_length
!= i
)
17007 p_data
->stride_length
= i
;
17008 stat
= tng_allocate_particle_data_mem(tng_data
, p_data
, n_frames
,
17010 n_values_per_frame
);
17011 if(stat
!= TNG_SUCCESS
)
17013 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
17014 __FILE__
, __LINE__
);
17022 if(tng_data_find(tng_data
, block_id
, &np_data
) != TNG_SUCCESS
)
17024 stat
= tng_data_block_add(tng_data
, block_id
, block_name
,
17025 TNG_FLOAT_DATA
, TNG_TRAJECTORY_BLOCK
,
17026 n_frames
, n_values_per_frame
,
17027 i
, compression
, 0);
17028 if(stat
!= TNG_SUCCESS
)
17030 fprintf(stderr
, "TNG library: Error %s adding data block. %s: %d\n", block_name
,
17031 __FILE__
, __LINE__
);
17034 np_data
= &frame_set
->tr_data
[frame_set
->
17035 n_data_blocks
- 1];
17036 stat
= tng_allocate_data_mem(tng_data
, np_data
, n_frames
,
17037 i
, n_values_per_frame
);
17038 if(stat
!= TNG_SUCCESS
)
17040 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
17041 __FILE__
, __LINE__
);
17047 if(np_data
->stride_length
!= i
)
17049 np_data
->stride_length
= i
;
17050 stat
= tng_allocate_data_mem(tng_data
, np_data
, n_frames
,
17051 i
, n_values_per_frame
);
17052 if(stat
!= TNG_SUCCESS
)
17054 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
17055 __FILE__
, __LINE__
);
17062 return(TNG_SUCCESS
);
17065 tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_double_set
17066 (tng_trajectory_t tng_data
,
17068 const int64_t n_values_per_frame
,
17069 const int64_t block_id
,
17070 const char *block_name
,
17071 const char particle_dependency
,
17072 const char compression
)
17074 tng_trajectory_frame_set_t frame_set
;
17075 tng_particle_data_t p_data
;
17076 tng_non_particle_data_t np_data
;
17077 int64_t n_particles
, n_frames
;
17078 tng_function_status stat
;
17080 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17081 TNG_ASSERT(i
>= 0, "TNG library: i (writing interval) must be >= 0.");
17085 fprintf(stderr
, "TNG library: Cannot set writing frequency to %"PRId64
". %s: %d\n",
17086 i
, __FILE__
, __LINE__
);
17087 return(TNG_FAILURE
);
17090 frame_set
= &tng_data
->current_trajectory_frame_set
;
17092 if(!frame_set
|| tng_data
->n_trajectory_frame_sets
<= 0)
17094 n_frames
= tng_data
->frame_set_n_frames
;
17096 stat
= tng_frame_set_new(tng_data
, 0, n_frames
);
17097 if(stat
!= TNG_SUCCESS
)
17099 fprintf(stderr
, "TNG library: Cannot create frame set. %s: %d\n", __FILE__
,
17106 n_frames
= frame_set
->n_frames
;
17109 if(particle_dependency
== TNG_PARTICLE_BLOCK_DATA
)
17111 tng_num_particles_get(tng_data
, &n_particles
);
17113 if(n_particles
<= 0)
17115 return(TNG_FAILURE
);
17118 if(tng_particle_data_find(tng_data
, block_id
, &p_data
)
17121 stat
= tng_particle_data_block_add(tng_data
, block_id
,
17124 TNG_TRAJECTORY_BLOCK
,
17125 n_frames
, n_values_per_frame
, i
,
17128 if(stat
!= TNG_SUCCESS
)
17130 fprintf(stderr
, "TNG library: Error %s adding data block. %s: %d\n", block_name
,
17131 __FILE__
, __LINE__
);
17134 p_data
= &frame_set
->tr_particle_data
[frame_set
->
17135 n_particle_data_blocks
- 1];
17136 stat
= tng_allocate_particle_data_mem(tng_data
, p_data
, n_frames
,
17138 n_values_per_frame
);
17139 if(stat
!= TNG_SUCCESS
)
17141 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
17142 __FILE__
, __LINE__
);
17148 p_data
->stride_length
= i
;
17153 if(tng_data_find(tng_data
, block_id
, &np_data
) != TNG_SUCCESS
)
17155 stat
= tng_data_block_add(tng_data
, block_id
, block_name
,
17156 TNG_DOUBLE_DATA
, TNG_TRAJECTORY_BLOCK
,
17157 n_frames
, n_values_per_frame
,
17158 i
, compression
, 0);
17159 if(stat
!= TNG_SUCCESS
)
17161 fprintf(stderr
, "TNG library: Error %s adding data block. %s: %d\n", block_name
,
17162 __FILE__
, __LINE__
);
17165 np_data
= &frame_set
->tr_data
[frame_set
->
17166 n_data_blocks
- 1];
17167 stat
= tng_allocate_data_mem(tng_data
, np_data
, n_frames
,
17168 i
, n_values_per_frame
);
17169 if(stat
!= TNG_SUCCESS
)
17171 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
17172 __FILE__
, __LINE__
);
17178 np_data
->stride_length
= i
;
17182 return(TNG_SUCCESS
);
17185 tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_frequency_set
17186 (tng_trajectory_t tng_data
,
17188 const int64_t n_values_per_frame
,
17189 const int64_t block_id
,
17190 const char *block_name
,
17191 const char particle_dependency
,
17192 const char compression
)
17194 fprintf(stderr
, "TNG library: Using obsolete function tng_util_generic_write_frequency_set(). "
17195 "See documentation. %s: %d", __FILE__
, __LINE__
);
17196 return(tng_util_generic_write_interval_set(tng_data
, i
, n_values_per_frame
,
17197 block_id
, block_name
,
17198 particle_dependency
,
17201 tng_function_status DECLSPECDLLEXPORT tng_util_pos_write_interval_set
17202 (tng_trajectory_t tng_data
,
17205 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17206 TNG_ASSERT(i
> 0, "TNG library: i (writing interval) must be >= 0.");
17208 return(tng_util_generic_write_interval_set(tng_data
, i
, 3,
17209 TNG_TRAJ_POSITIONS
,
17211 TNG_PARTICLE_BLOCK_DATA
,
17212 TNG_TNG_COMPRESSION
));
17215 tng_function_status DECLSPECDLLEXPORT tng_util_pos_write_interval_double_set
17216 (tng_trajectory_t tng_data
,
17219 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17220 TNG_ASSERT(i
> 0, "TNG library: i (writing interval) must be >= 0.");
17222 return(tng_util_generic_write_interval_double_set(tng_data
, i
, 3,
17223 TNG_TRAJ_POSITIONS
,
17225 TNG_PARTICLE_BLOCK_DATA
,
17226 TNG_TNG_COMPRESSION
));
17229 tng_function_status DECLSPECDLLEXPORT tng_util_pos_write_frequency_set
17230 (tng_trajectory_t tng_data
,
17233 fprintf(stderr
, "TNG library: Using obsolete function tng_util_pos_write_frequency_set(). "
17234 "See documentation. %s: %d", __FILE__
, __LINE__
);
17235 return(tng_util_pos_write_interval_set(tng_data
, i
));
17238 tng_function_status DECLSPECDLLEXPORT tng_util_vel_write_interval_set
17239 (tng_trajectory_t tng_data
,
17242 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17243 TNG_ASSERT(i
> 0, "TNG library: i (writing interval) must be >= 0.");
17245 return(tng_util_generic_write_interval_set(tng_data
, i
, 3,
17246 TNG_TRAJ_VELOCITIES
,
17248 TNG_PARTICLE_BLOCK_DATA
,
17249 TNG_TNG_COMPRESSION
));
17252 tng_function_status DECLSPECDLLEXPORT tng_util_vel_write_interval_double_set
17253 (tng_trajectory_t tng_data
,
17256 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17257 TNG_ASSERT(i
> 0, "TNG library: i (writing interval) must be >= 0.");
17259 return(tng_util_generic_write_interval_double_set(tng_data
, i
, 3,
17260 TNG_TRAJ_VELOCITIES
,
17262 TNG_PARTICLE_BLOCK_DATA
,
17263 TNG_TNG_COMPRESSION
));
17266 tng_function_status DECLSPECDLLEXPORT tng_util_vel_write_frequency_set
17267 (tng_trajectory_t tng_data
,
17270 fprintf(stderr
, "TNG library: Using obsolete function tng_util_vel_write_frequency_set(). "
17271 "See documentation. %s: %d", __FILE__
, __LINE__
);
17272 return(tng_util_vel_write_interval_set(tng_data
, i
));
17275 tng_function_status DECLSPECDLLEXPORT tng_util_force_write_interval_set
17276 (tng_trajectory_t tng_data
,
17279 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17280 TNG_ASSERT(i
> 0, "TNG library: i (writing interval) must be >= 0.");
17282 return(tng_util_generic_write_interval_set(tng_data
, i
, 3,
17285 TNG_PARTICLE_BLOCK_DATA
,
17286 TNG_GZIP_COMPRESSION
));
17289 tng_function_status DECLSPECDLLEXPORT tng_util_force_write_interval_double_set
17290 (tng_trajectory_t tng_data
,
17293 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17294 TNG_ASSERT(i
> 0, "TNG library: i (writing interval) must be >= 0.");
17296 return(tng_util_generic_write_interval_double_set(tng_data
, i
, 3,
17299 TNG_PARTICLE_BLOCK_DATA
,
17300 TNG_GZIP_COMPRESSION
));
17303 tng_function_status DECLSPECDLLEXPORT tng_util_force_write_frequency_set
17304 (tng_trajectory_t tng_data
,
17307 fprintf(stderr
, "TNG library: Using obsolete function tng_util_force_write_frequency_set(). "
17308 "See documentation. %s: %d", __FILE__
, __LINE__
);
17309 return(tng_util_force_write_interval_set(tng_data
, i
));
17312 tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_interval_set
17313 (tng_trajectory_t tng_data
,
17316 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17317 TNG_ASSERT(i
> 0, "TNG library: i (writing interval) must be >= 0.");
17319 return(tng_util_generic_write_interval_set(tng_data
, i
, 9,
17320 TNG_TRAJ_BOX_SHAPE
,
17322 TNG_NON_PARTICLE_BLOCK_DATA
,
17323 TNG_GZIP_COMPRESSION
));
17326 tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_interval_double_set
17327 (tng_trajectory_t tng_data
,
17330 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17331 TNG_ASSERT(i
> 0, "TNG library: i (writing interval) must be >= 0.");
17333 return(tng_util_generic_write_interval_double_set(tng_data
, i
, 9,
17334 TNG_TRAJ_BOX_SHAPE
,
17336 TNG_NON_PARTICLE_BLOCK_DATA
,
17337 TNG_GZIP_COMPRESSION
));
17340 tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_frequency_set
17341 (tng_trajectory_t tng_data
,
17344 fprintf(stderr
, "TNG library: Using obsolete function tng_util_box_shape_write_frequency_set(). "
17345 "See documentation. %s: %d", __FILE__
, __LINE__
);
17346 return(tng_util_box_shape_write_interval_set(tng_data
, i
));
17349 tng_function_status DECLSPECDLLEXPORT tng_util_generic_write
17350 (tng_trajectory_t tng_data
,
17351 const int64_t frame_nr
,
17352 const float *values
,
17353 const int64_t n_values_per_frame
,
17354 const int64_t block_id
,
17355 const char *block_name
,
17356 const char particle_dependency
,
17357 const char compression
)
17359 tng_trajectory_frame_set_t frame_set
;
17360 tng_particle_data_t p_data
;
17361 tng_non_particle_data_t np_data
;
17362 int64_t n_particles
, n_frames
, stride_length
= 100, frame_pos
;
17363 int64_t last_frame
;
17364 int is_first_frame_flag
= 0;
17365 char block_type_flag
;
17366 tng_function_status stat
;
17368 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17369 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17370 TNG_ASSERT(values
, "TNG library: values must not be a NULL pointer");
17372 if(particle_dependency
== TNG_PARTICLE_BLOCK_DATA
)
17374 tng_num_particles_get(tng_data
, &n_particles
);
17375 TNG_ASSERT(n_particles
> 0, "TNG library: There must be particles in the system to write particle data.");
17380 return(TNG_FAILURE
);
17383 frame_set
= &tng_data
->current_trajectory_frame_set
;
17387 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
17388 n_frames
= stride_length
= 1;
17392 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
17394 if(!frame_set
|| tng_data
->n_trajectory_frame_sets
<= 0)
17396 stat
= tng_frame_set_new(tng_data
, 0, tng_data
->frame_set_n_frames
);
17397 if(stat
!= TNG_SUCCESS
)
17399 fprintf(stderr
, "TNG library: Cannot create frame set. %s: %d\n", __FILE__
,
17404 last_frame
= frame_set
->first_frame
+
17405 frame_set
->n_frames
- 1;
17406 if(frame_nr
> last_frame
)
17408 stat
= tng_frame_set_write(tng_data
, TNG_USE_HASH
);
17409 if(stat
!= TNG_SUCCESS
)
17411 fprintf(stderr
, "TNG library: Cannot write frame set. %s: %d\n", __FILE__
,
17415 if(last_frame
+ tng_data
->frame_set_n_frames
< frame_nr
)
17417 last_frame
= frame_nr
- 1;
17419 stat
= tng_frame_set_new(tng_data
, last_frame
+ 1,
17420 tng_data
->frame_set_n_frames
);
17421 if(stat
!= TNG_SUCCESS
)
17423 fprintf(stderr
, "TNG library: Cannot create frame set. %s: %d\n", __FILE__
,
17428 if(frame_set
->n_unwritten_frames
== 0)
17430 is_first_frame_flag
= 1;
17432 frame_set
->n_unwritten_frames
= frame_nr
-
17433 frame_set
->first_frame
+ 1;
17435 n_frames
= frame_set
->n_frames
;
17438 if(particle_dependency
== TNG_PARTICLE_BLOCK_DATA
)
17440 if(tng_particle_data_find(tng_data
, block_id
, &p_data
)
17443 stat
= tng_particle_data_block_add(tng_data
, block_id
,
17447 n_frames
, n_values_per_frame
,
17451 if(stat
!= TNG_SUCCESS
)
17453 fprintf(stderr
, "TNG library: Error %s adding data block. %s: %d\n", block_name
,
17454 __FILE__
, __LINE__
);
17457 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
17459 p_data
= &frame_set
->tr_particle_data
[frame_set
->
17460 n_particle_data_blocks
- 1];
17464 p_data
= &tng_data
->non_tr_particle_data
[tng_data
->
17465 n_particle_data_blocks
- 1];
17467 stat
= tng_allocate_particle_data_mem(tng_data
, p_data
, n_frames
,
17468 stride_length
, n_particles
,
17469 n_values_per_frame
);
17470 if(stat
!= TNG_SUCCESS
)
17472 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
17473 __FILE__
, __LINE__
);
17478 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
17480 stride_length
= p_data
->stride_length
;
17482 if(is_first_frame_flag
|| p_data
->first_frame_with_data
< frame_set
->first_frame
)
17484 p_data
->first_frame_with_data
= frame_nr
;
17489 frame_pos
= (frame_nr
- frame_set
->first_frame
) / stride_length
;
17492 memcpy((char *)p_data
->values
+ sizeof(float) * frame_pos
* n_particles
*
17493 n_values_per_frame
, values
, sizeof(float) *
17494 n_particles
* n_values_per_frame
);
17498 memcpy(p_data
->values
, values
, sizeof(float) * n_particles
*
17499 n_values_per_frame
);
17504 if(tng_data_find(tng_data
, block_id
, &np_data
) != TNG_SUCCESS
)
17506 stat
= tng_data_block_add(tng_data
, block_id
, block_name
,
17507 TNG_FLOAT_DATA
, block_type_flag
,
17508 n_frames
, n_values_per_frame
,
17509 stride_length
, compression
, 0);
17510 if(stat
!= TNG_SUCCESS
)
17512 fprintf(stderr
, "TNG library: Error %s adding data block. %s: %d\n", block_name
,
17513 __FILE__
, __LINE__
);
17516 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
17518 np_data
= &frame_set
->tr_data
[frame_set
->
17519 n_data_blocks
- 1];
17523 np_data
= &tng_data
->non_tr_data
[tng_data
->
17524 n_data_blocks
- 1];
17526 stat
= tng_allocate_data_mem(tng_data
, np_data
, n_frames
,
17527 stride_length
, n_values_per_frame
);
17528 if(stat
!= TNG_SUCCESS
)
17530 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
17531 __FILE__
, __LINE__
);
17536 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
17538 stride_length
= np_data
->stride_length
;
17540 if(is_first_frame_flag
|| np_data
->first_frame_with_data
< frame_set
->first_frame
)
17542 np_data
->first_frame_with_data
= frame_nr
;
17547 frame_pos
= (frame_nr
- frame_set
->first_frame
) / stride_length
;
17550 memcpy((char *)np_data
->values
+ sizeof(float) * frame_pos
*
17551 n_values_per_frame
, values
, sizeof(float) *
17552 n_values_per_frame
);
17556 memcpy(np_data
->values
, values
, sizeof(float) * n_values_per_frame
);
17560 return(TNG_SUCCESS
);
17563 tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write
17564 (tng_trajectory_t tng_data
,
17565 const int64_t frame_nr
,
17566 const double *values
,
17567 const int64_t n_values_per_frame
,
17568 const int64_t block_id
,
17569 const char *block_name
,
17570 const char particle_dependency
,
17571 const char compression
)
17573 tng_trajectory_frame_set_t frame_set
;
17574 tng_particle_data_t p_data
;
17575 tng_non_particle_data_t np_data
;
17576 int64_t n_particles
, n_frames
, stride_length
= 100, frame_pos
;
17577 int64_t last_frame
;
17578 int is_first_frame_flag
= 0;
17579 char block_type_flag
;
17580 tng_function_status stat
;
17582 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17583 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17584 TNG_ASSERT(values
, "TNG library: values must not be a NULL pointer");
17586 if(particle_dependency
== TNG_PARTICLE_BLOCK_DATA
)
17588 tng_num_particles_get(tng_data
, &n_particles
);
17589 TNG_ASSERT(n_particles
> 0, "TNG library: There must be particles in the system to write particle data.");
17594 return(TNG_FAILURE
);
17597 frame_set
= &tng_data
->current_trajectory_frame_set
;
17601 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
17602 n_frames
= stride_length
= 1;
17606 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
17608 n_frames
= tng_data
->frame_set_n_frames
;
17610 if(!frame_set
|| tng_data
->n_trajectory_frame_sets
<= 0)
17612 stat
= tng_frame_set_new(tng_data
, 0, n_frames
);
17613 if(stat
!= TNG_SUCCESS
)
17615 fprintf(stderr
, "TNG library: Cannot create frame set. %s: %d\n", __FILE__
,
17622 n_frames
= frame_set
->n_frames
;
17624 last_frame
= frame_set
->first_frame
+
17625 frame_set
->n_frames
- 1;
17626 if(frame_nr
> last_frame
)
17628 stat
= tng_frame_set_write(tng_data
, TNG_USE_HASH
);
17629 if(stat
!= TNG_SUCCESS
)
17631 fprintf(stderr
, "TNG library: Cannot write frame set. %s: %d\n", __FILE__
,
17635 if(last_frame
+ tng_data
->frame_set_n_frames
< frame_nr
)
17637 last_frame
= frame_nr
- 1;
17639 stat
= tng_frame_set_new(tng_data
, last_frame
+ 1, n_frames
);
17640 if(stat
!= TNG_SUCCESS
)
17642 fprintf(stderr
, "TNG library: Cannot create frame set. %s: %d\n", __FILE__
,
17647 if(frame_set
->n_unwritten_frames
== 0)
17649 is_first_frame_flag
= 1;
17651 frame_set
->n_unwritten_frames
= frame_nr
-
17652 frame_set
->first_frame
+ 1;
17655 if(particle_dependency
== TNG_PARTICLE_BLOCK_DATA
)
17657 if(tng_particle_data_find(tng_data
, block_id
, &p_data
)
17660 stat
= tng_particle_data_block_add(tng_data
, block_id
,
17664 n_frames
, n_values_per_frame
,
17668 if(stat
!= TNG_SUCCESS
)
17670 fprintf(stderr
, "TNG library: Error %s adding data block. %s: %d\n", block_name
,
17671 __FILE__
, __LINE__
);
17674 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
17676 p_data
= &frame_set
->tr_particle_data
[frame_set
->
17677 n_particle_data_blocks
- 1];
17681 p_data
= &tng_data
->non_tr_particle_data
[tng_data
->
17682 n_particle_data_blocks
- 1];
17684 stat
= tng_allocate_particle_data_mem(tng_data
, p_data
, n_frames
,
17685 stride_length
, n_particles
,
17686 n_values_per_frame
);
17687 if(stat
!= TNG_SUCCESS
)
17689 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
17690 __FILE__
, __LINE__
);
17695 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
17697 stride_length
= p_data
->stride_length
;
17699 if(is_first_frame_flag
)
17701 p_data
->first_frame_with_data
= frame_nr
;
17706 frame_pos
= (frame_nr
- frame_set
->first_frame
) / stride_length
;
17709 memcpy((char *)p_data
->values
+ sizeof(double) * frame_pos
* n_particles
*
17710 n_values_per_frame
, values
, sizeof(double) *
17711 n_particles
* n_values_per_frame
);
17715 memcpy(p_data
->values
, values
, sizeof(double) * n_particles
*
17716 n_values_per_frame
);
17721 if(tng_data_find(tng_data
, block_id
, &np_data
) != TNG_SUCCESS
)
17723 stat
= tng_data_block_add(tng_data
, block_id
, block_name
,
17724 TNG_DOUBLE_DATA
, block_type_flag
,
17725 n_frames
, n_values_per_frame
,
17726 stride_length
, compression
, 0);
17727 if(stat
!= TNG_SUCCESS
)
17729 fprintf(stderr
, "TNG library: Error %s adding data block. %s: %d\n", block_name
,
17730 __FILE__
, __LINE__
);
17733 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
17735 np_data
= &frame_set
->tr_data
[frame_set
->
17736 n_data_blocks
- 1];
17740 np_data
= &tng_data
->non_tr_data
[tng_data
->
17741 n_data_blocks
- 1];
17743 stat
= tng_allocate_data_mem(tng_data
, np_data
, n_frames
,
17744 stride_length
, n_values_per_frame
);
17745 if(stat
!= TNG_SUCCESS
)
17747 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
17748 __FILE__
, __LINE__
);
17753 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
17755 stride_length
= np_data
->stride_length
;
17757 if(is_first_frame_flag
)
17759 np_data
->first_frame_with_data
= frame_nr
;
17764 frame_pos
= (frame_nr
- frame_set
->first_frame
) / stride_length
;
17767 memcpy((char *)np_data
->values
+ sizeof(double) * frame_pos
*
17768 n_values_per_frame
, values
, sizeof(double) *
17769 n_values_per_frame
);
17773 memcpy(np_data
->values
, values
, sizeof(double) * n_values_per_frame
);
17777 return(TNG_SUCCESS
);
17780 tng_function_status DECLSPECDLLEXPORT tng_util_pos_write
17781 (tng_trajectory_t tng_data
,
17782 const int64_t frame_nr
,
17783 const float *positions
)
17785 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17786 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17787 TNG_ASSERT(positions
, "TNG library: positions must not be a NULL pointer");
17789 return(tng_util_generic_write(tng_data
, frame_nr
, positions
, 3,
17790 TNG_TRAJ_POSITIONS
, "POSITIONS",
17791 TNG_PARTICLE_BLOCK_DATA
,
17792 TNG_TNG_COMPRESSION
));
17795 tng_function_status DECLSPECDLLEXPORT tng_util_pos_double_write
17796 (tng_trajectory_t tng_data
,
17797 const int64_t frame_nr
,
17798 const double *positions
)
17800 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17801 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17802 TNG_ASSERT(positions
, "TNG library: positions must not be a NULL pointer");
17804 return(tng_util_generic_double_write(tng_data
, frame_nr
, positions
, 3,
17805 TNG_TRAJ_POSITIONS
, "POSITIONS",
17806 TNG_PARTICLE_BLOCK_DATA
,
17807 TNG_TNG_COMPRESSION
));
17810 tng_function_status DECLSPECDLLEXPORT tng_util_vel_write
17811 (tng_trajectory_t tng_data
,
17812 const int64_t frame_nr
,
17813 const float *velocities
)
17815 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17816 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17817 TNG_ASSERT(velocities
, "TNG library: velocities must not be a NULL pointer");
17819 return(tng_util_generic_write(tng_data
, frame_nr
, velocities
, 3,
17820 TNG_TRAJ_VELOCITIES
, "VELOCITIES",
17821 TNG_PARTICLE_BLOCK_DATA
,
17822 TNG_TNG_COMPRESSION
));
17825 tng_function_status DECLSPECDLLEXPORT tng_util_vel_double_write
17826 (tng_trajectory_t tng_data
,
17827 const int64_t frame_nr
,
17828 const double *velocities
)
17830 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17831 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17832 TNG_ASSERT(velocities
, "TNG library: velocities must not be a NULL pointer");
17834 return(tng_util_generic_double_write(tng_data
, frame_nr
, velocities
, 3,
17835 TNG_TRAJ_VELOCITIES
, "VELOCITIES",
17836 TNG_PARTICLE_BLOCK_DATA
,
17837 TNG_TNG_COMPRESSION
));
17840 tng_function_status DECLSPECDLLEXPORT tng_util_force_write
17841 (tng_trajectory_t tng_data
,
17842 const int64_t frame_nr
,
17843 const float *forces
)
17845 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17846 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17847 TNG_ASSERT(forces
, "TNG library: forces must not be a NULL pointer");
17849 return(tng_util_generic_write(tng_data
, frame_nr
, forces
, 3,
17850 TNG_TRAJ_FORCES
, "FORCES",
17851 TNG_PARTICLE_BLOCK_DATA
,
17852 TNG_GZIP_COMPRESSION
));
17855 tng_function_status DECLSPECDLLEXPORT tng_util_force_double_write
17856 (tng_trajectory_t tng_data
,
17857 const int64_t frame_nr
,
17858 const double *forces
)
17860 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17861 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17862 TNG_ASSERT(forces
, "TNG library: forces must not be a NULL pointer");
17864 return(tng_util_generic_double_write(tng_data
, frame_nr
, forces
, 3,
17865 TNG_TRAJ_FORCES
, "FORCES",
17866 TNG_PARTICLE_BLOCK_DATA
,
17867 TNG_GZIP_COMPRESSION
));
17870 tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write
17871 (tng_trajectory_t tng_data
,
17872 const int64_t frame_nr
,
17873 const float *box_shape
)
17875 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17876 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17877 TNG_ASSERT(box_shape
, "TNG library: box_shape must not be a NULL pointer");
17879 return(tng_util_generic_write(tng_data
, frame_nr
, box_shape
, 9,
17880 TNG_TRAJ_BOX_SHAPE
, "BOX SHAPE",
17881 TNG_NON_PARTICLE_BLOCK_DATA
,
17882 TNG_GZIP_COMPRESSION
));
17885 tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_double_write
17886 (tng_trajectory_t tng_data
,
17887 const int64_t frame_nr
,
17888 const double *box_shape
)
17890 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17891 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17892 TNG_ASSERT(box_shape
, "TNG library: box_shape must not be a NULL pointer");
17894 return(tng_util_generic_double_write(tng_data
, frame_nr
, box_shape
, 9,
17895 TNG_TRAJ_BOX_SHAPE
, "BOX SHAPE",
17896 TNG_NON_PARTICLE_BLOCK_DATA
,
17897 TNG_GZIP_COMPRESSION
));
17900 tng_function_status DECLSPECDLLEXPORT tng_util_generic_with_time_write
17901 (tng_trajectory_t tng_data
,
17902 const int64_t frame_nr
,
17904 const float *values
,
17905 const int64_t n_values_per_frame
,
17906 const int64_t block_id
,
17907 const char *block_name
,
17908 const char particle_dependency
,
17909 const char compression
)
17911 tng_trajectory_frame_set_t frame_set
;
17912 tng_function_status stat
;
17914 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17915 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17916 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
17917 TNG_ASSERT(values
, "TNG library: values must not be a NULL pointer");
17919 stat
= tng_util_generic_write(tng_data
, frame_nr
, values
, n_values_per_frame
,
17920 block_id
, block_name
,
17921 particle_dependency
,
17924 if(stat
!= TNG_SUCCESS
)
17929 frame_set
= &tng_data
->current_trajectory_frame_set
;
17931 /* first_frame_time is -1 when it is not yet set. */
17932 if(frame_set
->first_frame_time
< -0.1)
17934 if(frame_nr
> frame_set
->first_frame
)
17936 stat
= tng_frame_set_first_frame_time_set(tng_data
,
17939 frame_set
->first_frame
) *
17940 tng_data
->time_per_frame
);
17944 stat
= tng_frame_set_first_frame_time_set(tng_data
, time
);
17950 tng_function_status DECLSPECDLLEXPORT tng_util_generic_with_time_double_write
17951 (tng_trajectory_t tng_data
,
17952 const int64_t frame_nr
,
17954 const double *values
,
17955 const int64_t n_values_per_frame
,
17956 const int64_t block_id
,
17957 const char *block_name
,
17958 const char particle_dependency
,
17959 const char compression
)
17961 tng_trajectory_frame_set_t frame_set
;
17962 tng_function_status stat
;
17964 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17965 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17966 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
17967 TNG_ASSERT(values
, "TNG library: values must not be a NULL pointer");
17969 stat
= tng_util_generic_double_write(tng_data
, frame_nr
, values
, n_values_per_frame
,
17970 block_id
, block_name
,
17971 particle_dependency
,
17974 if(stat
!= TNG_SUCCESS
)
17979 frame_set
= &tng_data
->current_trajectory_frame_set
;
17981 /* first_frame_time is -1 when it is not yet set. */
17982 if(frame_set
->first_frame_time
< -0.1)
17984 if(frame_nr
> frame_set
->first_frame
)
17986 stat
= tng_frame_set_first_frame_time_set(tng_data
,
17989 frame_set
->first_frame
) *
17990 tng_data
->time_per_frame
);
17994 stat
= tng_frame_set_first_frame_time_set(tng_data
, time
);
18000 tng_function_status DECLSPECDLLEXPORT tng_util_pos_with_time_write
18001 (tng_trajectory_t tng_data
,
18002 const int64_t frame_nr
,
18004 const float *positions
)
18006 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18007 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
18008 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
18009 TNG_ASSERT(positions
, "TNG library: positions must not be a NULL pointer");
18011 return(tng_util_generic_with_time_write(tng_data
, frame_nr
, time
, positions
,
18012 3, TNG_TRAJ_POSITIONS
, "POSITIONS",
18013 TNG_PARTICLE_BLOCK_DATA
,
18014 TNG_TNG_COMPRESSION
));
18017 tng_function_status DECLSPECDLLEXPORT tng_util_pos_with_time_double_write
18018 (tng_trajectory_t tng_data
,
18019 const int64_t frame_nr
,
18021 const double *positions
)
18023 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18024 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
18025 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
18026 TNG_ASSERT(positions
, "TNG library: positions must not be a NULL pointer");
18028 return(tng_util_generic_with_time_double_write(tng_data
, frame_nr
, time
,
18030 TNG_TRAJ_POSITIONS
,
18032 TNG_PARTICLE_BLOCK_DATA
,
18033 TNG_TNG_COMPRESSION
));
18036 tng_function_status DECLSPECDLLEXPORT tng_util_vel_with_time_write
18037 (tng_trajectory_t tng_data
,
18038 const int64_t frame_nr
,
18040 const float *velocities
)
18042 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18043 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
18044 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
18045 TNG_ASSERT(velocities
, "TNG library: velocities must not be a NULL pointer");
18047 return(tng_util_generic_with_time_write(tng_data
, frame_nr
, time
,
18049 TNG_TRAJ_VELOCITIES
,
18051 TNG_PARTICLE_BLOCK_DATA
,
18052 TNG_TNG_COMPRESSION
));
18055 tng_function_status DECLSPECDLLEXPORT tng_util_vel_with_time_double_write
18056 (tng_trajectory_t tng_data
,
18057 const int64_t frame_nr
,
18059 const double *velocities
)
18061 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18062 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
18063 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
18064 TNG_ASSERT(velocities
, "TNG library: velocities must not be a NULL pointer");
18066 return(tng_util_generic_with_time_double_write(tng_data
, frame_nr
, time
,
18068 TNG_TRAJ_VELOCITIES
,
18070 TNG_PARTICLE_BLOCK_DATA
,
18071 TNG_TNG_COMPRESSION
));
18074 tng_function_status DECLSPECDLLEXPORT tng_util_force_with_time_write
18075 (tng_trajectory_t tng_data
,
18076 const int64_t frame_nr
,
18078 const float *forces
)
18080 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18081 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
18082 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
18083 TNG_ASSERT(forces
, "TNG library: forces must not be a NULL pointer");
18085 return(tng_util_generic_with_time_write(tng_data
, frame_nr
, time
, forces
,
18086 3, TNG_TRAJ_FORCES
, "FORCES",
18087 TNG_PARTICLE_BLOCK_DATA
,
18088 TNG_GZIP_COMPRESSION
));
18091 tng_function_status DECLSPECDLLEXPORT tng_util_force_with_time_double_write
18092 (tng_trajectory_t tng_data
,
18093 const int64_t frame_nr
,
18095 const double *forces
)
18097 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18098 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
18099 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
18100 TNG_ASSERT(forces
, "TNG library: forces must not be a NULL pointer");
18102 return(tng_util_generic_with_time_double_write(tng_data
, frame_nr
, time
,
18104 TNG_TRAJ_FORCES
, "FORCES",
18105 TNG_PARTICLE_BLOCK_DATA
,
18106 TNG_GZIP_COMPRESSION
));
18109 tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_with_time_write
18110 (tng_trajectory_t tng_data
,
18111 const int64_t frame_nr
,
18113 const float *box_shape
)
18115 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18116 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
18117 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
18118 TNG_ASSERT(box_shape
, "TNG library: box_shape must not be a NULL pointer");
18120 return(tng_util_generic_with_time_write(tng_data
, frame_nr
, time
, box_shape
,
18121 9, TNG_TRAJ_BOX_SHAPE
, "BOX SHAPE",
18122 TNG_NON_PARTICLE_BLOCK_DATA
,
18123 TNG_GZIP_COMPRESSION
));
18126 tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_with_time_double_write
18127 (tng_trajectory_t tng_data
,
18128 const int64_t frame_nr
,
18130 const double *box_shape
)
18132 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18133 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
18134 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
18135 TNG_ASSERT(box_shape
, "TNG library: box_shape must not be a NULL pointer");
18137 return(tng_util_generic_with_time_double_write(tng_data
, frame_nr
,
18138 time
, box_shape
, 9,
18139 TNG_TRAJ_BOX_SHAPE
,
18141 TNG_NON_PARTICLE_BLOCK_DATA
,
18142 TNG_GZIP_COMPRESSION
));
18145 tng_function_status DECLSPECDLLEXPORT tng_util_frame_current_compression_get
18146 (tng_trajectory_t tng_data
,
18147 const int64_t block_id
,
18151 tng_trajectory_frame_set_t frame_set
;
18152 tng_particle_data_t p_data
;
18153 tng_non_particle_data_t np_data
;
18154 tng_function_status stat
;
18156 int block_type
= -1;
18158 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18159 TNG_ASSERT(codec_id
, "TNG library: The pointer to the returned codec id must not be a NULL pointer.");
18160 TNG_ASSERT(factor
, "TNG library: The pointer to the returned multiplication factor must not be a NULL pointer.");
18162 frame_set
= &tng_data
->current_trajectory_frame_set
;
18164 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
18165 if(stat
== TNG_SUCCESS
)
18167 block_type
= TNG_PARTICLE_BLOCK_DATA
;
18171 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
18172 if(stat
== TNG_SUCCESS
)
18174 block_type
= TNG_NON_PARTICLE_BLOCK_DATA
;
18178 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
18179 if(stat
!= TNG_SUCCESS
)
18183 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
18184 if(stat
== TNG_SUCCESS
)
18186 block_type
= TNG_PARTICLE_BLOCK_DATA
;
18190 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
18191 if(stat
== TNG_SUCCESS
)
18193 block_type
= TNG_NON_PARTICLE_BLOCK_DATA
;
18202 if(block_type
== TNG_PARTICLE_BLOCK_DATA
)
18204 if(p_data
->last_retrieved_frame
< 0)
18206 i
= p_data
->first_frame_with_data
;
18210 i
= p_data
->last_retrieved_frame
;
18213 else if(block_type
== TNG_NON_PARTICLE_BLOCK_DATA
)
18215 if(np_data
->last_retrieved_frame
< 0)
18217 i
= np_data
->first_frame_with_data
;
18221 i
= np_data
->last_retrieved_frame
;
18226 return(TNG_FAILURE
);
18228 if(i
< frame_set
->first_frame
|| i
>= frame_set
->first_frame
+ frame_set
->n_frames
)
18230 stat
= tng_frame_set_of_frame_find(tng_data
, i
);
18231 if(stat
!= TNG_SUCCESS
)
18235 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
18236 if(stat
!= TNG_SUCCESS
)
18238 fprintf(stderr
, "TNG library: Cannot read data block of frame set. %s: %d\n",
18239 __FILE__
, __LINE__
);
18243 if(block_type
== TNG_PARTICLE_BLOCK_DATA
)
18245 *codec_id
= p_data
->codec_id
;
18246 *factor
= (float)p_data
->compression_multiplier
;
18248 else if(block_type
== TNG_NON_PARTICLE_BLOCK_DATA
)
18250 *codec_id
= np_data
->codec_id
;
18251 *factor
= (float)np_data
->compression_multiplier
;
18253 return(TNG_SUCCESS
);
18256 tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_data_blocks_find
18257 (tng_trajectory_t tng_data
,
18258 int64_t current_frame
,
18259 const int64_t n_requested_data_block_ids
,
18260 const int64_t *requested_data_block_ids
,
18261 int64_t *next_frame
,
18262 int64_t *n_data_blocks_in_next_frame
,
18263 int64_t **data_block_ids_in_next_frame
)
18265 tng_trajectory_frame_set_t frame_set
;
18266 tng_function_status stat
;
18267 tng_particle_data_t p_data
;
18268 tng_non_particle_data_t np_data
;
18269 tng_gen_block_t block
;
18270 int64_t i
, j
, block_id
, *temp
;
18271 int64_t data_frame
, frame_diff
, min_diff
;
18272 int64_t size
, frame_set_file_pos
;
18273 int found
, read_all
= 0;
18276 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18277 TNG_ASSERT(next_frame
, "TNG library: The pointer to the next frame must not be NULL.");
18278 TNG_ASSERT(n_data_blocks_in_next_frame
, "TNG library: The pointer to n_data_blocks_in_next_frame must not be NULL.");
18279 TNG_ASSERT(data_block_ids_in_next_frame
, "TNG library: The pointer to the list of data block IDs must not be NULL.");
18281 if(n_requested_data_block_ids
)
18283 TNG_ASSERT(requested_data_block_ids
, "TNG library: If the number of requested data blocks is > 0 then the array of data block IDs must not be NULL.");
18284 size
= sizeof(int64_t) * n_requested_data_block_ids
;
18285 temp
= realloc(*data_block_ids_in_next_frame
, size
);
18288 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
18289 sizeof(int64_t) * (*n_data_blocks_in_next_frame
),
18290 __FILE__
, __LINE__
);
18291 free(*data_block_ids_in_next_frame
);
18292 *data_block_ids_in_next_frame
= 0;
18293 return(TNG_CRITICAL
);
18295 *data_block_ids_in_next_frame
= temp
;
18298 frame_set
= &tng_data
->current_trajectory_frame_set
;
18300 current_frame
+= 1;
18302 if(current_frame
< frame_set
->first_frame
||
18303 current_frame
>= frame_set
->first_frame
+ frame_set
->n_frames
)
18305 frame_set_file_pos
= tng_data
->current_trajectory_frame_set_input_file_pos
;
18306 stat
= tng_frame_set_of_frame_find(tng_data
, current_frame
);
18307 if(stat
!= TNG_SUCCESS
)
18309 /* If the frame set search found the frame set after the starting
18310 * frame set there is a gap in the frame sets. So, even if the frame
18311 * was not found the next frame with data is still in the found
18313 if(stat
== TNG_CRITICAL
|| frame_set
->prev_frame_set_file_pos
!=
18314 frame_set_file_pos
)
18318 current_frame
= frame_set
->first_frame
;
18322 if(frame_set
->n_particle_data_blocks
<= 0 || frame_set
->n_data_blocks
<= 0)
18324 tng_block_init(&block
);
18325 file_pos
= ftell(tng_data
->input_file
);
18326 /* Read all blocks until next frame set block */
18327 stat
= tng_block_header_read(tng_data
, block
);
18328 while(file_pos
< tng_data
->input_file_len
&&
18329 stat
!= TNG_CRITICAL
&&
18330 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
18332 stat
= tng_block_read_next(tng_data
, block
,
18334 if(stat
!= TNG_CRITICAL
)
18336 file_pos
= ftell(tng_data
->input_file
);
18337 if(file_pos
< tng_data
->input_file_len
)
18339 stat
= tng_block_header_read(tng_data
, block
);
18343 tng_block_destroy(&block
);
18344 if(stat
== TNG_CRITICAL
)
18346 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
18347 file_pos
, __FILE__
, __LINE__
);
18355 *n_data_blocks_in_next_frame
= 0;
18357 for(i
= 0; i
< frame_set
->n_particle_data_blocks
; i
++)
18359 p_data
= &frame_set
->tr_particle_data
[i
];
18360 block_id
= p_data
->block_id
;
18362 if(n_requested_data_block_ids
> 0)
18365 for(j
= 0; j
< n_requested_data_block_ids
; j
++)
18367 if(block_id
== requested_data_block_ids
[j
])
18379 if(!read_all
&& (p_data
->last_retrieved_frame
< frame_set
->first_frame
||
18380 p_data
->last_retrieved_frame
>=
18381 frame_set
->first_frame
+ frame_set
->n_frames
))
18383 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
,
18384 TNG_USE_HASH
, block_id
);
18385 if(stat
== TNG_CRITICAL
)
18387 fprintf(stderr
, "TNG library: Cannot read data block of frame set. %s: %d\n",
18388 __FILE__
, __LINE__
);
18391 if(stat
== TNG_FAILURE
)
18396 if(frame_set
->first_frame
!= current_frame
&&
18397 p_data
->last_retrieved_frame
>= 0)
18399 data_frame
= p_data
->last_retrieved_frame
+ p_data
->stride_length
;
18403 data_frame
= p_data
->first_frame_with_data
;
18405 frame_diff
= data_frame
- current_frame
;
18410 if(min_diff
== -1 || frame_diff
<= min_diff
)
18412 if(frame_diff
< min_diff
)
18414 *n_data_blocks_in_next_frame
= 1;
18418 *n_data_blocks_in_next_frame
+= 1;
18420 if(n_requested_data_block_ids
<= 0)
18422 size
= sizeof(int64_t) * (*n_data_blocks_in_next_frame
);
18423 temp
= realloc(*data_block_ids_in_next_frame
, size
);
18426 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
18427 sizeof(int64_t) * (*n_data_blocks_in_next_frame
),
18428 __FILE__
, __LINE__
);
18429 free(*data_block_ids_in_next_frame
);
18430 *data_block_ids_in_next_frame
= 0;
18431 return(TNG_CRITICAL
);
18433 *data_block_ids_in_next_frame
= temp
;
18437 TNG_ASSERT(*n_data_blocks_in_next_frame
<= n_requested_data_block_ids
, "TNG library: Array of data block IDs out of bounds");
18439 (*data_block_ids_in_next_frame
)[(*n_data_blocks_in_next_frame
) - 1] = block_id
;
18441 min_diff
= frame_diff
;
18444 for(i
= 0; i
< frame_set
->n_data_blocks
; i
++)
18446 np_data
= &frame_set
->tr_data
[i
];
18447 block_id
= np_data
->block_id
;
18449 if(n_requested_data_block_ids
> 0)
18452 for(j
= 0; j
< n_requested_data_block_ids
; j
++)
18454 if(block_id
== requested_data_block_ids
[j
])
18466 if(!read_all
&& (np_data
->last_retrieved_frame
< frame_set
->first_frame
||
18467 np_data
->last_retrieved_frame
>=
18468 frame_set
->first_frame
+ frame_set
->n_frames
))
18470 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
,
18471 TNG_USE_HASH
, block_id
);
18472 if(stat
== TNG_CRITICAL
)
18474 fprintf(stderr
, "TNG library: Cannot read data block of frame set. %s: %d\n",
18475 __FILE__
, __LINE__
);
18478 if(stat
== TNG_FAILURE
)
18483 if(frame_set
->first_frame
!= current_frame
&&
18484 np_data
->last_retrieved_frame
>= 0)
18486 data_frame
= np_data
->last_retrieved_frame
+ np_data
->stride_length
;
18490 data_frame
= np_data
->first_frame_with_data
;
18492 frame_diff
= data_frame
- current_frame
;
18497 if(min_diff
== -1 || frame_diff
<= min_diff
)
18499 if(frame_diff
< min_diff
)
18501 *n_data_blocks_in_next_frame
= 1;
18505 *n_data_blocks_in_next_frame
+= 1;
18507 if(n_requested_data_block_ids
<= 0)
18509 size
= sizeof(int64_t) * (*n_data_blocks_in_next_frame
);
18510 temp
= realloc(*data_block_ids_in_next_frame
, size
);
18513 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
18514 sizeof(int64_t) * (*n_data_blocks_in_next_frame
),
18515 __FILE__
, __LINE__
);
18516 free(*data_block_ids_in_next_frame
);
18517 *data_block_ids_in_next_frame
= 0;
18518 return(TNG_CRITICAL
);
18520 *data_block_ids_in_next_frame
= temp
;
18524 TNG_ASSERT(*n_data_blocks_in_next_frame
<= n_requested_data_block_ids
, "TNG library: Array of data block IDs out of bounds");
18526 (*data_block_ids_in_next_frame
)[(*n_data_blocks_in_next_frame
) - 1] = block_id
;
18528 min_diff
= frame_diff
;
18533 return(TNG_FAILURE
);
18535 *next_frame
= current_frame
+ min_diff
;
18537 return(TNG_SUCCESS
);
18541 tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_all_data_block_types_get
18542 (tng_trajectory_t tng_data,
18543 int64_t *n_data_blocks,
18544 int64_t **data_block_ids,
18545 char ***data_block_names,
18546 int64_t **stride_lengths,
18547 int64_t **n_values_per_frame,
18548 char **block_types,
18549 char **dependencies,
18550 char **compressions)
18552 tng_gen_block_t block;
18553 long orig_file_pos, file_pos;
18555 TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
18556 TNG_ASSERT(n_data_blocks, "TNG library: The pointer to n_data_blocks must not be NULL.");
18557 TNG_ASSERT(data_block_ids, "TNG library: The pointer to the list of data block IDs must not be NULL.");
18558 TNG_ASSERT(data_block_names, "TNG library: The pointer to the list of data block names must not be NULL.");
18559 TNG_ASSERT(stride_lengths, "TNG library: The pointer to the list of stride lengths must not be NULL.");
18561 orig_file_pos = ftell(tng_data->input_file);
18563 if(!tng_data->input_file_len)
18565 fseek(tng_data->input_file, 0, SEEK_END);
18566 tng_data->input_file_len = ftell(tng_data->input_file);
18569 fseek(tng_data->input_file, 0, SEEK_SET);
18572 *n_data_blocks = 0;
18574 tng_block_init(&block);
18576 while(file_pos < tng_data->input_file_len &&
18577 tng_block_header_read(tng_data, block) != TNG_CRITICAL)
18579 if(block->id > TNG_TRAJECTORY_FRAME_SET)
18583 file_pos += (long)(block->block_contents_size + block->header_contents_size);
18584 fseek(tng_data->input_file, (long)block->block_contents_size, SEEK_CUR);
18587 fseek(tng_data->input_file, orig_file_pos, SEEK_SET);
18589 return(TNG_SUCCESS);
18592 tng_function_status DECLSPECDLLEXPORT tng_util_prepare_append_after_frame
18593 (tng_trajectory_t tng_data
,
18594 const int64_t prev_frame
)
18596 tng_function_status stat
;
18597 FILE *temp
= tng_data
->input_file
;
18599 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18600 TNG_ASSERT(prev_frame
>= 0, "TNG library: The previous frame must not be negative.");
18602 tng_data
->input_file
= tng_data
->output_file
;
18604 stat
= tng_frame_set_of_frame_find(tng_data
, prev_frame
);
18605 if(stat
!= TNG_SUCCESS
)
18610 tng_data
->current_trajectory_frame_set_output_file_pos
=
18611 tng_data
->current_trajectory_frame_set_input_file_pos
;
18613 tng_data
->input_file
= temp
;
18615 return(TNG_SUCCESS
);