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);
1033 static tng_function_status tng_reread_frame_set_at_file_pos
1034 (tng_trajectory_t tng_data
,
1037 tng_gen_block_t block
;
1038 tng_function_status stat
;
1040 tng_block_init(&block
);
1042 fseek(tng_data
->input_file
, pos
, SEEK_SET
);
1045 stat
= tng_block_header_read(tng_data
, block
);
1046 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
1048 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n", pos
,
1049 __FILE__
, __LINE__
);
1050 tng_block_destroy(&block
);
1051 return(TNG_FAILURE
);
1054 if(tng_block_read_next(tng_data
, block
,
1055 TNG_SKIP_HASH
) != TNG_SUCCESS
)
1057 tng_block_destroy(&block
);
1058 return(TNG_CRITICAL
);
1062 tng_block_destroy(&block
);
1064 return(TNG_SUCCESS
);
1067 /** Write the header of a data block, regardless of its type
1068 * @param tng_data is a trajectory data container.
1069 * @param block is a general block container.
1070 * @param hash_mode is an option to decide whether to use the md5 hash or not.
1071 * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
1072 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
1073 * error has occured.
1075 static tng_function_status tng_block_header_write
1076 (tng_trajectory_t tng_data
,
1077 tng_gen_block_t block
,
1078 const char hash_mode
)
1080 int name_len
, offset
= 0;
1082 TNG_ASSERT(block
!= 0, "TNG library: Trying to write uninitialized block (NULL pointer).");
1084 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
1086 fprintf(stderr
, "TNG library: Cannot initialise destination file. %s: %d\n",
1087 __FILE__
, __LINE__
);
1088 return(TNG_CRITICAL
);
1093 block
->name
= malloc(1);
1096 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1097 __FILE__
, __LINE__
);
1098 return(TNG_CRITICAL
);
1103 name_len
= tng_min_i((int)strlen(block
->name
) + 1, TNG_MAX_STR_LEN
);
1105 if(hash_mode
== TNG_USE_HASH
)
1107 tng_block_md5_hash_generate(block
);
1110 /* Calculate the size of the header to write */
1111 block
->header_contents_size
= sizeof(block
->header_contents_size
) +
1112 sizeof(block
->block_contents_size
) +
1114 sizeof(block
->block_version
) +
1118 if(block
->header_contents
)
1120 free(block
->header_contents
);
1123 block
->header_contents
= malloc(block
->header_contents_size
);
1124 if(!block
->header_contents
)
1126 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
1127 block
->header_contents_size
, __FILE__
, __LINE__
);
1128 return(TNG_CRITICAL
);
1131 /* First copy all data into the header_contents block and finally write
1132 * the whole block at once. */
1133 memcpy(block
->header_contents
, &block
->header_contents_size
,
1134 sizeof(block
->header_contents_size
));
1135 if(tng_data
->output_endianness_swap_func_64
)
1137 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1138 (int64_t *)block
->header_contents
+offset
)
1141 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1142 __FILE__
, __LINE__
);
1145 offset
+= sizeof(block
->header_contents_size
);
1147 memcpy(block
->header_contents
+offset
, &block
->block_contents_size
,
1148 sizeof(block
->block_contents_size
));
1149 if(tng_data
->output_endianness_swap_func_64
)
1151 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1152 (int64_t *)block
->header_contents
+offset
)
1155 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1156 __FILE__
, __LINE__
);
1159 offset
+= sizeof(block
->block_contents_size
);
1161 memcpy(block
->header_contents
+offset
, &block
->id
, sizeof(block
->id
));
1162 if(tng_data
->output_endianness_swap_func_64
)
1164 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1165 (int64_t *)block
->header_contents
+offset
)
1168 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1169 __FILE__
, __LINE__
);
1172 offset
+= sizeof(block
->id
);
1174 memcpy(block
->header_contents
+offset
, block
->md5_hash
, TNG_MD5_HASH_LEN
);
1175 offset
+= TNG_MD5_HASH_LEN
;
1177 strncpy(block
->header_contents
+offset
, block
->name
, name_len
);
1180 memcpy(block
->header_contents
+offset
, &block
->block_version
,
1181 sizeof(block
->block_version
));
1182 if(tng_data
->output_endianness_swap_func_64
)
1184 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1185 (int64_t *)block
->header_contents
+offset
)
1188 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1189 __FILE__
, __LINE__
);
1193 if(fwrite(block
->header_contents
, block
->header_contents_size
,
1194 1, tng_data
->output_file
) != 1)
1196 fprintf(stderr
, "TNG library: Could not write all header data. %s: %d\n", __FILE__
, __LINE__
);
1197 return(TNG_CRITICAL
);
1199 return(TNG_SUCCESS
);
1202 /** Read a general info block. This is the first block of a TNG file.
1203 * Populate the fields in tng_data.
1204 * @param tng_data is a trajectory data container.
1205 * @param block is a general block container.
1206 * @param hash_mode is an option to decide whether to use the md5 hash or not.
1207 * If hash_mode == TNG_USE_HASH the written md5 hash in the file will be
1208 * compared to the md5 hash of the read contents to ensure valid data.
1209 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
1210 * error has occured.
1212 static tng_function_status tng_general_info_block_read
1213 (tng_trajectory_t tng_data
, tng_gen_block_t block
,
1214 const char hash_mode
)
1216 int len
, offset
= 0;
1221 TNG_ASSERT(block
!= 0, "TNG library: Trying to read data to an uninitialized block (NULL pointer)");
1223 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
1225 return(TNG_CRITICAL
);
1228 temp
= realloc(block
->block_contents
, block
->block_contents_size
);
1231 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
1232 block
->block_contents_size
, __FILE__
, __LINE__
);
1233 free(block
->block_contents
);
1234 block
->block_contents
= 0;
1235 return(TNG_CRITICAL
);
1237 block
->block_contents
= temp
;
1239 /* Read the whole block into block_contents to be able to write it to disk
1240 * even if it cannot be interpreted. */
1241 if(fread(block
->block_contents
, block
->block_contents_size
, 1,
1242 tng_data
->input_file
) == 0)
1244 fprintf(stderr
, "TNG library: Cannot read block. %s: %d\n", __FILE__
, __LINE__
);
1245 return(TNG_CRITICAL
);
1248 /* FIXME: Does not check if the size of the contents matches the expected
1249 * size or if the contents can be read. */
1251 if(hash_mode
== TNG_USE_HASH
)
1253 tng_md5_hash_match_verify(block
, &same_hash
);
1254 if(same_hash
!= TNG_TRUE
)
1256 fprintf(stderr
, "TNG library: General info block contents corrupt. Hashes do not match. "
1258 __FILE__
, __LINE__
);
1259 /* return(TNG_FAILURE); */
1263 len
= tng_min_i((int)strlen(block
->block_contents
) + 1, TNG_MAX_STR_LEN
);
1264 temp
= realloc(tng_data
->first_program_name
, len
);
1267 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
1268 __FILE__
, __LINE__
);
1269 free(tng_data
->first_program_name
);
1270 tng_data
->first_program_name
= 0;
1271 return(TNG_CRITICAL
);
1273 tng_data
->first_program_name
= temp
;
1274 strncpy(tng_data
->first_program_name
, block
->block_contents
, len
);
1277 len
= tng_min_i((int)strlen(block
->block_contents
+ offset
) + 1, TNG_MAX_STR_LEN
);
1278 temp
= realloc(tng_data
->last_program_name
, len
);
1281 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
1282 __FILE__
, __LINE__
);
1283 free(tng_data
->last_program_name
);
1284 tng_data
->last_program_name
= 0;
1285 return(TNG_CRITICAL
);
1287 tng_data
->last_program_name
= temp
;
1288 strncpy(tng_data
->last_program_name
, block
->block_contents
+ offset
, len
);
1291 len
= tng_min_i((int)strlen(block
->block_contents
+offset
) + 1, TNG_MAX_STR_LEN
);
1292 temp
= realloc(tng_data
->first_user_name
, len
);
1295 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
1296 __FILE__
, __LINE__
);
1297 free(tng_data
->first_user_name
);
1298 tng_data
->first_user_name
= 0;
1299 return(TNG_CRITICAL
);
1301 tng_data
->first_user_name
= temp
;
1302 strncpy(tng_data
->first_user_name
, block
->block_contents
+offset
, len
);
1305 len
= tng_min_i((int)strlen(block
->block_contents
+offset
) + 1, TNG_MAX_STR_LEN
);
1306 temp
= realloc(tng_data
->last_user_name
, len
);
1309 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
1310 __FILE__
, __LINE__
);
1311 free(tng_data
->last_user_name
);
1312 tng_data
->last_user_name
= 0;
1313 return(TNG_CRITICAL
);
1315 tng_data
->last_user_name
= temp
;
1316 strncpy(tng_data
->last_user_name
, block
->block_contents
+offset
, len
);
1319 len
= tng_min_i((int)strlen(block
->block_contents
+offset
) + 1, TNG_MAX_STR_LEN
);
1320 temp
= realloc(tng_data
->first_computer_name
, len
);
1323 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
1324 __FILE__
, __LINE__
);
1325 free(tng_data
->first_computer_name
);
1326 tng_data
->first_computer_name
= 0;
1327 return(TNG_CRITICAL
);
1329 tng_data
->first_computer_name
= temp
;
1330 strncpy(tng_data
->first_computer_name
, block
->block_contents
+offset
, len
);
1333 len
= tng_min_i((int)strlen(block
->block_contents
+offset
) + 1, TNG_MAX_STR_LEN
);
1334 temp
= realloc(tng_data
->last_computer_name
, len
);
1337 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
1338 __FILE__
, __LINE__
);
1339 free(tng_data
->last_computer_name
);
1340 tng_data
->last_computer_name
= 0;
1341 return(TNG_CRITICAL
);
1343 tng_data
->last_computer_name
= temp
;
1344 strncpy(tng_data
->last_computer_name
, block
->block_contents
+offset
, len
);
1347 len
= tng_min_i((int)strlen(block
->block_contents
+offset
) + 1, TNG_MAX_STR_LEN
);
1348 temp
= realloc(tng_data
->first_pgp_signature
, len
);
1351 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
1352 __FILE__
, __LINE__
);
1353 free(tng_data
->first_pgp_signature
);
1354 tng_data
->first_pgp_signature
= 0;
1355 return(TNG_CRITICAL
);
1357 tng_data
->first_pgp_signature
= temp
;
1358 strncpy(tng_data
->first_pgp_signature
, block
->block_contents
+offset
, len
);
1361 len
= tng_min_i((int)strlen(block
->block_contents
+offset
) + 1, TNG_MAX_STR_LEN
);
1362 temp
= realloc(tng_data
->last_pgp_signature
, len
);
1365 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
1366 __FILE__
, __LINE__
);
1367 free(tng_data
->last_pgp_signature
);
1368 tng_data
->last_pgp_signature
= 0;
1369 return(TNG_CRITICAL
);
1371 tng_data
->last_pgp_signature
= temp
;
1372 strncpy(tng_data
->last_pgp_signature
, block
->block_contents
+offset
, len
);
1375 len
= tng_min_i((int)strlen(block
->block_contents
+offset
) + 1, TNG_MAX_STR_LEN
);
1376 temp
= realloc(tng_data
->forcefield_name
, len
);
1379 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
1380 __FILE__
, __LINE__
);
1381 free(tng_data
->forcefield_name
);
1382 tng_data
->forcefield_name
= 0;
1383 return(TNG_CRITICAL
);
1385 tng_data
->forcefield_name
= temp
;
1386 strncpy(tng_data
->forcefield_name
, block
->block_contents
+offset
, len
);
1389 memcpy(&tng_data
->time
, block
->block_contents
+offset
,
1390 sizeof(tng_data
->time
));
1391 if(tng_data
->input_endianness_swap_func_64
)
1393 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1397 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1398 __FILE__
, __LINE__
);
1401 offset
+= sizeof(tng_data
->time
);
1403 memcpy(&tng_data
->var_num_atoms_flag
, block
->block_contents
+offset
,
1404 sizeof(tng_data
->var_num_atoms_flag
));
1405 offset
+= sizeof(tng_data
->var_num_atoms_flag
);
1407 memcpy(&tng_data
->frame_set_n_frames
, block
->block_contents
+offset
,
1408 sizeof(tng_data
->frame_set_n_frames
));
1409 if(tng_data
->input_endianness_swap_func_64
)
1411 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1412 &tng_data
->frame_set_n_frames
)
1415 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1416 __FILE__
, __LINE__
);
1419 offset
+= sizeof(tng_data
->frame_set_n_frames
);
1421 memcpy(&tng_data
->first_trajectory_frame_set_input_file_pos
,
1422 block
->block_contents
+offset
,
1423 sizeof(tng_data
->first_trajectory_frame_set_input_file_pos
));
1424 if(tng_data
->input_endianness_swap_func_64
)
1426 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1427 &tng_data
->first_trajectory_frame_set_input_file_pos
)
1430 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1431 __FILE__
, __LINE__
);
1434 offset
+= sizeof(tng_data
->first_trajectory_frame_set_input_file_pos
);
1436 tng_data
->current_trajectory_frame_set
.next_frame_set_file_pos
=
1437 tng_data
->first_trajectory_frame_set_input_file_pos
;
1440 memcpy(&tng_data
->last_trajectory_frame_set_input_file_pos
,
1441 block
->block_contents
+offset
,
1442 sizeof(tng_data
->last_trajectory_frame_set_input_file_pos
));
1443 if(tng_data
->input_endianness_swap_func_64
)
1445 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1446 &tng_data
->last_trajectory_frame_set_input_file_pos
)
1449 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1450 __FILE__
, __LINE__
);
1453 offset
+= sizeof(tng_data
->last_trajectory_frame_set_input_file_pos
);
1455 memcpy(&tng_data
->medium_stride_length
, block
->block_contents
+offset
,
1456 sizeof(tng_data
->medium_stride_length
));
1457 if(tng_data
->input_endianness_swap_func_64
)
1459 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1460 &tng_data
->medium_stride_length
)
1463 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1464 __FILE__
, __LINE__
);
1467 offset
+= sizeof(tng_data
->medium_stride_length
);
1469 memcpy(&tng_data
->long_stride_length
, block
->block_contents
+offset
,
1470 sizeof(tng_data
->long_stride_length
));
1471 if(tng_data
->input_endianness_swap_func_64
)
1473 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1474 &tng_data
->long_stride_length
)
1477 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1478 __FILE__
, __LINE__
);
1481 offset
+= sizeof(tng_data
->long_stride_length
);
1483 if(block
->block_version
>= 3)
1485 memcpy(&tng_data
->distance_unit_exponential
, block
->block_contents
+offset
,
1486 sizeof(tng_data
->distance_unit_exponential
));
1487 if(tng_data
->input_endianness_swap_func_64
)
1489 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1490 &tng_data
->distance_unit_exponential
)
1493 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1494 __FILE__
, __LINE__
);
1499 return(TNG_SUCCESS
);
1502 /** Write a general info block. This is the first block of a TNG file.
1503 * @param tng_data is a trajectory data container.
1504 * @param hash_mode is an option to decide whether to use the md5 hash or not.
1505 * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
1506 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
1507 * error has occured.
1509 static tng_function_status tng_general_info_block_write
1510 (tng_trajectory_t tng_data
,
1511 const char hash_mode
)
1513 int first_program_name_len
, first_user_name_len
;
1514 int first_computer_name_len
, first_pgp_signature_len
;
1515 int last_program_name_len
, last_user_name_len
;
1516 int last_computer_name_len
, last_pgp_signature_len
;
1517 int forcefield_name_len
, name_len
;
1519 tng_gen_block_t block
;
1521 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
1523 return(TNG_CRITICAL
);
1526 fseek(tng_data
->output_file
, 0, SEEK_SET
);
1528 /* If the strings are unallocated allocate memory for just string
1530 if(!tng_data
->first_program_name
)
1532 tng_data
->first_program_name
= malloc(1);
1533 if(!tng_data
->first_program_name
)
1535 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1536 __FILE__
, __LINE__
);
1537 return(TNG_CRITICAL
);
1539 tng_data
->first_program_name
[0] = 0;
1541 if(!tng_data
->last_program_name
)
1543 tng_data
->last_program_name
= malloc(1);
1544 if(!tng_data
->last_program_name
)
1546 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1547 __FILE__
, __LINE__
);
1548 return(TNG_CRITICAL
);
1550 tng_data
->last_program_name
[0] = 0;
1552 if(!tng_data
->first_user_name
)
1554 tng_data
->first_user_name
= malloc(1);
1555 if(!tng_data
->first_user_name
)
1557 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1558 __FILE__
, __LINE__
);
1559 return(TNG_CRITICAL
);
1561 tng_data
->first_user_name
[0] = 0;
1563 if(!tng_data
->last_user_name
)
1565 tng_data
->last_user_name
= malloc(1);
1566 if(!tng_data
->last_user_name
)
1568 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1569 __FILE__
, __LINE__
);
1570 return(TNG_CRITICAL
);
1572 tng_data
->last_user_name
[0] = 0;
1574 if(!tng_data
->first_computer_name
)
1576 tng_data
->first_computer_name
= malloc(1);
1577 if(!tng_data
->first_computer_name
)
1579 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1580 __FILE__
, __LINE__
);
1581 return(TNG_CRITICAL
);
1583 tng_data
->first_computer_name
[0] = 0;
1585 if(!tng_data
->last_computer_name
)
1587 tng_data
->last_computer_name
= malloc(1);
1588 if(!tng_data
->last_computer_name
)
1590 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1591 __FILE__
, __LINE__
);
1592 return(TNG_CRITICAL
);
1594 tng_data
->last_computer_name
[0] = 0;
1596 if(!tng_data
->first_pgp_signature
)
1598 tng_data
->first_pgp_signature
= malloc(1);
1599 if(!tng_data
->first_pgp_signature
)
1601 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1602 __FILE__
, __LINE__
);
1603 return(TNG_CRITICAL
);
1605 tng_data
->first_pgp_signature
[0] = 0;
1607 if(!tng_data
->last_pgp_signature
)
1609 tng_data
->last_pgp_signature
= malloc(1);
1610 if(!tng_data
->last_pgp_signature
)
1612 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1613 __FILE__
, __LINE__
);
1614 return(TNG_CRITICAL
);
1616 tng_data
->last_pgp_signature
[0] = 0;
1618 if(!tng_data
->forcefield_name
)
1620 tng_data
->forcefield_name
= malloc(1);
1621 if(!tng_data
->forcefield_name
)
1623 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
1624 __FILE__
, __LINE__
);
1625 return(TNG_CRITICAL
);
1627 tng_data
->forcefield_name
[0] = 0;
1630 tng_block_init(&block
);
1632 name_len
= (int)strlen("GENERAL INFO");
1634 block
->name
= malloc(name_len
+ 1);
1637 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
1638 name_len
+1, __FILE__
, __LINE__
);
1639 tng_block_destroy(&block
);
1640 return(TNG_CRITICAL
);
1643 strcpy(block
->name
, "GENERAL INFO");
1644 block
->id
= TNG_GENERAL_INFO
;
1646 first_program_name_len
= tng_min_i((int)strlen(tng_data
->first_program_name
) + 1,
1648 last_program_name_len
= tng_min_i((int)strlen(tng_data
->last_program_name
) + 1,
1650 first_user_name_len
= tng_min_i((int)strlen(tng_data
->first_user_name
) + 1,
1652 last_user_name_len
= tng_min_i((int)strlen(tng_data
->last_user_name
) + 1,
1654 first_computer_name_len
= tng_min_i((int)strlen(tng_data
->first_computer_name
) + 1,
1656 last_computer_name_len
= tng_min_i((int)strlen(tng_data
->last_computer_name
) + 1,
1658 first_pgp_signature_len
= tng_min_i((int)strlen(tng_data
->first_pgp_signature
) + 1,
1660 last_pgp_signature_len
= tng_min_i((int)strlen(tng_data
->last_pgp_signature
) + 1,
1662 forcefield_name_len
= tng_min_i((int)strlen(tng_data
->forcefield_name
) + 1,
1665 block
->block_contents_size
= sizeof(tng_data
->time
) +
1666 sizeof(tng_data
->var_num_atoms_flag
) +
1667 sizeof(tng_data
->frame_set_n_frames
) +
1668 sizeof(tng_data
->first_trajectory_frame_set_input_file_pos
) +
1669 sizeof(tng_data
->last_trajectory_frame_set_input_file_pos
) +
1670 sizeof(tng_data
->medium_stride_length
) +
1671 sizeof(tng_data
->long_stride_length
) +
1672 sizeof(tng_data
->distance_unit_exponential
) +
1673 first_program_name_len
+
1674 last_program_name_len
+
1675 first_user_name_len
+
1676 last_user_name_len
+
1677 first_computer_name_len
+
1678 last_computer_name_len
+
1679 first_pgp_signature_len
+
1680 last_pgp_signature_len
+
1681 forcefield_name_len
;
1683 if(block
->block_contents
)
1685 free(block
->block_contents
);
1687 block
->block_contents
= malloc(block
->block_contents_size
);
1688 if(!block
->block_contents
)
1690 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
1691 block
->block_contents_size
, __FILE__
, __LINE__
);
1692 tng_block_destroy(&block
);
1693 return(TNG_CRITICAL
);
1696 strncpy(block
->block_contents
, tng_data
->first_program_name
, first_program_name_len
);
1697 offset
+= first_program_name_len
;
1699 strncpy(block
->block_contents
+offset
, tng_data
->last_program_name
, last_program_name_len
);
1700 offset
+= last_program_name_len
;
1702 strncpy(block
->block_contents
+offset
, tng_data
->first_user_name
, first_user_name_len
);
1703 offset
+= first_user_name_len
;
1705 strncpy(block
->block_contents
+offset
, tng_data
->last_user_name
, last_user_name_len
);
1706 offset
+= last_user_name_len
;
1708 strncpy(block
->block_contents
+offset
, tng_data
->first_computer_name
,
1709 first_computer_name_len
);
1710 offset
+= first_computer_name_len
;
1712 strncpy(block
->block_contents
+offset
, tng_data
->last_computer_name
,
1713 last_computer_name_len
);
1714 offset
+= last_computer_name_len
;
1716 strncpy(block
->block_contents
+offset
, tng_data
->first_pgp_signature
,
1717 first_pgp_signature_len
);
1718 offset
+= first_pgp_signature_len
;
1720 strncpy(block
->block_contents
+offset
, tng_data
->last_pgp_signature
,
1721 last_pgp_signature_len
);
1722 offset
+= last_pgp_signature_len
;
1724 strncpy(block
->block_contents
+offset
, tng_data
->forcefield_name
,
1725 forcefield_name_len
);
1726 offset
+= forcefield_name_len
;
1728 memcpy(block
->block_contents
+offset
, &tng_data
->time
,
1729 sizeof(tng_data
->time
));
1730 if(tng_data
->output_endianness_swap_func_64
)
1732 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1733 (int64_t *)block
->header_contents
+offset
)
1736 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1737 __FILE__
, __LINE__
);
1740 offset
+= sizeof(tng_data
->time
);
1742 memcpy(block
->block_contents
+offset
, &tng_data
->var_num_atoms_flag
,
1743 sizeof(tng_data
->var_num_atoms_flag
));
1744 offset
+= sizeof(tng_data
->var_num_atoms_flag
);
1746 memcpy(block
->block_contents
+offset
, &tng_data
->frame_set_n_frames
,
1747 sizeof(tng_data
->frame_set_n_frames
));
1748 if(tng_data
->output_endianness_swap_func_64
)
1750 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1751 (int64_t *)block
->header_contents
+offset
)
1754 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1755 __FILE__
, __LINE__
);
1758 offset
+= sizeof(tng_data
->frame_set_n_frames
);
1760 memcpy(block
->block_contents
+offset
,
1761 &tng_data
->first_trajectory_frame_set_input_file_pos
,
1762 sizeof(tng_data
->first_trajectory_frame_set_input_file_pos
));
1763 if(tng_data
->output_endianness_swap_func_64
)
1765 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1766 (int64_t *)block
->header_contents
+offset
)
1769 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1770 __FILE__
, __LINE__
);
1773 offset
+= sizeof(tng_data
->first_trajectory_frame_set_input_file_pos
);
1775 memcpy(block
->block_contents
+offset
,
1776 &tng_data
->last_trajectory_frame_set_input_file_pos
,
1777 sizeof(tng_data
->last_trajectory_frame_set_input_file_pos
));
1778 if(tng_data
->output_endianness_swap_func_64
)
1780 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1781 (int64_t *)block
->header_contents
+offset
)
1784 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1785 __FILE__
, __LINE__
);
1788 offset
+= sizeof(tng_data
->last_trajectory_frame_set_input_file_pos
);
1790 memcpy(block
->block_contents
+offset
, &tng_data
->medium_stride_length
,
1791 sizeof(tng_data
->medium_stride_length
));
1792 if(tng_data
->output_endianness_swap_func_64
)
1794 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1795 (int64_t *)block
->header_contents
+offset
)
1798 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1799 __FILE__
, __LINE__
);
1802 offset
+= sizeof(tng_data
->medium_stride_length
);
1804 memcpy(block
->block_contents
+offset
, &tng_data
->long_stride_length
,
1805 sizeof(tng_data
->long_stride_length
));
1806 if(tng_data
->output_endianness_swap_func_64
)
1808 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1809 (int64_t *)block
->header_contents
+offset
)
1812 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1813 __FILE__
, __LINE__
);
1816 offset
+= sizeof(tng_data
->long_stride_length
);
1818 memcpy(block
->block_contents
+offset
, &tng_data
->distance_unit_exponential
,
1819 sizeof(tng_data
->distance_unit_exponential
));
1820 if(tng_data
->output_endianness_swap_func_64
)
1822 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1823 (int64_t *)block
->header_contents
+offset
)
1826 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1827 __FILE__
, __LINE__
);
1831 if(tng_block_header_write(tng_data
, block
, hash_mode
) != TNG_SUCCESS
)
1833 fprintf(stderr
, "TNG library: Cannot write header of file %s. %s: %d\n",
1834 tng_data
->output_file_path
, __FILE__
, __LINE__
);
1835 tng_block_destroy(&block
);
1836 return(TNG_CRITICAL
);
1839 if(fwrite(block
->block_contents
, block
->block_contents_size
, 1,
1840 tng_data
->output_file
) != 1)
1842 fprintf(stderr
, "TNG library: Could not write all block data. %s: %d\n", __FILE__
, __LINE__
);
1843 tng_block_destroy(&block
);
1844 return(TNG_CRITICAL
);
1847 tng_block_destroy(&block
);
1849 return(TNG_SUCCESS
);
1852 /** Read the chain data of a molecules block.
1853 * @param tng_data is a trajectory data container.
1854 * @param block is a general block container.
1855 * @param chain is the chain data container.
1856 * @param offset is the offset of the block input and is updated when reading.
1857 * @return TNG_SUCCESS(0) is successful.
1859 static tng_function_status
tng_chain_data_read(tng_trajectory_t tng_data
,
1860 tng_gen_block_t block
,
1866 TNG_ASSERT(offset
!= 0, "TNG library: offset must not be a NULL pointer.");
1868 memcpy(&chain
->id
, block
->block_contents
+*offset
,
1870 if(tng_data
->input_endianness_swap_func_64
)
1872 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1876 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1877 __FILE__
, __LINE__
);
1880 *offset
+= sizeof(chain
->id
);
1882 len
= tng_min_i((int)strlen(block
->block_contents
+*offset
) + 1,
1884 chain
->name
= malloc(len
);
1885 strncpy(chain
->name
,
1886 block
->block_contents
+*offset
, len
);
1889 memcpy(&chain
->n_residues
, block
->block_contents
+*offset
,
1890 sizeof(chain
->n_residues
));
1891 if(tng_data
->input_endianness_swap_func_64
)
1893 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1897 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1898 __FILE__
, __LINE__
);
1901 *offset
+= sizeof(chain
->n_residues
);
1903 return(TNG_SUCCESS
);
1906 /** Write the chain data of a molecules block.
1907 * @param tng_data is a trajectory data container.
1908 * @param block is a general block container.
1909 * @param chain is the chain data container.
1910 * @param offset is the offset of the block output and is updated when writing.
1911 * @return TNG_SUCCESS(0) is successful.
1913 static tng_function_status
tng_chain_data_write(tng_trajectory_t tng_data
,
1914 tng_gen_block_t block
,
1920 TNG_ASSERT(offset
!= 0, "TNG library: offset must not be a NULL pointer.");
1922 memcpy(block
->block_contents
+*offset
, &chain
->id
, sizeof(chain
->id
));
1923 if(tng_data
->output_endianness_swap_func_64
)
1925 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1926 (int64_t *)block
->header_contents
+*offset
)
1929 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1930 __FILE__
, __LINE__
);
1933 *offset
+= sizeof(chain
->id
);
1935 len
= tng_min_i((int)strlen(chain
->name
) + 1, TNG_MAX_STR_LEN
);
1936 strncpy(block
->block_contents
+ *offset
, chain
->name
, len
);
1939 memcpy(block
->block_contents
+*offset
, &chain
->n_residues
,
1940 sizeof(chain
->n_residues
));
1941 if(tng_data
->output_endianness_swap_func_64
)
1943 if(tng_data
->output_endianness_swap_func_64(tng_data
,
1944 (int64_t *)block
->header_contents
+*offset
)
1947 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1948 __FILE__
, __LINE__
);
1951 *offset
+= sizeof(chain
->n_residues
);
1953 return(TNG_SUCCESS
);
1956 /** Read the residue data of a molecules block.
1957 * @param tng_data is a trajectory data container.
1958 * @param block is a general block container.
1959 * @param residue is the residue data container.
1960 * @param offset is the offset of the block input and is updated when reading.
1961 * @return TNG_SUCCESS(0) is successful.
1963 static tng_function_status
tng_residue_data_read(tng_trajectory_t tng_data
,
1964 tng_gen_block_t block
,
1965 tng_residue_t residue
,
1970 TNG_ASSERT(offset
!= 0, "TNG library: offset must not be a NULL pointer.");
1972 memcpy(&residue
->id
, block
->block_contents
+*offset
,
1973 sizeof(residue
->id
));
1974 if(tng_data
->input_endianness_swap_func_64
)
1976 if(tng_data
->input_endianness_swap_func_64(tng_data
,
1980 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
1981 __FILE__
, __LINE__
);
1984 *offset
+= sizeof(residue
->id
);
1986 len
= tng_min_i((int)strlen(block
->block_contents
+*offset
) + 1,
1988 residue
->name
= malloc(len
);
1989 strncpy(residue
->name
,
1990 block
->block_contents
+*offset
, len
);
1993 memcpy(&residue
->n_atoms
, block
->block_contents
+*offset
,
1994 sizeof(residue
->n_atoms
));
1995 if(tng_data
->input_endianness_swap_func_64
)
1997 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2001 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2002 __FILE__
, __LINE__
);
2005 *offset
+= sizeof(residue
->n_atoms
);
2007 return(TNG_SUCCESS
);
2010 /** Write the residue data of a molecules block.
2011 * @param tng_data is a trajectory data container.
2012 * @param block is a general block container.
2013 * @param residue is the residue data container.
2014 * @param offset is the offset of the block output and is updated when writing.
2015 * @return TNG_SUCCESS(0) is successful.
2017 static tng_function_status
tng_residue_data_write(tng_trajectory_t tng_data
,
2018 tng_gen_block_t block
,
2019 tng_residue_t residue
,
2024 TNG_ASSERT(offset
!= 0, "TNG library: offset must not be a NULL pointer.");
2026 memcpy(block
->block_contents
+*offset
, &residue
->id
, sizeof(residue
->id
));
2027 if(tng_data
->output_endianness_swap_func_64
)
2029 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2030 (int64_t *)block
->header_contents
+*offset
)
2033 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2034 __FILE__
, __LINE__
);
2037 *offset
+= sizeof(residue
->id
);
2039 len
= tng_min_i((int)strlen(residue
->name
) + 1, TNG_MAX_STR_LEN
);
2040 strncpy(block
->block_contents
+ *offset
, residue
->name
, len
);
2043 memcpy(block
->block_contents
+*offset
, &residue
->n_atoms
,
2044 sizeof(residue
->n_atoms
));
2045 if(tng_data
->output_endianness_swap_func_64
)
2047 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2048 (int64_t *)block
->header_contents
+*offset
)
2051 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2052 __FILE__
, __LINE__
);
2055 *offset
+= sizeof(residue
->n_atoms
);
2057 return(TNG_SUCCESS
);
2060 /** Read the atom data of a molecules block.
2061 * @param tng_data is a trajectory data container.
2062 * @param block is a general block container.
2063 * @param atom is the atom data container.
2064 * @param offset is the offset of the block input and is updated when reading.
2065 * @return TNG_SUCCESS(0) is successful.
2067 static tng_function_status
tng_atom_data_read(tng_trajectory_t tng_data
,
2068 tng_gen_block_t block
,
2074 TNG_ASSERT(offset
!= 0, "TNG library: offset must not be a NULL pointer.");
2076 memcpy(&atom
->id
, block
->block_contents
+*offset
,
2078 if(tng_data
->input_endianness_swap_func_64
)
2080 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2084 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2085 __FILE__
, __LINE__
);
2088 *offset
+= sizeof(atom
->id
);
2090 len
= tng_min_i((int)strlen(block
->block_contents
+*offset
) + 1,
2092 atom
->name
= malloc(len
);
2094 block
->block_contents
+*offset
, len
);
2097 len
= tng_min_i((int)strlen(block
->block_contents
+*offset
) + 1,
2099 atom
->atom_type
= malloc(len
);
2100 strncpy(atom
->atom_type
,
2101 block
->block_contents
+*offset
, len
);
2104 return(TNG_SUCCESS
);
2107 /** Write the atom data of a molecules block.
2108 * @param tng_data is a trajectory data container.
2109 * @param block is a general block container.
2110 * @param atom is the atom data container.
2111 * @param offset is the offset of the block output and is updated when writing.
2112 * @return TNG_SUCCESS(0) is successful.
2114 static tng_function_status
tng_atom_data_write(tng_trajectory_t tng_data
,
2115 tng_gen_block_t block
,
2121 TNG_ASSERT(offset
!= 0, "TNG library: offset must not be a NULL pointer.");
2123 memcpy(block
->block_contents
+*offset
, &atom
->id
,
2125 if(tng_data
->output_endianness_swap_func_64
)
2127 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2128 (int64_t *)block
->header_contents
+*offset
)
2131 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2132 __FILE__
, __LINE__
);
2135 *offset
+= sizeof(atom
->id
);
2137 len
= tng_min_i((int)strlen(atom
->name
) + 1, TNG_MAX_STR_LEN
);
2138 strncpy(block
->block_contents
+ *offset
, atom
->name
, len
);
2141 len
= tng_min_i((int)strlen(atom
->atom_type
) + 1, TNG_MAX_STR_LEN
);
2142 strncpy(block
->block_contents
+ *offset
, atom
->atom_type
, len
);
2145 return(TNG_SUCCESS
);
2148 /** Read a molecules block. Contains chain, residue and atom data
2149 * @param tng_data is a trajectory data container.
2150 * @param block is a general block container.
2151 * @param hash_mode is an option to decide whether to use the md5 hash or not.
2152 * If hash_mode == TNG_USE_HASH the written md5 hash in the file will be
2153 * compared to the md5 hash of the read contents to ensure valid data.
2154 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
2155 * error has occured.
2157 static tng_function_status tng_molecules_block_read
2158 (tng_trajectory_t tng_data
,
2159 tng_gen_block_t block
,
2160 const char hash_mode
)
2163 int len
, offset
= 0;
2164 tng_molecule_t molecule
;
2166 tng_residue_t residue
;
2171 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
2173 return(TNG_CRITICAL
);
2176 if(block
->block_contents
)
2178 free(block
->block_contents
);
2181 block
->block_contents
= malloc(block
->block_contents_size
);
2182 if(!block
->block_contents
)
2184 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
2185 block
->block_contents_size
, __FILE__
, __LINE__
);
2186 return(TNG_CRITICAL
);
2189 /* Read the whole block into block_contents to be able to write it to disk
2190 * even if it cannot be interpreted. */
2191 if(fread(block
->block_contents
, block
->block_contents_size
, 1,
2192 tng_data
->input_file
) == 0)
2194 fprintf(stderr
, "TNG library: Cannot read block. %s: %d\n", __FILE__
, __LINE__
);
2197 /* FIXME: Does not check if the size of the contents matches the expected
2198 * size or if the contents can be read. */
2200 if(hash_mode
== TNG_USE_HASH
)
2202 tng_md5_hash_match_verify(block
, &same_hash
);
2203 if(same_hash
!= TNG_TRUE
)
2205 fprintf(stderr
, "TNG library: Molecules block contents corrupt. Hashes do not match. "
2207 __FILE__
, __LINE__
);
2211 if(tng_data
->molecules
)
2213 for(i
=tng_data
->n_molecules
; i
--;)
2215 tng_molecule_destroy(tng_data
, &tng_data
->molecules
[i
]);
2217 free(tng_data
->molecules
);
2218 tng_data
->molecules
= 0;
2219 tng_data
->n_molecules
= 0;
2222 memcpy(&tng_data
->n_molecules
, block
->block_contents
,
2223 sizeof(tng_data
->n_molecules
));
2224 if(tng_data
->input_endianness_swap_func_64
)
2226 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2227 &tng_data
->n_molecules
)
2230 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2231 __FILE__
, __LINE__
);
2234 offset
+= sizeof(tng_data
->n_molecules
);
2236 if(tng_data
->molecules
)
2238 free(tng_data
->molecules
);
2241 tng_data
->n_particles
= 0;
2243 tng_data
->molecules
= malloc(tng_data
->n_molecules
*
2244 sizeof(struct tng_molecule
));
2245 if(!tng_data
->molecules
)
2247 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
2248 tng_data
->n_molecules
* sizeof(struct tng_molecule
),
2249 __FILE__
, __LINE__
);
2250 return(TNG_CRITICAL
);
2253 if(!tng_data
->var_num_atoms_flag
)
2255 if(tng_data
->molecule_cnt_list
)
2257 free(tng_data
->molecule_cnt_list
);
2259 tng_data
->molecule_cnt_list
= malloc(sizeof(int64_t) *
2260 tng_data
->n_molecules
);
2261 if(!tng_data
->molecule_cnt_list
)
2263 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
2264 tng_data
->n_molecules
* sizeof(struct tng_molecule
),
2265 __FILE__
, __LINE__
);
2266 return(TNG_CRITICAL
);
2270 /* Read each molecule from file */
2271 for(i
=0; i
< tng_data
->n_molecules
; i
++)
2273 molecule
= &tng_data
->molecules
[i
];
2275 memcpy(&molecule
->id
, block
->block_contents
+offset
,
2276 sizeof(molecule
->id
));
2277 if(tng_data
->input_endianness_swap_func_64
)
2279 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2283 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2284 __FILE__
, __LINE__
);
2287 offset
+= sizeof(molecule
->id
);
2289 /* fprintf(stderr, "TNG library: Read id: %"PRId64" offset: %d\n", molecule->id, offset);*/
2290 len
= tng_min_i((int)strlen(block
->block_contents
+offset
) + 1, TNG_MAX_STR_LEN
);
2291 molecule
->name
= malloc(len
);
2292 strncpy(molecule
->name
, block
->block_contents
+offset
, len
);
2295 memcpy(&molecule
->quaternary_str
, block
->block_contents
+offset
,
2296 sizeof(molecule
->quaternary_str
));
2297 if(tng_data
->input_endianness_swap_func_64
)
2299 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2300 &molecule
->quaternary_str
)
2303 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2304 __FILE__
, __LINE__
);
2307 offset
+= sizeof(molecule
->quaternary_str
);
2309 if(!tng_data
->var_num_atoms_flag
)
2311 memcpy(&tng_data
->molecule_cnt_list
[i
],
2312 block
->block_contents
+offset
,
2314 if(tng_data
->input_endianness_swap_func_64
)
2316 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2317 &tng_data
->molecule_cnt_list
[i
])
2320 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2321 __FILE__
, __LINE__
);
2324 offset
+= sizeof(int64_t);
2328 memcpy(&molecule
->n_chains
, block
->block_contents
+offset
,
2329 sizeof(molecule
->n_chains
));
2330 if(tng_data
->input_endianness_swap_func_64
)
2332 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2333 &molecule
->n_chains
)
2336 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2337 __FILE__
, __LINE__
);
2340 offset
+= sizeof(molecule
->n_chains
);
2342 memcpy(&molecule
->n_residues
, block
->block_contents
+offset
,
2343 sizeof(molecule
->n_residues
));
2344 if(tng_data
->input_endianness_swap_func_64
)
2346 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2347 &molecule
->n_residues
)
2350 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2351 __FILE__
, __LINE__
);
2354 offset
+= sizeof(molecule
->n_residues
);
2356 memcpy(&molecule
->n_atoms
, block
->block_contents
+offset
,
2357 sizeof(molecule
->n_atoms
));
2358 if(tng_data
->input_endianness_swap_func_64
)
2360 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2364 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2365 __FILE__
, __LINE__
);
2368 offset
+= sizeof(molecule
->n_atoms
);
2370 tng_data
->n_particles
+= molecule
->n_atoms
*
2371 tng_data
->molecule_cnt_list
[i
];
2373 if(molecule
->n_chains
> 0)
2375 molecule
->chains
= malloc(molecule
->n_chains
*
2376 sizeof(struct tng_chain
));
2377 if(!molecule
->chains
)
2379 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
2380 molecule
->n_chains
* sizeof(struct tng_chain
),
2381 __FILE__
, __LINE__
);
2382 return(TNG_CRITICAL
);
2385 chain
= molecule
->chains
;
2392 if(molecule
->n_residues
> 0)
2394 molecule
->residues
= malloc(molecule
->n_residues
*
2395 sizeof(struct tng_residue
));
2396 if(!molecule
->residues
)
2398 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
2399 molecule
->n_residues
* sizeof(struct tng_residue
),
2400 __FILE__
, __LINE__
);
2401 if(molecule
->chains
)
2403 free(molecule
->chains
);
2404 molecule
->chains
= 0;
2406 return(TNG_CRITICAL
);
2409 residue
= molecule
->residues
;
2416 molecule
->atoms
= malloc(molecule
->n_atoms
*
2417 sizeof(struct tng_atom
));
2418 if(!molecule
->atoms
)
2420 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
2421 molecule
->n_atoms
* sizeof(struct tng_atom
),
2422 __FILE__
, __LINE__
);
2423 if(molecule
->chains
)
2425 free(molecule
->chains
);
2426 molecule
->chains
= 0;
2428 if(molecule
->residues
)
2430 free(molecule
->residues
);
2431 molecule
->residues
= 0;
2433 return(TNG_CRITICAL
);
2436 atom
= molecule
->atoms
;
2438 if(molecule
->n_chains
> 0)
2440 /* Read the chains of the molecule */
2441 for(j
=molecule
->n_chains
; j
--;)
2443 chain
->molecule
= molecule
;
2445 tng_chain_data_read(tng_data
, block
, chain
, &offset
);
2447 chain
->residues
= molecule
->residues
;
2448 residue
= chain
->residues
;
2450 /* Read the residues of the chain */
2451 for(k
=chain
->n_residues
; k
--;)
2453 residue
->chain
= chain
;
2455 tng_residue_data_read(tng_data
, block
, residue
, &offset
);
2457 residue
->atoms_offset
= atom
- molecule
->atoms
;
2458 /* Read the atoms of the residue */
2459 for(l
=residue
->n_atoms
; l
--;)
2461 atom
->residue
= residue
;
2463 tng_atom_data_read(tng_data
, block
, atom
, &offset
);
2474 if(molecule
->n_residues
> 0)
2476 for(k
=molecule
->n_residues
; k
--;)
2480 tng_residue_data_read(tng_data
, block
, residue
, &offset
);
2482 residue
->atoms_offset
= atom
- molecule
->atoms
;
2483 /* Read the atoms of the residue */
2484 for(l
=residue
->n_atoms
; l
--;)
2486 atom
->residue
= residue
;
2488 tng_atom_data_read(tng_data
, block
, atom
, &offset
);
2497 for(l
=molecule
->n_atoms
; l
--;)
2501 tng_atom_data_read(tng_data
, block
, atom
, &offset
);
2508 memcpy(&molecule
->n_bonds
, block
->block_contents
+offset
,
2509 sizeof(molecule
->n_bonds
));
2510 if(tng_data
->input_endianness_swap_func_64
)
2512 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2516 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2517 __FILE__
, __LINE__
);
2520 offset
+= sizeof(molecule
->n_bonds
);
2522 if(molecule
->n_bonds
> 0)
2524 tng_data
->molecules
[i
].bonds
= malloc(molecule
->n_bonds
*
2525 sizeof(struct tng_bond
));
2526 if(!molecule
->bonds
)
2528 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
2529 molecule
->n_bonds
* sizeof(struct tng_bond
),
2530 __FILE__
, __LINE__
);
2531 if(molecule
->chains
)
2533 free(molecule
->chains
);
2534 molecule
->chains
= 0;
2536 if(molecule
->residues
)
2538 free(molecule
->residues
);
2539 molecule
->residues
= 0;
2543 free(molecule
->atoms
);
2544 molecule
->atoms
= 0;
2546 return(TNG_CRITICAL
);
2549 bond
= molecule
->bonds
;
2551 for(j
=molecule
->n_bonds
; j
--;)
2553 memcpy(&bond
->from_atom_id
, block
->block_contents
+offset
,
2554 sizeof(bond
->from_atom_id
));
2555 if(tng_data
->input_endianness_swap_func_64
)
2557 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2558 &bond
->from_atom_id
)
2561 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2562 __FILE__
, __LINE__
);
2565 offset
+= sizeof(bond
->from_atom_id
);
2567 memcpy(&bond
->to_atom_id
, block
->block_contents
+offset
,
2568 sizeof(bond
->to_atom_id
));
2569 if(tng_data
->input_endianness_swap_func_64
)
2571 if(tng_data
->input_endianness_swap_func_64(tng_data
,
2575 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2576 __FILE__
, __LINE__
);
2579 offset
+= sizeof(bond
->to_atom_id
);
2586 molecule
->bonds
= 0;
2590 return(TNG_SUCCESS
);
2593 /** Write a molecules block.
2594 * @param tng_data is a trajectory data container.
2595 * @param hash_mode is an option to decide whether to use the md5 hash or not.
2596 * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
2597 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
2598 * error has occured.
2600 static tng_function_status tng_molecules_block_write
2601 (tng_trajectory_t tng_data
,
2602 const char hash_mode
)
2604 int len
= 0, name_len
, offset
= 0;
2606 tng_molecule_t molecule
;
2608 tng_residue_t residue
;
2611 tng_gen_block_t block
;
2613 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
2615 return(TNG_CRITICAL
);
2618 /* First predict the size of the block */
2619 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
2621 molecule
= &tng_data
->molecules
[i
];
2624 molecule
->name
= malloc(1);
2627 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
2628 __FILE__
, __LINE__
);
2629 return(TNG_CRITICAL
);
2631 molecule
->name
[0] = 0;
2633 len
+= tng_min_i((int)strlen(molecule
->name
) + 1, TNG_MAX_STR_LEN
);
2635 chain
= molecule
->chains
;
2636 for(j
= molecule
->n_chains
; j
--;)
2638 len
+= sizeof(chain
->id
);
2642 chain
->name
= malloc(1);
2645 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
2646 __FILE__
, __LINE__
);
2647 return(TNG_CRITICAL
);
2651 len
+= tng_min_i((int)strlen(chain
->name
) + 1, TNG_MAX_STR_LEN
);
2653 len
+= sizeof(chain
->n_residues
);
2658 residue
= molecule
->residues
;
2659 for(j
= molecule
->n_residues
; j
--;)
2661 len
+= sizeof(residue
->id
);
2665 residue
->name
= malloc(1);
2668 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
2669 __FILE__
, __LINE__
);
2670 return(TNG_CRITICAL
);
2672 residue
->name
[0] = 0;
2674 len
+= tng_min_i((int)strlen(residue
->name
) + 1, TNG_MAX_STR_LEN
);
2676 len
+= sizeof(residue
->n_atoms
);
2681 atom
= molecule
->atoms
;
2682 for(j
= molecule
->n_atoms
; j
--;)
2684 len
+= sizeof(atom
->id
);
2687 atom
->name
= malloc(1);
2690 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
2691 __FILE__
, __LINE__
);
2692 return(TNG_CRITICAL
);
2696 len
+= tng_min_i((int)strlen(atom
->name
) + 1, TNG_MAX_STR_LEN
);
2698 if(!atom
->atom_type
)
2700 atom
->atom_type
= malloc(1);
2701 if(!atom
->atom_type
)
2703 fprintf(stderr
, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
2704 __FILE__
, __LINE__
);
2705 return(TNG_CRITICAL
);
2707 atom
->atom_type
[0] = 0;
2709 len
+= tng_min_i((int)strlen(atom
->atom_type
) + 1, TNG_MAX_STR_LEN
);
2714 for(j
= molecule
->n_bonds
; j
--;)
2716 len
+= sizeof(bond
->from_atom_id
) + sizeof(bond
->to_atom_id
);
2720 tng_block_init(&block
);
2722 name_len
= (int)strlen("MOLECULES");
2724 block
->name
= malloc(name_len
+ 1);
2727 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
2728 name_len
+1, __FILE__
, __LINE__
);
2729 tng_block_destroy(&block
);
2730 return(TNG_CRITICAL
);
2733 strcpy(block
->name
, "MOLECULES");
2734 block
->id
= TNG_MOLECULES
;
2736 block
->block_contents_size
= sizeof(tng_data
->n_molecules
) +
2737 (sizeof(molecule
->id
) +
2738 sizeof(molecule
->quaternary_str
) +
2739 sizeof(molecule
->n_chains
) +
2740 sizeof(molecule
->n_residues
) +
2741 sizeof(molecule
->n_atoms
) +
2742 sizeof(molecule
->n_bonds
)) *
2743 tng_data
->n_molecules
+
2746 if(!tng_data
->var_num_atoms_flag
)
2748 block
->block_contents_size
+= tng_data
->n_molecules
* sizeof(int64_t);
2751 block
->block_contents
= malloc(block
->block_contents_size
);
2752 if(!block
->block_contents
)
2754 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
2755 block
->block_contents_size
, __FILE__
, __LINE__
);
2756 tng_block_destroy(&block
);
2757 return(TNG_CRITICAL
);
2760 memcpy(block
->block_contents
+offset
, &tng_data
->n_molecules
,
2761 sizeof(tng_data
->n_molecules
));
2762 if(tng_data
->output_endianness_swap_func_64
)
2764 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2765 (int64_t *)block
->header_contents
+offset
)
2768 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2769 __FILE__
, __LINE__
);
2772 offset
+= sizeof(tng_data
->n_molecules
);
2774 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
2776 molecule
= &tng_data
->molecules
[i
];
2777 memcpy(block
->block_contents
+offset
, &molecule
->id
,
2778 sizeof(molecule
->id
));
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(molecule
->id
);
2791 /* fprintf(stderr, "TNG library: Wrote id: %"PRId64" offset: %d\n", molecule->id, offset); */
2792 len
= tng_min_i((int)strlen(molecule
->name
) + 1, TNG_MAX_STR_LEN
);
2793 strncpy(block
->block_contents
+ offset
, molecule
->name
, len
);
2796 memcpy(block
->block_contents
+offset
, &molecule
->quaternary_str
,
2797 sizeof(molecule
->quaternary_str
));
2798 if(tng_data
->output_endianness_swap_func_64
)
2800 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2801 (int64_t *)block
->header_contents
+offset
)
2804 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2805 __FILE__
, __LINE__
);
2808 offset
+= sizeof(molecule
->quaternary_str
);
2810 if(!tng_data
->var_num_atoms_flag
)
2812 memcpy(block
->block_contents
+offset
,
2813 &tng_data
->molecule_cnt_list
[i
], sizeof(int64_t));
2814 if(tng_data
->output_endianness_swap_func_64
)
2816 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2817 (int64_t *)block
->header_contents
+offset
)
2820 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2821 __FILE__
, __LINE__
);
2824 offset
+= sizeof(int64_t);
2827 memcpy(block
->block_contents
+offset
, &molecule
->n_chains
,
2828 sizeof(molecule
->n_chains
));
2829 if(tng_data
->output_endianness_swap_func_64
)
2831 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2832 (int64_t *)block
->header_contents
+offset
)
2835 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2836 __FILE__
, __LINE__
);
2839 offset
+= sizeof(molecule
->n_chains
);
2841 memcpy(block
->block_contents
+offset
, &molecule
->n_residues
,
2842 sizeof(molecule
->n_residues
));
2843 if(tng_data
->output_endianness_swap_func_64
)
2845 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2846 (int64_t *)block
->header_contents
+offset
)
2849 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2850 __FILE__
, __LINE__
);
2853 offset
+= sizeof(molecule
->n_residues
);
2855 memcpy(block
->block_contents
+offset
, &molecule
->n_atoms
,
2856 sizeof(molecule
->n_atoms
));
2857 if(tng_data
->output_endianness_swap_func_64
)
2859 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2860 (int64_t *)block
->header_contents
+offset
)
2863 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2864 __FILE__
, __LINE__
);
2867 offset
+= sizeof(molecule
->n_atoms
);
2869 if(molecule
->n_chains
> 0)
2871 chain
= molecule
->chains
;
2872 for(j
= molecule
->n_chains
; j
--;)
2874 tng_chain_data_write(tng_data
, block
, chain
, &offset
);
2876 residue
= chain
->residues
;
2877 for(k
= chain
->n_residues
; k
--;)
2879 tng_residue_data_write(tng_data
, block
, residue
, &offset
);
2881 atom
= molecule
->atoms
+ residue
->atoms_offset
;
2882 for(l
= residue
->n_atoms
; l
--;)
2884 tng_atom_data_write(tng_data
, block
, atom
, &offset
);
2895 if(molecule
->n_residues
> 0)
2897 residue
= molecule
->residues
;
2898 for(k
= molecule
->n_residues
; k
--;)
2900 tng_residue_data_write(tng_data
, block
, residue
, &offset
);
2902 atom
= molecule
->atoms
+ residue
->atoms_offset
;
2903 for(l
= residue
->n_atoms
; l
--;)
2905 tng_atom_data_write(tng_data
, block
, atom
, &offset
);
2914 atom
= molecule
->atoms
;
2915 for(l
= molecule
->n_atoms
; l
--;)
2917 tng_atom_data_write(tng_data
, block
, atom
, &offset
);
2924 memcpy(block
->block_contents
+offset
, &molecule
->n_bonds
,
2925 sizeof(molecule
->n_bonds
));
2926 if(tng_data
->output_endianness_swap_func_64
)
2928 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2929 (int64_t *)block
->header_contents
+offset
)
2932 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2933 __FILE__
, __LINE__
);
2936 offset
+= sizeof(molecule
->n_bonds
);
2938 bond
= molecule
->bonds
;
2939 for(j
= molecule
->n_bonds
; j
--;)
2941 memcpy(block
->block_contents
+offset
, &bond
->from_atom_id
,
2942 sizeof(bond
->from_atom_id
));
2943 if(tng_data
->output_endianness_swap_func_64
)
2945 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2946 (int64_t *)block
->header_contents
+offset
)
2949 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2950 __FILE__
, __LINE__
);
2953 offset
+= sizeof(bond
->from_atom_id
);
2955 memcpy(block
->block_contents
+offset
, &bond
->to_atom_id
,
2956 sizeof(bond
->to_atom_id
));
2957 if(tng_data
->output_endianness_swap_func_64
)
2959 if(tng_data
->output_endianness_swap_func_64(tng_data
,
2960 (int64_t *)block
->header_contents
+offset
)
2963 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
2964 __FILE__
, __LINE__
);
2967 offset
+= sizeof(bond
->to_atom_id
);
2973 if(tng_block_header_write(tng_data
, block
, hash_mode
) != TNG_SUCCESS
)
2975 fprintf(stderr
, "TNG library: Cannot write header of file %s. %s: %d\n",
2976 tng_data
->output_file_path
, __FILE__
, __LINE__
);
2977 tng_block_destroy(&block
);
2978 return(TNG_CRITICAL
);
2981 if(fwrite(block
->block_contents
, block
->block_contents_size
, 1,
2982 tng_data
->output_file
) != 1)
2984 fprintf(stderr
, "TNG library: Could not write all block data. %s: %d\n",
2985 __FILE__
, __LINE__
);
2986 tng_block_destroy(&block
);
2987 return(TNG_CRITICAL
);
2990 tng_block_destroy(&block
);
2992 return(TNG_SUCCESS
);
2995 /** Read a frame set block. Update tng_data->current_trajectory_frame_set
2996 * @param tng_data is a trajectory data container.
2997 * @param block is a general block container.
2998 * @param hash_mode is an option to decide whether to use the md5 hash or not.
2999 * If hash_mode == TNG_USE_HASH the written md5 hash in the file will be
3000 * compared to the md5 hash of the read contents to ensure valid data.
3001 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
3002 * error has occured.
3004 static tng_function_status tng_frame_set_block_read
3005 (tng_trajectory_t tng_data
,
3006 tng_gen_block_t block
,
3007 const char hash_mode
)
3011 int64_t i
, prev_n_particles
;
3013 tng_trajectory_frame_set_t frame_set
=
3014 &tng_data
->current_trajectory_frame_set
;
3016 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
3018 return(TNG_CRITICAL
);
3021 if(block
->block_contents
)
3023 free(block
->block_contents
);
3026 block
->block_contents
= malloc(block
->block_contents_size
);
3027 if(!block
->block_contents
)
3029 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
3030 block
->block_contents_size
, __FILE__
, __LINE__
);
3031 return(TNG_CRITICAL
);
3034 /* Read the whole block into block_contents to be able to write it to
3035 * disk even if it cannot be interpreted. */
3036 if(fread(block
->block_contents
, block
->block_contents_size
, 1,
3037 tng_data
->input_file
) == 0)
3039 fprintf(stderr
, "TNG library: Cannot read block. %s: %d\n", __FILE__
, __LINE__
);
3040 return(TNG_CRITICAL
);
3043 /* FIXME: Does not check if the size of the contents matches the expected
3044 * size or if the contents can be read. */
3046 file_pos
= (int64_t)ftell(tng_data
->input_file
) -
3047 (long)(block
->block_contents_size
+ block
->header_contents_size
);
3049 if(hash_mode
== TNG_USE_HASH
)
3051 tng_md5_hash_match_verify(block
, &same_hash
);
3052 if(same_hash
!= TNG_TRUE
)
3054 fprintf(stderr
, "TNG library: Frame set block contents corrupt. File pos %ld Hashes do not match. "
3056 file_pos
, __FILE__
, __LINE__
);
3057 /* return(TNG_FAILURE); */
3061 tng_data
->current_trajectory_frame_set_input_file_pos
= file_pos
;
3063 tng_frame_set_particle_mapping_free(tng_data
);
3065 if(tng_data
->first_trajectory_frame_set_input_file_pos
<= 0)
3067 tng_data
->first_trajectory_frame_set_input_file_pos
= file_pos
;
3069 /* FIXME: Should check the frame number instead of the file_pos, in case
3070 * frame sets are not in order */
3071 if(tng_data
->last_trajectory_frame_set_input_file_pos
< file_pos
)
3073 tng_data
->last_trajectory_frame_set_input_file_pos
= file_pos
;
3076 memcpy(&frame_set
->first_frame
, block
->block_contents
,
3077 sizeof(frame_set
->first_frame
));
3078 if(tng_data
->input_endianness_swap_func_64
)
3080 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3081 &frame_set
->first_frame
)
3084 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3085 __FILE__
, __LINE__
);
3088 offset
+= sizeof(frame_set
->first_frame
);
3090 memcpy(&frame_set
->n_frames
, block
->block_contents
+ offset
,
3091 sizeof(frame_set
->n_frames
));
3092 if(tng_data
->input_endianness_swap_func_64
)
3094 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3095 &frame_set
->n_frames
)
3098 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3099 __FILE__
, __LINE__
);
3102 offset
+= sizeof(frame_set
->n_frames
);
3104 if(tng_data
->var_num_atoms_flag
)
3106 prev_n_particles
= frame_set
->n_particles
;
3107 frame_set
->n_particles
= 0;
3108 /* If the list of molecule counts has already been created assume that
3109 * it is of correct size. */
3110 if(!frame_set
->molecule_cnt_list
)
3112 frame_set
->molecule_cnt_list
=
3113 malloc(sizeof(int64_t) * tng_data
->n_molecules
);
3115 if(!frame_set
->molecule_cnt_list
)
3117 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
3118 sizeof(int64_t) * tng_data
->n_molecules
,
3119 __FILE__
, __LINE__
);
3120 return(TNG_CRITICAL
);
3123 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
3125 memcpy(&frame_set
->molecule_cnt_list
[i
],
3126 block
->block_contents
+ offset
,
3128 if(tng_data
->input_endianness_swap_func_64
)
3130 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3131 &frame_set
->molecule_cnt_list
[i
])
3134 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3135 __FILE__
, __LINE__
);
3138 offset
+= sizeof(int64_t);
3139 frame_set
->n_particles
+= tng_data
->molecules
[i
].n_atoms
*
3140 frame_set
->molecule_cnt_list
[i
];
3142 if(prev_n_particles
&& frame_set
->n_particles
!= prev_n_particles
)
3144 /* FIXME: Particle dependent data memory management */
3148 memcpy(&frame_set
->next_frame_set_file_pos
,
3149 block
->block_contents
+ offset
,
3150 sizeof(frame_set
->next_frame_set_file_pos
));
3151 if(tng_data
->input_endianness_swap_func_64
)
3153 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3154 &frame_set
->next_frame_set_file_pos
)
3157 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3158 __FILE__
, __LINE__
);
3161 offset
+= sizeof(frame_set
->next_frame_set_file_pos
);
3163 memcpy(&frame_set
->prev_frame_set_file_pos
,
3164 block
->block_contents
+ offset
,
3165 sizeof(frame_set
->prev_frame_set_file_pos
));
3166 if(tng_data
->input_endianness_swap_func_64
)
3168 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3169 &frame_set
->prev_frame_set_file_pos
)
3172 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3173 __FILE__
, __LINE__
);
3176 offset
+= sizeof(frame_set
->prev_frame_set_file_pos
);
3178 memcpy(&frame_set
->medium_stride_next_frame_set_file_pos
,
3179 block
->block_contents
+ offset
,
3180 sizeof(frame_set
->medium_stride_next_frame_set_file_pos
));
3181 if(tng_data
->input_endianness_swap_func_64
)
3183 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3184 &frame_set
->medium_stride_next_frame_set_file_pos
)
3187 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3188 __FILE__
, __LINE__
);
3191 offset
+= sizeof(frame_set
->medium_stride_next_frame_set_file_pos
);
3193 memcpy(&frame_set
->medium_stride_prev_frame_set_file_pos
,
3194 block
->block_contents
+ offset
,
3195 sizeof(frame_set
->medium_stride_prev_frame_set_file_pos
));
3196 if(tng_data
->input_endianness_swap_func_64
)
3198 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3199 &frame_set
->medium_stride_prev_frame_set_file_pos
)
3202 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3203 __FILE__
, __LINE__
);
3206 offset
+= sizeof(frame_set
->medium_stride_prev_frame_set_file_pos
);
3208 memcpy(&frame_set
->long_stride_next_frame_set_file_pos
,
3209 block
->block_contents
+ offset
,
3210 sizeof(frame_set
->long_stride_next_frame_set_file_pos
));
3211 if(tng_data
->input_endianness_swap_func_64
)
3213 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3214 &frame_set
->long_stride_next_frame_set_file_pos
)
3217 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3218 __FILE__
, __LINE__
);
3221 offset
+= sizeof(frame_set
->long_stride_next_frame_set_file_pos
);
3223 memcpy(&frame_set
->long_stride_prev_frame_set_file_pos
,
3224 block
->block_contents
+ offset
,
3225 sizeof(frame_set
->long_stride_prev_frame_set_file_pos
));
3226 if(tng_data
->input_endianness_swap_func_64
)
3228 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3229 &frame_set
->long_stride_prev_frame_set_file_pos
)
3232 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3233 __FILE__
, __LINE__
);
3236 offset
+= sizeof(frame_set
->long_stride_prev_frame_set_file_pos
);
3238 if(block
->block_version
>= 3)
3240 memcpy(&frame_set
->first_frame_time
,
3241 block
->block_contents
+ offset
,
3242 sizeof(frame_set
->first_frame_time
));
3243 if(tng_data
->input_endianness_swap_func_64
)
3245 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3246 (int64_t *)&frame_set
->first_frame_time
)
3249 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3250 __FILE__
, __LINE__
);
3253 offset
+= sizeof(frame_set
->first_frame_time
);
3255 memcpy(&tng_data
->time_per_frame
,
3256 block
->block_contents
+ offset
,
3257 sizeof(tng_data
->time_per_frame
));
3258 if(tng_data
->input_endianness_swap_func_64
)
3260 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3261 (int64_t *)&tng_data
->time_per_frame
)
3264 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3265 __FILE__
, __LINE__
);
3271 frame_set
->first_frame_time
= -1;
3272 tng_data
->time_per_frame
= -1;
3275 frame_set
->n_written_frames
= frame_set
->n_frames
;
3277 return(TNG_SUCCESS
);
3280 /** Write tng_data->current_trajectory_frame_set to file
3281 * @param tng_data is a trajectory data container.
3282 * @param block is a general block container.
3283 * @param hash_mode is an option to decide whether to use the md5 hash or not.
3284 * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
3285 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
3286 * error has occured.
3288 static tng_function_status tng_frame_set_block_write
3289 (tng_trajectory_t tng_data
,
3290 tng_gen_block_t block
,
3291 const char hash_mode
)
3296 unsigned int name_len
;
3297 tng_trajectory_frame_set_t frame_set
=
3298 &tng_data
->current_trajectory_frame_set
;
3300 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
3302 return(TNG_CRITICAL
);
3305 name_len
= (int)strlen("TRAJECTORY FRAME SET");
3307 if(!block
->name
|| strlen(block
->name
) < name_len
)
3309 temp_name
= realloc(block
->name
, name_len
+ 1);
3312 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
3313 name_len
+1, __FILE__
, __LINE__
);
3316 return(TNG_CRITICAL
);
3318 block
->name
= temp_name
;
3320 strcpy(block
->name
, "TRAJECTORY FRAME SET");
3321 block
->id
= TNG_TRAJECTORY_FRAME_SET
;
3323 block
->block_contents_size
= sizeof(int64_t) * 8;
3324 block
->block_contents_size
+= sizeof(double) * 2;
3326 if(tng_data
->var_num_atoms_flag
)
3328 block
->block_contents_size
+= sizeof(int64_t) * tng_data
->n_molecules
;
3331 if(block
->block_contents
)
3333 free(block
->block_contents
);
3335 block
->block_contents
= malloc(block
->block_contents_size
);
3336 if(!block
->block_contents
)
3338 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
3339 block
->block_contents_size
, __FILE__
, __LINE__
);
3340 return(TNG_CRITICAL
);
3343 memcpy(block
->block_contents
, &frame_set
->first_frame
,
3344 sizeof(frame_set
->first_frame
));
3345 if(tng_data
->output_endianness_swap_func_64
)
3347 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3348 (int64_t *)block
->header_contents
+offset
)
3351 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3352 __FILE__
, __LINE__
);
3355 offset
+= sizeof(frame_set
->first_frame
);
3357 memcpy(block
->block_contents
+offset
, &frame_set
->n_frames
,
3358 sizeof(frame_set
->n_frames
));
3359 if(tng_data
->output_endianness_swap_func_64
)
3361 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3362 (int64_t *)block
->header_contents
+offset
)
3365 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3366 __FILE__
, __LINE__
);
3369 offset
+= sizeof(frame_set
->n_frames
);
3371 if(tng_data
->var_num_atoms_flag
)
3373 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
3375 memcpy(block
->block_contents
+offset
,
3376 &frame_set
->molecule_cnt_list
[i
],
3378 if(tng_data
->output_endianness_swap_func_64
)
3380 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3381 (int64_t *)block
->header_contents
+offset
)
3384 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3385 __FILE__
, __LINE__
);
3388 offset
+= sizeof(int64_t);
3393 memcpy(block
->block_contents
+offset
, &frame_set
->next_frame_set_file_pos
,
3394 sizeof(frame_set
->next_frame_set_file_pos
));
3395 if(tng_data
->output_endianness_swap_func_64
)
3397 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3398 (int64_t *)block
->header_contents
+offset
)
3401 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3402 __FILE__
, __LINE__
);
3405 offset
+= sizeof(frame_set
->next_frame_set_file_pos
);
3407 memcpy(block
->block_contents
+offset
, &frame_set
->prev_frame_set_file_pos
,
3408 sizeof(frame_set
->prev_frame_set_file_pos
));
3409 if(tng_data
->output_endianness_swap_func_64
)
3411 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3412 (int64_t *)block
->header_contents
+offset
)
3415 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3416 __FILE__
, __LINE__
);
3419 offset
+= sizeof(frame_set
->prev_frame_set_file_pos
);
3421 memcpy(block
->block_contents
+offset
,
3422 &frame_set
->medium_stride_next_frame_set_file_pos
,
3423 sizeof(frame_set
->medium_stride_next_frame_set_file_pos
));
3424 if(tng_data
->output_endianness_swap_func_64
)
3426 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3427 (int64_t *)block
->header_contents
+offset
)
3430 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3431 __FILE__
, __LINE__
);
3434 offset
+= sizeof(frame_set
->medium_stride_next_frame_set_file_pos
);
3436 memcpy(block
->block_contents
+offset
,
3437 &frame_set
->medium_stride_prev_frame_set_file_pos
,
3438 sizeof(frame_set
->medium_stride_prev_frame_set_file_pos
));
3439 if(tng_data
->output_endianness_swap_func_64
)
3441 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3442 (int64_t *)block
->header_contents
+offset
)
3445 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3446 __FILE__
, __LINE__
);
3449 offset
+= sizeof(frame_set
->medium_stride_prev_frame_set_file_pos
);
3451 memcpy(block
->block_contents
+offset
,
3452 &frame_set
->long_stride_next_frame_set_file_pos
,
3453 sizeof(frame_set
->long_stride_next_frame_set_file_pos
));
3454 if(tng_data
->output_endianness_swap_func_64
)
3456 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3457 (int64_t *)block
->header_contents
+offset
)
3460 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3461 __FILE__
, __LINE__
);
3464 offset
+= sizeof(frame_set
->long_stride_next_frame_set_file_pos
);
3466 memcpy(block
->block_contents
+offset
,
3467 &frame_set
->long_stride_prev_frame_set_file_pos
,
3468 sizeof(frame_set
->long_stride_prev_frame_set_file_pos
));
3469 if(tng_data
->output_endianness_swap_func_64
)
3471 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3472 (int64_t *)block
->header_contents
+offset
)
3475 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3476 __FILE__
, __LINE__
);
3479 offset
+= sizeof(frame_set
->long_stride_prev_frame_set_file_pos
);
3481 memcpy(block
->block_contents
+offset
,
3482 &frame_set
->first_frame_time
,
3483 sizeof(frame_set
->first_frame_time
));
3484 if(tng_data
->output_endianness_swap_func_64
)
3486 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3487 (int64_t *)block
->header_contents
+offset
)
3490 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3491 __FILE__
, __LINE__
);
3494 offset
+= sizeof(frame_set
->first_frame_time
);
3496 memcpy(block
->block_contents
+offset
,
3497 &tng_data
->time_per_frame
,
3498 sizeof(tng_data
->time_per_frame
));
3499 if(tng_data
->output_endianness_swap_func_64
)
3501 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3502 (int64_t *)block
->header_contents
+offset
)
3505 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3506 __FILE__
, __LINE__
);
3510 if(tng_block_header_write(tng_data
, block
, hash_mode
) != TNG_SUCCESS
)
3512 fprintf(stderr
, "TNG library: Cannot write header of file %s. %s: %d\n",
3513 tng_data
->output_file_path
, __FILE__
, __LINE__
);
3514 return(TNG_CRITICAL
);
3517 if(fwrite(block
->block_contents
, block
->block_contents_size
, 1,
3518 tng_data
->output_file
) != 1)
3520 fprintf(stderr
, "TNG library: Could not write all block data. %s: %d\n", __FILE__
, __LINE__
);
3521 return(TNG_CRITICAL
);
3524 return(TNG_SUCCESS
);
3528 /** Read an atom mappings block (translating between real atom indexes and how
3529 * the atom info is written in this frame set).
3530 * @param tng_data is a trajectory data container.
3531 * @param block is a general block container.
3532 * @param hash_mode is an option to decide whether to use the md5 hash or not.
3533 * If hash_mode == TNG_USE_HASH the written md5 hash in the file will be
3534 * compared to the md5 hash of the read contents to ensure valid data.
3535 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
3536 * error has occured.
3538 static tng_function_status tng_trajectory_mapping_block_read
3539 (tng_trajectory_t tng_data
,
3540 tng_gen_block_t block
,
3541 const char hash_mode
)
3546 tng_trajectory_frame_set_t frame_set
=
3547 &tng_data
->current_trajectory_frame_set
;
3549 tng_particle_mapping_t mapping
, mappings
;
3551 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
3553 return(TNG_CRITICAL
);
3556 if(block
->block_contents
)
3558 free(block
->block_contents
);
3561 block
->block_contents
= malloc(block
->block_contents_size
);
3562 if(!block
->block_contents
)
3564 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
3565 block
->block_contents_size
, __FILE__
, __LINE__
);
3566 return(TNG_CRITICAL
);
3569 /* Read the whole block into block_contents to be able to write it to disk
3570 * even if it cannot be interpreted. */
3571 if(fread(block
->block_contents
, block
->block_contents_size
, 1,
3572 tng_data
->input_file
) == 0)
3574 fprintf(stderr
, "TNG library: Cannot read block. %s: %d\n", __FILE__
, __LINE__
);
3575 return(TNG_CRITICAL
);
3578 /* FIXME: Does not check if the size of the contents matches the expected
3579 * size or if the contents can be read. */
3581 if(hash_mode
== TNG_USE_HASH
)
3583 tng_md5_hash_match_verify(block
, &same_hash
);
3584 if(same_hash
!= TNG_TRUE
)
3586 fprintf(stderr
, "TNG library: Particle mapping block contents corrupt. Hashes do not match. "
3588 __FILE__
, __LINE__
);
3589 /* return(TNG_FAILURE); */
3593 frame_set
->n_mapping_blocks
++;
3594 mappings
= realloc(frame_set
->mappings
,
3595 sizeof(struct tng_particle_mapping
) *
3596 frame_set
->n_mapping_blocks
);
3599 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
3600 block
->block_contents_size
, __FILE__
, __LINE__
);
3601 free(frame_set
->mappings
);
3602 frame_set
->mappings
= 0;
3603 return(TNG_CRITICAL
);
3605 frame_set
->mappings
= mappings
;
3606 mapping
= &mappings
[frame_set
->n_mapping_blocks
- 1];
3609 memcpy(&mapping
->num_first_particle
, block
->block_contents
+offset
,
3610 sizeof(mapping
->num_first_particle
));
3611 if(tng_data
->input_endianness_swap_func_64
)
3613 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3614 &mapping
->num_first_particle
)
3617 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3618 __FILE__
, __LINE__
);
3621 offset
+= sizeof(mapping
->num_first_particle
);
3623 memcpy(&mapping
->n_particles
, block
->block_contents
+offset
,
3624 sizeof(mapping
->n_particles
));
3625 if(tng_data
->input_endianness_swap_func_64
)
3627 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3628 &mapping
->n_particles
)
3631 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3632 __FILE__
, __LINE__
);
3635 offset
+= sizeof(mapping
->n_particles
);
3637 mapping
->real_particle_numbers
= malloc(mapping
->n_particles
*
3639 if(!mapping
->real_particle_numbers
)
3641 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
3642 mapping
->n_particles
* sizeof(int64_t), __FILE__
, __LINE__
);
3643 return(TNG_CRITICAL
);
3646 /* If the byte order needs to be swapped the data must be read one value at
3647 * a time and swapped */
3648 if(tng_data
->input_endianness_swap_func_64
)
3650 for(i
= 0; i
< mapping
->n_particles
; i
++)
3652 memcpy(&mapping
->real_particle_numbers
[i
],
3653 block
->block_contents
+ offset
,
3655 if(tng_data
->input_endianness_swap_func_64(tng_data
,
3656 &mapping
->real_particle_numbers
[i
])
3659 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3660 __FILE__
, __LINE__
);
3662 offset
+= sizeof(int64_t);
3665 /* Otherwise the data can be read all at once */
3668 memcpy(mapping
->real_particle_numbers
, block
->block_contents
+ offset
,
3669 mapping
->n_particles
* sizeof(int64_t));
3673 return(TNG_SUCCESS
);
3676 /** Write the atom mappings of the current trajectory frame set
3677 * @param tng_data is a trajectory data container.
3678 * @param block is a general block container.
3679 * @param mapping_block_nr is the index of the mapping block to write.
3680 * @param hash_mode is an option to decide whether to use the md5 hash or not.
3681 * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
3682 * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if a minor error
3683 * has occurred or TNG_CRITICAL (2) if a major error has occured.
3685 static tng_function_status tng_trajectory_mapping_block_write
3686 (tng_trajectory_t tng_data
,
3687 tng_gen_block_t block
,
3688 int mapping_block_nr
,
3689 const char hash_mode
)
3693 unsigned int name_len
;
3694 tng_particle_mapping_t mapping
=
3695 &tng_data
->current_trajectory_frame_set
.mappings
[mapping_block_nr
];
3697 if(mapping_block_nr
>=
3698 tng_data
->current_trajectory_frame_set
.n_mapping_blocks
)
3700 fprintf(stderr
, "TNG library: Mapping block index out of bounds. %s: %d\n",
3701 __FILE__
, __LINE__
);
3702 return(TNG_FAILURE
);
3705 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
3707 return(TNG_CRITICAL
);
3710 name_len
= (int)strlen("PARTICLE MAPPING");
3712 if(!block
->name
|| strlen(block
->name
) < name_len
)
3714 temp_name
= realloc(block
->name
, name_len
+ 1);
3717 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
3718 name_len
+1, __FILE__
, __LINE__
);
3721 return(TNG_CRITICAL
);
3723 block
->name
= temp_name
;
3725 strcpy(block
->name
, "PARTICLE MAPPING");
3726 block
->id
= TNG_PARTICLE_MAPPING
;
3728 block
->block_contents_size
= sizeof(int64_t) * (2 + mapping
->n_particles
);
3730 if(block
->block_contents
)
3732 free(block
->block_contents
);
3734 block
->block_contents
= malloc(block
->block_contents_size
);
3735 if(!block
->block_contents
)
3737 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
3738 block
->block_contents_size
, __FILE__
, __LINE__
);
3739 return(TNG_CRITICAL
);
3742 memcpy(block
->block_contents
, &mapping
->num_first_particle
,
3743 sizeof(mapping
->num_first_particle
));
3744 if(tng_data
->output_endianness_swap_func_64
)
3746 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3747 (int64_t *)block
->header_contents
+offset
)
3750 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3751 __FILE__
, __LINE__
);
3754 offset
+= sizeof(mapping
->num_first_particle
);
3756 memcpy(block
->block_contents
+offset
, &mapping
->n_particles
,
3757 sizeof(mapping
->n_particles
));
3758 if(tng_data
->output_endianness_swap_func_64
)
3760 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3761 (int64_t *)block
->header_contents
+offset
)
3764 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3765 __FILE__
, __LINE__
);
3768 offset
+= sizeof(mapping
->n_particles
);
3770 if(tng_data
->output_endianness_swap_func_64
)
3772 for(i
= 0; i
< mapping
->n_particles
; i
++)
3774 memcpy(block
->block_contents
+offset
, &mapping
->real_particle_numbers
[i
],
3776 if(tng_data
->output_endianness_swap_func_64(tng_data
,
3777 (int64_t *)block
->header_contents
+offset
)
3780 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
3781 __FILE__
, __LINE__
);
3783 offset
+= sizeof(int64_t);
3788 memcpy(block
->block_contents
+offset
, mapping
->real_particle_numbers
,
3789 mapping
->n_particles
* sizeof(int64_t));
3793 if(tng_block_header_write(tng_data
, block
, hash_mode
) != TNG_SUCCESS
)
3795 fprintf(stderr
, "TNG library: Cannot write header of file %s. %s: %d\n",
3796 tng_data
->output_file_path
, __FILE__
, __LINE__
);
3797 return(TNG_CRITICAL
);
3800 if(fwrite(block
->block_contents
, block
->block_contents_size
, 1,
3801 tng_data
->output_file
) != 1)
3803 fprintf(stderr
, "TNG library: Could not write all block data. %s: %d\n", __FILE__
, __LINE__
);
3804 return(TNG_CRITICAL
);
3807 return(TNG_SUCCESS
);
3810 /** Prepare a block for storing particle data
3811 * @param tng_data is a trajectory data container.
3812 * @param block_type_flag specifies if this is a trajectory block or a
3813 * non-trajectory block. (TNG_TRAJECTORY_BLOCK or TNG_NON_TRAJECTORY_BLOCK)
3814 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
3815 * error has occured.
3817 static tng_function_status tng_particle_data_block_create
3818 (tng_trajectory_t tng_data
,
3819 const char block_type_flag
)
3821 tng_trajectory_frame_set_t frame_set
=
3822 &tng_data
->current_trajectory_frame_set
;
3824 tng_particle_data_t data
;
3826 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
3828 frame_set
->n_particle_data_blocks
++;
3829 data
= realloc(frame_set
->tr_particle_data
,
3830 sizeof(struct tng_particle_data
) *
3831 frame_set
->n_particle_data_blocks
);
3834 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
3835 sizeof(struct tng_particle_data
) *
3836 frame_set
->n_particle_data_blocks
,
3837 __FILE__
, __LINE__
);
3838 free(frame_set
->tr_particle_data
);
3839 frame_set
->tr_particle_data
= 0;
3840 return(TNG_CRITICAL
);
3842 frame_set
->tr_particle_data
= data
;
3846 tng_data
->n_particle_data_blocks
++;
3847 data
= realloc(tng_data
->non_tr_particle_data
,
3848 sizeof(struct tng_particle_data
) *
3849 tng_data
->n_particle_data_blocks
);
3852 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
3853 sizeof(struct tng_particle_data
) *
3854 tng_data
->n_particle_data_blocks
,
3855 __FILE__
, __LINE__
);
3856 free(tng_data
->non_tr_particle_data
);
3857 tng_data
->non_tr_particle_data
= 0;
3858 return(TNG_CRITICAL
);
3860 tng_data
->non_tr_particle_data
= data
;
3863 return(TNG_SUCCESS
);
3866 static tng_function_status
tng_compress(tng_trajectory_t tng_data
,
3867 tng_gen_block_t block
,
3868 const int64_t n_frames
,
3869 const int64_t n_particles
,
3877 int64_t algo_find_n_frames
;
3878 unsigned long offset
;
3882 if(block
->id
!= TNG_TRAJ_POSITIONS
&&
3883 block
->id
!= TNG_TRAJ_VELOCITIES
)
3885 fprintf(stderr
, "TNG library: Can only compress positions and velocities with the "
3886 "TNG method. %s: %d\n", __FILE__
, __LINE__
);
3887 return(TNG_FAILURE
);
3889 if(type
!= TNG_FLOAT_DATA
&& type
!= TNG_DOUBLE_DATA
)
3891 fprintf(stderr
, "TNG library: Data type not supported. %s: %d\n", __FILE__
, __LINE__
);
3892 return(TNG_FAILURE
);
3895 if(n_frames
<= 0 || n_particles
<= 0)
3897 fprintf(stderr
, "TNG library: Missing frames or particles. Cannot compress data "
3898 "with the TNG method. %s: %d\n", __FILE__
, __LINE__
);
3899 return(TNG_FAILURE
);
3902 f_precision
= 1/(float)tng_data
->compression_precision
;
3903 d_precision
= 1/tng_data
->compression_precision
;
3905 if(block
->id
== TNG_TRAJ_POSITIONS
)
3907 /* If there is only one frame in this frame set and there might be more
3908 * do not store the algorithm as the compression algorithm, but find
3909 * the best one without storing it */
3910 if(n_frames
== 1 && tng_data
->frame_set_n_frames
> 1)
3912 nalgo
= tng_compress_nalgo();
3913 alt_algo
=malloc(nalgo
* sizeof *tng_data
->compress_algo_pos
);
3914 if(type
== TNG_FLOAT_DATA
)
3916 dest
= tng_compress_pos_float_find_algo(start_pos
, (int)n_particles
,
3925 dest
= tng_compress_pos_find_algo(start_pos
, (int)n_particles
,
3932 else if(!tng_data
->compress_algo_pos
)
3936 algo_find_n_frames
= 5;
3940 algo_find_n_frames
= n_frames
;
3943 nalgo
= tng_compress_nalgo();
3944 tng_data
->compress_algo_pos
=malloc(nalgo
*
3945 sizeof *tng_data
->compress_algo_pos
);
3946 if(type
== TNG_FLOAT_DATA
)
3948 dest
= tng_compress_pos_float_find_algo(start_pos
, (int)n_particles
,
3949 (int)algo_find_n_frames
,
3955 if(algo_find_n_frames
< n_frames
)
3957 dest
= tng_compress_pos_float(start_pos
, (int)n_particles
,
3960 0, tng_data
->compress_algo_pos
,
3966 dest
= tng_compress_pos_find_algo(start_pos
, (int)n_particles
,
3967 (int)algo_find_n_frames
,
3973 if(algo_find_n_frames
< n_frames
)
3975 dest
= tng_compress_pos(start_pos
, (int)n_particles
,
3978 tng_data
->compress_algo_pos
,
3985 if(type
== TNG_FLOAT_DATA
)
3987 dest
= tng_compress_pos_float(start_pos
, (int)n_particles
,
3990 tng_data
->compress_algo_pos
, &new_len
);
3994 dest
= tng_compress_pos(start_pos
, (int)n_particles
,
3997 tng_data
->compress_algo_pos
,
4002 else if(block
->id
== TNG_TRAJ_VELOCITIES
)
4004 /* If there is only one frame in this frame set and there might be more
4005 * do not store the algorithm as the compression algorithm, but find
4006 * the best one without storing it */
4007 if(n_frames
== 1 && tng_data
->frame_set_n_frames
> 1)
4009 nalgo
= tng_compress_nalgo();
4010 alt_algo
=malloc(nalgo
* sizeof *tng_data
->compress_algo_pos
);
4011 if(type
== TNG_FLOAT_DATA
)
4013 dest
= tng_compress_vel_float_find_algo(start_pos
, (int)n_particles
,
4022 dest
= tng_compress_vel_find_algo(start_pos
, (int)n_particles
,
4029 else if(!tng_data
->compress_algo_vel
)
4033 algo_find_n_frames
= 5;
4037 algo_find_n_frames
= n_frames
;
4040 nalgo
= tng_compress_nalgo();
4041 tng_data
->compress_algo_vel
=malloc(nalgo
*
4042 sizeof *tng_data
->compress_algo_vel
);
4044 if(type
== TNG_FLOAT_DATA
)
4046 dest
= tng_compress_vel_float_find_algo(start_pos
, (int)n_particles
,
4047 (int)algo_find_n_frames
,
4052 if(algo_find_n_frames
< n_frames
)
4054 dest
= tng_compress_vel_float(start_pos
, (int)n_particles
,
4057 0, tng_data
->compress_algo_vel
,
4063 dest
= tng_compress_vel_find_algo(start_pos
, (int)n_particles
,
4064 (int)algo_find_n_frames
,
4069 if(algo_find_n_frames
< n_frames
)
4071 dest
= tng_compress_vel(start_pos
, (int)n_particles
,
4074 0, tng_data
->compress_algo_vel
,
4081 if(type
== TNG_FLOAT_DATA
)
4083 dest
= tng_compress_vel_float(start_pos
, (int)n_particles
,
4092 dest
= tng_compress_vel(start_pos
, (int)n_particles
,
4103 fprintf(stderr
, "TNG library: Can only compress positions and velocities using TNG-MF1 algorithms.\n");
4104 return(TNG_FAILURE
);
4107 offset
= (unsigned long)((char *)start_pos
- block
->block_contents
);
4114 block
->block_contents_size
= new_len
+ offset
;
4116 temp
= realloc(block
->block_contents
, block
->block_contents_size
);
4119 free(block
->block_contents
);
4120 block
->block_contents
= 0;
4121 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
4122 block
->block_contents_size
, __FILE__
, __LINE__
);
4123 return(TNG_CRITICAL
);
4125 block
->block_contents
= temp
;
4128 memcpy(temp
+ offset
, dest
, new_len
);
4133 fprintf(stderr
, "TNG library: Error during TNG compression. %s: %d\n", __FILE__
, __LINE__
);
4134 return(TNG_FAILURE
);
4137 return(TNG_SUCCESS
);
4140 static tng_function_status
tng_uncompress(tng_trajectory_t tng_data
,
4141 tng_gen_block_t block
,
4144 const unsigned long uncompressed_len
)
4149 unsigned long offset
;
4153 TNG_ASSERT(uncompressed_len
, "TNG library: The full length of the uncompressed data must be > 0.");
4155 if(block
->id
!= TNG_TRAJ_POSITIONS
&&
4156 block
->id
!= TNG_TRAJ_VELOCITIES
)
4158 fprintf(stderr
, "TNG library: Can only uncompress positions and velocities with the"
4160 return(TNG_FAILURE
);
4162 if(type
!= TNG_FLOAT_DATA
&& type
!= TNG_DOUBLE_DATA
)
4164 fprintf(stderr
, "TNG library: Data type not supported.\n");
4165 return(TNG_FAILURE
);
4168 if(type
== TNG_FLOAT_DATA
)
4170 f_dest
= malloc(uncompressed_len
);
4173 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
4174 uncompressed_len
, __FILE__
, __LINE__
);
4175 return(TNG_CRITICAL
);
4177 result
= tng_compress_uncompress_float(start_pos
, f_dest
);
4181 d_dest
= malloc(uncompressed_len
);
4184 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
4185 uncompressed_len
, __FILE__
, __LINE__
);
4186 return(TNG_CRITICAL
);
4188 result
= tng_compress_uncompress(start_pos
, d_dest
);
4193 fprintf(stderr
, "TNG library: Cannot uncompress TNG compressed block.\n");
4194 return(TNG_FAILURE
);
4197 offset
= (unsigned long)((char *)start_pos
- (char *)block
->block_contents
);
4199 block
->block_contents_size
= (int64_t)(uncompressed_len
+ offset
);
4201 temp
= realloc(block
->block_contents
, uncompressed_len
+ offset
);
4204 free(block
->block_contents
);
4205 block
->block_contents
= 0;
4214 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
4215 block
->block_contents_size
, __FILE__
, __LINE__
);
4216 return(TNG_CRITICAL
);
4219 if(type
== TNG_FLOAT_DATA
)
4221 memcpy(temp
+ offset
, f_dest
, uncompressed_len
);
4225 memcpy(temp
+ offset
, d_dest
, uncompressed_len
);
4228 block
->block_contents
= temp
;
4238 return(TNG_SUCCESS
);
4242 static tng_function_status
tng_gzip_compress(tng_trajectory_t tng_data
,
4243 tng_gen_block_t block
,
4244 void *start_pos
, const int len
)
4248 unsigned long max_len
, stat
, offset
;
4251 max_len
= compressBound(len
);
4252 dest
= malloc(max_len
);
4255 fprintf(stderr
, "TNG library: Cannot allocate memory (%ld bytes). %s: %d\n",
4256 max_len
, __FILE__
, __LINE__
);
4257 return(TNG_CRITICAL
);
4260 stat
= compress(dest
, &max_len
, start_pos
, len
);
4261 if(stat
!= (unsigned long)Z_OK
)
4264 if(stat
== (unsigned long)Z_MEM_ERROR
)
4266 fprintf(stderr
, "TNG library: Not enough memory. ");
4268 else if(stat
== (unsigned long)Z_BUF_ERROR
)
4270 fprintf(stderr
, "TNG library: Destination buffer too small. ");
4272 fprintf(stderr
, "TNG library: Error gzipping data. %s: %d\n", __FILE__
, __LINE__
);
4273 return(TNG_FAILURE
);
4276 offset
= (char *)start_pos
- block
->block_contents
;
4278 block
->block_contents_size
= max_len
+ offset
;
4280 temp
= realloc(block
->block_contents
, block
->block_contents_size
);
4283 free(block
->block_contents
);
4285 block
->block_contents
= 0;
4286 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
4287 block
->block_contents_size
, __FILE__
, __LINE__
);
4288 return(TNG_CRITICAL
);
4291 block
->block_contents
= temp
;
4293 memcpy(temp
+ offset
, dest
, max_len
);
4297 return(TNG_SUCCESS
);
4300 static tng_function_status
tng_gzip_uncompress(tng_trajectory_t tng_data
,
4301 tng_gen_block_t block
,
4303 unsigned long uncompressed_len
)
4311 offset
= (char *)start_pos
- (char *)block
->block_contents
;
4313 dest
= malloc(uncompressed_len
);
4316 fprintf(stderr
, "TNG library: Cannot allocate memory (%lud bytes). %s: %d\n",
4317 uncompressed_len
, __FILE__
, __LINE__
);
4318 return(TNG_CRITICAL
);
4321 stat
= uncompress(dest
, &uncompressed_len
, (Bytef
*) start_pos
,
4322 block
->block_contents_size
- offset
);
4327 if(stat
== (unsigned long)Z_MEM_ERROR
)
4329 fprintf(stderr
, "TNG library: Not enough memory. ");
4331 else if(stat
== (unsigned long)Z_BUF_ERROR
)
4333 fprintf(stderr
, "TNG library: Destination buffer too small. ");
4335 else if(stat
== (unsigned long)Z_DATA_ERROR
)
4337 fprintf(stderr
, "TNG library: Data corrupt. ");
4339 fprintf(stderr
, "TNG library: Error uncompressing gzipped data. %s: %d\n", __FILE__
,
4341 return(TNG_FAILURE
);
4345 block
->block_contents_size
= uncompressed_len
+ offset
;
4347 temp
= realloc(block
->block_contents
, uncompressed_len
+ offset
);
4350 free(block
->block_contents
);
4351 block
->block_contents
= 0;
4353 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
4354 block
->block_contents_size
, __FILE__
, __LINE__
);
4355 return(TNG_CRITICAL
);
4358 memcpy(temp
+ offset
, dest
, uncompressed_len
);
4360 block
->block_contents
= temp
;
4363 return(TNG_SUCCESS
);
4367 /** Allocate memory for storing particle data.
4368 * The allocated block will be refered to by data->values.
4369 * @param tng_data is a trajectory data container.
4370 * @param data is the data struct, which will contain the allocated memory in
4372 * @param n_frames is the number of frames of data to store.
4373 * @param n_particles is the number of particles with data.
4374 * @param n_values_per_frame is the number of data values per particle and
4376 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
4377 * error has occured.
4379 static tng_function_status tng_allocate_particle_data_mem
4380 (tng_trajectory_t tng_data
,
4381 tng_particle_data_t data
,
4383 int64_t stride_length
,
4384 const int64_t n_particles
,
4385 const int64_t n_values_per_frame
)
4388 int64_t i
, j
, k
, size
, frame_alloc
;
4391 if(n_particles
== 0 || n_values_per_frame
== 0)
4393 return(TNG_FAILURE
);
4396 if(data
->strings
&& data
->datatype
== TNG_CHAR_DATA
)
4398 for(i
= data
->n_frames
; i
--;)
4400 for(j
= n_particles
; j
--;)
4402 for(k
= data
->n_values_per_frame
; k
--;)
4404 if(data
->strings
[i
][j
][k
])
4406 free(data
->strings
[i
][j
][k
]);
4409 free(data
->strings
[i
][j
]);
4411 free(data
->strings
[i
]);
4413 free(data
->strings
);
4415 data
->n_frames
= n_frames
;
4416 n_frames
= tng_max_i64(1, n_frames
);
4417 data
->stride_length
= tng_max_i64(1, stride_length
);
4418 data
->n_values_per_frame
= n_values_per_frame
;
4419 frame_alloc
= (n_frames
% stride_length
) ? n_frames
/ stride_length
+ 1 : n_frames
/ stride_length
;
4421 if(data
->datatype
== TNG_CHAR_DATA
)
4423 data
->strings
= malloc(sizeof(char ***) * frame_alloc
);
4424 for(i
= frame_alloc
; i
-- ;)
4426 data
->strings
[i
] = malloc(sizeof(char **) *
4428 if(!data
->strings
[i
])
4430 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
4431 sizeof(union data_values
*) * n_particles
,
4432 __FILE__
, __LINE__
);
4433 return(TNG_CRITICAL
);
4435 for(j
= n_particles
; j
--;)
4437 data
->strings
[i
][j
] = malloc(sizeof(char *) *
4438 n_values_per_frame
);
4439 if(!data
->strings
[i
][j
])
4441 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
4442 sizeof(union data_values
) * n_values_per_frame
,
4443 __FILE__
, __LINE__
);
4444 return(TNG_CRITICAL
);
4446 for(k
= n_values_per_frame
; k
--;)
4448 data
->strings
[i
][j
][k
] = 0;
4455 switch(data
->datatype
)
4458 size
= sizeof(int64_t);
4460 case TNG_FLOAT_DATA
:
4461 size
= sizeof(float);
4463 case TNG_DOUBLE_DATA
:
4465 size
= sizeof(double);
4468 values
= realloc(data
->values
,
4469 size
* frame_alloc
*
4470 n_particles
* n_values_per_frame
);
4473 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
4474 size
* frame_alloc
*
4475 n_particles
* n_values_per_frame
,
4476 __FILE__
, __LINE__
);
4479 return(TNG_CRITICAL
);
4481 data
->values
= values
;
4483 return(TNG_SUCCESS
);
4486 static tng_function_status tng_particle_data_find
4487 (tng_trajectory_t tng_data
,
4489 tng_particle_data_t
*data
)
4491 int64_t block_index
, i
;
4492 tng_trajectory_frame_set_t frame_set
= &tng_data
->
4493 current_trajectory_frame_set
;
4494 char block_type_flag
;
4496 if(tng_data
->current_trajectory_frame_set_input_file_pos
> 0 ||
4497 tng_data
->current_trajectory_frame_set_output_file_pos
> 0)
4499 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
4503 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
4507 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
4509 for(i
= frame_set
->n_particle_data_blocks
; i
-- ;)
4511 *data
= &frame_set
->tr_particle_data
[i
];
4512 if((*data
)->block_id
== id
)
4521 for(i
= tng_data
->n_particle_data_blocks
; i
-- ;)
4523 *data
= &tng_data
->non_tr_particle_data
[i
];
4524 if((*data
)->block_id
== id
)
4531 if(block_index
== -1)
4533 return(TNG_FAILURE
);
4535 return(TNG_SUCCESS
);
4538 static tng_function_status tng_data_find
4539 (tng_trajectory_t tng_data
,
4541 tng_non_particle_data_t
*data
)
4543 int64_t block_index
, i
;
4544 tng_trajectory_frame_set_t frame_set
= &tng_data
->
4545 current_trajectory_frame_set
;
4546 char block_type_flag
;
4548 if(tng_data
->current_trajectory_frame_set_input_file_pos
> 0 ||
4549 tng_data
->current_trajectory_frame_set_output_file_pos
> 0)
4551 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
4555 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
4559 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
4561 for(i
= frame_set
->n_data_blocks
; i
-- ;)
4563 *data
= &frame_set
->tr_data
[i
];
4564 if((*data
)->block_id
== id
)
4570 if(block_index
== -1)
4572 for(i
= tng_data
->n_data_blocks
; i
-- ;)
4574 *data
= &tng_data
->non_tr_data
[i
];
4575 if((*data
)->block_id
== id
)
4585 for(i
= tng_data
->n_data_blocks
; i
-- ;)
4587 *data
= &tng_data
->non_tr_data
[i
];
4588 if((*data
)->block_id
== id
)
4595 if(block_index
== -1)
4597 return(TNG_FAILURE
);
4599 return(TNG_SUCCESS
);
4602 /** Read the values of a particle data block
4603 * @param tng_data is a trajectory data container.
4604 * @param block is the block to store the data (should already contain
4605 * the block headers and the block contents).
4606 * @param offset is the reading offset to point at the place where the actual
4607 * values are stored, starting from the beginning of the block_contents. The
4608 * offset is changed during the reading.
4609 * @param datatype is the type of data of the data block (char, int, float or
4611 * @param num_first_particle is the number of the first particle in the data
4612 * block. This should be the same as in the corresponding particle mapping
4614 * @param n_particles is the number of particles in the data block. This should
4615 * be the same as in the corresponding particle mapping block.
4616 * @param first_frame_with_data is the frame number of the first frame with data
4617 * in this data block.
4618 * @param stride_length is the number of frames between each data entry.
4619 * @param n_frames is the number of frames in this data block.
4620 * @param n_values is the number of values per particle and frame stored in this
4622 * @param codec_id is the ID of the codec to compress the data.
4623 * @param multiplier is the multiplication factor applied to each data value
4624 * before compression. This factor is applied since some compression algorithms
4625 * work only on integers.
4626 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
4627 * error has occured.
4629 static tng_function_status tng_particle_data_read
4630 (tng_trajectory_t tng_data
,
4631 tng_gen_block_t block
,
4633 const char datatype
,
4634 const int64_t num_first_particle
,
4635 const int64_t n_particles
,
4636 const int64_t first_frame_with_data
,
4637 const int64_t stride_length
,
4639 const int64_t n_values
,
4640 const int64_t codec_id
,
4641 const double multiplier
)
4643 int64_t i
, j
, k
, tot_n_particles
, n_frames_div
;
4645 unsigned long data_size
;
4646 char ***first_dim_values
, **second_dim_values
;
4647 tng_particle_data_t data
;
4648 tng_trajectory_frame_set_t frame_set
=
4649 &tng_data
->current_trajectory_frame_set
;
4650 char block_type_flag
;
4652 TNG_ASSERT(offset
!= 0, "TNG library: offset must not be a NULL pointer.");
4660 size
= sizeof(int64_t);
4662 case TNG_FLOAT_DATA
:
4663 size
= sizeof(float);
4665 case TNG_DOUBLE_DATA
:
4667 size
= sizeof(double);
4670 /* If the block does not exist, create it */
4671 if(tng_particle_data_find(tng_data
, block
->id
, &data
) != TNG_SUCCESS
)
4673 if(tng_data
->current_trajectory_frame_set_input_file_pos
> 0)
4675 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
4679 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
4682 if(tng_particle_data_block_create(tng_data
, block_type_flag
) !=
4685 fprintf(stderr
, "TNG library: Cannot create particle data block. %s: %d\n",
4686 __FILE__
, __LINE__
);
4687 return(TNG_CRITICAL
);
4689 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
4691 data
= &frame_set
->tr_particle_data
[frame_set
->
4692 n_particle_data_blocks
- 1];
4696 data
= &tng_data
->non_tr_particle_data
[tng_data
->
4697 n_particle_data_blocks
- 1];
4699 data
->block_id
= block
->id
;
4701 data
->block_name
= malloc(strlen(block
->name
) + 1);
4702 if(!data
->block_name
)
4704 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
4705 (int)strlen(block
->name
)+1, __FILE__
, __LINE__
);
4706 return(TNG_CRITICAL
);
4708 strcpy(data
->block_name
, block
->name
);
4710 data
->datatype
= datatype
;
4713 /* FIXME: Memory leak from strings. */
4716 data
->codec_id
= codec_id
;
4717 data
->compression_multiplier
= multiplier
;
4718 data
->last_retrieved_frame
= -1;
4721 if(/*block_type_flag == TNG_TRAJECTORY_BLOCK &&*/
4722 tng_data
->current_trajectory_frame_set_input_file_pos
> 0 &&
4723 tng_data
->var_num_atoms_flag
)
4725 tot_n_particles
= frame_set
->n_particles
;
4729 tot_n_particles
= tng_data
->n_particles
;
4732 n_frames_div
= (n_frames
% stride_length
) ? n_frames
/ stride_length
+ 1 : n_frames
/ stride_length
;
4734 if(codec_id
!= TNG_UNCOMPRESSED
)
4736 data_size
= (unsigned long)(n_frames_div
* size
* n_particles
* n_values
);
4739 case TNG_XTC_COMPRESSION
:
4740 fprintf(stderr
, "TNG library: XTC compression not implemented yet.\n");
4742 case TNG_TNG_COMPRESSION
:
4743 /* fprintf(stderr, "TNG library: Before TNG uncompression: %"PRId64"\n", block->block_contents_size);*/
4744 if(tng_uncompress(tng_data
, block
, datatype
,
4745 block
->block_contents
+ *offset
,
4746 data_size
) != TNG_SUCCESS
)
4748 fprintf(stderr
, "TNG library: Could not read tng compressed block data. %s: %d\n",
4749 __FILE__
, __LINE__
);
4750 return(TNG_CRITICAL
);
4752 /* fprintf(stderr, "TNG library: After TNG uncompression: %"PRId64"\n", block->block_contents_size);*/
4755 case TNG_GZIP_COMPRESSION
:
4756 /* fprintf(stderr, "TNG library: Before GZIP uncompression: %"PRId64"\n", block->block_contents_size);*/
4757 if(tng_gzip_uncompress(tng_data
, block
,
4758 block
->block_contents
+ *offset
,
4759 data_size
) != TNG_SUCCESS
)
4761 fprintf(stderr
, "TNG library: Could not read gzipped block data. %s: %d\n", __FILE__
,
4763 return(TNG_CRITICAL
);
4765 /* fprintf(stderr, "TNG library: After GZIP uncompression: %"PRId64"\n", block->block_contents_size);*/
4770 /* Allocate memory */
4771 if(!data
->values
|| data
->n_frames
!= n_frames
||
4772 data
->n_values_per_frame
!= n_values
)
4774 if(tng_allocate_particle_data_mem(tng_data
, data
, n_frames
,
4776 tot_n_particles
, n_values
) !=
4779 fprintf(stderr
, "TNG library: Cannot allocate memory for particle data. %s: %d\n",
4780 __FILE__
, __LINE__
);
4781 return(TNG_CRITICAL
);
4785 data
->first_frame_with_data
= first_frame_with_data
;
4787 if(datatype
== TNG_CHAR_DATA
)
4789 for(i
= 0; i
< n_frames_div
; i
++)
4791 first_dim_values
= data
->strings
[i
];
4792 for(j
= num_first_particle
; j
< num_first_particle
+ n_particles
;
4795 second_dim_values
= first_dim_values
[j
];
4796 for(k
= 0; k
< n_values
; k
++)
4798 len
= tng_min_i((int)strlen(block
->block_contents
+*offset
) + 1,
4800 if(second_dim_values
[k
])
4802 free(second_dim_values
[k
]);
4804 second_dim_values
[k
] = malloc(len
);
4805 if(!second_dim_values
[k
])
4807 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
4808 len
, __FILE__
, __LINE__
);
4809 return(TNG_CRITICAL
);
4811 strncpy(second_dim_values
[k
],
4812 block
->block_contents
+*offset
, len
);
4820 memcpy((char *)data
->values
+ n_frames_div
* size
* n_values
*
4822 block
->block_contents
+ *offset
,
4823 block
->block_contents_size
- *offset
);
4826 case TNG_FLOAT_DATA
:
4827 if(tng_data
->input_endianness_swap_func_32
)
4829 for(i
= 0; i
< (block
->block_contents_size
- *offset
); i
+=size
)
4831 if(tng_data
->input_endianness_swap_func_32(tng_data
,
4832 (int32_t *)((char *)data
->values
+ i
))
4835 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
4836 __FILE__
, __LINE__
);
4842 case TNG_DOUBLE_DATA
:
4843 if(tng_data
->input_endianness_swap_func_64
)
4845 for(i
= 0; i
< (block
->block_contents_size
- *offset
); i
+=size
)
4847 if(tng_data
->input_endianness_swap_func_64(tng_data
,
4848 (int64_t *)((char *)data
->values
+ i
))
4851 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
4852 __FILE__
, __LINE__
);
4861 return(TNG_SUCCESS
);
4864 /** Write a particle data block
4865 * @param tng_data is a trajectory data container.
4866 * @param block is the block to store the data (should already contain
4867 * the block headers and the block contents).
4868 * @param block_index is the index number of the data block in the frame set.
4869 * @param mapping is the particle mapping that is relevant for the data block.
4870 * @param hash_mode is an option to decide whether to use the md5 hash or not.
4871 * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
4872 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
4873 * error has occured.
4875 static tng_function_status tng_particle_data_block_write
4876 (tng_trajectory_t tng_data
,
4877 tng_gen_block_t block
,
4878 const int64_t block_index
,
4879 const tng_particle_mapping_t mapping
,
4880 const char hash_mode
)
4882 int64_t n_particles
, num_first_particle
, n_frames
, stride_length
;
4883 int64_t frame_step
, data_start_pos
;
4886 size_t len
, offset
= 0;
4887 char dependency
, temp
, *temp_name
;
4889 char ***first_dim_values
, **second_dim_values
;
4890 tng_trajectory_frame_set_t frame_set
;
4891 tng_function_status stat
;
4893 tng_particle_data_t data
;
4894 char block_type_flag
;
4896 frame_set
= &tng_data
->current_trajectory_frame_set
;
4898 /* If we have already started writing frame sets it is too late to write
4899 * non-trajectory data blocks */
4900 if(tng_data
->current_trajectory_frame_set_output_file_pos
> 0)
4902 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
4906 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
4909 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
4911 return(TNG_CRITICAL
);
4914 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
4916 data
= &frame_set
->tr_particle_data
[block_index
];
4918 /* If this data block has not had any data added in this frame set
4919 * do not write it. */
4920 if(data
->first_frame_with_data
< frame_set
->first_frame
)
4922 return(TNG_SUCCESS
);
4925 stride_length
= tng_max_i64(1, data
->stride_length
);
4929 data
= &tng_data
->non_tr_particle_data
[block_index
];
4933 switch(data
->datatype
)
4939 size
= sizeof(int64_t);
4941 case TNG_FLOAT_DATA
:
4942 size
= sizeof(float);
4944 case TNG_DOUBLE_DATA
:
4946 size
= sizeof(double);
4949 len
= strlen(data
->block_name
) + 1;
4951 if(!block
->name
|| strlen(block
->name
) < len
)
4953 temp_name
= realloc(block
->name
, len
);
4956 fprintf(stderr
, "TNG library: Cannot allocate memory (%lud bytes). %s: %d\n", len
,
4957 __FILE__
, __LINE__
);
4960 return(TNG_CRITICAL
);
4962 block
->name
= temp_name
;
4964 strncpy(block
->name
, data
->block_name
, len
);
4965 block
->id
= data
->block_id
;
4967 /* If writing frame independent data data->n_frames is 0, but n_frames
4968 is used for the loop writing the data (and reserving memory) and needs
4970 n_frames
= tng_max_i64(1, data
->n_frames
);
4972 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
4974 /* If the frame set is finished before writing the full number of frames
4975 make sure the data block is not longer than the frame set. */
4976 n_frames
= tng_min_i64(n_frames
, frame_set
->n_frames
);
4978 n_frames
-= (data
->first_frame_with_data
- frame_set
->first_frame
);
4981 frame_step
= (n_frames
% stride_length
) ? n_frames
/ stride_length
+ 1:
4982 n_frames
/ stride_length
;
4984 /* TNG compression will use compression precision to get integers from
4985 * floating point data. The compression multiplier stores that information
4986 * to be able to return the precision of the compressed data. */
4987 if(data
->codec_id
== TNG_TNG_COMPRESSION
)
4989 data
->compression_multiplier
= tng_data
->compression_precision
;
4991 /* Uncompressed data blocks do not use compression multipliers at all.
4992 * GZip compression does not need it either. */
4993 else if(data
->codec_id
== TNG_UNCOMPRESSED
|| data
->codec_id
== TNG_GZIP_COMPRESSION
)
4995 data
->compression_multiplier
= 1.0;
4998 if(mapping
&& mapping
->n_particles
!= 0)
5000 n_particles
= mapping
->n_particles
;
5001 num_first_particle
= mapping
->num_first_particle
;
5005 num_first_particle
= 0;
5006 if(tng_data
->var_num_atoms_flag
)
5008 n_particles
= frame_set
->n_particles
;
5012 n_particles
= tng_data
->n_particles
;
5016 block
->block_contents_size
= sizeof(char) * 2 +
5017 sizeof(data
->n_values_per_frame
) +
5018 sizeof(data
->codec_id
) +
5019 sizeof(num_first_particle
) +
5020 sizeof(n_particles
);
5022 if(stride_length
> 1)
5024 block
->block_contents_size
+= sizeof(data
->first_frame_with_data
) +
5025 sizeof(data
->stride_length
);
5028 if(data
->codec_id
!= TNG_UNCOMPRESSED
)
5030 block
->block_contents_size
+= sizeof(data
->compression_multiplier
);
5033 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
&& data
->n_frames
> 0)
5035 dependency
= TNG_FRAME_DEPENDENT
+ TNG_PARTICLE_DEPENDENT
;
5039 dependency
= TNG_PARTICLE_DEPENDENT
;
5041 if(dependency
& TNG_FRAME_DEPENDENT
)
5043 block
->block_contents_size
+= sizeof(char);
5046 data_start_pos
= block
->block_contents_size
;
5048 if(data
->datatype
== TNG_CHAR_DATA
)
5050 for(i
= n_frames
; i
--;)
5052 first_dim_values
= data
->strings
[i
];
5053 for(j
= num_first_particle
; j
< num_first_particle
+ n_particles
;
5056 second_dim_values
= first_dim_values
[j
];
5057 for(k
= data
->n_values_per_frame
; k
--;)
5059 block
->block_contents_size
+=
5060 strlen(second_dim_values
[k
]) + 1;
5067 block
->block_contents_size
+= size
* frame_step
*
5068 n_particles
* data
->n_values_per_frame
;
5071 if(block
->block_contents
)
5073 free(block
->block_contents
);
5075 block
->block_contents
= malloc(block
->block_contents_size
);
5076 if(!block
->block_contents
)
5078 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
5079 block
->block_contents_size
, __FILE__
, __LINE__
);
5080 return(TNG_CRITICAL
);
5084 memcpy(block
->block_contents
, &data
->datatype
, sizeof(char));
5085 offset
+= sizeof(char);
5087 memcpy(block
->block_contents
+offset
, &dependency
, sizeof(char));
5088 offset
+= sizeof(char);
5090 if(dependency
& TNG_FRAME_DEPENDENT
)
5092 if(stride_length
> 1)
5100 memcpy(block
->block_contents
+offset
, &temp
, sizeof(char));
5101 offset
+= sizeof(char);
5104 memcpy(block
->block_contents
+offset
, &data
->n_values_per_frame
,
5105 sizeof(data
->n_values_per_frame
));
5106 if(tng_data
->output_endianness_swap_func_64
)
5108 if(tng_data
->output_endianness_swap_func_64(tng_data
,
5109 (int64_t *)block
->header_contents
+offset
)
5112 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5113 __FILE__
, __LINE__
);
5116 offset
+= sizeof(data
->n_values_per_frame
);
5118 memcpy(block
->block_contents
+offset
, &data
->codec_id
,
5119 sizeof(data
->codec_id
));
5120 if(tng_data
->output_endianness_swap_func_64
)
5122 if(tng_data
->output_endianness_swap_func_64(tng_data
,
5123 (int64_t *)block
->header_contents
+offset
)
5126 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5127 __FILE__
, __LINE__
);
5130 offset
+= sizeof(data
->codec_id
);
5132 if(data
->codec_id
!= TNG_UNCOMPRESSED
)
5134 memcpy(block
->block_contents
+offset
, &data
->compression_multiplier
,
5135 sizeof(data
->compression_multiplier
));
5136 if(tng_data
->output_endianness_swap_func_64
)
5138 if(tng_data
->output_endianness_swap_func_64(tng_data
,
5139 (int64_t *)block
->header_contents
+offset
)
5142 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5143 __FILE__
, __LINE__
);
5146 offset
+= sizeof(data
->compression_multiplier
);
5149 if(data
->n_frames
> 0 && stride_length
> 1)
5151 /* FIXME: first_frame_with_data is not reliably set */
5152 if(data
->first_frame_with_data
== 0)
5154 data
->first_frame_with_data
= frame_set
->first_frame
;
5156 memcpy(block
->block_contents
+offset
, &data
->first_frame_with_data
,
5157 sizeof(data
->first_frame_with_data
));
5158 if(tng_data
->output_endianness_swap_func_64
)
5160 if(tng_data
->output_endianness_swap_func_64(tng_data
,
5161 (int64_t *)block
->header_contents
+offset
)
5164 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5165 __FILE__
, __LINE__
);
5168 offset
+= sizeof(data
->first_frame_with_data
);
5170 memcpy(block
->block_contents
+offset
, &stride_length
,
5171 sizeof(stride_length
));
5172 if(tng_data
->output_endianness_swap_func_64
)
5174 if(tng_data
->output_endianness_swap_func_64(tng_data
,
5175 (int64_t *)block
->header_contents
+offset
)
5178 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5179 __FILE__
, __LINE__
);
5182 offset
+= sizeof(stride_length
);
5186 memcpy(block
->block_contents
+offset
, &num_first_particle
,
5187 sizeof(num_first_particle
));
5188 if(tng_data
->output_endianness_swap_func_64
)
5190 if(tng_data
->output_endianness_swap_func_64(tng_data
,
5191 (int64_t *)block
->header_contents
+offset
)
5194 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5195 __FILE__
, __LINE__
);
5198 offset
+= sizeof(num_first_particle
);
5200 memcpy(block
->block_contents
+offset
, &n_particles
, sizeof(n_particles
));
5201 if(tng_data
->output_endianness_swap_func_64
)
5203 if(tng_data
->output_endianness_swap_func_64(tng_data
,
5204 (int64_t *)block
->header_contents
+offset
)
5207 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5208 __FILE__
, __LINE__
);
5211 offset
+= sizeof(n_particles
);
5213 if(data
->datatype
== TNG_CHAR_DATA
)
5217 for(i
= 0; i
< frame_step
; i
++)
5219 first_dim_values
= data
->strings
[i
];
5220 for(j
= num_first_particle
; j
< num_first_particle
+ n_particles
;
5223 second_dim_values
= first_dim_values
[j
];
5224 for(k
= 0; k
< data
->n_values_per_frame
; k
++)
5226 len
= (unsigned int)strlen(second_dim_values
[k
]) + 1;
5227 strncpy(block
->block_contents
+offset
,
5228 second_dim_values
[k
], len
);
5235 else if(data
->values
)
5237 memcpy(block
->block_contents
+ offset
, data
->values
,
5238 block
->block_contents_size
- offset
);
5240 switch(data
->datatype
)
5242 case TNG_FLOAT_DATA
:
5243 if(data
->codec_id
== TNG_UNCOMPRESSED
|| data
-> codec_id
== TNG_GZIP_COMPRESSION
||
5244 data
->codec_id
== TNG_TNG_COMPRESSION
)
5246 if(tng_data
->input_endianness_swap_func_32
)
5248 for(i
= offset
; i
< block
->block_contents_size
; i
+=size
)
5250 if(tng_data
->input_endianness_swap_func_32(tng_data
,
5251 (int32_t *)(block
->block_contents
+ i
))
5254 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5255 __FILE__
, __LINE__
);
5262 multiplier
= data
->compression_multiplier
;
5263 if(fabs(multiplier
- 1.0) > 0.00001 ||
5264 tng_data
->input_endianness_swap_func_32
)
5266 for(i
= offset
; i
< block
->block_contents_size
; i
+=size
)
5268 *(float *)(block
->block_contents
+ i
) *= (float)multiplier
;
5269 if(tng_data
->input_endianness_swap_func_32
&&
5270 tng_data
->input_endianness_swap_func_32(tng_data
,
5271 (int32_t *)(block
->block_contents
+ i
))
5274 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5275 __FILE__
, __LINE__
);
5282 if(tng_data
->input_endianness_swap_func_64
)
5284 for(i
= offset
; i
< block
->block_contents_size
; i
+=size
)
5286 if(tng_data
->input_endianness_swap_func_64(tng_data
,
5287 (int64_t *)(block
->block_contents
+ i
))
5290 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5291 __FILE__
, __LINE__
);
5296 case TNG_DOUBLE_DATA
:
5297 if(data
->codec_id
== TNG_UNCOMPRESSED
|| data
-> codec_id
== TNG_GZIP_COMPRESSION
||
5298 data
->codec_id
== TNG_TNG_COMPRESSION
)
5300 if(tng_data
->input_endianness_swap_func_64
)
5302 for(i
= offset
; i
< block
->block_contents_size
; i
+=size
)
5304 if(tng_data
->input_endianness_swap_func_64(tng_data
,
5305 (int64_t *)(block
->block_contents
+ i
))
5308 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5309 __FILE__
, __LINE__
);
5316 multiplier
= data
->compression_multiplier
;
5317 if(fabs(multiplier
- 1.0) > 0.00001 ||
5318 tng_data
->input_endianness_swap_func_64
)
5320 for(i
= offset
; i
< block
->block_contents_size
; i
+=size
)
5322 *(double *)(block
->block_contents
+ i
) *= multiplier
;
5323 if(tng_data
->input_endianness_swap_func_64
&&
5324 tng_data
->input_endianness_swap_func_64(tng_data
,
5325 (int64_t *)(block
->block_contents
+ i
))
5328 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5329 __FILE__
, __LINE__
);
5341 memset(block
->block_contents
+offset
, 0, block
->block_contents_size
- offset
);
5344 frame_set
->n_written_frames
+= frame_set
->n_unwritten_frames
;
5345 frame_set
->n_unwritten_frames
= 0;
5347 if(block_type_flag
== TNG_NON_TRAJECTORY_BLOCK
|| frame_set
->n_written_frames
> 0)
5349 switch(data
->codec_id
)
5351 case TNG_XTC_COMPRESSION
:
5352 fprintf(stderr
, "TNG library: XTC compression not implemented yet.\n");
5353 data
->codec_id
= TNG_UNCOMPRESSED
;
5355 case TNG_TNG_COMPRESSION
:
5356 stat
= tng_compress(tng_data
, block
, frame_step
,
5357 n_particles
, data
->datatype
,
5358 block
->block_contents
+ data_start_pos
);
5359 if(stat
!= TNG_SUCCESS
)
5361 fprintf(stderr
, "TNG library: Could not write tng compressed block data. %s: %d\n",
5362 __FILE__
, __LINE__
);
5363 if(stat
== TNG_CRITICAL
)
5365 return(TNG_CRITICAL
);
5367 /* Set the data again, but with no compression (to write only
5368 * the relevant data) */
5369 data
->codec_id
= TNG_UNCOMPRESSED
;
5370 stat
= tng_particle_data_block_write(tng_data
, block
,
5371 block_index
, mapping
,
5377 case TNG_GZIP_COMPRESSION
:
5378 /* fprintf(stderr, "TNG library: Before compression: %"PRId64"\n", block->block_contents_size);*/
5379 stat
= tng_gzip_compress(tng_data
, block
,
5380 block
->block_contents
+ data_start_pos
,
5381 block
->block_contents_size
- data_start_pos
);
5382 if(stat
!= TNG_SUCCESS
)
5384 fprintf(stderr
, "TNG library: Could not write gzipped block data. %s: %d\n", __FILE__
,
5386 if(stat
== TNG_CRITICAL
)
5388 return(TNG_CRITICAL
);
5390 /* Set the data again, but with no compression (to write only
5391 * the relevant data) */
5392 data
->codec_id
= TNG_UNCOMPRESSED
;
5393 stat
= tng_particle_data_block_write(tng_data
, block
,
5394 block_index
, mapping
,
5398 /* fprintf(stderr, "TNG library: After compression: %"PRId64"\n", block->block_contents_size);*/
5404 if(tng_block_header_write(tng_data
, block
, hash_mode
) != TNG_SUCCESS
)
5406 fprintf(stderr
, "TNG library: Cannot write header of file %s. %s: %d\n",
5407 tng_data
->output_file_path
, __FILE__
, __LINE__
);
5408 return(TNG_CRITICAL
);
5411 if(fwrite(block
->block_contents
, block
->block_contents_size
, 1,
5412 tng_data
->output_file
) != 1)
5414 fprintf(stderr
, "TNG library: Could not write all block data. %s: %d\n", __FILE__
,
5416 return(TNG_CRITICAL
);
5419 return(TNG_SUCCESS
);
5423 /** Create a non-particle data block
5424 * @param tng_data is a trajectory data container.
5425 * @param block_type_flag specifies if this is a trajectory block or a
5426 * non-trajectory block. (TNG_TRAJECTORY_BLOCK or TNG_NON_TRAJECTORY_BLOCK)
5427 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
5428 * error has occured.
5430 static tng_function_status tng_data_block_create
5431 (tng_trajectory_t tng_data
,
5432 const char block_type_flag
)
5434 tng_trajectory_frame_set_t frame_set
=
5435 &tng_data
->current_trajectory_frame_set
;
5437 tng_non_particle_data_t data
;
5439 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
5441 frame_set
->n_data_blocks
++;
5442 data
= realloc(frame_set
->tr_data
, sizeof(struct tng_non_particle_data
) *
5443 frame_set
->n_data_blocks
);
5446 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
5447 sizeof(struct tng_non_particle_data
) * frame_set
->n_data_blocks
,
5448 __FILE__
, __LINE__
);
5449 free(frame_set
->tr_data
);
5450 frame_set
->tr_data
= 0;
5451 return(TNG_CRITICAL
);
5453 frame_set
->tr_data
= data
;
5457 tng_data
->n_data_blocks
++;
5458 data
= realloc(tng_data
->non_tr_data
, sizeof(struct tng_non_particle_data
) *
5459 tng_data
->n_data_blocks
);
5462 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
5463 sizeof(struct tng_non_particle_data
) * tng_data
->n_data_blocks
,
5464 __FILE__
, __LINE__
);
5465 free(tng_data
->non_tr_data
);
5466 tng_data
->non_tr_data
= 0;
5467 return(TNG_CRITICAL
);
5469 tng_data
->non_tr_data
= data
;
5472 return(TNG_SUCCESS
);
5476 /** Allocate memory for storing non-particle data.
5477 * The allocated block will be refered to by data->values.
5478 * @param tng_data is a trajectory data container.
5479 * @param data is the data struct, which will contain the allocated memory in
5481 * @param n_frames is the number of frames of data to store.
5482 * @param n_values_per_frame is the number of data values per frame.
5483 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
5484 * error has occured.
5486 static tng_function_status tng_allocate_data_mem
5487 (tng_trajectory_t tng_data
,
5488 tng_non_particle_data_t data
,
5490 int64_t stride_length
,
5491 const int64_t n_values_per_frame
)
5494 int64_t i
, j
, size
, frame_alloc
;
5497 if(n_values_per_frame
== 0)
5499 return(TNG_FAILURE
);
5502 if(data
->strings
&& data
->datatype
== TNG_CHAR_DATA
)
5504 for(i
= data
->n_frames
; i
--;)
5506 for(j
= data
->n_values_per_frame
; j
--;)
5508 if(data
->strings
[i
][j
])
5510 free(data
->strings
[i
][j
]);
5511 data
->strings
[i
][j
] = 0;
5514 free(data
->strings
[i
]);
5515 data
->strings
[i
] = 0;
5517 free(data
->strings
);
5519 data
->n_frames
= n_frames
;
5520 data
->stride_length
= tng_max_i64(1, stride_length
);
5521 n_frames
= tng_max_i64(1, n_frames
);
5522 data
->n_values_per_frame
= n_values_per_frame
;
5523 frame_alloc
= (n_frames
% stride_length
) ? n_frames
/ stride_length
+ 1 : n_frames
/ stride_length
;
5525 if(data
->datatype
== TNG_CHAR_DATA
)
5527 data
->strings
= malloc(sizeof(char **) * frame_alloc
);
5528 for(i
= frame_alloc
; i
-- ;)
5530 data
->strings
[i
] = malloc(sizeof(char *) * n_values_per_frame
);
5531 if(!data
->strings
[i
])
5533 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
5535 __FILE__
, __LINE__
);
5536 return(TNG_CRITICAL
);
5538 for(j
= n_values_per_frame
; j
--;)
5540 data
->strings
[i
][j
] = 0;
5546 switch(data
->datatype
)
5549 size
= sizeof(int64_t);
5551 case TNG_FLOAT_DATA
:
5552 size
= sizeof(float);
5554 case TNG_DOUBLE_DATA
:
5556 size
= sizeof(double);
5559 values
= realloc(data
->values
,
5560 size
* frame_alloc
*
5561 n_values_per_frame
);
5564 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
5565 size
* frame_alloc
*
5567 __FILE__
, __LINE__
);
5570 return(TNG_CRITICAL
);
5572 data
->values
= values
;
5575 return(TNG_SUCCESS
);
5578 /** Read the values of a non-particle data block
5579 * @param tng_data is a trajectory data container.
5580 * @param block is the block to store the data (should already contain
5581 * the block headers and the block contents).
5582 * @param offset is the reading offset to point at the place where the actual
5583 * values are stored, starting from the beginning of the block_contents. The
5584 * offset is changed during the reading.
5585 * @param datatype is the type of data of the data block (char, int, float or
5587 * @param first_frame_with_data is the frame number of the first frame with data
5588 * in this data block.
5589 * @param stride_length is the number of frames between each data entry.
5590 * @param n_frames is the number of frames in this data block.
5591 * @param n_values is the number of values per frame stored in this data block.
5592 * @param codec_id is the ID of the codec to compress the data.
5593 * @param multiplier is the multiplication factor applied to each data value
5594 * before compression. This factor is applied since some compression algorithms
5595 * work only on integers.
5596 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
5597 * error has occured.
5599 static tng_function_status
tng_data_read(tng_trajectory_t tng_data
,
5600 tng_gen_block_t block
,
5602 const char datatype
,
5603 const int64_t first_frame_with_data
,
5604 const int64_t stride_length
,
5606 const int64_t n_values
,
5607 const int64_t codec_id
,
5608 const double multiplier
)
5610 int64_t i
, j
, n_frames_div
;
5613 unsigned long data_size
;
5615 tng_non_particle_data_t data
;
5616 tng_trajectory_frame_set_t frame_set
=
5617 &tng_data
->current_trajectory_frame_set
;
5618 char block_type_flag
;
5620 TNG_ASSERT(offset
!= 0, "TNG library: offset must not be a NULL pointer.");
5622 /* fprintf(stderr, "TNG library: %s\n", block->name);*/
5630 size
= sizeof(int64_t);
5632 case TNG_FLOAT_DATA
:
5633 size
= sizeof(float);
5635 case TNG_DOUBLE_DATA
:
5637 size
= sizeof(double);
5640 /* If the block does not exist, create it */
5641 if(tng_data_find(tng_data
, block
->id
, &data
) != TNG_SUCCESS
)
5643 if(tng_data
->current_trajectory_frame_set_input_file_pos
> 0)
5645 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
5649 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
5652 if(tng_data_block_create(tng_data
, block_type_flag
) !=
5655 fprintf(stderr
, "TNG library: Cannot create particle data block. %s: %d\n",
5656 __FILE__
, __LINE__
);
5657 return(TNG_CRITICAL
);
5659 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
5661 data
= &frame_set
->tr_data
[frame_set
->n_data_blocks
- 1];
5665 data
= &tng_data
->non_tr_data
[tng_data
->n_data_blocks
- 1];
5667 data
->block_id
= block
->id
;
5669 data
->block_name
= malloc(strlen(block
->name
) + 1);
5670 if(!data
->block_name
)
5672 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
5673 (int)strlen(block
->name
)+1, __FILE__
, __LINE__
);
5674 return(TNG_CRITICAL
);
5676 strcpy(data
->block_name
, block
->name
);
5678 data
->datatype
= datatype
;
5681 /* FIXME: Memory leak from strings. */
5684 data
->codec_id
= codec_id
;
5685 data
->compression_multiplier
= multiplier
;
5686 data
->last_retrieved_frame
= -1;
5689 n_frames_div
= (n_frames
% stride_length
) ? n_frames
/ stride_length
+ 1 : n_frames
/ stride_length
;
5691 if(codec_id
!= TNG_UNCOMPRESSED
)
5696 case TNG_GZIP_COMPRESSION
:
5697 data_size
= n_frames_div
* size
* n_values
;
5698 /* fprintf(stderr, "TNG library: Before compression: %"PRId64"\n", block->block_contents_size); */
5699 if(tng_gzip_uncompress(tng_data
, block
,
5700 block
->block_contents
+ *offset
,
5701 data_size
) != TNG_SUCCESS
)
5703 fprintf(stderr
, "TNG library: Could not read gzipped block data. %s: %d\n", __FILE__
,
5705 return(TNG_CRITICAL
);
5707 /* fprintf(stderr, "TNG library: After compression: %"PRId64"\n", block->block_contents_size); */
5713 /* Allocate memory */
5714 if(!data
->values
|| data
->n_frames
!= n_frames
||
5715 data
->n_values_per_frame
!= n_values
)
5717 if(tng_allocate_data_mem(tng_data
, data
, n_frames
, stride_length
,
5721 fprintf(stderr
, "TNG library: Cannot allocate memory for data. %s: %d\n",
5722 __FILE__
, __LINE__
);
5723 return(TNG_CRITICAL
);
5727 data
->first_frame_with_data
= first_frame_with_data
;
5729 if(datatype
== TNG_CHAR_DATA
)
5731 for(i
= 0; i
< n_frames_div
; i
++)
5733 for(j
= 0; j
< n_values
; j
++)
5735 len
= tng_min_i((int)strlen(block
->block_contents
+*offset
) + 1,
5737 if(data
->strings
[i
][j
])
5739 free(data
->strings
[i
][j
]);
5741 data
->strings
[i
][j
] = malloc(len
);
5742 if(!data
->strings
[i
][j
])
5744 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
5745 len
, __FILE__
, __LINE__
);
5746 return(TNG_CRITICAL
);
5748 strncpy(data
->strings
[i
][j
], block
->block_contents
+*offset
,
5756 memcpy(data
->values
, block
->block_contents
+ *offset
,
5757 block
->block_contents_size
- *offset
);
5760 case TNG_FLOAT_DATA
:
5761 if(tng_data
->input_endianness_swap_func_32
)
5763 for(i
= 0; i
< (block
->block_contents_size
- *offset
); i
+=size
)
5765 if(tng_data
->input_endianness_swap_func_32(tng_data
,
5766 (int32_t *)((char *)data
->values
+ i
))
5769 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5770 __FILE__
, __LINE__
);
5776 case TNG_DOUBLE_DATA
:
5777 if(tng_data
->input_endianness_swap_func_64
)
5779 for(i
= 0; i
< (block
->block_contents_size
- *offset
); i
+=size
)
5781 if(tng_data
->input_endianness_swap_func_64(tng_data
,
5782 (int64_t *)((char *)data
->values
+ i
))
5785 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
5786 __FILE__
, __LINE__
);
5795 return(TNG_SUCCESS
);
5798 /** Write a non-particle data block
5799 * @param tng_data is a trajectory data container.
5800 * @param block is the block to store the data (should already contain
5801 * the block headers and the block contents).
5802 * @param block_index is the index number of the data block in the frame set.
5803 * @param hash_mode is an option to decide whether to use the md5 hash or not.
5804 * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
5805 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
5806 * error has occured.
5808 static tng_function_status
tng_data_block_write(tng_trajectory_t tng_data
,
5809 tng_gen_block_t block
,
5810 const int64_t block_index
,
5811 const char hash_mode
)
5813 int64_t n_frames
, stride_length
, frame_step
;
5815 int offset
= 0, size
;
5819 tng_function_status stat
;
5821 char temp
, dependency
, *temp_name
;
5823 tng_trajectory_frame_set_t frame_set
=
5824 &tng_data
->current_trajectory_frame_set
;
5826 tng_non_particle_data_t data
;
5827 char block_type_flag
;
5829 /* If we have already started writing frame sets it is too late to write
5830 * non-trajectory data blocks */
5831 if(tng_data
->current_trajectory_frame_set_output_file_pos
> 0)
5833 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
5837 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
5840 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
5842 return(TNG_CRITICAL
);
5845 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
5847 data
= &frame_set
->tr_data
[block_index
];
5849 /* If this data block has not had any data added in this frame set
5850 * do not write it. */
5851 if(data
->first_frame_with_data
< frame_set
->first_frame
)
5853 return(TNG_SUCCESS
);
5856 stride_length
= tng_max_i64(1, data
->stride_length
);
5860 data
= &tng_data
->non_tr_data
[block_index
];
5864 switch(data
->datatype
)
5870 size
= sizeof(int64_t);
5872 case TNG_FLOAT_DATA
:
5873 size
= sizeof(float);
5875 case TNG_DOUBLE_DATA
:
5877 size
= sizeof(double);
5880 len
= (unsigned int)strlen(data
->block_name
) + 1;
5882 if(!block
->name
|| strlen(block
->name
) < len
)
5884 temp_name
= realloc(block
->name
, len
);
5887 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
+1,
5888 __FILE__
, __LINE__
);
5891 return(TNG_CRITICAL
);
5893 block
->name
= temp_name
;
5895 strncpy(block
->name
, data
->block_name
, len
);
5896 block
->id
= data
->block_id
;
5898 /* If writing frame independent data data->n_frames is 0, but n_frames
5899 is used for the loop writing the data (and reserving memory) and needs
5901 n_frames
= tng_max_i64(1, data
->n_frames
);
5903 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
5905 /* If the frame set is finished before writing the full number of frames
5906 make sure the data block is not longer than the frame set. */
5907 n_frames
= tng_min_i64(n_frames
, frame_set
->n_frames
);
5909 n_frames
-= (data
->first_frame_with_data
- frame_set
->first_frame
);
5912 frame_step
= (n_frames
% stride_length
) ? n_frames
/ stride_length
+ 1:
5913 n_frames
/ stride_length
;
5915 /* TNG compression will use compression precision to get integers from
5916 * floating point data. The compression multiplier stores that information
5917 * to be able to return the precision of the compressed data. */
5918 if(data
->codec_id
== TNG_TNG_COMPRESSION
)
5920 data
->compression_multiplier
= tng_data
->compression_precision
;
5922 /* Uncompressed data blocks do not use compression multipliers at all.
5923 * GZip compression does not need it either. */
5924 else if(data
->codec_id
== TNG_UNCOMPRESSED
|| data
->codec_id
== TNG_GZIP_COMPRESSION
)
5926 data
->compression_multiplier
= 1.0;
5929 block
->block_contents_size
= sizeof(char) * 2 +
5930 sizeof(data
->n_values_per_frame
) +
5931 sizeof(data
->codec_id
);
5933 if(stride_length
> 1)
5935 block
->block_contents_size
+= sizeof(data
->first_frame_with_data
) +
5936 sizeof(data
->stride_length
);
5939 if(data
->codec_id
!= TNG_UNCOMPRESSED
)
5941 block
->block_contents_size
+= sizeof(data
->compression_multiplier
);
5944 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
&& data
->n_frames
> 0)
5946 dependency
= TNG_FRAME_DEPENDENT
;
5952 if(dependency
& TNG_FRAME_DEPENDENT
)
5954 block
->block_contents_size
+= sizeof(char);
5958 data_start_pos
= block
->block_contents_size
;
5961 if(data
->datatype
== TNG_CHAR_DATA
)
5963 for(i
= n_frames
; i
--;)
5965 for(j
= data
->n_values_per_frame
; j
--;)
5967 block
->block_contents_size
+= strlen(data
->strings
[i
][j
]) + 1;
5973 block
->block_contents_size
+= size
* frame_step
*
5974 data
->n_values_per_frame
;
5977 if(block
->block_contents
)
5979 free(block
->block_contents
);
5981 block
->block_contents
= malloc(block
->block_contents_size
);
5982 if(!block
->block_contents
)
5984 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
5985 block
->block_contents_size
, __FILE__
, __LINE__
);
5986 return(TNG_CRITICAL
);
5990 memcpy(block
->block_contents
, &data
->datatype
, sizeof(char));
5991 offset
+= sizeof(char);
5993 memcpy(block
->block_contents
+offset
, &dependency
, sizeof(char));
5994 offset
+= sizeof(char);
5996 if(dependency
& TNG_FRAME_DEPENDENT
)
5998 if(stride_length
> 1)
6006 memcpy(block
->block_contents
+offset
, &temp
, sizeof(char));
6007 offset
+= sizeof(char);
6010 memcpy(block
->block_contents
+offset
, &data
->n_values_per_frame
,
6011 sizeof(data
->n_values_per_frame
));
6012 if(tng_data
->output_endianness_swap_func_64
)
6014 if(tng_data
->output_endianness_swap_func_64(tng_data
,
6015 (int64_t *)block
->header_contents
+offset
)
6018 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6019 __FILE__
, __LINE__
);
6022 offset
+= sizeof(data
->n_values_per_frame
);
6024 memcpy(block
->block_contents
+offset
, &data
->codec_id
,
6025 sizeof(data
->codec_id
));
6026 if(tng_data
->output_endianness_swap_func_64
)
6028 if(tng_data
->output_endianness_swap_func_64(tng_data
,
6029 (int64_t *)block
->header_contents
+offset
)
6032 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6033 __FILE__
, __LINE__
);
6036 offset
+= sizeof(data
->codec_id
);
6038 if(data
->codec_id
!= TNG_UNCOMPRESSED
)
6040 memcpy(block
->block_contents
+offset
, &data
->compression_multiplier
,
6041 sizeof(data
->compression_multiplier
));
6042 if(tng_data
->output_endianness_swap_func_64
)
6044 if(tng_data
->output_endianness_swap_func_64(tng_data
,
6045 (int64_t *)block
->header_contents
+offset
)
6048 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6049 __FILE__
, __LINE__
);
6052 offset
+= sizeof(data
->compression_multiplier
);
6055 if(data
->n_frames
> 0 && stride_length
> 1)
6057 /* FIXME: first_frame_with_data is not reliably set */
6058 if(data
->first_frame_with_data
== 0)
6060 data
->first_frame_with_data
= frame_set
->first_frame
;
6062 memcpy(block
->block_contents
+offset
, &data
->first_frame_with_data
,
6063 sizeof(data
->first_frame_with_data
));
6064 if(tng_data
->output_endianness_swap_func_64
)
6066 if(tng_data
->output_endianness_swap_func_64(tng_data
,
6067 (int64_t *)block
->header_contents
+offset
)
6070 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6071 __FILE__
, __LINE__
);
6074 offset
+= sizeof(data
->first_frame_with_data
);
6076 memcpy(block
->block_contents
+offset
, &stride_length
,
6077 sizeof(data
->stride_length
));
6078 if(tng_data
->output_endianness_swap_func_64
)
6080 if(tng_data
->output_endianness_swap_func_64(tng_data
,
6081 (int64_t *)block
->header_contents
+offset
)
6084 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6085 __FILE__
, __LINE__
);
6088 offset
+= sizeof(data
->stride_length
);
6091 if(data
->datatype
== TNG_CHAR_DATA
)
6095 for(i
= 0; i
< frame_step
; i
++)
6097 for(j
= 0; j
< data
->n_values_per_frame
; j
++)
6099 len
= (unsigned int)strlen(data
->strings
[i
][j
]) + 1;
6100 strncpy(block
->block_contents
+offset
, data
->strings
[i
][j
],
6107 else if(data
->values
)
6109 memcpy(block
->block_contents
+ offset
, data
->values
,
6110 block
->block_contents_size
- offset
);
6111 switch(data
->datatype
)
6113 case TNG_FLOAT_DATA
:
6114 if(data
->codec_id
== TNG_UNCOMPRESSED
|| data
-> codec_id
== TNG_GZIP_COMPRESSION
||
6115 data
->codec_id
== TNG_TNG_COMPRESSION
)
6117 if(tng_data
->input_endianness_swap_func_32
)
6119 for(i
= offset
; i
< block
->block_contents_size
; i
+=size
)
6121 if(tng_data
->input_endianness_swap_func_32(tng_data
,
6122 (int32_t *)(block
->block_contents
+ i
))
6125 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6126 __FILE__
, __LINE__
);
6133 multiplier
= data
->compression_multiplier
;
6134 if(fabs(multiplier
- 1.0) > 0.00001 ||
6135 tng_data
->input_endianness_swap_func_32
)
6137 for(i
= offset
; block
->block_contents_size
; i
+=size
)
6139 *(float *)(block
->block_contents
+ i
) *= (float)multiplier
;
6140 if(tng_data
->input_endianness_swap_func_32
&&
6141 tng_data
->input_endianness_swap_func_32(tng_data
,
6142 (int32_t *)(block
->block_contents
+ i
))
6145 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6146 __FILE__
, __LINE__
);
6153 if(tng_data
->input_endianness_swap_func_64
)
6155 for(i
= offset
; i
< block
->block_contents_size
; i
+=size
)
6157 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6158 (int64_t *)(block
->block_contents
+ i
))
6161 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6162 __FILE__
, __LINE__
);
6167 case TNG_DOUBLE_DATA
:
6168 if(data
->codec_id
== TNG_UNCOMPRESSED
|| data
-> codec_id
== TNG_GZIP_COMPRESSION
||
6169 data
->codec_id
== TNG_TNG_COMPRESSION
)
6171 if(tng_data
->input_endianness_swap_func_64
)
6173 for(i
= offset
; i
< block
->block_contents_size
; i
+=size
)
6175 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6176 (int64_t *)(block
->block_contents
+ i
))
6179 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6180 __FILE__
, __LINE__
);
6187 multiplier
= data
->compression_multiplier
;
6188 if(fabs(multiplier
- 1.0) > 0.00001 ||
6189 tng_data
->input_endianness_swap_func_64
)
6191 for(i
= offset
; i
< block
->block_contents_size
; i
+=size
)
6193 *(double *)(block
->block_contents
+ i
) *= multiplier
;
6194 if(tng_data
->input_endianness_swap_func_64
&&
6195 tng_data
->input_endianness_swap_func_64(tng_data
,
6196 (int64_t *)(block
->block_contents
+ i
))
6199 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6200 __FILE__
, __LINE__
);
6212 memset(block
->block_contents
+offset
, 0, block
->block_contents_size
- offset
);
6215 frame_set
->n_written_frames
+= frame_set
->n_unwritten_frames
;
6216 frame_set
->n_unwritten_frames
= 0;
6218 if(block_type_flag
== TNG_NON_TRAJECTORY_BLOCK
|| frame_set
->n_written_frames
> 0)
6220 switch(data
->codec_id
)
6223 case TNG_GZIP_COMPRESSION
:
6224 /* fprintf(stderr, "TNG library: Before compression: %"PRId64"\n", block->block_contents_size); */
6225 stat
= tng_gzip_compress(tng_data
, block
,
6226 block
->block_contents
+ data_start_pos
,
6227 block
->block_contents_size
- data_start_pos
);
6228 if(stat
!= TNG_SUCCESS
)
6230 fprintf(stderr
, "TNG library: Could not write gzipped block data. %s: %d\n", __FILE__
,
6232 if(stat
== TNG_CRITICAL
)
6234 return(TNG_CRITICAL
);
6236 data
->codec_id
= TNG_UNCOMPRESSED
;
6238 /* fprintf(stderr, "TNG library: After compression: %"PRId64"\n", block->block_contents_size); */
6244 if(tng_block_header_write(tng_data
, block
, hash_mode
) != TNG_SUCCESS
)
6246 fprintf(stderr
, "TNG library: Cannot write header of file %s. %s: %d\n",
6247 tng_data
->output_file_path
, __FILE__
, __LINE__
);
6248 return(TNG_CRITICAL
);
6251 if(fwrite(block
->block_contents
, block
->block_contents_size
, 1,
6252 tng_data
->output_file
) != 1)
6254 fprintf(stderr
, "TNG library: Could not write all block data. %s: %d\n",
6255 __FILE__
, __LINE__
);
6256 return(TNG_CRITICAL
);
6259 return(TNG_SUCCESS
);
6262 /** Read the meta information of a data block (particle or non-particle data).
6263 * @param tng_data is a trajectory data container.
6264 * @param block is the block to store the data (should already contain
6265 * the block headers).
6266 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
6267 * error has occured.
6269 static tng_function_status tng_data_block_meta_information_read
6270 (tng_trajectory_t tng_data
,
6271 tng_gen_block_t block
,
6278 int64_t *first_frame_with_data
,
6279 int64_t *stride_length
,
6281 int64_t *num_first_particle
,
6282 int64_t *block_n_particles
,
6288 if(block
->block_contents
)
6290 contents
= block
->block_contents
;
6294 meta_size
= 3 * sizeof(char) + sizeof(double) + 6 * sizeof(int64_t);
6295 contents
= malloc(meta_size
);
6298 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
6299 meta_size
, __FILE__
, __LINE__
);
6302 if(fread(contents
, meta_size
, 1, tng_data
->input_file
) == 0)
6304 fprintf(stderr
, "TNG library: Cannot read data block meta information. %s: %d\n", __FILE__
, __LINE__
);
6306 return(TNG_CRITICAL
);
6310 memcpy(datatype
, contents
+*offset
,
6312 *offset
+= sizeof(*datatype
);
6314 memcpy(dependency
, contents
+*offset
,
6315 sizeof(*dependency
));
6316 *offset
+= sizeof(*dependency
);
6318 if(*dependency
& TNG_FRAME_DEPENDENT
)
6320 memcpy(sparse_data
, contents
+*offset
,
6321 sizeof(*sparse_data
));
6322 *offset
+= sizeof(*sparse_data
);
6325 memcpy(n_values
, contents
+*offset
,
6327 if(tng_data
->input_endianness_swap_func_64
)
6329 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6333 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6334 __FILE__
, __LINE__
);
6337 *offset
+= sizeof(*n_values
);
6339 memcpy(codec_id
, contents
+*offset
,
6341 if(tng_data
->input_endianness_swap_func_64
)
6343 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6347 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6348 __FILE__
, __LINE__
);
6351 *offset
+= sizeof(*codec_id
);
6353 if(*codec_id
!= TNG_UNCOMPRESSED
)
6355 memcpy(multiplier
, contents
+*offset
,
6356 sizeof(*multiplier
));
6357 if(tng_data
->input_endianness_swap_func_64
)
6359 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6360 (int64_t *) multiplier
)
6363 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6364 __FILE__
, __LINE__
);
6367 *offset
+= sizeof(*multiplier
);
6374 if(*dependency
& TNG_FRAME_DEPENDENT
)
6378 memcpy(first_frame_with_data
, contents
+*offset
,
6379 sizeof(*first_frame_with_data
));
6380 if(tng_data
->input_endianness_swap_func_64
)
6382 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6383 first_frame_with_data
)
6386 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6387 __FILE__
, __LINE__
);
6390 *offset
+= sizeof(*first_frame_with_data
);
6392 memcpy(stride_length
, contents
+*offset
,
6393 sizeof(*stride_length
));
6394 if(tng_data
->input_endianness_swap_func_64
)
6396 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6400 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6401 __FILE__
, __LINE__
);
6404 *offset
+= sizeof(*stride_length
);
6405 *n_frames
= tng_data
->current_trajectory_frame_set
.n_frames
-
6406 (*first_frame_with_data
-
6407 tng_data
->current_trajectory_frame_set
.first_frame
);
6411 *first_frame_with_data
= 0;
6413 *n_frames
= tng_data
->current_trajectory_frame_set
.n_frames
;
6418 *first_frame_with_data
= 0;
6423 if (*dependency
& TNG_PARTICLE_DEPENDENT
)
6425 memcpy(num_first_particle
, contents
+*offset
,
6426 sizeof(*num_first_particle
));
6427 if(tng_data
->input_endianness_swap_func_64
)
6429 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6433 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6434 __FILE__
, __LINE__
);
6437 *offset
+= sizeof(*num_first_particle
);
6439 memcpy(block_n_particles
, contents
+*offset
,
6440 sizeof(*block_n_particles
));
6441 if(tng_data
->input_endianness_swap_func_64
)
6443 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6447 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6448 __FILE__
, __LINE__
);
6451 *offset
+= sizeof(*block_n_particles
);
6454 if(!block
->block_contents
)
6458 return(TNG_SUCCESS
);
6461 /** Read the contents of a data block (particle or non-particle data).
6462 * @param tng_data is a trajectory data container.
6463 * @param block is the block to store the data (should already contain
6464 * the block headers).
6465 * @param hash_mode is an option to decide whether to use the md5 hash or not.
6466 * If hash_mode == TNG_USE_HASH the written md5 hash in the file will be
6467 * compared to the md5 hash of the read contents to ensure valid data.
6468 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
6469 * error has occured.
6471 static tng_function_status tng_data_block_contents_read
6472 (tng_trajectory_t tng_data
,
6473 tng_gen_block_t block
,
6474 const char hash_mode
)
6476 int64_t n_values
, codec_id
, n_frames
, first_frame_with_data
;
6477 int64_t stride_length
, block_n_particles
, num_first_particle
;
6479 char datatype
, dependency
, sparse_data
;
6483 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
6485 return(TNG_CRITICAL
);
6488 if(block
->block_contents
)
6490 free(block
->block_contents
);
6493 block
->block_contents
= malloc(block
->block_contents_size
);
6494 if(!block
->block_contents
)
6496 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
6497 block
->block_contents_size
, __FILE__
, __LINE__
);
6498 return(TNG_CRITICAL
);
6501 /* Read the whole block into block_contents to be able to write it to
6502 * disk even if it cannot be interpreted. */
6503 if(fread(block
->block_contents
, block
->block_contents_size
, 1,
6504 tng_data
->input_file
) == 0)
6506 fprintf(stderr
, "TNG library: Cannot read block. %s: %d\n", __FILE__
, __LINE__
);
6507 return(TNG_CRITICAL
);
6510 /* FIXME: Does not check if the size of the contents matches the expected
6511 * size or if the contents can be read. */
6513 if(hash_mode
== TNG_USE_HASH
)
6515 tng_md5_hash_match_verify(block
, &same_hash
);
6516 if(same_hash
!= TNG_TRUE
)
6518 fprintf(stderr
, "TNG library: '%s' data block contents corrupt. Hashes do not match. %s: %d\n",
6519 block
->name
, __FILE__
, __LINE__
);
6520 /* return(TNG_FAILURE); */
6524 if(tng_data_block_meta_information_read(tng_data
, block
,
6526 &dependency
, &sparse_data
,
6527 &n_values
, &codec_id
,
6528 &first_frame_with_data
,
6529 &stride_length
, &n_frames
,
6530 &num_first_particle
,
6532 &multiplier
) == TNG_CRITICAL
)
6534 fprintf(stderr
, "TNG library: Cannot read data block (%s) meta information. %s: %d\n",
6535 block
->name
, __FILE__
, __LINE__
);
6536 return(TNG_CRITICAL
);
6539 if (dependency
& TNG_PARTICLE_DEPENDENT
)
6541 return(tng_particle_data_read(tng_data
, block
,
6545 first_frame_with_data
,
6548 codec_id
, multiplier
));
6552 return(tng_data_read(tng_data
, block
,
6554 first_frame_with_data
,
6557 codec_id
, multiplier
));
6561 /** Update the md5 hash of a block already written to the file
6562 * @param tng_data is a trajectory data container.
6563 * @param block is the block, of which to update the md5 hash.
6564 * @param header_start_pos is the file position where the block header starts.
6565 * @param contents_start_pos is the file position where the block contents
6567 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
6568 * error has occured.
6570 static tng_function_status
tng_md5_hash_update(tng_trajectory_t tng_data
,
6571 tng_gen_block_t block
,
6572 const int64_t header_start_pos
,
6573 const int64_t contents_start_pos
)
6575 if(block
->block_contents
)
6577 free(block
->block_contents
);
6580 block
->block_contents
= malloc(block
->block_contents_size
);
6581 if(!block
->block_contents
)
6583 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
6584 block
->block_contents_size
, __FILE__
, __LINE__
);
6585 return(TNG_CRITICAL
);
6588 fseek(tng_data
->output_file
, (long)contents_start_pos
, SEEK_SET
);
6589 if(fread(block
->block_contents
, block
->block_contents_size
, 1,
6590 tng_data
->output_file
) == 0)
6592 fprintf(stderr
, "TNG library: Cannot read block. %s: %d\n", __FILE__
, __LINE__
);
6593 return(TNG_CRITICAL
);
6596 tng_block_md5_hash_generate(block
);
6598 fseek(tng_data
->output_file
, (long)header_start_pos
+ 3 * sizeof(int64_t),
6600 fwrite(block
->md5_hash
, TNG_MD5_HASH_LEN
, 1, tng_data
->output_file
);
6602 return(TNG_SUCCESS
);
6605 /** Update the frame set pointers in the file header (general info block),
6606 * already written to disk
6607 * @param tng_data is a trajectory data container.
6608 * @param hash_mode specifies whether to update the block md5 hash when
6609 * updating the pointers.
6610 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
6611 * error has occured.
6613 static tng_function_status tng_header_pointers_update
6614 (tng_trajectory_t tng_data
, const char hash_mode
)
6616 tng_gen_block_t block
;
6617 FILE *temp
= tng_data
->input_file
;
6618 int64_t output_file_pos
, pos
, contents_start_pos
;
6620 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
6622 fprintf(stderr
, "TNG library: Cannot initialise destination file. %s: %d\n",
6623 __FILE__
, __LINE__
);
6624 return(TNG_CRITICAL
);
6627 tng_data
->input_file
= tng_data
->output_file
;
6629 tng_block_init(&block
);
6631 output_file_pos
= ftell(tng_data
->output_file
);
6632 fseek(tng_data
->output_file
, 0, SEEK_SET
);
6634 if(tng_block_header_read(tng_data
, block
) != TNG_SUCCESS
)
6636 fprintf(stderr
, "TNG library: Cannot read general info header. %s: %d\n",
6637 __FILE__
, __LINE__
);
6638 tng_data
->input_file
= temp
;
6639 tng_block_destroy(&block
);
6640 return(TNG_CRITICAL
);
6643 contents_start_pos
= ftell(tng_data
->output_file
);
6645 fseek(tng_data
->output_file
, (long)block
->block_contents_size
- 5 *
6646 sizeof(int64_t), SEEK_CUR
);
6648 tng_data
->input_file
= temp
;
6650 pos
= tng_data
->first_trajectory_frame_set_output_file_pos
;
6652 if(tng_data
->input_endianness_swap_func_64
)
6654 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6658 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6659 __FILE__
, __LINE__
);
6663 if(fwrite(&pos
, sizeof(int64_t), 1, tng_data
->output_file
) != 1)
6665 tng_block_destroy(&block
);
6666 return(TNG_CRITICAL
);
6669 pos
= tng_data
->last_trajectory_frame_set_output_file_pos
;
6671 if(tng_data
->input_endianness_swap_func_64
)
6673 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6677 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6678 __FILE__
, __LINE__
);
6683 sizeof(int64_t), 1, tng_data
->output_file
) != 1)
6685 tng_block_destroy(&block
);
6686 return(TNG_CRITICAL
);
6689 if(hash_mode
== TNG_USE_HASH
)
6691 tng_md5_hash_update(tng_data
, block
, 0, contents_start_pos
);
6694 tng_block_destroy(&block
);
6696 fseek(tng_data
->output_file
, (long)output_file_pos
, SEEK_SET
);
6698 return(TNG_SUCCESS
);
6701 /** Update the frame set pointers in the current frame set block, already
6702 * written to disk. It also updates the pointers of the blocks pointing to
6703 * the current frame set block.
6704 * @param tng_data is a trajectory data container.
6705 * @param hash_mode specifies whether to update the block md5 hash when
6706 * updating the pointers.
6707 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
6708 * error has occured.
6710 static tng_function_status tng_frame_set_pointers_update
6711 (tng_trajectory_t tng_data
, const char hash_mode
)
6713 tng_gen_block_t block
;
6714 tng_trajectory_frame_set_t frame_set
;
6715 FILE *temp
= tng_data
->input_file
;
6716 int64_t pos
, output_file_pos
, header_start_pos
, contents_start_pos
;
6718 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
6720 fprintf(stderr
, "TNG library: Cannot initialise destination file. %s: %d\n",
6721 __FILE__
, __LINE__
);
6722 return(TNG_CRITICAL
);
6725 tng_block_init(&block
);
6726 output_file_pos
= ftell(tng_data
->output_file
);
6728 tng_data
->input_file
= tng_data
->output_file
;
6730 frame_set
= &tng_data
->current_trajectory_frame_set
;
6732 /* Update previous frame set */
6733 if(frame_set
->prev_frame_set_file_pos
!= -1 &&
6734 frame_set
->prev_frame_set_file_pos
!= 0)
6736 fseek(tng_data
->output_file
, (long)frame_set
->prev_frame_set_file_pos
,
6739 header_start_pos
= frame_set
->prev_frame_set_file_pos
;
6741 if(tng_block_header_read(tng_data
, block
) != TNG_SUCCESS
)
6743 fprintf(stderr
, "TNG library: Cannot read frame header. %s: %d\n",
6744 __FILE__
, __LINE__
);
6745 tng_data
->input_file
= temp
;
6746 tng_block_destroy(&block
);
6747 return(TNG_CRITICAL
);
6750 contents_start_pos
= ftell(tng_data
->output_file
);
6752 fseek(tng_data
->output_file
, (long)block
->block_contents_size
- (6 *
6753 sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR
);
6755 pos
= tng_data
->current_trajectory_frame_set_output_file_pos
;
6757 if(tng_data
->input_endianness_swap_func_64
)
6759 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6763 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6764 __FILE__
, __LINE__
);
6768 if(fwrite(&pos
, sizeof(int64_t), 1, tng_data
->output_file
) != 1)
6770 tng_data
->input_file
= temp
;
6771 tng_block_destroy(&block
);
6772 return(TNG_CRITICAL
);
6775 if(hash_mode
== TNG_USE_HASH
)
6777 tng_md5_hash_update(tng_data
, block
, header_start_pos
,
6778 contents_start_pos
);
6780 fseek(tng_data
->output_file
, (long)output_file_pos
, SEEK_SET
);
6783 /* Update the frame set one medium stride step before */
6784 if(frame_set
->medium_stride_prev_frame_set_file_pos
!= -1 &&
6785 frame_set
->medium_stride_prev_frame_set_file_pos
!= 0)
6787 fseek(tng_data
->output_file
,
6788 (long)frame_set
->medium_stride_prev_frame_set_file_pos
,
6791 if(tng_block_header_read(tng_data
, block
) != TNG_SUCCESS
)
6793 fprintf(stderr
, "TNG library: Cannot read frame set header. %s: %d\n",
6794 __FILE__
, __LINE__
);
6795 tng_data
->input_file
= temp
;
6796 tng_block_destroy(&block
);
6797 return(TNG_CRITICAL
);
6800 contents_start_pos
= ftell(tng_data
->output_file
);
6802 fseek(tng_data
->output_file
, (long)block
->block_contents_size
- (4 *
6803 sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR
);
6805 pos
= tng_data
->current_trajectory_frame_set_output_file_pos
;
6807 if(tng_data
->input_endianness_swap_func_64
)
6809 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6813 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6814 __FILE__
, __LINE__
);
6818 if(fwrite(&pos
, sizeof(int64_t), 1, tng_data
->output_file
) != 1)
6820 tng_data
->input_file
= temp
;
6821 tng_block_destroy(&block
);
6822 return(TNG_CRITICAL
);
6825 if(hash_mode
== TNG_USE_HASH
)
6827 tng_md5_hash_update(tng_data
, block
,
6828 frame_set
->medium_stride_prev_frame_set_file_pos
,
6829 contents_start_pos
);
6833 /* Update the frame set one long stride step before */
6834 if(frame_set
->long_stride_prev_frame_set_file_pos
!= -1 &&
6835 frame_set
->long_stride_prev_frame_set_file_pos
!= 0)
6837 fseek(tng_data
->output_file
,
6838 (long)frame_set
->long_stride_prev_frame_set_file_pos
,
6841 if(tng_block_header_read(tng_data
, block
) != TNG_SUCCESS
)
6843 fprintf(stderr
, "TNG library: Cannot read frame set header. %s: %d\n",
6844 __FILE__
, __LINE__
);
6845 tng_data
->input_file
= temp
;
6846 tng_block_destroy(&block
);
6847 return(TNG_CRITICAL
);
6850 contents_start_pos
= ftell(tng_data
->output_file
);
6852 fseek(tng_data
->output_file
, (long)block
->block_contents_size
- (2 *
6853 sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR
);
6855 pos
= tng_data
->current_trajectory_frame_set_output_file_pos
;
6857 if(tng_data
->input_endianness_swap_func_64
)
6859 if(tng_data
->input_endianness_swap_func_64(tng_data
,
6863 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
6864 __FILE__
, __LINE__
);
6868 if(fwrite(&pos
, sizeof(int64_t), 1, tng_data
->output_file
) != 1)
6870 tng_data
->input_file
= temp
;
6871 tng_block_destroy(&block
);
6872 return(TNG_CRITICAL
);
6875 if(hash_mode
== TNG_USE_HASH
)
6877 tng_md5_hash_update(tng_data
, block
,
6878 frame_set
->long_stride_prev_frame_set_file_pos
,
6879 contents_start_pos
);
6883 fseek(tng_data
->output_file
, (long)output_file_pos
, SEEK_SET
);
6885 tng_data
->input_file
= temp
;
6887 tng_block_destroy(&block
);
6889 return(TNG_SUCCESS
);
6892 // ** Move the blocks in a frame set so that there is no unused space between
6893 // * them. This can only be done on the last frame set in the file and should
6894 // * be done e.g. if the last frame set in the file has fewer frames than
6895 // * default or after compressing data blocks in a frame set.
6896 // * @param tng_data is a trajectory data container.
6897 // * @details the current_trajectory_frame_set is the one that will be modified.
6898 // * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the frame set
6899 // * cannot be aligned or TNG_CRITICAL (2) if a major error has occured.
6900 // * FIXME: This function is not finished!!!
6902 // static tng_function_status tng_frame_set_align(tng_trajectory_t tng_data)
6904 // tng_gen_block_t block;
6905 // tng_trajectory_frame_set_t frame_set;
6906 // FILE *temp = tng_data->input_file;
6907 // int64_t pos, contents_start_pos, output_file_len;
6909 // frame_set = &tng_data->current_trajectory_frame_set;
6911 // if(frame_set->n_written_frames == frame_set->n_frames)
6913 // return(TNG_SUCCESS);
6916 // if(tng_data->current_trajectory_frame_set_output_file_pos !=
6917 // tng_data->last_trajectory_frame_set_output_file_pos)
6921 // if(tng_output_file_init(tng_data) != TNG_SUCCESS)
6923 // fprintf(stderr, "TNG library: Cannot initialise destination file. %s: %d\n",
6924 // __FILE__, __LINE__);
6925 // return(TNG_CRITICAL);
6928 // tng_block_init(&block);
6929 // // output_file_pos = ftell(tng_data->output_file);
6931 // tng_data->input_file = tng_data->output_file;
6933 // pos = tng_data->current_trajectory_frame_set_output_file_pos;
6935 // fseek(tng_data->output_file, pos, SEEK_SET);
6936 // if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
6938 // fprintf(stderr, "TNG library: Cannot read frame set header. %s: %d\n",
6939 // __FILE__, __LINE__);
6940 // tng_data->input_file = temp;
6941 // tng_block_destroy(&block);
6942 // return(TNG_CRITICAL);
6945 // contents_start_pos = ftell(tng_data->output_file);
6947 // fseek(tng_data->output_file, 0, SEEK_END);
6948 // output_file_len = ftell(tng_data->output_file);
6949 // pos = contents_start_pos + block->block_contents_size;
6950 // fseek(tng_data->output_file, pos,
6953 // while(pos < output_file_len)
6955 // if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
6957 // fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", pos,
6958 // __FILE__, __LINE__);
6959 // tng_data->input_file = temp;
6960 // tng_block_destroy(&block);
6961 // return(TNG_CRITICAL);
6963 // pos += block->header_contents_size + block->block_contents_size;
6964 // fseek(tng_data->output_file, pos, SEEK_SET);
6967 // return(TNG_SUCCESS);
6970 /** Finish writing the current frame set. Update the number of frames
6971 * and the hashes of the frame set and all its data blocks (if hash_mode
6973 * @param tng_data is a trajectory data container.
6974 * @param hash_mode specifies whether to update the block md5 hash when
6975 * updating the pointers.
6976 * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
6977 * error has occured.
6979 static tng_function_status tng_frame_set_finalize
6980 (tng_trajectory_t tng_data
, const char hash_mode
)
6982 tng_gen_block_t block
;
6983 tng_trajectory_frame_set_t frame_set
;
6984 FILE *temp
= tng_data
->input_file
;
6985 int64_t pos
, contents_start_pos
, output_file_len
;
6987 frame_set
= &tng_data
->current_trajectory_frame_set
;
6989 if(frame_set
->n_written_frames
== frame_set
->n_frames
)
6991 return(TNG_SUCCESS
);
6994 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
6996 fprintf(stderr
, "TNG library: Cannot initialise destination file. %s: %d\n",
6997 __FILE__
, __LINE__
);
6998 return(TNG_CRITICAL
);
7001 tng_block_init(&block
);
7002 /* output_file_pos = ftell(tng_data->output_file); */
7004 tng_data
->input_file
= tng_data
->output_file
;
7006 pos
= tng_data
->current_trajectory_frame_set_output_file_pos
;
7008 fseek(tng_data
->output_file
, (long)pos
, SEEK_SET
);
7010 if(tng_block_header_read(tng_data
, block
) != TNG_SUCCESS
)
7012 fprintf(stderr
, "TNG library: Cannot read frame set header. %s: %d\n",
7013 __FILE__
, __LINE__
);
7014 tng_data
->input_file
= temp
;
7015 tng_block_destroy(&block
);
7016 return(TNG_CRITICAL
);
7019 contents_start_pos
= ftell(tng_data
->output_file
);
7021 fseek(tng_data
->output_file
, sizeof(frame_set
->first_frame
), SEEK_CUR
);
7022 if(fwrite(&frame_set
->n_written_frames
, sizeof(frame_set
->n_frames
),
7023 1, tng_data
->output_file
) != 1)
7025 tng_data
->input_file
= temp
;
7026 tng_block_destroy(&block
);
7027 return(TNG_CRITICAL
);
7031 if(hash_mode
== TNG_USE_HASH
)
7033 tng_md5_hash_update(tng_data
, block
, pos
,
7034 pos
+ block
->header_contents_size
);
7037 fseek(tng_data
->output_file
, 0, SEEK_END
);
7038 output_file_len
= ftell(tng_data
->output_file
);
7039 pos
= contents_start_pos
+ block
->block_contents_size
;
7040 fseek(tng_data
->output_file
, (long)pos
, SEEK_SET
);
7042 while(pos
< output_file_len
)
7044 if(tng_block_header_read(tng_data
, block
) != TNG_SUCCESS
)
7046 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n", pos
,
7047 __FILE__
, __LINE__
);
7048 tng_data
->input_file
= temp
;
7049 tng_block_destroy(&block
);
7050 return(TNG_CRITICAL
);
7053 if(hash_mode
== TNG_USE_HASH
)
7055 tng_md5_hash_update(tng_data
, block
, pos
,
7056 pos
+ block
->header_contents_size
);
7058 pos
+= block
->header_contents_size
+ block
->block_contents_size
;
7059 fseek(tng_data
->output_file
, (long)pos
, SEEK_SET
);
7062 tng_data
->input_file
= temp
;
7063 tng_block_destroy(&block
);
7064 return(TNG_SUCCESS
);
7068 // ** Sets the name of a file contents block
7069 // * @param tng_data is a trajectory data container.
7070 // * @param block is the block, of which to change names.
7071 // * @param new_name is the new name of the block.
7072 // * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
7073 // * error has occured.
7075 // static tng_function_status tng_block_name_set(tng_trajectory_t tng_data,
7076 // tng_gen_block_t block,
7077 // const char *new_name)
7081 // len = tng_min_i((int)strlen(new_name) + 1, TNG_MAX_STR_LEN);
7083 // * If the currently stored string length is not enough to store the new
7084 // * string it is freed and reallocated. *
7085 // if(block->name && strlen(block->name) < len)
7087 // free(block->name);
7092 // block->name = malloc(len);
7095 // fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
7096 // __FILE__, __LINE__);
7097 // return(TNG_CRITICAL);
7101 // strncpy(block->name, new_name, len);
7103 // return(TNG_SUCCESS);
7107 tng_function_status
tng_atom_residue_get(const tng_trajectory_t tng_data
,
7108 const tng_atom_t atom
,
7109 tng_residue_t
*residue
)
7113 TNG_ASSERT(atom
, "TNG library: atom must not be NULL");
7115 *residue
= atom
->residue
;
7117 return(TNG_SUCCESS
);
7120 tng_function_status
tng_atom_name_get(const tng_trajectory_t tng_data
,
7121 const tng_atom_t atom
,
7126 TNG_ASSERT(atom
, "TNG library: atom must not be NULL");
7127 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
7129 strncpy(name
, atom
->name
, max_len
- 1);
7130 name
[max_len
- 1] = 0;
7132 if(strlen(atom
->name
) > (unsigned int)max_len
- 1)
7134 return(TNG_FAILURE
);
7136 return(TNG_SUCCESS
);
7139 tng_function_status
tng_atom_name_set(tng_trajectory_t tng_data
,
7141 const char *new_name
)
7146 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7147 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer.");
7149 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
7151 /* If the currently stored string length is not enough to store the new
7152 * string it is freed and reallocated. */
7153 if(atom
->name
&& strlen(atom
->name
) < len
)
7160 atom
->name
= malloc(len
);
7163 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
7164 __FILE__
, __LINE__
);
7165 return(TNG_CRITICAL
);
7169 strncpy(atom
->name
, new_name
, len
);
7171 return(TNG_SUCCESS
);
7174 tng_function_status
tng_atom_type_get(const tng_trajectory_t tng_data
,
7175 const tng_atom_t atom
,
7180 TNG_ASSERT(atom
, "TNG library: atom must not be NULL");
7181 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer");
7183 strncpy(type
, atom
->atom_type
, max_len
- 1);
7184 type
[max_len
- 1] = 0;
7186 if(strlen(atom
->atom_type
) > (unsigned int)max_len
- 1)
7188 return(TNG_FAILURE
);
7190 return(TNG_SUCCESS
);
7193 tng_function_status
tng_atom_type_set(tng_trajectory_t tng_data
,
7195 const char *new_type
)
7200 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7201 TNG_ASSERT(new_type
, "TNG library: new_type must not be a NULL pointer.");
7203 len
= tng_min_i((int)strlen(new_type
) + 1, TNG_MAX_STR_LEN
);
7205 /* If the currently stored string length is not enough to store the new
7206 * string it is freed and reallocated. */
7207 if(atom
->atom_type
&& strlen(atom
->atom_type
) < len
)
7209 free(atom
->atom_type
);
7210 atom
->atom_type
= 0;
7212 if(!atom
->atom_type
)
7214 atom
->atom_type
= malloc(len
);
7215 if(!atom
->atom_type
)
7217 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
7218 __FILE__
, __LINE__
);
7219 return(TNG_CRITICAL
);
7223 strncpy(atom
->atom_type
, new_type
, len
);
7225 return(TNG_SUCCESS
);
7228 /** Initialise an atom struct
7229 * @param atom is the atom to initialise.
7230 * @return TNG_SUCCESS (0) if successful.
7232 static tng_function_status
tng_atom_init(tng_atom_t atom
)
7235 atom
->atom_type
= 0;
7237 return(TNG_SUCCESS
);
7240 /** Free the memory in an atom struct
7241 * @param atom is the atom to destroy.
7242 * @return TNG_SUCCESS (0) if successful.
7244 static tng_function_status
tng_atom_destroy(tng_atom_t atom
)
7253 free(atom
->atom_type
);
7254 atom
->atom_type
= 0;
7257 return(TNG_SUCCESS
);
7260 tng_function_status DECLSPECDLLEXPORT tng_molecule_add
7261 (tng_trajectory_t tng_data
,
7263 tng_molecule_t
*molecule
)
7266 tng_bool found_id
= TNG_TRUE
;
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 /* Find an unused ID */
7275 found_id
= TNG_FALSE
;
7276 for(i
= tng_data
->n_molecules
; i
--;)
7278 if(tng_data
->molecules
[i
].id
== id
)
7280 found_id
= TNG_TRUE
;
7290 return(tng_molecule_w_id_add(tng_data
, name
, id
, molecule
));
7293 tng_function_status DECLSPECDLLEXPORT tng_molecule_w_id_add
7294 (tng_trajectory_t tng_data
,
7297 tng_molecule_t
*molecule
)
7299 tng_molecule_t new_molecules
;
7300 int64_t *new_molecule_cnt_list
, i
;
7301 tng_function_status stat
= TNG_SUCCESS
;
7303 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7304 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
7306 new_molecules
= realloc(tng_data
->molecules
,
7307 sizeof(struct tng_molecule
) *
7308 (tng_data
->n_molecules
+ 1));
7312 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
7313 sizeof(struct tng_molecule
) * (tng_data
->n_molecules
+ 1),
7314 __FILE__
, __LINE__
);
7315 free(tng_data
->molecules
);
7316 tng_data
->molecules
= 0;
7317 return(TNG_CRITICAL
);
7320 new_molecule_cnt_list
= realloc(tng_data
->molecule_cnt_list
,
7322 (tng_data
->n_molecules
+ 1));
7324 if(!new_molecule_cnt_list
)
7326 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
7327 sizeof(int64_t) * (tng_data
->n_molecules
+ 1),
7328 __FILE__
, __LINE__
);
7329 free(tng_data
->molecule_cnt_list
);
7330 tng_data
->molecule_cnt_list
= 0;
7331 free(new_molecules
);
7332 return(TNG_CRITICAL
);
7335 tng_data
->molecules
= new_molecules
;
7336 tng_data
->molecule_cnt_list
= new_molecule_cnt_list
;
7338 *molecule
= &new_molecules
[tng_data
->n_molecules
];
7340 tng_molecule_init(tng_data
, *molecule
);
7341 tng_molecule_name_set(tng_data
, *molecule
, name
);
7343 /* FIXME: Should this be a function argument instead? */
7344 tng_data
->molecule_cnt_list
[tng_data
->n_molecules
] = 0;
7346 for(i
= tng_data
->n_molecules
; i
--;)
7348 if(tng_data
->molecules
[i
].id
== id
)
7351 fprintf(stderr
, "TNG library: Molecule ID %"PRId64
" already in use. %s: %d\n", id
,
7352 __FILE__
, __LINE__
);
7357 (*molecule
)->id
= id
;
7359 tng_data
->n_molecules
++;
7364 tng_function_status DECLSPECDLLEXPORT tng_molecule_existing_add
7365 (tng_trajectory_t tng_data
,
7366 tng_molecule_t
*molecule_p
)
7368 tng_bool found_id
= TNG_TRUE
;
7369 tng_molecule_t new_molecules
, molecule
;
7370 int64_t *new_molecule_cnt_list
, i
, id
;
7372 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7374 /* Find an unused ID */
7378 found_id
= TNG_FALSE
;
7379 for(i
= tng_data
->n_molecules
; i
--;)
7381 if(tng_data
->molecules
[i
].id
== id
)
7383 found_id
= TNG_TRUE
;
7393 new_molecules
= realloc(tng_data
->molecules
,
7394 sizeof(struct tng_molecule
) *
7395 (tng_data
->n_molecules
+ 1));
7399 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
7400 sizeof(struct tng_molecule
) * (tng_data
->n_molecules
+ 1),
7401 __FILE__
, __LINE__
);
7402 free(tng_data
->molecules
);
7403 tng_data
->molecules
= 0;
7404 return(TNG_CRITICAL
);
7407 new_molecule_cnt_list
= realloc(tng_data
->molecule_cnt_list
,
7409 (tng_data
->n_molecules
+ 1));
7411 if(!new_molecule_cnt_list
)
7413 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
7414 sizeof(int64_t) * (tng_data
->n_molecules
+ 1),
7415 __FILE__
, __LINE__
);
7416 free(tng_data
->molecule_cnt_list
);
7417 tng_data
->molecule_cnt_list
= 0;
7418 free(new_molecules
);
7419 return(TNG_CRITICAL
);
7422 molecule
= *molecule_p
;
7424 tng_data
->molecules
= new_molecules
;
7425 tng_data
->molecule_cnt_list
= new_molecule_cnt_list
;
7427 new_molecules
[tng_data
->n_molecules
] = *molecule
;
7429 tng_data
->molecule_cnt_list
[tng_data
->n_molecules
] = 0;
7433 molecule
= &new_molecules
[tng_data
->n_molecules
];
7435 *molecule_p
= molecule
;
7439 tng_data
->n_molecules
++;
7441 return(TNG_SUCCESS
);
7444 tng_function_status
tng_molecule_name_get(const tng_trajectory_t tng_data
,
7445 const tng_molecule_t molecule
,
7450 TNG_ASSERT(molecule
, "TNG library: molecule must not be NULL");
7451 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
7453 strncpy(name
, molecule
->name
, max_len
- 1);
7454 name
[max_len
- 1] = 0;
7456 if(strlen(molecule
->name
) > (unsigned int)max_len
- 1)
7458 return(TNG_FAILURE
);
7460 return(TNG_SUCCESS
);
7463 tng_function_status DECLSPECDLLEXPORT tng_molecule_name_set
7464 (tng_trajectory_t tng_data
,
7465 tng_molecule_t molecule
,
7466 const char *new_name
)
7471 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7472 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer.");
7474 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
7476 /* If the currently stored string length is not enough to store the new
7477 * string it is freed and reallocated. */
7478 if(molecule
->name
&& strlen(molecule
->name
) < len
)
7480 free(molecule
->name
);
7485 molecule
->name
= malloc(len
);
7488 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
7489 __FILE__
, __LINE__
);
7490 return(TNG_CRITICAL
);
7494 strncpy(molecule
->name
, new_name
, len
);
7496 return(TNG_SUCCESS
);
7499 tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_get
7500 (const tng_trajectory_t tng_data
,
7501 const tng_molecule_t molecule
,
7504 int64_t i
, index
= -1;
7506 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7507 TNG_ASSERT(cnt
, "TNG library: cnt must not be a NULL pointer.");
7509 for(i
= tng_data
->n_molecules
; i
--;)
7511 if(&tng_data
->molecules
[i
] == molecule
)
7519 return(TNG_FAILURE
);
7521 *cnt
= tng_data
->molecule_cnt_list
[index
];
7523 return(TNG_SUCCESS
);
7526 tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_set
7527 (tng_trajectory_t tng_data
,
7528 tng_molecule_t molecule
,
7531 int64_t i
, old_cnt
, index
= -1;
7533 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7535 for(i
= tng_data
->n_molecules
; i
--;)
7537 if(&tng_data
->molecules
[i
] == molecule
)
7545 fprintf(stderr
, "TNG library: Could not find molecule in TNG trajectory. %s: %d\n",
7546 __FILE__
, __LINE__
);
7547 return(TNG_FAILURE
);
7549 if(tng_data
->var_num_atoms_flag
== TNG_CONSTANT_N_ATOMS
)
7551 old_cnt
= tng_data
->molecule_cnt_list
[index
];
7552 tng_data
->molecule_cnt_list
[index
] = cnt
;
7554 tng_data
->n_particles
+= (cnt
-old_cnt
) *
7555 tng_data
->molecules
[index
].n_atoms
;
7559 old_cnt
= tng_data
->current_trajectory_frame_set
.molecule_cnt_list
[index
];
7560 tng_data
->current_trajectory_frame_set
.molecule_cnt_list
[index
] = cnt
;
7562 tng_data
->current_trajectory_frame_set
.n_particles
+= (cnt
-old_cnt
) *
7563 tng_data
->molecules
[index
].n_atoms
;
7566 return(TNG_SUCCESS
);
7569 tng_function_status DECLSPECDLLEXPORT tng_molecule_find
7570 (tng_trajectory_t tng_data
,
7573 tng_molecule_t
*molecule
)
7575 int64_t i
, n_molecules
;
7577 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7578 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
7579 TNG_ASSERT(molecule
, "TNG library: molecule must not be a NULL pointer.");
7581 n_molecules
= tng_data
->n_molecules
;
7583 for(i
= 0; i
< n_molecules
; i
++)
7585 *molecule
= &tng_data
->molecules
[i
];
7586 if(name
[0] == 0 || strcmp(name
, (*molecule
)->name
) == 0)
7588 if(nr
== -1 || nr
== (*molecule
)->id
)
7590 return(TNG_SUCCESS
);
7597 return(TNG_FAILURE
);
7600 tng_function_status DECLSPECDLLEXPORT tng_molecule_of_index_get
7601 (tng_trajectory_t tng_data
,
7603 tng_molecule_t
*molecule
)
7605 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7606 TNG_ASSERT(molecule
, "TNG library: molecule must not be a NULL pointer.");
7608 if(index
>= tng_data
->n_molecules
)
7611 return(TNG_FAILURE
);
7613 *molecule
= &tng_data
->molecules
[index
];
7614 return(TNG_SUCCESS
);
7617 tng_function_status DECLSPECDLLEXPORT
tng_molecule_system_copy(tng_trajectory_t tng_data_src
,
7618 tng_trajectory_t tng_data_dest
)
7620 tng_molecule_t molecule
, molecule_temp
;
7621 tng_chain_t chain
, chain_temp
;
7622 tng_residue_t residue
, residue_temp
;
7623 tng_atom_t atom
, atom_temp
;
7624 tng_bond_t bond_temp
;
7625 tng_function_status stat
;
7626 int64_t i
, j
, k
, l
, *list_temp
;
7628 TNG_ASSERT(tng_data_src
, "TNG library: Trajectory container not properly setup.");
7629 TNG_ASSERT(tng_data_dest
, "TNG library: Trajectory container not properly setup.");
7631 for(i
= 0; i
< tng_data_dest
->n_molecules
; i
++)
7633 molecule
= &tng_data_dest
->molecules
[i
];
7634 tng_molecule_destroy(tng_data_dest
, molecule
);
7637 tng_data_dest
->n_molecules
= 0;
7638 tng_data_dest
->n_particles
= 0;
7640 molecule_temp
= realloc(tng_data_dest
->molecules
,
7641 sizeof(struct tng_molecule
) * tng_data_src
->n_molecules
);
7644 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
7645 sizeof(struct tng_molecule
) * tng_data_src
->n_molecules
,
7646 __FILE__
, __LINE__
);
7647 free(tng_data_dest
->molecules
);
7648 tng_data_dest
->molecules
= 0;
7649 return(TNG_CRITICAL
);
7651 list_temp
= realloc(tng_data_dest
->molecule_cnt_list
,
7652 sizeof(int64_t) * tng_data_src
->n_molecules
);
7655 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
7656 sizeof(int64_t) * tng_data_src
->n_molecules
,
7657 __FILE__
, __LINE__
);
7658 free(tng_data_dest
->molecule_cnt_list
);
7659 tng_data_dest
->molecule_cnt_list
= 0;
7660 free(molecule_temp
);
7661 return(TNG_CRITICAL
);
7664 tng_data_dest
->molecules
= molecule_temp
;
7665 tng_data_dest
->molecule_cnt_list
= list_temp
;
7667 for(i
= 0; i
< tng_data_src
->n_molecules
; i
++)
7669 molecule
= &tng_data_src
->molecules
[i
];
7670 stat
= tng_molecule_w_id_add(tng_data_dest
, molecule
->name
, molecule
->id
,
7672 if(stat
!= TNG_SUCCESS
)
7674 fprintf(stderr
, "TNG library: Cannot create new molecule to make a copy. %s: %d\n",
7675 __FILE__
, __LINE__
);
7678 molecule_temp
->quaternary_str
= molecule
->quaternary_str
;
7679 for(j
= 0; j
< molecule
->n_chains
; j
++)
7681 chain
= &molecule
->chains
[j
];
7682 stat
= tng_molecule_chain_w_id_add(tng_data_dest
, molecule_temp
,
7683 chain
->name
, chain
->id
,
7685 if(stat
!= TNG_SUCCESS
)
7687 fprintf(stderr
, "TNG library: Cannot create new chain to make a copy. %s: %d\n",
7688 __FILE__
, __LINE__
);
7691 for(k
= 0; k
< chain
->n_residues
; k
++)
7693 residue
= &chain
->residues
[k
];
7694 stat
= tng_chain_residue_w_id_add(tng_data_dest
, chain_temp
,
7695 residue
->name
, residue
->id
,
7697 if(stat
!= TNG_SUCCESS
)
7699 fprintf(stderr
, "TNG library: Cannot create new residue to make a copy. %s: %d\n",
7700 __FILE__
, __LINE__
);
7703 for(l
= 0; l
< residue
->n_atoms
; l
++)
7705 atom
= &molecule
->atoms
[residue
->atoms_offset
+ l
];
7706 stat
= tng_residue_atom_w_id_add(tng_data_dest
, residue_temp
,
7707 atom
->name
, atom
->atom_type
,
7708 atom
->id
, &atom_temp
);
7709 if(stat
!= TNG_SUCCESS
)
7711 fprintf(stderr
, "TNG library: Cannot create new atom to make a copy. %s: %d\n",
7712 __FILE__
, __LINE__
);
7718 molecule_temp
->n_bonds
= molecule
->n_bonds
;
7719 bond_temp
= realloc(molecule_temp
->bonds
, sizeof(struct tng_bond
) *
7723 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
7724 sizeof(struct tng_bond
) * molecule
->n_bonds
,
7725 __FILE__
, __LINE__
);
7726 free(molecule_temp
->bonds
);
7727 molecule_temp
->n_bonds
= 0;
7728 return(TNG_CRITICAL
);
7730 molecule_temp
->bonds
= bond_temp
;
7731 for(j
= 0; j
< molecule
->n_bonds
; j
++)
7733 molecule_temp
->bonds
[j
] = molecule
->bonds
[j
];
7735 stat
= tng_molecule_cnt_set(tng_data_dest
, molecule_temp
,
7736 tng_data_src
->molecule_cnt_list
[i
]);
7737 if(stat
!= TNG_SUCCESS
)
7739 fprintf(stderr
, "TNG library: Cannot set molecule count. %s: %d.\n",
7740 __FILE__
, __LINE__
);
7744 return(TNG_SUCCESS
);
7747 tng_function_status DECLSPECDLLEXPORT tng_molecule_num_chains_get
7748 (const tng_trajectory_t tng_data
,
7749 const tng_molecule_t molecule
,
7753 TNG_ASSERT(molecule
, "TNG library: molecule must not be NULL");
7754 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
7756 *n
= molecule
->n_chains
;
7758 return(TNG_SUCCESS
);
7761 tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_of_index_get
7762 (tng_trajectory_t tng_data
,
7763 tng_molecule_t molecule
,
7768 TNG_ASSERT(molecule
, "TNG library: molecule must not be a NULL pointer.");
7769 TNG_ASSERT(chain
, "TNG library: chain must not be a NULL pointer.");
7771 if(index
>= molecule
->n_chains
)
7774 return(TNG_FAILURE
);
7776 *chain
= &molecule
->chains
[index
];
7777 return(TNG_SUCCESS
);
7780 tng_function_status DECLSPECDLLEXPORT tng_molecule_num_residues_get
7781 (const tng_trajectory_t tng_data
,
7782 const tng_molecule_t molecule
,
7786 TNG_ASSERT(molecule
, "TNG library: molecule must not be NULL");
7787 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
7789 *n
= molecule
->n_residues
;
7791 return(TNG_SUCCESS
);
7794 tng_function_status DECLSPECDLLEXPORT tng_molecule_residue_of_index_get
7795 (const tng_trajectory_t tng_data
,
7796 const tng_molecule_t molecule
,
7797 const int64_t index
,
7798 tng_residue_t
*residue
)
7801 TNG_ASSERT(molecule
, "TNG library: molecule must not be a NULL pointer.");
7802 TNG_ASSERT(residue
, "TNG library: residue must not be a NULL pointer.");
7804 if(index
>= molecule
->n_residues
)
7807 return(TNG_FAILURE
);
7809 *residue
= &molecule
->residues
[index
];
7810 return(TNG_SUCCESS
);
7813 tng_function_status DECLSPECDLLEXPORT tng_molecule_num_atoms_get
7814 (const tng_trajectory_t tng_data
,
7815 const tng_molecule_t molecule
,
7819 TNG_ASSERT(molecule
, "TNG library: molecule must not be NULL");
7820 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
7822 *n
= molecule
->n_atoms
;
7824 return(TNG_SUCCESS
);
7827 tng_function_status DECLSPECDLLEXPORT tng_molecule_atom_of_index_get
7828 (const tng_trajectory_t tng_data
,
7829 const tng_molecule_t molecule
,
7830 const int64_t index
,
7834 TNG_ASSERT(molecule
, "TNG library: molecule must not be a NULL pointer.");
7835 TNG_ASSERT(atom
, "TNG library: atom must not be a NULL pointer.");
7837 if(index
>= molecule
->n_atoms
)
7840 return(TNG_FAILURE
);
7842 *atom
= &molecule
->atoms
[index
];
7843 return(TNG_SUCCESS
);
7846 tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_find
7847 (tng_trajectory_t tng_data
,
7848 tng_molecule_t molecule
,
7853 int64_t i
, n_chains
;
7856 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7857 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
7859 n_chains
= molecule
->n_chains
;
7861 for(i
= 0; i
< n_chains
; i
++)
7863 *chain
= &molecule
->chains
[i
];
7864 if(name
[0] == 0 || strcmp(name
, (*chain
)->name
) == 0)
7866 if(nr
== -1 || nr
== (*chain
)->id
)
7868 return(TNG_SUCCESS
);
7875 return(TNG_FAILURE
);
7878 tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_add
7879 (tng_trajectory_t tng_data
,
7880 tng_molecule_t molecule
,
7884 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7885 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
7887 return(tng_molecule_chain_w_id_add(tng_data
, molecule
, name
,
7888 molecule
->n_chains
+ 1, chain
));
7891 tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_w_id_add
7892 (tng_trajectory_t tng_data
,
7893 tng_molecule_t molecule
,
7899 tng_chain_t new_chains
;
7900 tng_function_status stat
= TNG_SUCCESS
;
7902 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
7903 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
7905 new_chains
= realloc(molecule
->chains
,
7906 sizeof(struct tng_chain
) *
7907 (molecule
->n_chains
+ 1));
7911 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
7912 sizeof(struct tng_chain
) * (molecule
->n_chains
+ 1),
7913 __FILE__
, __LINE__
);
7914 free(molecule
->chains
);
7915 molecule
->chains
= 0;
7916 return(TNG_CRITICAL
);
7919 molecule
->chains
= new_chains
;
7921 *chain
= &new_chains
[molecule
->n_chains
];
7924 tng_chain_name_set(tng_data
, *chain
, name
);
7926 (*chain
)->molecule
= molecule
;
7927 (*chain
)->n_residues
= 0;
7929 for(i
= molecule
->n_chains
; i
--;)
7931 if(molecule
->chains
[i
].id
== id
)
7934 fprintf(stderr
, "TNG library: Chain ID already in use. %s: %d\n", __FILE__
, __LINE__
);
7939 molecule
->n_chains
++;
7946 tng_function_status DECLSPECDLLEXPORT tng_molecule_bond_add
7947 (const tng_trajectory_t tng_data
,
7948 tng_molecule_t molecule
,
7949 const int64_t from_atom_id
,
7950 const int64_t to_atom_id
,
7954 tng_bond_t new_bonds
;
7957 for(i
= 0; i
< molecule
->n_bonds
; i
++)
7959 *bond
= &molecule
->bonds
[i
];
7960 /* Check if the bond already exists */
7961 if(((*bond
)->from_atom_id
== from_atom_id
&& (*bond
)->to_atom_id
== to_atom_id
) ||
7962 ((*bond
)->to_atom_id
== from_atom_id
&& (*bond
)->from_atom_id
== to_atom_id
))
7964 return(TNG_SUCCESS
);
7968 new_bonds
= realloc(molecule
->bonds
,
7969 sizeof(struct tng_bond
) *
7970 (molecule
->n_bonds
+ 1));
7974 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
7975 sizeof(struct tng_bond
) * (molecule
->n_bonds
+ 1),
7976 __FILE__
, __LINE__
);
7978 free(molecule
->bonds
);
7979 molecule
->bonds
= 0;
7980 return(TNG_CRITICAL
);
7983 molecule
->bonds
= new_bonds
;
7985 *bond
= &new_bonds
[molecule
->n_bonds
];
7987 (*bond
)->from_atom_id
= from_atom_id
;
7988 (*bond
)->to_atom_id
= to_atom_id
;
7990 molecule
->n_bonds
++;
7992 return(TNG_SUCCESS
);
7995 tng_function_status DECLSPECDLLEXPORT tng_molecule_atom_find
7996 (tng_trajectory_t tng_data
,
7997 tng_molecule_t molecule
,
8005 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
8007 n_atoms
= molecule
->n_atoms
;
8009 for(i
= 0; i
< n_atoms
; i
++)
8011 *atom
= &molecule
->atoms
[i
];
8012 if(name
[0] == 0 || strcmp(name
, (*atom
)->name
) == 0)
8014 if(id
== -1 || id
== (*atom
)->id
)
8016 return(TNG_SUCCESS
);
8023 return(TNG_FAILURE
);
8026 tng_function_status
tng_chain_name_get(const tng_trajectory_t tng_data
,
8027 const tng_chain_t chain
,
8032 TNG_ASSERT(chain
, "TNG library: chain must not be NULL");
8033 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
8035 strncpy(name
, chain
->name
, max_len
- 1);
8036 name
[max_len
- 1] = 0;
8038 if(strlen(chain
->name
) > (unsigned int)max_len
- 1)
8040 return(TNG_FAILURE
);
8042 return(TNG_SUCCESS
);
8045 tng_function_status DECLSPECDLLEXPORT tng_chain_name_set
8046 (tng_trajectory_t tng_data
,
8048 const char *new_name
)
8053 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer.");
8055 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
8057 /* If the currently stored string length is not enough to store the new
8058 * string it is freed and reallocated. */
8059 if(chain
->name
&& strlen(chain
->name
) < len
)
8066 chain
->name
= malloc(len
);
8069 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
8070 __FILE__
, __LINE__
);
8071 return(TNG_CRITICAL
);
8075 strncpy(chain
->name
, new_name
, len
);
8077 return(TNG_SUCCESS
);
8080 tng_function_status DECLSPECDLLEXPORT tng_chain_num_residues_get
8081 (const tng_trajectory_t tng_data
,
8082 const tng_chain_t chain
,
8086 TNG_ASSERT(chain
, "TNG library: chain must not be NULL");
8087 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
8089 *n
= chain
->n_residues
;
8091 return(TNG_SUCCESS
);
8094 tng_function_status DECLSPECDLLEXPORT tng_chain_residue_of_index_get
8095 (const tng_trajectory_t tng_data
,
8096 const tng_chain_t chain
,
8097 const int64_t index
,
8098 tng_residue_t
*residue
)
8101 TNG_ASSERT(chain
, "TNG library: chain must not be a NULL pointer.");
8102 TNG_ASSERT(residue
, "TNG library: residue must not be a NULL pointer.");
8104 if(index
>= chain
->n_residues
)
8107 return(TNG_FAILURE
);
8109 *residue
= &chain
->residues
[index
];
8110 return(TNG_SUCCESS
);
8113 tng_function_status DECLSPECDLLEXPORT tng_chain_residue_find
8114 (tng_trajectory_t tng_data
,
8118 tng_residue_t
*residue
)
8120 int64_t i
, n_residues
;
8123 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
8125 n_residues
= chain
->n_residues
;
8127 for(i
= 0; i
< n_residues
; i
++)
8129 *residue
= &chain
->residues
[i
];
8130 if(name
[0] == 0 || strcmp(name
, (*residue
)->name
) == 0)
8132 if(id
== -1 || id
== (*residue
)->id
)
8134 return(TNG_SUCCESS
);
8141 return(TNG_FAILURE
);
8144 tng_function_status DECLSPECDLLEXPORT tng_chain_residue_add
8145 (tng_trajectory_t tng_data
,
8148 tng_residue_t
*residue
)
8150 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8151 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
8153 return(tng_chain_residue_w_id_add(tng_data
, chain
, name
,
8154 chain
->n_residues
+ 1, residue
));
8157 tng_function_status DECLSPECDLLEXPORT tng_chain_residue_w_id_add
8158 (tng_trajectory_t tng_data
,
8162 tng_residue_t
*residue
)
8164 int64_t i
, curr_index
;
8165 tng_residue_t new_residues
, temp_residue
, last_residue
;
8166 tng_molecule_t molecule
= chain
->molecule
;
8167 tng_function_status stat
= TNG_SUCCESS
;
8169 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8170 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
8172 if(chain
->n_residues
)
8174 curr_index
= chain
->residues
- molecule
->residues
;
8181 new_residues
= realloc(molecule
->residues
,
8182 sizeof(struct tng_residue
) *
8183 (molecule
->n_residues
+ 1));
8187 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
8188 sizeof(struct tng_residue
) * (molecule
->n_residues
+ 1),
8189 __FILE__
, __LINE__
);
8190 free(molecule
->residues
);
8191 molecule
->residues
= 0;
8192 return(TNG_CRITICAL
);
8195 molecule
->residues
= new_residues
;
8197 if(curr_index
!= -1)
8199 chain
->residues
= new_residues
+ curr_index
;
8200 if(molecule
->n_residues
)
8202 last_residue
= &new_residues
[molecule
->n_residues
- 1];
8204 temp_residue
= chain
->residues
+ (chain
->n_residues
- 1);
8205 /* Make space in list of residues to add the new residues together with the other
8206 * residues of this chain */
8207 if(temp_residue
!= last_residue
)
8210 memmove(temp_residue
+ 1, temp_residue
,
8211 last_residue
- temp_residue
);
8217 curr_index
= molecule
->n_residues
;
8220 *residue
= &molecule
->residues
[curr_index
+ chain
->n_residues
];
8222 if(!chain
->n_residues
)
8224 chain
->residues
= *residue
;
8227 (*residue
)->name
= 0;
8228 tng_residue_name_set(tng_data
, *residue
, name
);
8230 (*residue
)->chain
= chain
;
8231 (*residue
)->n_atoms
= 0;
8232 (*residue
)->atoms_offset
= 0;
8234 for(i
= chain
->n_residues
; i
--;)
8236 if(chain
->residues
[i
].id
== id
)
8239 fprintf(stderr
, "TNG library: Residue ID already in use. %s: %d\n", __FILE__
, __LINE__
);
8244 chain
->n_residues
++;
8245 molecule
->n_residues
++;
8247 (*residue
)->id
= id
;
8252 tng_function_status
tng_residue_name_get(const tng_trajectory_t tng_data
,
8253 const tng_residue_t residue
,
8258 TNG_ASSERT(residue
, "TNG library: residue must not be NULL");
8259 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
8261 strncpy(name
, residue
->name
, max_len
- 1);
8262 name
[max_len
- 1] = 0;
8264 if(strlen(residue
->name
) > (unsigned int)max_len
- 1)
8266 return(TNG_FAILURE
);
8268 return(TNG_SUCCESS
);
8271 tng_function_status DECLSPECDLLEXPORT
tng_residue_name_set(tng_trajectory_t tng_data
,
8272 tng_residue_t residue
,
8273 const char *new_name
)
8278 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8279 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer");
8281 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
8283 /* If the currently stored string length is not enough to store the new
8284 * string it is freed and reallocated. */
8285 if(residue
->name
&& strlen(residue
->name
) < len
)
8287 free(residue
->name
);
8292 residue
->name
= malloc(len
);
8295 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
8296 __FILE__
, __LINE__
);
8297 return(TNG_CRITICAL
);
8301 strncpy(residue
->name
, new_name
, len
);
8303 return(TNG_SUCCESS
);
8306 tng_function_status DECLSPECDLLEXPORT tng_residue_num_atoms_get
8307 (const tng_trajectory_t tng_data
,
8308 const tng_residue_t residue
,
8312 TNG_ASSERT(residue
, "TNG library: residue must not be NULL");
8313 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
8315 *n
= residue
->n_atoms
;
8317 return(TNG_SUCCESS
);
8320 tng_function_status DECLSPECDLLEXPORT tng_residue_atom_of_index_get
8321 (const tng_trajectory_t tng_data
,
8322 const tng_residue_t residue
,
8323 const int64_t index
,
8327 tng_molecule_t molecule
;
8330 TNG_ASSERT(residue
, "TNG library: residue must not be a NULL pointer.");
8331 TNG_ASSERT(atom
, "TNG library: atom must not be a NULL pointer.");
8333 if(index
>= residue
->n_atoms
)
8336 return(TNG_FAILURE
);
8338 chain
= residue
->chain
;
8339 molecule
= chain
->molecule
;
8341 if(index
+ residue
->atoms_offset
>= molecule
->n_atoms
)
8344 return(TNG_FAILURE
);
8347 *atom
= &molecule
->atoms
[residue
->atoms_offset
+ index
];
8348 return(TNG_SUCCESS
);
8351 tng_function_status DECLSPECDLLEXPORT tng_residue_atom_add
8352 (tng_trajectory_t tng_data
,
8353 tng_residue_t residue
,
8354 const char *atom_name
,
8355 const char *atom_type
,
8358 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8359 TNG_ASSERT(atom_name
, "TNG library: atom_name must not be a NULL pointer.");
8360 TNG_ASSERT(atom_type
, "TNG library: atom_type must not be a NULL pointer.");
8362 return(tng_residue_atom_w_id_add(tng_data
, residue
, atom_name
, atom_type
,
8363 residue
->chain
->molecule
->n_atoms
+ 1,
8367 tng_function_status DECLSPECDLLEXPORT tng_residue_atom_w_id_add
8368 (tng_trajectory_t tng_data
,
8369 tng_residue_t residue
,
8370 const char *atom_name
,
8371 const char *atom_type
,
8376 tng_atom_t new_atoms
;
8377 tng_molecule_t molecule
= residue
->chain
->molecule
;
8378 tng_function_status stat
= TNG_SUCCESS
;
8380 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8381 TNG_ASSERT(atom_name
, "TNG library: atom_name must not be a NULL pointer.");
8382 TNG_ASSERT(atom_type
, "TNG library: atom_type must not be a NULL pointer.");
8384 if(!residue
->n_atoms
)
8386 residue
->atoms_offset
= molecule
->n_atoms
;
8389 new_atoms
= realloc(molecule
->atoms
,
8390 sizeof(struct tng_atom
) *
8391 (molecule
->n_atoms
+ 1));
8395 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
8396 sizeof(struct tng_atom
) * (molecule
->n_atoms
+ 1),
8397 __FILE__
, __LINE__
);
8398 free(molecule
->atoms
);
8399 molecule
->atoms
= 0;
8400 return(TNG_CRITICAL
);
8403 molecule
->atoms
= new_atoms
;
8405 *atom
= &new_atoms
[molecule
->n_atoms
];
8407 tng_atom_init(*atom
);
8408 tng_atom_name_set(tng_data
, *atom
, atom_name
);
8409 tng_atom_type_set(tng_data
, *atom
, atom_type
);
8411 (*atom
)->residue
= residue
;
8413 for(i
= molecule
->n_atoms
; i
--;)
8415 if(molecule
->atoms
[i
].id
== id
)
8418 fprintf(stderr
, "TNG library: Atom ID %"PRId64
" already in use. %s: %d\n", id
, __FILE__
, __LINE__
);
8424 molecule
->n_atoms
++;
8431 tng_function_status DECLSPECDLLEXPORT
tng_molecule_alloc(const tng_trajectory_t tng_data
,
8432 tng_molecule_t
*molecule_p
)
8434 *molecule_p
= malloc(sizeof(struct tng_molecule
));
8437 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
8438 sizeof(struct tng_molecule
), __FILE__
, __LINE__
);
8439 return(TNG_CRITICAL
);
8442 tng_molecule_init(tng_data
, *molecule_p
);
8444 return(TNG_SUCCESS
);
8447 tng_function_status DECLSPECDLLEXPORT
tng_molecule_free(const tng_trajectory_t tng_data
,
8448 tng_molecule_t
*molecule_p
)
8452 return(TNG_SUCCESS
);
8455 tng_molecule_destroy(tng_data
, *molecule_p
);
8460 return(TNG_SUCCESS
);
8463 tng_function_status DECLSPECDLLEXPORT
tng_molecule_init(const tng_trajectory_t tng_data
,
8464 tng_molecule_t molecule
)
8467 molecule
->quaternary_str
= 1;
8469 molecule
->n_chains
= 0;
8470 molecule
->chains
= 0;
8471 molecule
->n_residues
= 0;
8472 molecule
->residues
= 0;
8473 molecule
->n_atoms
= 0;
8474 molecule
->atoms
= 0;
8475 molecule
->n_bonds
= 0;
8476 molecule
->bonds
= 0;
8478 return(TNG_SUCCESS
);
8481 tng_function_status DECLSPECDLLEXPORT
tng_molecule_destroy(const tng_trajectory_t tng_data
,
8482 tng_molecule_t molecule
)
8489 free(molecule
->name
);
8493 if(molecule
->chains
)
8495 for(i
= molecule
->n_chains
; i
--;)
8497 if(molecule
->chains
[i
].name
)
8499 free(molecule
->chains
[i
].name
);
8500 molecule
->chains
[i
].name
= 0;
8503 free(molecule
->chains
);
8504 molecule
->chains
= 0;
8506 molecule
->n_chains
= 0;
8508 if(molecule
->residues
)
8510 for(i
= molecule
->n_residues
; i
--;)
8512 if(molecule
->residues
[i
].name
)
8514 free(molecule
->residues
[i
].name
);
8515 molecule
->residues
[i
].name
= 0;
8518 free(molecule
->residues
);
8519 molecule
->residues
= 0;
8521 molecule
->n_residues
= 0;
8525 for(i
= molecule
->n_atoms
; i
--;)
8527 tng_atom_destroy(&molecule
->atoms
[i
]);
8529 free(molecule
->atoms
);
8530 molecule
->atoms
= 0;
8532 molecule
->n_atoms
= 0;
8536 free(molecule
->bonds
);
8537 molecule
->bonds
= 0;
8539 molecule
->n_bonds
= 0;
8541 return(TNG_SUCCESS
);
8544 tng_function_status DECLSPECDLLEXPORT tng_molecule_name_of_particle_nr_get
8545 (const tng_trajectory_t tng_data
,
8550 int64_t cnt
= 0, i
, *molecule_cnt_list
= 0;
8552 tng_bool found
= TNG_FALSE
;
8554 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8555 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
8557 tng_molecule_cnt_list_get(tng_data
, &molecule_cnt_list
);
8559 if(!molecule_cnt_list
)
8561 return(TNG_FAILURE
);
8564 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8566 mol
= &tng_data
->molecules
[i
];
8567 if(cnt
+ mol
->n_atoms
* molecule_cnt_list
[i
] - 1 < nr
)
8569 cnt
+= mol
->n_atoms
* molecule_cnt_list
[i
];
8577 return(TNG_FAILURE
);
8580 strncpy(name
, mol
->name
, max_len
- 1);
8581 name
[max_len
- 1] = 0;
8583 if(strlen(mol
->name
) > (unsigned int)max_len
- 1)
8585 return(TNG_FAILURE
);
8587 return(TNG_SUCCESS
);
8590 tng_function_status DECLSPECDLLEXPORT tng_molecule_id_of_particle_nr_get
8591 (const tng_trajectory_t tng_data
,
8595 int64_t cnt
= 0, i
, *molecule_cnt_list
= 0;
8597 tng_bool found
= TNG_FALSE
;
8599 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8600 TNG_ASSERT(id
, "TNG library: id must not be a NULL pointer.");
8602 tng_molecule_cnt_list_get(tng_data
, &molecule_cnt_list
);
8604 if(!molecule_cnt_list
)
8606 return(TNG_FAILURE
);
8609 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8611 mol
= &tng_data
->molecules
[i
];
8612 if(cnt
+ mol
->n_atoms
* molecule_cnt_list
[i
] - 1 < nr
)
8614 cnt
+= mol
->n_atoms
* molecule_cnt_list
[i
];
8622 return(TNG_FAILURE
);
8627 return(TNG_SUCCESS
);
8630 tng_function_status DECLSPECDLLEXPORT tng_molsystem_bonds_get
8631 (const tng_trajectory_t tng_data
,
8633 int64_t **from_atoms
,
8636 int64_t atom_cnt
= 0, cnt
, mol_cnt
, i
, j
, k
;
8637 int64_t from_atom
, to_atom
, *molecule_cnt_list
= 0;
8641 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8642 TNG_ASSERT(n_bonds
, "TNG library: n_bonds must not be a NULL pointer.");
8643 TNG_ASSERT(from_atoms
, "TNG library: from_atoms must not be a NULL pointer.");
8644 TNG_ASSERT(to_atoms
, "TNG library: to_atoms must not be a NULL pointer.");
8646 tng_molecule_cnt_list_get(tng_data
, &molecule_cnt_list
);
8648 if(!molecule_cnt_list
)
8650 return(TNG_FAILURE
);
8654 /* First count the total number of bonds to allocate memory */
8655 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8657 mol
= &tng_data
->molecules
[i
];
8658 mol_cnt
= molecule_cnt_list
[i
];
8659 *n_bonds
+= mol_cnt
* mol
->n_bonds
;
8663 return(TNG_SUCCESS
);
8666 *from_atoms
= malloc(sizeof(int64_t) * (*n_bonds
));
8669 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
8670 sizeof(int64_t) * (*n_bonds
), __FILE__
, __LINE__
);
8671 return(TNG_CRITICAL
);
8673 *to_atoms
= malloc(sizeof(int64_t) * (*n_bonds
));
8676 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
8677 sizeof(int64_t) * (*n_bonds
), __FILE__
, __LINE__
);
8680 return(TNG_CRITICAL
);
8684 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8686 mol
= &tng_data
->molecules
[i
];
8687 mol_cnt
= molecule_cnt_list
[i
];
8688 for(j
= 0; j
< mol_cnt
; j
++)
8690 for(k
= 0; k
< mol
->n_bonds
; k
++)
8692 bond
= &mol
->bonds
[k
];
8693 from_atom
= atom_cnt
+ bond
->from_atom_id
;
8694 to_atom
= atom_cnt
+ bond
->to_atom_id
;
8695 (*from_atoms
)[cnt
] = from_atom
;
8696 (*to_atoms
)[cnt
++] = to_atom
;
8698 atom_cnt
+= mol
->n_atoms
;
8702 return(TNG_SUCCESS
);
8705 tng_function_status DECLSPECDLLEXPORT tng_chain_name_of_particle_nr_get
8706 (const tng_trajectory_t tng_data
,
8711 int64_t cnt
= 0, i
, *molecule_cnt_list
= 0;
8714 tng_bool found
= TNG_FALSE
;
8716 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8717 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
8719 tng_molecule_cnt_list_get(tng_data
, &molecule_cnt_list
);
8721 if(!molecule_cnt_list
)
8723 return(TNG_FAILURE
);
8726 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8728 mol
= &tng_data
->molecules
[i
];
8729 if(cnt
+ mol
->n_atoms
* molecule_cnt_list
[i
] - 1 < nr
)
8731 cnt
+= mol
->n_atoms
* molecule_cnt_list
[i
];
8734 atom
= &mol
->atoms
[nr
% mol
->n_atoms
];
8740 return(TNG_FAILURE
);
8742 if(!atom
->residue
|| !atom
->residue
->chain
)
8744 return(TNG_FAILURE
);
8747 strncpy(name
, atom
->residue
->chain
->name
, max_len
- 1);
8748 name
[max_len
- 1] = 0;
8750 if(strlen(atom
->residue
->chain
->name
) > (unsigned int)max_len
- 1)
8752 return(TNG_FAILURE
);
8754 return(TNG_SUCCESS
);
8757 tng_function_status DECLSPECDLLEXPORT tng_residue_name_of_particle_nr_get
8758 (const tng_trajectory_t tng_data
,
8763 int64_t cnt
= 0, i
, *molecule_cnt_list
= 0;
8766 tng_bool found
= TNG_FALSE
;
8768 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8769 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
8771 tng_molecule_cnt_list_get(tng_data
, &molecule_cnt_list
);
8773 if(!molecule_cnt_list
)
8775 return(TNG_FAILURE
);
8778 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8780 mol
= &tng_data
->molecules
[i
];
8781 if(cnt
+ mol
->n_atoms
* molecule_cnt_list
[i
] - 1 < nr
)
8783 cnt
+= mol
->n_atoms
* molecule_cnt_list
[i
];
8786 atom
= &mol
->atoms
[nr
% mol
->n_atoms
];
8792 return(TNG_FAILURE
);
8796 return(TNG_FAILURE
);
8799 strncpy(name
, atom
->residue
->name
, max_len
- 1);
8800 name
[max_len
- 1] = 0;
8802 if(strlen(atom
->residue
->name
) > (unsigned int)max_len
- 1)
8804 return(TNG_FAILURE
);
8806 return(TNG_SUCCESS
);
8809 tng_function_status DECLSPECDLLEXPORT tng_residue_id_of_particle_nr_get
8810 (const tng_trajectory_t tng_data
,
8814 int64_t cnt
= 0, i
, *molecule_cnt_list
= 0;
8817 tng_bool found
= TNG_FALSE
;
8819 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8820 TNG_ASSERT(id
, "TNG library: id must not be a NULL pointer.");
8822 tng_molecule_cnt_list_get(tng_data
, &molecule_cnt_list
);
8824 if(!molecule_cnt_list
)
8826 return(TNG_FAILURE
);
8829 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8831 mol
= &tng_data
->molecules
[i
];
8832 if(cnt
+ mol
->n_atoms
* molecule_cnt_list
[i
] - 1 < nr
)
8834 cnt
+= mol
->n_atoms
* molecule_cnt_list
[i
];
8837 atom
= &mol
->atoms
[nr
% mol
->n_atoms
];
8843 return(TNG_FAILURE
);
8847 return(TNG_FAILURE
);
8850 *id
= atom
->residue
->id
;
8852 return(TNG_SUCCESS
);
8855 tng_function_status DECLSPECDLLEXPORT tng_global_residue_id_of_particle_nr_get
8856 (const tng_trajectory_t tng_data
,
8860 int64_t cnt
= 0, i
, offset
= 0, *molecule_cnt_list
= 0;
8863 tng_bool found
= TNG_FALSE
;
8865 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8866 TNG_ASSERT(id
, "TNG library: id must not be a NULL pointer.");
8868 tng_molecule_cnt_list_get(tng_data
, &molecule_cnt_list
);
8870 if(!molecule_cnt_list
)
8872 return(TNG_FAILURE
);
8875 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8877 mol
= &tng_data
->molecules
[i
];
8878 if(cnt
+ mol
->n_atoms
* molecule_cnt_list
[i
] - 1 < nr
)
8880 cnt
+= mol
->n_atoms
* molecule_cnt_list
[i
];
8881 offset
+= mol
->n_residues
* molecule_cnt_list
[i
];
8884 atom
= &mol
->atoms
[nr
% mol
->n_atoms
];
8890 return(TNG_FAILURE
);
8894 return(TNG_FAILURE
);
8897 offset
+= mol
->n_residues
* ((nr
- cnt
) / mol
->n_atoms
);
8899 *id
= atom
->residue
->id
+ offset
;
8901 return(TNG_SUCCESS
);
8904 tng_function_status DECLSPECDLLEXPORT tng_atom_name_of_particle_nr_get
8905 (const tng_trajectory_t tng_data
,
8910 int64_t cnt
= 0, i
, *molecule_cnt_list
= 0;
8913 tng_bool found
= TNG_FALSE
;
8915 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8916 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
8918 tng_molecule_cnt_list_get(tng_data
, &molecule_cnt_list
);
8920 if(!molecule_cnt_list
)
8922 return(TNG_FAILURE
);
8925 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8927 mol
= &tng_data
->molecules
[i
];
8928 if(cnt
+ mol
->n_atoms
* molecule_cnt_list
[i
] - 1 < nr
)
8930 cnt
+= mol
->n_atoms
* molecule_cnt_list
[i
];
8933 atom
= &mol
->atoms
[nr
% mol
->n_atoms
];
8939 return(TNG_FAILURE
);
8942 strncpy(name
, atom
->name
, max_len
- 1);
8943 name
[max_len
- 1] = 0;
8945 if(strlen(atom
->name
) > (unsigned int)max_len
- 1)
8947 return(TNG_FAILURE
);
8949 return(TNG_SUCCESS
);
8952 tng_function_status tng_atom_type_of_particle_nr_get
8953 (const tng_trajectory_t tng_data
,
8958 int64_t cnt
= 0, i
, *molecule_cnt_list
= 0;
8961 tng_bool found
= TNG_FALSE
;
8963 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
8964 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer.");
8966 tng_molecule_cnt_list_get(tng_data
, &molecule_cnt_list
);
8968 if(!molecule_cnt_list
)
8970 return(TNG_FAILURE
);
8973 for(i
= 0; i
< tng_data
->n_molecules
; i
++)
8975 mol
= &tng_data
->molecules
[i
];
8976 if(cnt
+ mol
->n_atoms
* molecule_cnt_list
[i
] - 1 < nr
)
8978 cnt
+= mol
->n_atoms
* molecule_cnt_list
[i
];
8981 atom
= &mol
->atoms
[nr
% mol
->n_atoms
];
8987 return(TNG_FAILURE
);
8990 strncpy(type
, atom
->atom_type
, max_len
- 1);
8991 type
[max_len
- 1] = 0;
8993 if(strlen(atom
->atom_type
) > (unsigned int)max_len
- 1)
8995 return(TNG_FAILURE
);
8997 return(TNG_SUCCESS
);
9000 tng_function_status DECLSPECDLLEXPORT tng_particle_mapping_add
9001 (tng_trajectory_t tng_data
,
9002 const int64_t num_first_particle
,
9003 const int64_t n_particles
,
9004 const int64_t *mapping_table
)
9007 tng_particle_mapping_t mapping
;
9008 tng_trajectory_frame_set_t frame_set
;
9010 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
9012 frame_set
= &tng_data
->current_trajectory_frame_set
;
9014 /* Sanity check of the particle ranges. Split into multiple if
9015 * statements for improved readability */
9016 for(i
= 0; i
< frame_set
->n_mapping_blocks
; i
++)
9018 mapping
= &frame_set
->mappings
[i
];
9019 if(num_first_particle
>= mapping
->num_first_particle
&&
9020 num_first_particle
< mapping
->num_first_particle
+
9021 mapping
->n_particles
)
9023 fprintf(stderr
, "TNG library: Particle mapping overlap. %s: %d\n", __FILE__
, __LINE__
);
9024 return(TNG_FAILURE
);
9026 if(num_first_particle
+ n_particles
>=
9027 mapping
->num_first_particle
&&
9028 num_first_particle
+ n_particles
<
9029 mapping
->num_first_particle
+ mapping
->n_particles
)
9031 fprintf(stderr
, "TNG library: Particle mapping overlap. %s: %d\n", __FILE__
, __LINE__
);
9032 return(TNG_FAILURE
);
9034 if(mapping
->num_first_particle
>= num_first_particle
&&
9035 mapping
->num_first_particle
< num_first_particle
+
9038 fprintf(stderr
, "TNG library: Particle mapping overlap. %s: %d\n", __FILE__
, __LINE__
);
9039 return(TNG_FAILURE
);
9041 if(mapping
->num_first_particle
+ mapping
->n_particles
>
9042 num_first_particle
&&
9043 mapping
->num_first_particle
+ mapping
->n_particles
<
9044 num_first_particle
+ n_particles
)
9046 fprintf(stderr
, "TNG library: Particle mapping overlap. %s: %d\n", __FILE__
, __LINE__
);
9047 return(TNG_FAILURE
);
9051 frame_set
->n_mapping_blocks
++;
9053 mapping
= realloc(frame_set
->mappings
, sizeof(struct tng_particle_mapping
) *
9054 frame_set
->n_mapping_blocks
);
9058 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
9059 sizeof(struct tng_particle_mapping
)*frame_set
->n_mapping_blocks
,
9060 __FILE__
, __LINE__
);
9061 free(frame_set
->mappings
);
9062 frame_set
->mappings
= 0;
9063 return(TNG_CRITICAL
);
9065 frame_set
->mappings
= mapping
;
9067 frame_set
->mappings
[frame_set
->n_mapping_blocks
- 1].num_first_particle
= num_first_particle
;
9068 frame_set
->mappings
[frame_set
->n_mapping_blocks
- 1].n_particles
= n_particles
;
9070 frame_set
->mappings
[frame_set
->n_mapping_blocks
- 1].real_particle_numbers
= malloc(sizeof(int64_t) * n_particles
);
9071 if(!frame_set
->mappings
[frame_set
->n_mapping_blocks
- 1].real_particle_numbers
)
9073 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
9074 sizeof(int64_t) * n_particles
, __FILE__
, __LINE__
);
9075 return(TNG_CRITICAL
);
9078 for(i
=0; i
<n_particles
; i
++)
9080 frame_set
->mappings
[frame_set
->n_mapping_blocks
- 1].real_particle_numbers
[i
] = mapping_table
[i
];
9083 return(TNG_SUCCESS
);
9086 tng_function_status DECLSPECDLLEXPORT
tng_frame_set_particle_mapping_free(tng_trajectory_t tng_data
)
9088 tng_trajectory_frame_set_t frame_set
;
9089 tng_particle_mapping_t mapping
;
9092 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
9094 frame_set
= &tng_data
->current_trajectory_frame_set
;
9096 if(frame_set
->n_mapping_blocks
&& frame_set
->mappings
)
9098 for(i
= frame_set
->n_mapping_blocks
; i
--;)
9100 mapping
= &frame_set
->mappings
[i
];
9101 if(mapping
->real_particle_numbers
)
9103 free(mapping
->real_particle_numbers
);
9104 mapping
->real_particle_numbers
= 0;
9107 free(frame_set
->mappings
);
9108 frame_set
->mappings
= 0;
9109 frame_set
->n_mapping_blocks
= 0;
9112 return(TNG_SUCCESS
);
9115 tng_function_status DECLSPECDLLEXPORT
tng_trajectory_init(tng_trajectory_t
*tng_data_p
)
9118 tng_trajectory_frame_set_t frame_set
;
9119 tng_trajectory_t tng_data
;
9121 *tng_data_p
= malloc(sizeof(struct tng_trajectory
));
9124 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
9125 sizeof(struct tng_trajectory
), __FILE__
, __LINE__
);
9126 return(TNG_CRITICAL
);
9129 tng_data
= *tng_data_p
;
9131 frame_set
= &tng_data
->current_trajectory_frame_set
;
9133 tng_data
->input_file_path
= 0;
9134 tng_data
->input_file
= 0;
9135 tng_data
->input_file_len
= 0;
9136 tng_data
->output_file_path
= 0;
9137 tng_data
->output_file
= 0;
9139 tng_data
->first_program_name
= 0;
9140 tng_data
->first_user_name
= 0;
9141 tng_data
->first_computer_name
= 0;
9142 tng_data
->first_pgp_signature
= 0;
9143 tng_data
->last_program_name
= 0;
9144 tng_data
->last_user_name
= 0;
9145 tng_data
->last_computer_name
= 0;
9146 tng_data
->last_pgp_signature
= 0;
9147 tng_data
->forcefield_name
= 0;
9152 fprintf(stderr
, "TNG library: Cannot get time. %s: %d\n", __FILE__
, __LINE__
);
9156 tng_data
->time
= seconds
;
9159 tng_data
->var_num_atoms_flag
= TNG_CONSTANT_N_ATOMS
;
9160 tng_data
->first_trajectory_frame_set_input_file_pos
= -1;
9161 tng_data
->last_trajectory_frame_set_input_file_pos
= -1;
9162 tng_data
->current_trajectory_frame_set_input_file_pos
= -1;
9163 tng_data
->first_trajectory_frame_set_output_file_pos
= -1;
9164 tng_data
->last_trajectory_frame_set_output_file_pos
= -1;
9165 tng_data
->current_trajectory_frame_set_output_file_pos
= -1;
9166 tng_data
->frame_set_n_frames
= 100;
9167 tng_data
->n_trajectory_frame_sets
= 0;
9168 tng_data
->n_trajectory_blocks
= 0;
9169 tng_data
->medium_stride_length
= 100;
9170 tng_data
->long_stride_length
= 10000;
9172 tng_data
->time_per_frame
= -1;
9174 tng_data
->n_particle_data_blocks
= 0;
9175 tng_data
->n_data_blocks
= 0;
9177 tng_data
->non_tr_particle_data
= 0;
9178 tng_data
->non_tr_data
= 0;
9180 tng_data
->compress_algo_pos
= 0;
9181 tng_data
->compress_algo_vel
= 0;
9182 tng_data
->compression_precision
= 1000;
9183 tng_data
->distance_unit_exponential
= -9;
9185 frame_set
->first_frame
= -1;
9186 frame_set
->n_mapping_blocks
= 0;
9187 frame_set
->mappings
= 0;
9188 frame_set
->molecule_cnt_list
= 0;
9190 frame_set
->n_particle_data_blocks
= 0;
9191 frame_set
->n_data_blocks
= 0;
9193 frame_set
->tr_particle_data
= 0;
9194 frame_set
->tr_data
= 0;
9196 frame_set
->n_written_frames
= 0;
9197 frame_set
->n_unwritten_frames
= 0;
9199 frame_set
->next_frame_set_file_pos
= -1;
9200 frame_set
->prev_frame_set_file_pos
= -1;
9201 frame_set
->medium_stride_next_frame_set_file_pos
= -1;
9202 frame_set
->medium_stride_prev_frame_set_file_pos
= -1;
9203 frame_set
->long_stride_next_frame_set_file_pos
= -1;
9204 frame_set
->long_stride_prev_frame_set_file_pos
= -1;
9206 frame_set
->first_frame_time
= -1;
9208 tng_data
->n_molecules
= 0;
9209 tng_data
->molecules
= 0;
9210 tng_data
->molecule_cnt_list
= 0;
9211 tng_data
->n_particles
= 0;
9214 /* Check the endianness of the computer */
9215 static int32_t endianness_32
= 0x01234567;
9217 if ( *(const unsigned char*)&endianness_32
== 0x01 )
9219 tng_data
->endianness_32
= TNG_BIG_ENDIAN_32
;
9223 else if( *(const unsigned char*)&endianness_32
== 0x67 )
9225 tng_data
->endianness_32
= TNG_LITTLE_ENDIAN_32
;
9230 else if ( *(const unsigned char*)&endianness_32
== 0x45 )
9232 tng_data
->endianness_32
= TNG_BYTE_PAIR_SWAP_32
;
9236 static int64_t endianness_64
= 0x0123456789ABCDEFLL
;
9237 /* 0x0123456789ABCDEF */
9238 if ( *(const unsigned char*)&endianness_64
== 0x01 )
9240 tng_data
->endianness_64
= TNG_BIG_ENDIAN_64
;
9243 /* 0xEFCDAB8967452301 */
9244 else if ( *(const unsigned char*)&endianness_64
== 0xEF )
9246 tng_data
->endianness_64
= TNG_LITTLE_ENDIAN_64
;
9249 /* 0x89ABCDEF01234567 */
9250 else if ( *(const unsigned char*)&endianness_64
== 0x89 )
9252 tng_data
->endianness_64
= TNG_QUAD_SWAP_64
;
9255 /* 0x45670123CDEF89AB */
9256 else if ( *(const unsigned char*)&endianness_64
== 0x45 )
9258 tng_data
->endianness_64
= TNG_BYTE_PAIR_SWAP_64
;
9261 /* 0x23016745AB89EFCD */
9262 else if ( *(const unsigned char*)&endianness_64
== 0x23 )
9264 tng_data
->endianness_64
= TNG_BYTE_SWAP_64
;
9268 /* By default do not swap the byte order, i.e. keep the byte order of the
9269 * architecture. The input file endianness will be set when reading the
9270 * header. The output endianness can be changed - before the file is
9272 tng_data
->input_endianness_swap_func_32
= 0;
9273 tng_data
->input_endianness_swap_func_64
= 0;
9274 tng_data
->output_endianness_swap_func_32
= 0;
9275 tng_data
->output_endianness_swap_func_64
= 0;
9277 tng_data
->current_trajectory_frame_set
.next_frame_set_file_pos
= -1;
9278 tng_data
->current_trajectory_frame_set
.prev_frame_set_file_pos
= -1;
9279 tng_data
->current_trajectory_frame_set
.n_frames
= 0;
9281 return(TNG_SUCCESS
);
9284 tng_function_status DECLSPECDLLEXPORT
tng_trajectory_destroy(tng_trajectory_t
*tng_data_p
)
9287 int64_t n_particles
, n_values_per_frame
;
9288 tng_trajectory_t tng_data
= *tng_data_p
;
9289 tng_trajectory_frame_set_t frame_set
;
9293 return(TNG_SUCCESS
);
9296 frame_set
= &tng_data
->current_trajectory_frame_set
;
9298 if(tng_data
->input_file_path
)
9300 free(tng_data
->input_file_path
);
9301 tng_data
->input_file_path
= 0;
9304 if(tng_data
->input_file
)
9306 fclose(tng_data
->input_file
);
9307 tng_data
->input_file
= 0;
9310 if(tng_data
->output_file_path
)
9312 free(tng_data
->output_file_path
);
9313 tng_data
->output_file_path
= 0;
9316 if(tng_data
->output_file
)
9318 /* FIXME: Do not always write the hash */
9319 tng_frame_set_finalize(tng_data
, TNG_USE_HASH
);
9320 fclose(tng_data
->output_file
);
9321 tng_data
->output_file
= 0;
9324 if(tng_data
->first_program_name
)
9326 free(tng_data
->first_program_name
);
9327 tng_data
->first_program_name
= 0;
9330 if(tng_data
->last_program_name
)
9332 free(tng_data
->last_program_name
);
9333 tng_data
->last_program_name
= 0;
9336 if(tng_data
->first_user_name
)
9338 free(tng_data
->first_user_name
);
9339 tng_data
->first_user_name
= 0;
9342 if(tng_data
->last_user_name
)
9344 free(tng_data
->last_user_name
);
9345 tng_data
->last_user_name
= 0;
9348 if(tng_data
->first_computer_name
)
9350 free(tng_data
->first_computer_name
);
9351 tng_data
->first_computer_name
= 0;
9354 if(tng_data
->last_computer_name
)
9356 free(tng_data
->last_computer_name
);
9357 tng_data
->last_computer_name
= 0;
9360 if(tng_data
->first_pgp_signature
)
9362 free(tng_data
->first_pgp_signature
);
9363 tng_data
->first_pgp_signature
= 0;
9366 if(tng_data
->last_pgp_signature
)
9368 free(tng_data
->last_pgp_signature
);
9369 tng_data
->last_pgp_signature
= 0;
9372 if(tng_data
->forcefield_name
)
9374 free(tng_data
->forcefield_name
);
9375 tng_data
->forcefield_name
= 0;
9378 tng_frame_set_particle_mapping_free(tng_data
);
9380 if(frame_set
->molecule_cnt_list
)
9382 free(frame_set
->molecule_cnt_list
);
9383 frame_set
->molecule_cnt_list
= 0;
9386 if(tng_data
->var_num_atoms_flag
)
9388 n_particles
= frame_set
->n_particles
;
9392 n_particles
= tng_data
->n_particles
;
9395 if(tng_data
->non_tr_particle_data
)
9397 for(i
= tng_data
->n_particle_data_blocks
; i
--; )
9399 if(tng_data
->non_tr_particle_data
[i
].values
)
9401 free(tng_data
->non_tr_particle_data
[i
].values
);
9402 tng_data
->non_tr_particle_data
[i
].values
= 0;
9405 if(tng_data
->non_tr_particle_data
[i
].strings
)
9407 n_values_per_frame
= tng_data
->non_tr_particle_data
[i
].
9409 if(tng_data
->non_tr_particle_data
[i
].strings
[0])
9411 for(j
= n_particles
; j
--;)
9413 if(tng_data
->non_tr_particle_data
[i
].strings
[0][j
])
9415 for(k
= n_values_per_frame
; k
--;)
9417 if(tng_data
->non_tr_particle_data
[i
].
9420 free(tng_data
->non_tr_particle_data
[i
].
9422 tng_data
->non_tr_particle_data
[i
].
9423 strings
[0][j
][k
] = 0;
9426 free(tng_data
->non_tr_particle_data
[i
].
9428 tng_data
->non_tr_particle_data
[i
].strings
[0][j
] = 0;
9431 free(tng_data
->non_tr_particle_data
[i
].strings
[0]);
9432 tng_data
->non_tr_particle_data
[i
].strings
[0] = 0;
9434 free(tng_data
->non_tr_particle_data
[i
].strings
);
9435 tng_data
->non_tr_particle_data
[i
].strings
= 0;
9438 if(tng_data
->non_tr_particle_data
[i
].block_name
)
9440 free(tng_data
->non_tr_particle_data
[i
].block_name
);
9441 tng_data
->non_tr_particle_data
[i
].block_name
= 0;
9444 free(tng_data
->non_tr_particle_data
);
9445 tng_data
->non_tr_particle_data
= 0;
9448 if(tng_data
->non_tr_data
)
9450 for(i
= tng_data
->n_data_blocks
; i
--;)
9452 if(tng_data
->non_tr_data
[i
].values
)
9454 free(tng_data
->non_tr_data
[i
].values
);
9455 tng_data
->non_tr_data
[i
].values
= 0;
9458 if(tng_data
->non_tr_data
[i
].strings
)
9460 n_values_per_frame
= tng_data
->non_tr_data
[i
].
9462 if(tng_data
->non_tr_data
[i
].strings
[0])
9464 for(j
= n_values_per_frame
; j
--;)
9466 if(tng_data
->non_tr_data
[i
].strings
[0][j
])
9468 free(tng_data
->non_tr_data
[i
].strings
[0][j
]);
9469 tng_data
->non_tr_data
[i
].strings
[0][j
] = 0;
9472 free(tng_data
->non_tr_data
[i
].strings
[0]);
9473 tng_data
->non_tr_data
[i
].strings
[0] = 0;
9475 free(tng_data
->non_tr_data
[i
].strings
);
9476 tng_data
->non_tr_data
[i
].strings
= 0;
9479 if(tng_data
->non_tr_data
[i
].block_name
)
9481 free(tng_data
->non_tr_data
[i
].block_name
);
9482 tng_data
->non_tr_data
[i
].block_name
= 0;
9485 free(tng_data
->non_tr_data
);
9486 tng_data
->non_tr_data
= 0;
9489 tng_data
->n_particle_data_blocks
= 0;
9490 tng_data
->n_data_blocks
= 0;
9492 if(tng_data
->compress_algo_pos
)
9494 free(tng_data
->compress_algo_pos
);
9495 tng_data
->compress_algo_pos
= 0;
9497 if(tng_data
->compress_algo_vel
)
9499 free(tng_data
->compress_algo_vel
);
9500 tng_data
->compress_algo_vel
= 0;
9503 if(frame_set
->tr_particle_data
)
9505 for(i
= frame_set
->n_particle_data_blocks
; i
--; )
9507 if(frame_set
->tr_particle_data
[i
].values
)
9509 free(frame_set
->tr_particle_data
[i
].values
);
9510 frame_set
->tr_particle_data
[i
].values
= 0;
9513 if(frame_set
->tr_particle_data
[i
].strings
)
9515 n_values_per_frame
= frame_set
->tr_particle_data
[i
].
9517 for(j
= frame_set
->tr_particle_data
[i
].n_frames
; j
--;)
9519 if(frame_set
->tr_particle_data
[i
].strings
[j
])
9521 for(k
= n_particles
; k
--;)
9523 if(frame_set
->tr_particle_data
[i
].
9526 for(l
= n_values_per_frame
; l
--;)
9528 if(frame_set
->tr_particle_data
[i
].
9531 free(frame_set
->tr_particle_data
[i
].
9533 frame_set
->tr_particle_data
[i
].
9534 strings
[j
][k
][l
] = 0;
9537 free(frame_set
->tr_particle_data
[i
].
9539 frame_set
->tr_particle_data
[i
].
9543 free(frame_set
->tr_particle_data
[i
].strings
[j
]);
9544 frame_set
->tr_particle_data
[i
].strings
[j
] = 0;
9547 free(frame_set
->tr_particle_data
[i
].strings
);
9548 frame_set
->tr_particle_data
[i
].strings
= 0;
9551 if(frame_set
->tr_particle_data
[i
].block_name
)
9553 free(frame_set
->tr_particle_data
[i
].block_name
);
9554 frame_set
->tr_particle_data
[i
].block_name
= 0;
9557 free(frame_set
->tr_particle_data
);
9558 frame_set
->tr_particle_data
= 0;
9561 if(frame_set
->tr_data
)
9563 for(i
= frame_set
->n_data_blocks
; i
--;)
9565 if(frame_set
->tr_data
[i
].values
)
9567 free(frame_set
->tr_data
[i
].values
);
9568 frame_set
->tr_data
[i
].values
= 0;
9571 if(frame_set
->tr_data
[i
].strings
)
9573 n_values_per_frame
= frame_set
->tr_data
[i
].
9575 for(j
= frame_set
->tr_data
[i
].n_frames
; j
--;)
9577 if(frame_set
->tr_data
[i
].strings
[j
])
9579 for(k
= n_values_per_frame
; k
--;)
9581 if(frame_set
->tr_data
[i
].strings
[j
][k
])
9583 free(frame_set
->tr_data
[i
].strings
[j
][k
]);
9584 frame_set
->tr_data
[i
].strings
[j
][k
] = 0;
9587 free(frame_set
->tr_data
[i
].strings
[j
]);
9588 frame_set
->tr_data
[i
].strings
[j
] = 0;
9591 free(frame_set
->tr_data
[i
].strings
);
9592 frame_set
->tr_data
[i
].strings
= 0;
9595 if(frame_set
->tr_data
[i
].block_name
)
9597 free(frame_set
->tr_data
[i
].block_name
);
9598 frame_set
->tr_data
[i
].block_name
= 0;
9601 free(frame_set
->tr_data
);
9602 frame_set
->tr_data
= 0;
9605 frame_set
->n_particle_data_blocks
= 0;
9606 frame_set
->n_data_blocks
= 0;
9608 if(tng_data
->molecules
)
9610 for(i
=tng_data
->n_molecules
; i
--;)
9612 tng_molecule_destroy(tng_data
, &tng_data
->molecules
[i
]);
9614 free(tng_data
->molecules
);
9615 tng_data
->molecules
= 0;
9616 tng_data
->n_molecules
= 0;
9618 if(tng_data
->molecule_cnt_list
)
9620 free(tng_data
->molecule_cnt_list
);
9621 tng_data
->molecule_cnt_list
= 0;
9627 return(TNG_SUCCESS
);
9630 tng_function_status DECLSPECDLLEXPORT
tng_trajectory_init_from_src(tng_trajectory_t src
,
9631 tng_trajectory_t
*dest_p
)
9633 tng_trajectory_frame_set_t frame_set
;
9634 tng_trajectory_t dest
;
9636 TNG_ASSERT(src
!= 0, "TNG library: Source trajectory must not be NULL.");
9638 *dest_p
= malloc(sizeof(struct tng_trajectory
));
9641 fprintf(stderr
, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
9642 sizeof(struct tng_trajectory
), __FILE__
, __LINE__
);
9643 return(TNG_CRITICAL
);
9648 frame_set
= &dest
->current_trajectory_frame_set
;
9650 dest
->input_file_path
= malloc(strlen(src
->input_file_path
) + 1);
9651 if(!dest
->input_file_path
)
9653 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
9654 (int)strlen(src
->input_file_path
) + 1, __FILE__
, __LINE__
);
9655 return(TNG_CRITICAL
);
9657 strcpy(dest
->input_file_path
, src
->input_file_path
);
9658 dest
->input_file
= 0;
9659 dest
->input_file_len
= src
->input_file_len
;
9660 dest
->output_file_path
= malloc(strlen(src
->output_file_path
) + 1);
9661 if(!dest
->output_file_path
)
9663 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
9664 (int)strlen(src
->output_file_path
) + 1, __FILE__
, __LINE__
);
9665 return(TNG_CRITICAL
);
9667 strcpy(dest
->output_file_path
, src
->output_file_path
);
9668 dest
->output_file
= 0;
9670 dest
->first_program_name
= 0;
9671 dest
->first_user_name
= 0;
9672 dest
->first_computer_name
= 0;
9673 dest
->first_pgp_signature
= 0;
9674 dest
->last_program_name
= 0;
9675 dest
->last_user_name
= 0;
9676 dest
->last_computer_name
= 0;
9677 dest
->last_pgp_signature
= 0;
9678 dest
->forcefield_name
= 0;
9680 dest
->var_num_atoms_flag
= src
->var_num_atoms_flag
;
9681 dest
->first_trajectory_frame_set_input_file_pos
=
9682 src
->first_trajectory_frame_set_input_file_pos
;
9683 dest
->last_trajectory_frame_set_input_file_pos
=
9684 src
->last_trajectory_frame_set_input_file_pos
;
9685 dest
->current_trajectory_frame_set_input_file_pos
=
9686 src
->current_trajectory_frame_set_input_file_pos
;
9687 dest
->first_trajectory_frame_set_output_file_pos
=
9688 src
->first_trajectory_frame_set_output_file_pos
;
9689 dest
->last_trajectory_frame_set_output_file_pos
=
9690 src
->last_trajectory_frame_set_output_file_pos
;
9691 dest
->current_trajectory_frame_set_output_file_pos
=
9692 src
->current_trajectory_frame_set_output_file_pos
;
9693 dest
->frame_set_n_frames
= src
->frame_set_n_frames
;
9694 dest
->n_trajectory_frame_sets
= src
->n_trajectory_frame_sets
;
9695 dest
->n_trajectory_blocks
= src
->n_trajectory_blocks
;
9696 dest
->medium_stride_length
= src
->medium_stride_length
;
9697 dest
->long_stride_length
= src
->long_stride_length
;
9699 dest
->time_per_frame
= src
->time_per_frame
;
9701 /* Currently the non trajectory data blocks are not copied since it
9702 * can lead to problems when freeing memory in a parallel block. */
9703 dest
->n_particle_data_blocks
= 0;
9704 dest
->n_data_blocks
= 0;
9705 dest
->non_tr_particle_data
= 0;
9706 dest
->non_tr_data
= 0;
9708 dest
->compress_algo_pos
= 0;
9709 dest
->compress_algo_vel
= 0;
9710 dest
->distance_unit_exponential
= -9;
9711 dest
->compression_precision
= 1000;
9713 frame_set
->n_mapping_blocks
= 0;
9714 frame_set
->mappings
= 0;
9715 frame_set
->molecule_cnt_list
= 0;
9717 frame_set
->n_particle_data_blocks
= 0;
9718 frame_set
->n_data_blocks
= 0;
9720 frame_set
->tr_particle_data
= 0;
9721 frame_set
->tr_data
= 0;
9723 frame_set
->next_frame_set_file_pos
= -1;
9724 frame_set
->prev_frame_set_file_pos
= -1;
9725 frame_set
->medium_stride_next_frame_set_file_pos
= -1;
9726 frame_set
->medium_stride_prev_frame_set_file_pos
= -1;
9727 frame_set
->long_stride_next_frame_set_file_pos
= -1;
9728 frame_set
->long_stride_prev_frame_set_file_pos
= -1;
9729 frame_set
->first_frame
= -1;
9731 dest
->n_molecules
= 0;
9732 dest
->molecules
= 0;
9733 dest
->molecule_cnt_list
= 0;
9734 dest
->n_particles
= src
->n_particles
;
9736 dest
->endianness_32
= src
->endianness_32
;
9737 dest
->endianness_64
= src
->endianness_64
;
9738 dest
->input_endianness_swap_func_32
= src
->input_endianness_swap_func_32
;
9739 dest
->input_endianness_swap_func_64
= src
->input_endianness_swap_func_64
;
9740 dest
->output_endianness_swap_func_32
= src
->output_endianness_swap_func_32
;
9741 dest
->output_endianness_swap_func_64
= src
->output_endianness_swap_func_64
;
9743 dest
->current_trajectory_frame_set
.next_frame_set_file_pos
= -1;
9744 dest
->current_trajectory_frame_set
.prev_frame_set_file_pos
= -1;
9745 dest
->current_trajectory_frame_set
.n_frames
= 0;
9747 return(TNG_SUCCESS
);
9750 tng_function_status DECLSPECDLLEXPORT
tng_input_file_get(const tng_trajectory_t tng_data
,
9751 char *file_name
, const int max_len
)
9753 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
9754 TNG_ASSERT(file_name
, "TNG library: file_name must not be a NULL pointer");
9756 strncpy(file_name
, tng_data
->input_file_path
, max_len
- 1);
9757 file_name
[max_len
- 1] = 0;
9759 if(strlen(tng_data
->input_file_path
) > (unsigned int)max_len
- 1)
9761 return(TNG_FAILURE
);
9763 return(TNG_SUCCESS
);
9766 tng_function_status DECLSPECDLLEXPORT
tng_input_file_set(tng_trajectory_t tng_data
,
9767 const char *file_name
)
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");
9776 if(tng_data
->input_file_path
&& strcmp(tng_data
->input_file_path
,
9779 return(TNG_SUCCESS
);
9782 if(tng_data
->input_file
)
9784 fclose(tng_data
->input_file
);
9787 len
= tng_min_i((int)strlen(file_name
) + 1, TNG_MAX_STR_LEN
);
9788 temp
= realloc(tng_data
->input_file_path
, len
);
9791 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
9792 __FILE__
, __LINE__
);
9793 free(tng_data
->input_file_path
);
9794 tng_data
->input_file_path
= 0;
9795 return(TNG_CRITICAL
);
9797 tng_data
->input_file_path
= temp
;
9799 strncpy(tng_data
->input_file_path
, file_name
, len
);
9801 return(tng_input_file_init(tng_data
));
9804 tng_function_status
tng_output_file_get(const tng_trajectory_t tng_data
,
9805 char *file_name
, const int max_len
)
9807 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
9808 TNG_ASSERT(file_name
, "TNG library: file_name must not be a NULL pointer");
9810 strncpy(file_name
, tng_data
->output_file_path
, max_len
- 1);
9811 file_name
[max_len
- 1] = 0;
9813 if(strlen(tng_data
->output_file_path
) > (unsigned int)max_len
- 1)
9815 return(TNG_FAILURE
);
9817 return(TNG_SUCCESS
);
9820 tng_function_status DECLSPECDLLEXPORT
tng_output_file_set(tng_trajectory_t tng_data
,
9821 const char *file_name
)
9826 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
9827 TNG_ASSERT(file_name
, "TNG library: file_name must not be a NULL pointer");
9829 if(tng_data
->output_file_path
&&
9830 strcmp(tng_data
->output_file_path
, file_name
) == 0)
9832 return(TNG_SUCCESS
);
9835 if(tng_data
->output_file
)
9837 fclose(tng_data
->output_file
);
9840 len
= tng_min_i((int)strlen(file_name
) + 1, TNG_MAX_STR_LEN
);
9841 temp
= realloc(tng_data
->output_file_path
, len
);
9844 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
9845 __FILE__
, __LINE__
);
9846 free(tng_data
->output_file_path
);
9847 tng_data
->output_file_path
= 0;
9848 return(TNG_CRITICAL
);
9850 tng_data
->output_file_path
= temp
;
9852 strncpy(tng_data
->output_file_path
, file_name
, len
);
9854 return(tng_output_file_init(tng_data
));
9857 tng_function_status DECLSPECDLLEXPORT tng_output_append_file_set
9858 (tng_trajectory_t tng_data
,
9859 const char *file_name
)
9864 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
9865 TNG_ASSERT(file_name
, "TNG library: file_name must not be a NULL pointer");
9867 if(tng_data
->output_file_path
&&
9868 strcmp(tng_data
->output_file_path
, file_name
) == 0)
9870 return(TNG_SUCCESS
);
9873 if(tng_data
->output_file
)
9875 fclose(tng_data
->output_file
);
9878 len
= tng_min_i((int)strlen(file_name
) + 1, TNG_MAX_STR_LEN
);
9879 temp
= realloc(tng_data
->output_file_path
, len
);
9882 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len
,
9883 __FILE__
, __LINE__
);
9884 free(tng_data
->output_file_path
);
9885 tng_data
->output_file_path
= 0;
9886 return(TNG_CRITICAL
);
9888 tng_data
->output_file_path
= temp
;
9890 strncpy(tng_data
->output_file_path
, file_name
, len
);
9892 tng_data
->output_file
= fopen(tng_data
->output_file_path
, "rb+");
9893 if(!tng_data
->output_file
)
9895 fprintf(stderr
, "TNG library: Cannot open file %s. %s: %d\n",
9896 tng_data
->output_file_path
, __FILE__
, __LINE__
);
9897 return(TNG_CRITICAL
);
9900 return(TNG_SUCCESS
);
9903 tng_function_status DECLSPECDLLEXPORT tng_output_file_endianness_get
9904 (const tng_trajectory_t tng_data
, tng_file_endianness
*endianness
)
9906 tng_endianness_32 end_32
;
9907 tng_endianness_64 end_64
;
9909 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
9910 TNG_ASSERT(endianness
, "TNG library: endianness must not be a NULL pointer");
9912 if(tng_data
->output_endianness_swap_func_32
)
9914 /* If other endianness variants are added they must be added here as well */
9915 if(tng_data
->output_endianness_swap_func_32
==
9916 &tng_swap_byte_order_big_endian_32
)
9918 end_32
= TNG_BIG_ENDIAN_32
;
9920 else if(tng_data
->output_endianness_swap_func_32
==
9921 &tng_swap_byte_order_little_endian_32
)
9923 end_32
= TNG_LITTLE_ENDIAN_32
;
9927 return(TNG_FAILURE
);
9932 end_32
= (tng_endianness_32
)tng_data
->endianness_32
;
9935 if(tng_data
->output_endianness_swap_func_64
)
9937 /* If other endianness variants are added they must be added here as well */
9938 if(tng_data
->output_endianness_swap_func_64
==
9939 &tng_swap_byte_order_big_endian_64
)
9941 end_64
= TNG_BIG_ENDIAN_64
;
9943 else if(tng_data
->output_endianness_swap_func_64
==
9944 &tng_swap_byte_order_little_endian_64
)
9946 end_64
= TNG_LITTLE_ENDIAN_64
;
9950 return(TNG_FAILURE
);
9955 end_64
= (tng_endianness_64
)tng_data
->endianness_64
;
9958 if((int)end_32
!= (int)end_64
)
9960 return(TNG_FAILURE
);
9963 if(end_32
== TNG_LITTLE_ENDIAN_32
)
9965 *endianness
= TNG_LITTLE_ENDIAN
;
9968 else if(end_32
== TNG_BIG_ENDIAN_32
)
9970 *endianness
= TNG_BIG_ENDIAN
;
9974 return(TNG_FAILURE
);
9977 return(TNG_SUCCESS
);
9980 tng_function_status DECLSPECDLLEXPORT tng_output_file_endianness_set
9981 (tng_trajectory_t tng_data
,
9982 const tng_file_endianness endianness
)
9984 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
9986 /* Tne endianness cannot be changed if the data has already been written
9987 * to the output file. */
9988 if(ftell(tng_data
->output_file
) > 0)
9990 return(TNG_FAILURE
);
9993 if(endianness
== TNG_BIG_ENDIAN
)
9995 if(tng_data
->endianness_32
== TNG_BIG_ENDIAN_32
)
9997 tng_data
->output_endianness_swap_func_32
= 0;
10001 tng_data
->output_endianness_swap_func_32
=
10002 &tng_swap_byte_order_big_endian_32
;
10004 if(tng_data
->endianness_64
== TNG_BIG_ENDIAN_64
)
10006 tng_data
->output_endianness_swap_func_64
= 0;
10010 tng_data
->output_endianness_swap_func_64
=
10011 &tng_swap_byte_order_big_endian_64
;
10013 return(TNG_SUCCESS
);
10015 else if(endianness
== TNG_LITTLE_ENDIAN
)
10017 if(tng_data
->endianness_32
== TNG_LITTLE_ENDIAN_32
)
10019 tng_data
->output_endianness_swap_func_32
= 0;
10023 tng_data
->output_endianness_swap_func_32
=
10024 &tng_swap_byte_order_little_endian_32
;
10026 if(tng_data
->endianness_64
== TNG_LITTLE_ENDIAN_64
)
10028 tng_data
->output_endianness_swap_func_64
= 0;
10032 tng_data
->output_endianness_swap_func_64
=
10033 &tng_swap_byte_order_little_endian_64
;
10035 return(TNG_SUCCESS
);
10038 /* If the specified endianness is neither big nor little endian return a
10040 return(TNG_FAILURE
);
10043 tng_function_status DECLSPECDLLEXPORT tng_first_program_name_get
10044 (const tng_trajectory_t tng_data
,
10045 char *name
, const int max_len
)
10047 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10048 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
10050 strncpy(name
, tng_data
->first_program_name
, max_len
- 1);
10051 name
[max_len
- 1] = 0;
10053 if(strlen(tng_data
->first_program_name
) > (unsigned int)max_len
- 1)
10055 return(TNG_FAILURE
);
10057 return(TNG_SUCCESS
);
10060 tng_function_status DECLSPECDLLEXPORT
tng_first_program_name_set(tng_trajectory_t tng_data
,
10061 const char *new_name
)
10065 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10066 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer");
10068 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
10070 if(tng_data
->first_program_name
&& strlen(tng_data
->first_program_name
) < len
)
10072 free(tng_data
->first_program_name
);
10073 tng_data
->first_program_name
= 0;
10075 if(!tng_data
->first_program_name
)
10077 tng_data
->first_program_name
= malloc(len
);
10078 if(!tng_data
->first_program_name
)
10080 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
10081 __FILE__
, __LINE__
);
10082 return(TNG_CRITICAL
);
10086 strncpy(tng_data
->first_program_name
, new_name
, len
);
10088 return(TNG_SUCCESS
);
10091 tng_function_status DECLSPECDLLEXPORT tng_last_program_name_get
10092 (const tng_trajectory_t tng_data
,
10093 char *name
, const int max_len
)
10095 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10096 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
10098 strncpy(name
, tng_data
->last_program_name
, max_len
- 1);
10099 name
[max_len
- 1] = 0;
10101 if(strlen(tng_data
->last_program_name
) > (unsigned int)max_len
- 1)
10103 return(TNG_FAILURE
);
10105 return(TNG_SUCCESS
);
10108 tng_function_status DECLSPECDLLEXPORT tng_last_program_name_set
10109 (tng_trajectory_t tng_data
,
10110 const char *new_name
)
10114 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10115 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer");
10117 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
10119 if(tng_data
->last_program_name
&& strlen(tng_data
->last_program_name
) < len
)
10121 free(tng_data
->last_program_name
);
10122 tng_data
->last_program_name
= 0;
10124 if(!tng_data
->last_program_name
)
10126 tng_data
->last_program_name
= malloc(len
);
10127 if(!tng_data
->last_program_name
)
10129 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
10130 __FILE__
, __LINE__
);
10131 return(TNG_CRITICAL
);
10135 strncpy(tng_data
->last_program_name
, new_name
, len
);
10137 return(TNG_SUCCESS
);
10140 tng_function_status DECLSPECDLLEXPORT tng_first_user_name_get
10141 (const tng_trajectory_t tng_data
,
10142 char *name
, const int max_len
)
10144 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10145 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
10147 strncpy(name
, tng_data
->first_user_name
, max_len
- 1);
10148 name
[max_len
- 1] = 0;
10150 if(strlen(tng_data
->first_user_name
) > (unsigned int)max_len
- 1)
10152 return(TNG_FAILURE
);
10154 return(TNG_SUCCESS
);
10157 tng_function_status DECLSPECDLLEXPORT tng_first_user_name_set
10158 (tng_trajectory_t tng_data
,
10159 const char *new_name
)
10163 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10164 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer");
10166 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
10168 /* If the currently stored string length is not enough to store the new
10169 * string it is freed and reallocated. */
10170 if(tng_data
->first_user_name
&& strlen(tng_data
->first_user_name
) < len
)
10172 free(tng_data
->first_user_name
);
10173 tng_data
->first_user_name
= 0;
10175 if(!tng_data
->first_user_name
)
10177 tng_data
->first_user_name
= malloc(len
);
10178 if(!tng_data
->first_user_name
)
10180 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
10181 __FILE__
, __LINE__
);
10182 return(TNG_CRITICAL
);
10186 strncpy(tng_data
->first_user_name
, new_name
, len
);
10188 return(TNG_SUCCESS
);
10191 tng_function_status DECLSPECDLLEXPORT tng_last_user_name_get
10192 (const tng_trajectory_t tng_data
,
10193 char *name
, const int max_len
)
10195 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10196 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
10198 strncpy(name
, tng_data
->last_user_name
, max_len
- 1);
10199 name
[max_len
- 1] = 0;
10201 if(strlen(tng_data
->last_user_name
) > (unsigned int)max_len
- 1)
10203 return(TNG_FAILURE
);
10205 return(TNG_SUCCESS
);
10208 tng_function_status DECLSPECDLLEXPORT tng_last_user_name_set
10209 (tng_trajectory_t tng_data
,
10210 const char *new_name
)
10214 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10215 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer");
10217 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
10219 /* If the currently stored string length is not enough to store the new
10220 * string it is freed and reallocated. */
10221 if(tng_data
->last_user_name
&& strlen(tng_data
->last_user_name
) < len
)
10223 free(tng_data
->last_user_name
);
10224 tng_data
->last_user_name
= 0;
10226 if(!tng_data
->last_user_name
)
10228 tng_data
->last_user_name
= malloc(len
);
10229 if(!tng_data
->last_user_name
)
10231 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
10232 __FILE__
, __LINE__
);
10233 return(TNG_CRITICAL
);
10237 strncpy(tng_data
->last_user_name
, new_name
, len
);
10239 return(TNG_SUCCESS
);
10242 tng_function_status DECLSPECDLLEXPORT tng_first_computer_name_get
10243 (const tng_trajectory_t tng_data
,
10244 char *name
, const int max_len
)
10246 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10247 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
10249 strncpy(name
, tng_data
->first_computer_name
, max_len
- 1);
10250 name
[max_len
- 1] = 0;
10252 if(strlen(tng_data
->first_computer_name
) > (unsigned int)max_len
- 1)
10254 return(TNG_FAILURE
);
10256 return(TNG_SUCCESS
);
10259 tng_function_status DECLSPECDLLEXPORT tng_first_computer_name_set
10260 (tng_trajectory_t tng_data
,
10261 const char *new_name
)
10265 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10266 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer");
10268 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
10270 /* If the currently stored string length is not enough to store the new
10271 * string it is freed and reallocated. */
10272 if(tng_data
->first_computer_name
&& strlen(tng_data
->first_computer_name
) < len
)
10274 free(tng_data
->first_computer_name
);
10275 tng_data
->first_computer_name
= 0;
10277 if(!tng_data
->first_computer_name
)
10279 tng_data
->first_computer_name
= malloc(len
);
10280 if(!tng_data
->first_computer_name
)
10282 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
10283 __FILE__
, __LINE__
);
10284 return(TNG_CRITICAL
);
10288 strncpy(tng_data
->first_computer_name
, new_name
, len
);
10290 return(TNG_SUCCESS
);
10293 tng_function_status DECLSPECDLLEXPORT tng_last_computer_name_get
10294 (const tng_trajectory_t tng_data
,
10295 char *name
, const int max_len
)
10297 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10298 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
10300 strncpy(name
, tng_data
->last_computer_name
, max_len
- 1);
10301 name
[max_len
- 1] = 0;
10303 if(strlen(tng_data
->last_computer_name
) > (unsigned int)max_len
- 1)
10305 return(TNG_FAILURE
);
10307 return(TNG_SUCCESS
);
10310 tng_function_status DECLSPECDLLEXPORT tng_last_computer_name_set
10311 (tng_trajectory_t tng_data
,
10312 const char *new_name
)
10316 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10317 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer");
10319 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
10321 /* If the currently stored string length is not enough to store the new
10322 * string it is freed and reallocated. */
10323 if(tng_data
->last_computer_name
&& strlen(tng_data
->last_computer_name
) <
10326 free(tng_data
->last_computer_name
);
10327 tng_data
->last_computer_name
= 0;
10329 if(!tng_data
->last_computer_name
)
10331 tng_data
->last_computer_name
= malloc(len
);
10332 if(!tng_data
->last_computer_name
)
10334 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
10335 __FILE__
, __LINE__
);
10336 return(TNG_CRITICAL
);
10340 strncpy(tng_data
->last_computer_name
, new_name
, len
);
10342 return(TNG_SUCCESS
);
10345 tng_function_status DECLSPECDLLEXPORT tng_first_signature_get
10346 (const tng_trajectory_t tng_data
,
10347 char *signature
, const int max_len
)
10349 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10350 TNG_ASSERT(signature
, "TNG library: signature must not be a NULL pointer");
10352 strncpy(signature
, tng_data
->first_pgp_signature
, max_len
- 1);
10353 signature
[max_len
- 1] = 0;
10355 if(strlen(tng_data
->first_pgp_signature
) > (unsigned int)max_len
- 1)
10357 return(TNG_FAILURE
);
10359 return(TNG_SUCCESS
);
10362 tng_function_status DECLSPECDLLEXPORT tng_first_signature_set
10363 (tng_trajectory_t tng_data
,
10364 const char *signature
)
10368 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10369 TNG_ASSERT(signature
, "TNG library: signature must not be a NULL pointer");
10371 len
= tng_min_i((int)strlen(signature
) + 1, TNG_MAX_STR_LEN
);
10373 /* If the currently stored string length is not enough to store the new
10374 * string it is freed and reallocated. */
10375 if(tng_data
->first_pgp_signature
&& strlen(tng_data
->first_pgp_signature
) <
10378 free(tng_data
->first_pgp_signature
);
10379 tng_data
->first_pgp_signature
= 0;
10381 if(!tng_data
->first_pgp_signature
)
10383 tng_data
->first_pgp_signature
= malloc(len
);
10384 if(!tng_data
->first_pgp_signature
)
10386 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
10387 __FILE__
, __LINE__
);
10388 return(TNG_CRITICAL
);
10392 strncpy(tng_data
->first_pgp_signature
, signature
, len
);
10394 return(TNG_SUCCESS
);
10397 tng_function_status DECLSPECDLLEXPORT tng_last_signature_get
10398 (const tng_trajectory_t tng_data
,
10399 char *signature
, const int max_len
)
10401 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10402 TNG_ASSERT(signature
, "TNG library: signature must not be a NULL pointer");
10404 strncpy(signature
, tng_data
->last_pgp_signature
, max_len
- 1);
10405 signature
[max_len
- 1] = 0;
10407 if(strlen(tng_data
->last_pgp_signature
) > (unsigned int)max_len
- 1)
10409 return(TNG_FAILURE
);
10411 return(TNG_SUCCESS
);
10414 tng_function_status DECLSPECDLLEXPORT tng_last_signature_set
10415 (tng_trajectory_t tng_data
,
10416 const char *signature
)
10420 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10421 TNG_ASSERT(signature
, "TNG library: signature must not be a NULL pointer");
10423 len
= tng_min_i((int)strlen(signature
) + 1, TNG_MAX_STR_LEN
);
10425 /* If the currently stored string length is not enough to store the new
10426 * string it is freed and reallocated. */
10427 if(tng_data
->last_pgp_signature
&& strlen(tng_data
->last_pgp_signature
) <
10430 free(tng_data
->last_pgp_signature
);
10431 tng_data
->last_pgp_signature
= 0;
10433 if(!tng_data
->last_pgp_signature
)
10435 tng_data
->last_pgp_signature
= malloc(len
);
10436 if(!tng_data
->last_pgp_signature
)
10438 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
10439 __FILE__
, __LINE__
);
10440 return(TNG_CRITICAL
);
10444 strncpy(tng_data
->last_pgp_signature
, signature
, len
);
10446 return(TNG_SUCCESS
);
10449 tng_function_status DECLSPECDLLEXPORT tng_forcefield_name_get
10450 (const tng_trajectory_t tng_data
,
10451 char *name
, const int max_len
)
10453 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10454 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer");
10456 strncpy(name
, tng_data
->forcefield_name
, max_len
- 1);
10457 name
[max_len
- 1] = 0;
10459 if(strlen(tng_data
->forcefield_name
) > (unsigned int)max_len
- 1)
10461 return(TNG_FAILURE
);
10463 return(TNG_SUCCESS
);
10466 tng_function_status DECLSPECDLLEXPORT tng_forcefield_name_set
10467 (tng_trajectory_t tng_data
,
10468 const char *new_name
)
10472 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10473 TNG_ASSERT(new_name
, "TNG library: new_name must not be a NULL pointer");
10475 len
= tng_min_i((int)strlen(new_name
) + 1, TNG_MAX_STR_LEN
);
10477 /* If the currently stored string length is not enough to store the new
10478 * string it is freed and reallocated. */
10479 if(tng_data
->forcefield_name
&& strlen(tng_data
->forcefield_name
) < len
)
10481 free(tng_data
->forcefield_name
);
10482 tng_data
->forcefield_name
= 0;
10484 if(!tng_data
->forcefield_name
)
10486 tng_data
->forcefield_name
= malloc(len
);
10487 if(!tng_data
->forcefield_name
)
10489 fprintf(stderr
, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len
,
10490 __FILE__
, __LINE__
);
10491 return(TNG_CRITICAL
);
10495 strncpy(tng_data
->forcefield_name
, new_name
, len
);
10497 return(TNG_SUCCESS
);
10500 tng_function_status DECLSPECDLLEXPORT tng_medium_stride_length_get
10501 (const tng_trajectory_t tng_data
,
10504 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10505 TNG_ASSERT(len
, "TNG library: len must not be a NULL pointer");
10507 *len
= tng_data
->medium_stride_length
;
10509 return(TNG_SUCCESS
);
10512 tng_function_status DECLSPECDLLEXPORT tng_medium_stride_length_set
10513 (tng_trajectory_t tng_data
,
10516 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10518 if(len
>= tng_data
->long_stride_length
)
10520 return(TNG_FAILURE
);
10522 tng_data
->medium_stride_length
= len
;
10524 return(TNG_SUCCESS
);
10527 tng_function_status DECLSPECDLLEXPORT tng_long_stride_length_get
10528 (const tng_trajectory_t tng_data
,
10531 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10532 TNG_ASSERT(len
, "TNG library: len must not be a NULL pointer");
10534 *len
= tng_data
->long_stride_length
;
10536 return(TNG_SUCCESS
);
10539 tng_function_status DECLSPECDLLEXPORT tng_long_stride_length_set
10540 (tng_trajectory_t tng_data
,
10543 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10545 if(len
<= tng_data
->medium_stride_length
)
10547 return(TNG_FAILURE
);
10549 tng_data
->long_stride_length
= len
;
10551 return(TNG_SUCCESS
);
10554 tng_function_status DECLSPECDLLEXPORT tng_time_per_frame_get
10555 (const tng_trajectory_t tng_data
,
10558 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10559 TNG_ASSERT(time
, "TNG library: time must not be a NULL pointer");
10561 *time
= tng_data
->time_per_frame
;
10563 return(TNG_SUCCESS
);
10566 tng_function_status DECLSPECDLLEXPORT tng_time_per_frame_set
10567 (tng_trajectory_t tng_data
,
10570 tng_trajectory_frame_set_t frame_set
;
10572 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10573 TNG_ASSERT(time
>= 0, "TNG library: The time per frame must be >= 0.");
10575 if(fabs(time
- tng_data
->time_per_frame
) < 0.00001)
10577 return(TNG_SUCCESS
);
10580 frame_set
= &tng_data
->current_trajectory_frame_set
;
10582 /* If the current frame set is not finished write it to disk before
10583 changing time per frame. */
10584 if(tng_data
->time_per_frame
> 0 && frame_set
->n_unwritten_frames
> 0)
10586 frame_set
->n_frames
= frame_set
->n_unwritten_frames
;
10587 tng_frame_set_write(tng_data
, TNG_USE_HASH
);
10589 tng_data
->time_per_frame
= time
;
10591 return(TNG_SUCCESS
);
10594 tng_function_status DECLSPECDLLEXPORT tng_input_file_len_get
10595 (const tng_trajectory_t tng_data
,
10598 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10599 TNG_ASSERT(len
, "TNG library: len must not be a NULL pointer");
10601 *len
= tng_data
->input_file_len
;
10603 return(TNG_SUCCESS
);
10606 tng_function_status DECLSPECDLLEXPORT tng_num_frames_get
10607 (const tng_trajectory_t tng_data
,
10610 tng_gen_block_t block
;
10611 tng_function_status stat
;
10613 int64_t last_file_pos
, first_frame
, n_frames
;
10615 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10616 TNG_ASSERT(tng_data
->input_file
, "TNG library: An input file must be open to find the next frame set");
10617 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
10619 file_pos
= ftell(tng_data
->input_file
);
10620 last_file_pos
= tng_data
->last_trajectory_frame_set_input_file_pos
;
10622 if(last_file_pos
<= 0)
10624 return(TNG_FAILURE
);
10627 tng_block_init(&block
);
10628 fseek(tng_data
->input_file
,
10629 (long)last_file_pos
,
10631 /* Read block headers first to see that a frame set block is found. */
10632 stat
= tng_block_header_read(tng_data
, block
);
10633 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
10635 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n", last_file_pos
,
10636 __FILE__
, __LINE__
);
10637 tng_block_destroy(&block
);
10638 return(TNG_FAILURE
);
10640 tng_block_destroy(&block
);
10642 if(fread(&first_frame
, sizeof(int64_t), 1, tng_data
->input_file
) == 0)
10644 fprintf(stderr
, "TNG library: Cannot read first frame of frame set. %s: %d\n",
10645 __FILE__
, __LINE__
);
10646 return(TNG_CRITICAL
);
10648 if(fread(&n_frames
, sizeof(int64_t), 1, tng_data
->input_file
) == 0)
10650 fprintf(stderr
, "TNG library: Cannot read n frames of frame set. %s: %d\n",
10651 __FILE__
, __LINE__
);
10652 return(TNG_CRITICAL
);
10654 fseek(tng_data
->input_file
, file_pos
, SEEK_SET
);
10656 *n
= first_frame
+ n_frames
;
10658 return(TNG_SUCCESS
);
10661 tng_function_status DECLSPECDLLEXPORT tng_compression_precision_get
10662 (const tng_trajectory_t tng_data
,
10665 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10667 *precision
= tng_data
->compression_precision
;
10669 return(TNG_SUCCESS
);
10672 tng_function_status DECLSPECDLLEXPORT tng_compression_precision_set
10673 (tng_trajectory_t tng_data
,
10674 const double precision
)
10676 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10678 tng_data
->compression_precision
= precision
;
10680 return(TNG_SUCCESS
);
10683 tng_function_status DECLSPECDLLEXPORT tng_implicit_num_particles_set
10684 (tng_trajectory_t tng_data
,
10687 tng_molecule_t mol
;
10691 tng_function_status stat
;
10692 int64_t diff
, n_mod
, n_impl
;
10694 TNG_ASSERT(n
>= 0, "TNG library: The number of molecules must be >= 0");
10696 diff
= n
- tng_data
->n_particles
;
10698 stat
= tng_molecule_find(tng_data
, "TNG_IMPLICIT_MOL", -1, &mol
);
10699 if(stat
== TNG_SUCCESS
)
10701 if(tng_molecule_cnt_get(tng_data
, mol
, &n_impl
) != TNG_SUCCESS
)
10703 fprintf(stderr
, "TNG library: Cannot get the number of implicit molecules. %s: %d\n",
10704 __FILE__
, __LINE__
);
10705 return(TNG_FAILURE
);
10707 diff
-= n_impl
* mol
->n_atoms
;
10712 if(stat
== TNG_SUCCESS
)
10714 stat
= tng_molecule_cnt_set(tng_data
, mol
, 0);
10717 return(TNG_SUCCESS
);
10721 fprintf(stderr
, "TNG library: Already more actual particles than requested implicit ");
10722 fprintf(stderr
, "particle count.\n");
10723 fprintf(stderr
, "TNG library: Cannot set implicit particle count. %s: %d\n",
10724 __FILE__
, __LINE__
);
10725 /* FIXME: Should we set the count of all other molecules to 0 and add
10726 * implicit molecules? */
10727 return(TNG_FAILURE
);
10729 if(stat
!= TNG_SUCCESS
)
10731 stat
= tng_molecule_add(tng_data
,
10732 "TNG_IMPLICIT_MOL",
10734 if(stat
!= TNG_SUCCESS
)
10738 stat
= tng_molecule_chain_add(tng_data
, mol
, "", &chain
);
10739 if(stat
!= TNG_SUCCESS
)
10743 stat
= tng_chain_residue_add(tng_data
, chain
, "", &res
);
10744 if(stat
!= TNG_SUCCESS
)
10748 stat
= tng_residue_atom_add(tng_data
, res
, "", "", &atom
);
10749 if(stat
!= TNG_SUCCESS
)
10756 if(mol
->n_atoms
> 1)
10758 n_mod
= diff
% mol
->n_atoms
;
10761 fprintf(stderr
, "TNG library: Number of atoms in implicit molecule ");
10762 fprintf(stderr
, "not compatible with requested implicit particle cnt.\n");
10763 fprintf(stderr
, "TNG library: Cannot set implicit particle count. %s: %d\n",
10764 __FILE__
, __LINE__
);
10765 return(TNG_FAILURE
);
10767 diff
/= mol
->n_atoms
;
10770 stat
= tng_molecule_cnt_set(tng_data
, mol
, diff
);
10775 tng_function_status DECLSPECDLLEXPORT tng_num_particles_get
10776 (const tng_trajectory_t tng_data
,
10779 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10780 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
10782 if(tng_data
->var_num_atoms_flag
== TNG_CONSTANT_N_ATOMS
)
10784 *n
= tng_data
->n_particles
;
10788 *n
= tng_data
->current_trajectory_frame_set
.n_particles
;
10791 return(TNG_SUCCESS
);
10794 tng_function_status DECLSPECDLLEXPORT tng_num_particles_variable_get
10795 (const tng_trajectory_t tng_data
,
10798 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10799 TNG_ASSERT(variable
, "TNG library: variable must not be a NULL pointer");
10801 *variable
= tng_data
->var_num_atoms_flag
;
10803 return(TNG_SUCCESS
);
10806 tng_function_status DECLSPECDLLEXPORT tng_num_molecule_types_get
10807 (const tng_trajectory_t tng_data
,
10810 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10811 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
10813 *n
= tng_data
->n_molecules
;
10815 return(TNG_SUCCESS
);
10818 tng_function_status DECLSPECDLLEXPORT tng_num_molecules_get
10819 (const tng_trajectory_t tng_data
,
10822 int64_t *cnt_list
= 0, cnt
= 0, i
;
10824 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10825 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
10827 tng_molecule_cnt_list_get(tng_data
, &cnt_list
);
10831 return(TNG_FAILURE
);
10834 for(i
= tng_data
->n_molecules
; i
--;)
10836 cnt
+= cnt_list
[i
];
10841 return(TNG_SUCCESS
);
10844 tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_list_get
10845 (const tng_trajectory_t tng_data
,
10846 int64_t **mol_cnt_list
)
10848 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10850 if(tng_data
->var_num_atoms_flag
)
10852 *mol_cnt_list
= tng_data
->current_trajectory_frame_set
.
10857 *mol_cnt_list
= tng_data
->molecule_cnt_list
;
10859 if(*mol_cnt_list
== 0)
10861 return(TNG_FAILURE
);
10863 return(TNG_SUCCESS
);
10866 tng_function_status DECLSPECDLLEXPORT tng_distance_unit_exponential_get
10867 (const tng_trajectory_t tng_data
,
10870 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10871 TNG_ASSERT(exp
, "TNG library: exp must not be a NULL pointer");
10873 *exp
= tng_data
->distance_unit_exponential
;
10875 return(TNG_SUCCESS
);
10878 tng_function_status DECLSPECDLLEXPORT tng_distance_unit_exponential_set
10879 (const tng_trajectory_t tng_data
,
10882 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10884 tng_data
->distance_unit_exponential
= exp
;
10886 return(TNG_SUCCESS
);
10889 tng_function_status DECLSPECDLLEXPORT tng_num_frames_per_frame_set_get
10890 (const tng_trajectory_t tng_data
,
10893 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10894 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
10896 *n
= tng_data
->frame_set_n_frames
;
10898 return(TNG_SUCCESS
);
10901 tng_function_status DECLSPECDLLEXPORT tng_num_frames_per_frame_set_set
10902 (const tng_trajectory_t tng_data
,
10905 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10907 tng_data
->frame_set_n_frames
= n
;
10909 return(TNG_SUCCESS
);
10912 tng_function_status DECLSPECDLLEXPORT tng_num_frame_sets_get
10913 (const tng_trajectory_t tng_data
,
10916 int64_t long_stride_length
, medium_stride_length
;
10917 long file_pos
, orig_frame_set_file_pos
;
10918 tng_trajectory_frame_set_t frame_set
;
10919 struct tng_trajectory_frame_set orig_frame_set
;
10920 tng_gen_block_t block
;
10921 tng_function_status stat
;
10924 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
10925 TNG_ASSERT(n
, "TNG library: n must not be a NULL pointer");
10927 orig_frame_set
= tng_data
->current_trajectory_frame_set
;
10929 frame_set
= &tng_data
->current_trajectory_frame_set
;
10931 orig_frame_set_file_pos
= tng_data
->current_trajectory_frame_set_input_file_pos
;
10932 file_pos
= (long)tng_data
->first_trajectory_frame_set_input_file_pos
;
10934 tng_block_init(&block
);
10935 fseek(tng_data
->input_file
,
10938 tng_data
->current_trajectory_frame_set_input_file_pos
= file_pos
;
10939 /* Read block headers first to see what block is found. */
10940 stat
= tng_block_header_read(tng_data
, block
);
10941 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
10943 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n", file_pos
,
10944 __FILE__
, __LINE__
);
10945 tng_block_destroy(&block
);
10946 return(TNG_CRITICAL
);
10949 if(tng_block_read_next(tng_data
, block
,
10950 TNG_SKIP_HASH
) != TNG_SUCCESS
)
10952 tng_block_destroy(&block
);
10953 return(TNG_CRITICAL
);
10958 long_stride_length
= tng_data
->long_stride_length
;
10959 medium_stride_length
= tng_data
->medium_stride_length
;
10961 /* Take long steps forward until a long step forward would be too long or
10962 * the last frame set is found */
10963 file_pos
= (long)frame_set
->long_stride_next_frame_set_file_pos
;
10964 while(file_pos
> 0)
10968 cnt
+= long_stride_length
;
10969 fseek(tng_data
->input_file
, file_pos
, SEEK_SET
);
10970 /* Read block headers first to see what block is found. */
10971 stat
= tng_block_header_read(tng_data
, block
);
10972 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
10974 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
10975 file_pos
, __FILE__
, __LINE__
);
10976 tng_block_destroy(&block
);
10977 return(TNG_CRITICAL
);
10980 if(tng_block_read_next(tng_data
, block
,
10981 TNG_SKIP_HASH
) != TNG_SUCCESS
)
10983 tng_block_destroy(&block
);
10984 return(TNG_CRITICAL
);
10987 file_pos
= (long)frame_set
->long_stride_next_frame_set_file_pos
;
10990 /* Take medium steps forward until a medium step forward would be too long
10991 * or the last frame set is found */
10992 file_pos
= (long)frame_set
->medium_stride_next_frame_set_file_pos
;
10993 while(file_pos
> 0)
10997 cnt
+= medium_stride_length
;
10998 fseek(tng_data
->input_file
,
11001 /* Read block headers first to see what block is found. */
11002 stat
= tng_block_header_read(tng_data
, block
);
11003 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11005 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
11006 file_pos
, __FILE__
, __LINE__
);
11007 tng_block_destroy(&block
);
11008 return(TNG_CRITICAL
);
11011 if(tng_block_read_next(tng_data
, block
,
11012 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11014 tng_block_destroy(&block
);
11015 return(TNG_CRITICAL
);
11018 file_pos
= (long)frame_set
->medium_stride_next_frame_set_file_pos
;
11021 /* Take one step forward until the last frame set is found */
11022 file_pos
= (long)frame_set
->next_frame_set_file_pos
;
11023 while(file_pos
> 0)
11028 fseek(tng_data
->input_file
,
11031 /* Read block headers first to see what block is found. */
11032 stat
= tng_block_header_read(tng_data
, block
);
11033 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11035 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
11036 file_pos
, __FILE__
, __LINE__
);
11037 tng_block_destroy(&block
);
11038 return(TNG_CRITICAL
);
11041 if(tng_block_read_next(tng_data
, block
,
11042 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11044 tng_block_destroy(&block
);
11045 return(TNG_CRITICAL
);
11048 file_pos
= (long)frame_set
->next_frame_set_file_pos
;
11051 tng_block_destroy(&block
);
11053 *n
= tng_data
->n_trajectory_frame_sets
= cnt
;
11055 *frame_set
= orig_frame_set
;
11057 fseek(tng_data
->input_file
,
11058 (long)tng_data
->first_trajectory_frame_set_input_file_pos
,
11061 tng_data
->current_trajectory_frame_set_input_file_pos
= orig_frame_set_file_pos
;
11063 return(TNG_SUCCESS
);
11066 tng_function_status DECLSPECDLLEXPORT tng_current_frame_set_get
11067 (const tng_trajectory_t tng_data
,
11068 tng_trajectory_frame_set_t
*frame_set_p
)
11070 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
11072 *frame_set_p
= &tng_data
->current_trajectory_frame_set
;
11074 return(TNG_SUCCESS
);
11077 tng_function_status DECLSPECDLLEXPORT tng_frame_set_nr_find
11078 (tng_trajectory_t tng_data
,
11081 int64_t long_stride_length
, medium_stride_length
;
11082 int64_t file_pos
, curr_nr
= 0, n_frame_sets
;
11083 tng_trajectory_frame_set_t frame_set
;
11084 tng_gen_block_t block
;
11085 tng_function_status stat
;
11087 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
11088 TNG_ASSERT(nr
>= 0, "The frame set number (nr) must be >= 0");
11090 frame_set
= &tng_data
->current_trajectory_frame_set
;
11092 stat
= tng_num_frame_sets_get(tng_data
, &n_frame_sets
);
11094 if(stat
!= TNG_SUCCESS
)
11099 if(nr
>= n_frame_sets
)
11101 return(TNG_FAILURE
);
11104 long_stride_length
= tng_data
->long_stride_length
;
11105 medium_stride_length
= tng_data
->medium_stride_length
;
11107 /* FIXME: The frame set number of the current frame set is not stored */
11109 if(nr
< n_frame_sets
- 1 - nr
)
11111 /* Start from the beginning */
11112 file_pos
= tng_data
->first_trajectory_frame_set_input_file_pos
;
11116 /* Start from the end */
11117 file_pos
= tng_data
->last_trajectory_frame_set_input_file_pos
;
11118 curr_nr
= n_frame_sets
- 1;
11122 return(TNG_FAILURE
);
11125 tng_block_init(&block
);
11126 fseek(tng_data
->input_file
,
11129 tng_data
->current_trajectory_frame_set_input_file_pos
= (long)file_pos
;
11130 /* Read block headers first to see what block is found. */
11131 stat
= tng_block_header_read(tng_data
, block
);
11132 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11134 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n", file_pos
,
11135 __FILE__
, __LINE__
);
11136 tng_block_destroy(&block
);
11137 return(TNG_CRITICAL
);
11140 if(tng_block_read_next(tng_data
, block
,
11141 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11143 tng_block_destroy(&block
);
11144 return(TNG_CRITICAL
);
11149 tng_block_destroy(&block
);
11150 return(TNG_SUCCESS
);
11153 file_pos
= tng_data
->current_trajectory_frame_set_input_file_pos
;
11155 /* Take long steps forward until a long step forward would be too long or
11156 * the right frame set is found */
11157 while(file_pos
> 0 && curr_nr
+ long_stride_length
<= nr
)
11159 file_pos
= frame_set
->long_stride_next_frame_set_file_pos
;
11162 curr_nr
+= long_stride_length
;
11163 fseek(tng_data
->input_file
, (long)file_pos
, SEEK_SET
);
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 medium steps forward until a medium step forward would be too long
11189 * or the right frame set is found */
11190 while(file_pos
> 0 && curr_nr
+ medium_stride_length
<= nr
)
11192 file_pos
= frame_set
->medium_stride_next_frame_set_file_pos
;
11195 curr_nr
+= medium_stride_length
;
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 one step forward until the right frame set is found */
11224 while(file_pos
> 0 && curr_nr
< nr
)
11226 file_pos
= frame_set
->next_frame_set_file_pos
;
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 long steps backward until a long step backward would be too long
11259 * or the right frame set is found */
11260 while(file_pos
> 0 && curr_nr
- long_stride_length
>= nr
)
11262 file_pos
= frame_set
->long_stride_prev_frame_set_file_pos
;
11265 curr_nr
-= long_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 medium steps backward until a medium step backward would be too long
11294 * or the right frame set is found */
11295 while(file_pos
> 0 && curr_nr
- medium_stride_length
>= nr
)
11297 file_pos
= frame_set
->medium_stride_prev_frame_set_file_pos
;
11300 curr_nr
-= medium_stride_length
;
11301 fseek(tng_data
->input_file
,
11304 /* Read block headers first to see what block is found. */
11305 stat
= tng_block_header_read(tng_data
, block
);
11306 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11308 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11309 file_pos
, __FILE__
, __LINE__
);
11310 tng_block_destroy(&block
);
11311 return(TNG_CRITICAL
);
11314 if(tng_block_read_next(tng_data
, block
,
11315 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11317 tng_block_destroy(&block
);
11318 return(TNG_CRITICAL
);
11322 tng_block_destroy(&block
);
11323 return(TNG_SUCCESS
);
11328 /* Take one step backward until the right frame set is found */
11329 while(file_pos
> 0 && curr_nr
> nr
)
11331 file_pos
= frame_set
->prev_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 /* If for some reason the current frame set is not yet found,
11363 * take one step forward until the right frame set is found */
11364 while(file_pos
> 0 && curr_nr
< nr
)
11366 file_pos
= frame_set
->next_frame_set_file_pos
;
11370 fseek(tng_data
->input_file
,
11373 /* Read block headers first to see what block is found. */
11374 stat
= tng_block_header_read(tng_data
, block
);
11375 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11377 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11378 file_pos
, __FILE__
, __LINE__
);
11379 tng_block_destroy(&block
);
11380 return(TNG_CRITICAL
);
11383 if(tng_block_read_next(tng_data
, block
,
11384 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11386 tng_block_destroy(&block
);
11387 return(TNG_CRITICAL
);
11391 tng_block_destroy(&block
);
11392 return(TNG_SUCCESS
);
11397 tng_block_destroy(&block
);
11398 return(TNG_FAILURE
);
11401 tng_function_status DECLSPECDLLEXPORT tng_frame_set_of_frame_find
11402 (tng_trajectory_t tng_data
,
11403 const int64_t frame
)
11405 int64_t first_frame
, last_frame
, n_frames_per_frame_set
;
11406 int64_t long_stride_length
, medium_stride_length
;
11407 int64_t file_pos
, temp_frame
, n_frames
;
11408 tng_trajectory_frame_set_t frame_set
;
11409 tng_gen_block_t block
;
11410 tng_function_status stat
;
11412 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
11413 TNG_ASSERT(frame
>= 0, "TNG library: frame must be >= 0.");
11415 frame_set
= &tng_data
->current_trajectory_frame_set
;
11417 tng_block_init(&block
);
11419 if(tng_data
->current_trajectory_frame_set_input_file_pos
< 0)
11421 file_pos
= tng_data
->first_trajectory_frame_set_input_file_pos
;
11422 fseek(tng_data
->input_file
,
11425 tng_data
->current_trajectory_frame_set_input_file_pos
= (long)file_pos
;
11426 /* Read block headers first to see what block is found. */
11427 stat
= tng_block_header_read(tng_data
, block
);
11428 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11430 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11431 file_pos
, __FILE__
, __LINE__
);
11432 tng_block_destroy(&block
);
11433 return(TNG_CRITICAL
);
11436 if(tng_block_read_next(tng_data
, block
,
11437 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11439 tng_block_destroy(&block
);
11440 return(TNG_CRITICAL
);
11444 first_frame
= tng_max_i64(frame_set
->first_frame
, 0);
11445 last_frame
= first_frame
+ frame_set
->n_frames
- 1;
11446 /* Is this the right frame set? */
11447 if(first_frame
<= frame
&& frame
<= last_frame
)
11449 tng_block_destroy(&block
);
11450 return(TNG_SUCCESS
);
11453 n_frames_per_frame_set
= tng_data
->frame_set_n_frames
;
11454 long_stride_length
= tng_data
->long_stride_length
;
11455 medium_stride_length
= tng_data
->medium_stride_length
;
11457 if(tng_first_frame_nr_of_next_frame_set_get(tng_data
, &temp_frame
) ==
11460 if(temp_frame
- first_frame
> n_frames_per_frame_set
)
11462 n_frames_per_frame_set
= temp_frame
- first_frame
;
11466 tng_num_frames_get(tng_data
, &n_frames
);
11468 if(frame
>= n_frames
)
11470 tng_block_destroy(&block
);
11471 return(TNG_FAILURE
);
11474 if(first_frame
- frame
>= frame
||
11475 frame
- last_frame
>
11476 tng_data
->n_trajectory_frame_sets
* n_frames_per_frame_set
- frame
)
11478 /* Start from the beginning */
11479 if(first_frame
- frame
>= frame
)
11481 file_pos
= tng_data
->first_trajectory_frame_set_input_file_pos
;
11485 tng_block_destroy(&block
);
11486 return(TNG_FAILURE
);
11489 /* Start from the end */
11490 else if(frame
- first_frame
> (n_frames
- 1) - frame
)
11492 file_pos
= tng_data
->last_trajectory_frame_set_input_file_pos
;
11494 /* If the last frame set position is not set start from the current
11495 * frame set, since it will be closer than the first frame set. */
11497 /* Start from current */
11500 file_pos
= tng_data
->current_trajectory_frame_set_input_file_pos
;
11505 fseek(tng_data
->input_file
,
11508 tng_data
->current_trajectory_frame_set_input_file_pos
= (long)file_pos
;
11509 /* Read block headers first to see what block is found. */
11510 stat
= tng_block_header_read(tng_data
, block
);
11511 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11513 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11514 file_pos
, __FILE__
, __LINE__
);
11515 tng_block_destroy(&block
);
11516 return(TNG_CRITICAL
);
11519 if(tng_block_read_next(tng_data
, block
,
11520 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11522 tng_block_destroy(&block
);
11523 return(TNG_CRITICAL
);
11528 first_frame
= tng_max_i64(frame_set
->first_frame
, 0);
11529 last_frame
= first_frame
+ frame_set
->n_frames
- 1;
11531 if(frame
>= first_frame
&& frame
<= last_frame
)
11533 tng_block_destroy(&block
);
11534 return(TNG_SUCCESS
);
11537 file_pos
= tng_data
->current_trajectory_frame_set_input_file_pos
;
11539 /* Take long steps forward until a long step forward would be too long or
11540 * the right frame set is found */
11541 while(file_pos
> 0 && first_frame
+ long_stride_length
*
11542 n_frames_per_frame_set
<= frame
)
11544 file_pos
= frame_set
->long_stride_next_frame_set_file_pos
;
11547 fseek(tng_data
->input_file
, (long)file_pos
, SEEK_SET
);
11548 /* Read block headers first to see what block is found. */
11549 stat
= tng_block_header_read(tng_data
, block
);
11550 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11552 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11553 file_pos
, __FILE__
, __LINE__
);
11554 tng_block_destroy(&block
);
11555 return(TNG_CRITICAL
);
11558 if(tng_block_read_next(tng_data
, block
,
11559 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11561 tng_block_destroy(&block
);
11562 return(TNG_CRITICAL
);
11565 first_frame
= tng_max_i64(frame_set
->first_frame
, 0);
11566 last_frame
= first_frame
+ frame_set
->n_frames
- 1;
11567 if(frame
>= first_frame
&& frame
<= last_frame
)
11569 tng_block_destroy(&block
);
11570 return(TNG_SUCCESS
);
11574 /* Take medium steps forward until a medium step forward would be too long
11575 * or the right frame set is found */
11576 while(file_pos
> 0 && first_frame
+ medium_stride_length
*
11577 n_frames_per_frame_set
<= frame
)
11579 file_pos
= frame_set
->medium_stride_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 one step forward until the right frame set is found */
11612 while(file_pos
> 0 && first_frame
< frame
&& last_frame
< frame
)
11614 file_pos
= frame_set
->next_frame_set_file_pos
;
11617 fseek(tng_data
->input_file
,
11620 /* Read block headers first to see what block is found. */
11621 stat
= tng_block_header_read(tng_data
, block
);
11622 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11624 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11625 file_pos
, __FILE__
, __LINE__
);
11626 tng_block_destroy(&block
);
11627 return(TNG_CRITICAL
);
11630 if(tng_block_read_next(tng_data
, block
,
11631 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11633 tng_block_destroy(&block
);
11634 return(TNG_CRITICAL
);
11637 first_frame
= tng_max_i64(frame_set
->first_frame
, 0);
11638 last_frame
= first_frame
+ frame_set
->n_frames
- 1;
11639 if(frame
>= first_frame
&& frame
<= last_frame
)
11641 tng_block_destroy(&block
);
11642 return(TNG_SUCCESS
);
11646 /* Take long steps backward until a long step backward would be too long
11647 * or the right frame set is found */
11648 while(file_pos
> 0 && first_frame
- long_stride_length
*
11649 n_frames_per_frame_set
>= frame
)
11651 file_pos
= frame_set
->long_stride_prev_frame_set_file_pos
;
11654 fseek(tng_data
->input_file
,
11657 /* Read block headers first to see what block is found. */
11658 stat
= tng_block_header_read(tng_data
, block
);
11659 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11661 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11662 file_pos
, __FILE__
, __LINE__
);
11663 tng_block_destroy(&block
);
11664 return(TNG_CRITICAL
);
11667 if(tng_block_read_next(tng_data
, block
,
11668 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11670 tng_block_destroy(&block
);
11671 return(TNG_CRITICAL
);
11674 first_frame
= tng_max_i64(frame_set
->first_frame
, 0);
11675 last_frame
= first_frame
+ frame_set
->n_frames
- 1;
11676 if(frame
>= first_frame
&& frame
<= last_frame
)
11678 tng_block_destroy(&block
);
11679 return(TNG_SUCCESS
);
11683 /* Take medium steps backward until a medium step backward would be too long
11684 * or the right frame set is found */
11685 while(file_pos
> 0 && first_frame
- medium_stride_length
*
11686 n_frames_per_frame_set
>= frame
)
11688 file_pos
= frame_set
->medium_stride_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 /* Take one step backward until the right frame set is found */
11721 while(file_pos
> 0 && first_frame
> frame
&& last_frame
> frame
)
11723 file_pos
= frame_set
->prev_frame_set_file_pos
;
11726 fseek(tng_data
->input_file
,
11729 /* Read block headers first to see what block is found. */
11730 stat
= tng_block_header_read(tng_data
, block
);
11731 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11733 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11734 file_pos
, __FILE__
, __LINE__
);
11735 tng_block_destroy(&block
);
11736 return(TNG_CRITICAL
);
11739 if(tng_block_read_next(tng_data
, block
,
11740 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11742 tng_block_destroy(&block
);
11743 return(TNG_CRITICAL
);
11746 first_frame
= tng_max_i64(frame_set
->first_frame
, 0);
11747 last_frame
= first_frame
+ frame_set
->n_frames
- 1;
11748 if(frame
>= first_frame
&& frame
<= last_frame
)
11750 tng_block_destroy(&block
);
11751 return(TNG_SUCCESS
);
11755 /* If for some reason the current frame set is not yet found,
11756 * take one step forward until the right frame set is found */
11757 while(file_pos
> 0 && first_frame
< frame
&& last_frame
< frame
)
11759 file_pos
= frame_set
->next_frame_set_file_pos
;
11762 fseek(tng_data
->input_file
,
11765 /* Read block headers first to see what block is found. */
11766 stat
= tng_block_header_read(tng_data
, block
);
11767 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11769 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
11770 file_pos
, __FILE__
, __LINE__
);
11771 tng_block_destroy(&block
);
11772 return(TNG_CRITICAL
);
11775 if(tng_block_read_next(tng_data
, block
,
11776 TNG_SKIP_HASH
) != TNG_SUCCESS
)
11778 tng_block_destroy(&block
);
11779 return(TNG_CRITICAL
);
11782 first_frame
= tng_max_i64(frame_set
->first_frame
, 0);
11783 last_frame
= first_frame
+ frame_set
->n_frames
- 1;
11784 if(frame
>= first_frame
&& frame
<= last_frame
)
11786 tng_block_destroy(&block
);
11787 return(TNG_SUCCESS
);
11791 tng_block_destroy(&block
);
11792 return(TNG_FAILURE
);
11795 tng_function_status DECLSPECDLLEXPORT tng_frame_set_next_frame_set_file_pos_get
11796 (const tng_trajectory_t tng_data
,
11797 const tng_trajectory_frame_set_t frame_set
,
11802 TNG_ASSERT(frame_set
, "TNG library: frame_set not initialised before accessing data.");
11803 TNG_ASSERT(pos
, "TNG library: pos must not be a NULL pointer");
11805 *pos
= frame_set
->next_frame_set_file_pos
;
11807 return(TNG_SUCCESS
);
11810 tng_function_status DECLSPECDLLEXPORT tng_frame_set_prev_frame_set_file_pos_get
11811 (const tng_trajectory_t tng_data
,
11812 const tng_trajectory_frame_set_t frame_set
,
11817 TNG_ASSERT(frame_set
, "TNG library: frame_set not initialised before accessing data.");
11818 TNG_ASSERT(pos
, "TNG library: pos must not be a NULL pointer");
11820 *pos
= frame_set
->prev_frame_set_file_pos
;
11822 return(TNG_SUCCESS
);
11825 tng_function_status DECLSPECDLLEXPORT tng_frame_set_frame_range_get
11826 (const tng_trajectory_t tng_data
,
11827 const tng_trajectory_frame_set_t frame_set
,
11828 int64_t *first_frame
,
11829 int64_t *last_frame
)
11833 TNG_ASSERT(first_frame
, "TNG library: first_frame must not be a NULL pointer");
11834 TNG_ASSERT(last_frame
, "TNG library: last_frame must not be a NULL pointer");
11835 TNG_ASSERT(frame_set
, "TNG library: frame_set must not be a NULL pointer");
11837 *first_frame
= frame_set
->first_frame
;
11838 *last_frame
= *first_frame
+ frame_set
->n_frames
- 1;
11840 return(TNG_SUCCESS
);
11843 /** Translate from the particle numbering used in a frame set to the real
11844 * particle numbering - used in the molecule description.
11845 * @param frame_set is the frame_set containing the mappings to use.
11846 * @param local is the index number of the atom in this frame set
11847 * @param real is set to the index of the atom in the molecular system.
11848 * @return TNG_SUCCESS (0) if successful or TNG_FAILURE (1) if the mapping
11851 static TNG_INLINE tng_function_status tng_particle_mapping_get_real_particle
11852 (const tng_trajectory_frame_set_t frame_set
,
11853 const int64_t local
,
11856 int64_t i
, n_blocks
= frame_set
->n_mapping_blocks
, first
;
11857 tng_particle_mapping_t mapping
;
11861 return(TNG_SUCCESS
);
11863 for(i
= 0; i
< n_blocks
; i
++)
11865 mapping
= &frame_set
->mappings
[i
];
11866 first
= mapping
->num_first_particle
;
11867 if(local
< first
||
11868 local
>= first
+ mapping
->n_particles
)
11872 *real
= mapping
->real_particle_numbers
[local
-first
];
11873 return(TNG_SUCCESS
);
11876 return(TNG_FAILURE
);
11879 /** Translate from the real particle numbering to the particle numbering
11880 * used in a frame set.
11881 * @param frame_set is the frame_set containing the mappings to use.
11882 * @param real is the index number of the atom in the molecular system.
11883 * @param local is set to the index of the atom in this frame set.
11884 * @return TNG_SUCCESS (0) if successful or TNG_FAILURE (1) if the mapping
11887 /*static TNG_INLINE tng_function_status tng_particle_mapping_get_local_particle
11888 (const tng_trajectory_frame_set_t frame_set,
11889 const int64_t real,
11892 int64_t i, j, n_blocks = frame_set->n_mapping_blocks;
11893 tng_particle_mapping_t mapping;
11897 return(TNG_SUCCESS);
11899 for(i = 0; i < n_blocks; i++)
11901 mapping = &frame_set->mappings[i];
11902 for(j = mapping->n_particles; j--;)
11904 if(mapping->real_particle_numbers[j] == real)
11907 return(TNG_SUCCESS);
11911 return(TNG_FAILURE);
11915 tng_function_status DECLSPECDLLEXPORT tng_file_headers_read
11916 (tng_trajectory_t tng_data
,
11917 const char hash_mode
)
11919 int cnt
= 0, prev_pos
= 0;
11920 tng_gen_block_t block
;
11922 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
11924 tng_data
->n_trajectory_frame_sets
= 0;
11926 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
11928 return(TNG_CRITICAL
);
11931 if(!tng_data
->input_file_len
)
11933 fseek(tng_data
->input_file
, 0, SEEK_END
);
11934 tng_data
->input_file_len
= ftell(tng_data
->input_file
);
11935 fseek(tng_data
->input_file
, 0, SEEK_SET
);
11938 tng_block_init(&block
);
11939 /* Non trajectory blocks (they come before the trajectory
11940 * blocks in the file) */
11941 while (prev_pos
< tng_data
->input_file_len
&&
11942 tng_block_header_read(tng_data
, block
) != TNG_CRITICAL
&&
11944 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
11946 if(tng_block_read_next(tng_data
, block
,
11947 hash_mode
) == TNG_SUCCESS
)
11951 prev_pos
= ftell(tng_data
->input_file
);
11954 /* Go back if a trajectory block was encountered */
11955 if(block
->id
== TNG_TRAJECTORY_FRAME_SET
)
11957 fseek(tng_data
->input_file
, prev_pos
, SEEK_SET
);
11960 tng_block_destroy(&block
);
11962 return(TNG_SUCCESS
);
11965 tng_function_status DECLSPECDLLEXPORT tng_file_headers_write
11966 (tng_trajectory_t tng_data
,
11967 const char hash_mode
)
11970 tng_gen_block_t data_block
;
11972 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
11974 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
11976 return(TNG_CRITICAL
);
11979 /* TODO: If there is already frame set data written to this file (e.g. when
11980 * appending to an already existing file we might need to move frame sets to
11981 * the end of the file. */
11983 if(tng_general_info_block_write(tng_data
, hash_mode
)
11986 fprintf(stderr
, "TNG library: Error writing general info block of file %s. %s: %d\n",
11987 tng_data
->input_file_path
, __FILE__
, __LINE__
);
11988 return(TNG_CRITICAL
);
11991 if(tng_molecules_block_write(tng_data
, hash_mode
)
11994 fprintf(stderr
, "TNG library: Error writing atom names block of file %s. %s: %d\n",
11995 tng_data
->input_file_path
, __FILE__
, __LINE__
);
11996 return(TNG_CRITICAL
);
11999 /* FIXME: Currently writing non-trajectory data blocks here.
12000 * Should perhaps be moved. */
12001 tng_block_init(&data_block
);
12002 for(i
= 0; i
< tng_data
->n_data_blocks
; i
++)
12004 data_block
->id
= tng_data
->non_tr_data
[i
].block_id
;
12005 tng_data_block_write(tng_data
, data_block
,
12009 for(i
= 0; i
< tng_data
->n_particle_data_blocks
; i
++)
12011 data_block
->id
= tng_data
->non_tr_particle_data
[i
].block_id
;
12012 tng_particle_data_block_write(tng_data
, data_block
,
12016 tng_block_destroy(&data_block
);
12018 return(TNG_SUCCESS
);
12021 tng_function_status DECLSPECDLLEXPORT
tng_block_read_next(tng_trajectory_t tng_data
,
12022 tng_gen_block_t block
,
12023 const char hash_mode
)
12025 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12026 TNG_ASSERT(block
, "TNG library: block must be initialised and must not be a NULL pointer.");
12030 case TNG_TRAJECTORY_FRAME_SET
:
12031 return(tng_frame_set_block_read(tng_data
, block
, hash_mode
));
12032 case TNG_PARTICLE_MAPPING
:
12033 return(tng_trajectory_mapping_block_read(tng_data
, block
, hash_mode
));
12034 case TNG_GENERAL_INFO
:
12035 return(tng_general_info_block_read(tng_data
, block
, hash_mode
));
12036 case TNG_MOLECULES
:
12037 return(tng_molecules_block_read(tng_data
, block
, hash_mode
));
12039 if(block
->id
>= TNG_TRAJ_BOX_SHAPE
)
12041 return(tng_data_block_contents_read(tng_data
, block
, hash_mode
));
12045 /* Skip to the next block */
12046 fseek(tng_data
->input_file
, (long)block
->block_contents_size
, SEEK_CUR
);
12047 return(TNG_FAILURE
);
12052 tng_function_status DECLSPECDLLEXPORT tng_frame_set_read
12053 (tng_trajectory_t tng_data
,
12054 const char hash_mode
)
12057 tng_gen_block_t block
;
12058 tng_function_status stat
;
12060 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12062 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
12064 return(TNG_CRITICAL
);
12067 file_pos
= ftell(tng_data
->input_file
);
12069 tng_block_init(&block
);
12071 if(!tng_data
->input_file_len
)
12073 fseek(tng_data
->input_file
, 0, SEEK_END
);
12074 tng_data
->input_file_len
= ftell(tng_data
->input_file
);
12075 fseek(tng_data
->input_file
, file_pos
, SEEK_SET
);
12078 /* Read block headers first to see what block is found. */
12079 stat
= tng_block_header_read(tng_data
, block
);
12080 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
12082 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
12083 file_pos
, __FILE__
, __LINE__
);
12084 tng_block_destroy(&block
);
12085 return(TNG_CRITICAL
);
12088 tng_data
->current_trajectory_frame_set_input_file_pos
= file_pos
;
12090 if(tng_block_read_next(tng_data
, block
,
12091 hash_mode
) == TNG_SUCCESS
)
12093 tng_data
->n_trajectory_frame_sets
++;
12094 file_pos
= ftell(tng_data
->input_file
);
12095 /* Read all blocks until next frame set block */
12096 stat
= tng_block_header_read(tng_data
, block
);
12097 while(file_pos
< tng_data
->input_file_len
&&
12098 stat
!= TNG_CRITICAL
&&
12099 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
12101 stat
= tng_block_read_next(tng_data
, block
,
12103 if(stat
!= TNG_CRITICAL
)
12105 file_pos
= ftell(tng_data
->input_file
);
12106 if(file_pos
< tng_data
->input_file_len
)
12108 stat
= tng_block_header_read(tng_data
, block
);
12112 if(stat
== TNG_CRITICAL
)
12114 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
12115 file_pos
, __FILE__
, __LINE__
);
12116 tng_block_destroy(&block
);
12120 if(block
->id
== TNG_TRAJECTORY_FRAME_SET
)
12122 fseek(tng_data
->input_file
, file_pos
, SEEK_SET
);
12126 tng_block_destroy(&block
);
12128 return(TNG_SUCCESS
);
12132 tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_current_only_data_from_block_id
12133 (tng_trajectory_t tng_data
,
12134 const char hash_mode
,
12135 const int64_t block_id
)
12138 tng_gen_block_t block
;
12139 tng_function_status stat
;
12140 int found_flag
= 1;
12142 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12144 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
12146 return(TNG_CRITICAL
);
12149 file_pos
= (long)tng_data
->current_trajectory_frame_set_input_file_pos
;
12153 /* No current frame set. This means that the first frame set must be
12156 file_pos
= (long)tng_data
->first_trajectory_frame_set_input_file_pos
;
12161 fseek(tng_data
->input_file
,
12167 return(TNG_FAILURE
);
12170 tng_block_init(&block
);
12172 if(!tng_data
->input_file_len
)
12174 fseek(tng_data
->input_file
, 0, SEEK_END
);
12175 tng_data
->input_file_len
= ftell(tng_data
->input_file
);
12176 fseek(tng_data
->input_file
, file_pos
, SEEK_SET
);
12179 /* Read block headers first to see what block is found. */
12180 stat
= tng_block_header_read(tng_data
, block
);
12181 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
12183 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
12184 file_pos
, __FILE__
, __LINE__
);
12185 tng_block_destroy(&block
);
12186 return(TNG_CRITICAL
);
12188 /* If the current frame set had already been read skip its block contents */
12191 fseek(tng_data
->input_file
, (long)block
->block_contents_size
, SEEK_CUR
);
12193 /* Otherwiese read the frame set block */
12196 stat
= tng_block_read_next(tng_data
, block
,
12198 if(stat
!= TNG_SUCCESS
)
12200 fprintf(stderr
, "TNG library: Cannot read frame set block. %s: %d\n", __FILE__
, __LINE__
);
12201 tng_block_destroy(&block
);
12205 file_pos
= ftell(tng_data
->input_file
);
12209 /* Read only blocks of the requested ID
12210 * until next frame set block */
12211 stat
= tng_block_header_read(tng_data
, block
);
12212 while(file_pos
< tng_data
->input_file_len
&&
12213 stat
!= TNG_CRITICAL
&&
12214 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
12216 if(block
->id
== block_id
)
12218 stat
= tng_block_read_next(tng_data
, block
,
12220 if(stat
!= TNG_CRITICAL
)
12222 file_pos
= ftell(tng_data
->input_file
);
12224 if(file_pos
< tng_data
->input_file_len
)
12226 stat
= tng_block_header_read(tng_data
, block
);
12232 file_pos
+= (long)(block
->block_contents_size
+ block
->header_contents_size
);
12233 fseek(tng_data
->input_file
, (long)block
->block_contents_size
, SEEK_CUR
);
12234 if(file_pos
< tng_data
->input_file_len
)
12236 stat
= tng_block_header_read(tng_data
, block
);
12240 if(stat
== TNG_CRITICAL
)
12242 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
12243 file_pos
, __FILE__
, __LINE__
);
12244 tng_block_destroy(&block
);
12248 if(block
->id
== TNG_TRAJECTORY_FRAME_SET
)
12250 fseek(tng_data
->input_file
, file_pos
, SEEK_SET
);
12253 tng_block_destroy(&block
);
12257 return(TNG_SUCCESS
);
12261 return(TNG_FAILURE
);
12265 tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_next
12266 (tng_trajectory_t tng_data
,
12267 const char hash_mode
)
12271 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12273 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
12275 return(TNG_CRITICAL
);
12278 file_pos
= (long)tng_data
->current_trajectory_frame_set
.next_frame_set_file_pos
;
12280 if(file_pos
< 0 && tng_data
->current_trajectory_frame_set_input_file_pos
<= 0)
12282 file_pos
= (long)tng_data
->first_trajectory_frame_set_input_file_pos
;
12287 fseek(tng_data
->input_file
,
12293 return(TNG_FAILURE
);
12296 return(tng_frame_set_read(tng_data
, hash_mode
));
12299 tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_next_only_data_from_block_id
12300 (tng_trajectory_t tng_data
,
12301 const char hash_mode
,
12302 const int64_t block_id
)
12305 tng_gen_block_t block
;
12306 tng_function_status stat
;
12308 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12310 if(tng_input_file_init(tng_data
) != TNG_SUCCESS
)
12312 return(TNG_CRITICAL
);
12315 file_pos
= (long)tng_data
->current_trajectory_frame_set
.next_frame_set_file_pos
;
12317 if(file_pos
< 0 && tng_data
->current_trajectory_frame_set_input_file_pos
<= 0)
12319 file_pos
= (long)tng_data
->first_trajectory_frame_set_input_file_pos
;
12324 fseek(tng_data
->input_file
,
12330 return(TNG_FAILURE
);
12333 tng_block_init(&block
);
12335 if(!tng_data
->input_file_len
)
12337 fseek(tng_data
->input_file
, 0, SEEK_END
);
12338 tng_data
->input_file_len
= ftell(tng_data
->input_file
);
12339 fseek(tng_data
->input_file
, file_pos
, SEEK_SET
);
12342 /* Read block headers first to see what block is found. */
12343 stat
= tng_block_header_read(tng_data
, block
);
12344 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
12346 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
12347 file_pos
, __FILE__
, __LINE__
);
12348 tng_block_destroy(&block
);
12349 return(TNG_CRITICAL
);
12352 tng_data
->current_trajectory_frame_set_input_file_pos
= file_pos
;
12354 if(tng_block_read_next(tng_data
, block
,
12355 hash_mode
) == TNG_SUCCESS
)
12357 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, hash_mode
, block_id
);
12360 tng_block_destroy(&block
);
12365 tng_function_status
tng_frame_set_write(tng_trajectory_t tng_data
,
12366 const char hash_mode
)
12369 tng_gen_block_t block
;
12370 tng_trajectory_frame_set_t frame_set
;
12371 tng_function_status stat
;
12373 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12375 frame_set
= &tng_data
->current_trajectory_frame_set
;
12377 if(frame_set
->n_written_frames
== frame_set
->n_frames
)
12379 return(TNG_SUCCESS
);
12382 tng_data
->current_trajectory_frame_set_output_file_pos
=
12383 ftell(tng_data
->output_file
);
12384 tng_data
->last_trajectory_frame_set_output_file_pos
=
12385 tng_data
->current_trajectory_frame_set_output_file_pos
;
12387 if(tng_data
->current_trajectory_frame_set_output_file_pos
<= 0)
12389 return(TNG_FAILURE
);
12392 if(tng_data
->first_trajectory_frame_set_output_file_pos
== -1)
12394 tng_data
->first_trajectory_frame_set_output_file_pos
=
12395 tng_data
->current_trajectory_frame_set_output_file_pos
;
12398 tng_block_init(&block
);
12400 if(tng_frame_set_block_write(tng_data
, block
, hash_mode
) != TNG_SUCCESS
)
12402 tng_block_destroy(&block
);
12403 return(TNG_FAILURE
);
12406 /* Write non-particle data blocks */
12407 for(i
= 0; i
<frame_set
->n_data_blocks
; i
++)
12409 block
->id
= frame_set
->tr_data
[i
].block_id
;
12410 tng_data_block_write(tng_data
, block
, i
, hash_mode
);
12412 /* Write the mapping blocks and particle data blocks*/
12413 if(frame_set
->n_mapping_blocks
)
12415 for(i
= 0; i
< frame_set
->n_mapping_blocks
; i
++)
12417 block
->id
= TNG_PARTICLE_MAPPING
;
12418 if(frame_set
->mappings
[i
].n_particles
> 0)
12420 tng_trajectory_mapping_block_write(tng_data
, block
, i
, hash_mode
);
12421 for(j
= 0; j
<frame_set
->n_particle_data_blocks
; j
++)
12423 block
->id
= frame_set
->tr_particle_data
[j
].block_id
;
12424 tng_particle_data_block_write(tng_data
, block
,
12425 j
, &frame_set
->mappings
[i
],
12433 for(i
= 0; i
<frame_set
->n_particle_data_blocks
; i
++)
12435 block
->id
= frame_set
->tr_particle_data
[i
].block_id
;
12436 tng_particle_data_block_write(tng_data
, block
,
12442 /* Update pointers in the general info block */
12443 stat
= tng_header_pointers_update(tng_data
, hash_mode
);
12445 if(stat
== TNG_SUCCESS
)
12447 stat
= tng_frame_set_pointers_update(tng_data
, hash_mode
);
12450 tng_block_destroy(&block
);
12452 frame_set
->n_unwritten_frames
= 0;
12454 fflush(tng_data
->output_file
);
12459 tng_function_status DECLSPECDLLEXPORT tng_frame_set_premature_write
12460 (tng_trajectory_t tng_data
,
12461 const char hash_mode
)
12463 tng_trajectory_frame_set_t frame_set
;
12465 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12467 frame_set
= &tng_data
->current_trajectory_frame_set
;
12469 if(frame_set
->n_unwritten_frames
== 0)
12471 return(TNG_SUCCESS
);
12473 frame_set
->n_frames
= frame_set
->n_unwritten_frames
;
12475 return(tng_frame_set_write(tng_data
, hash_mode
));
12478 tng_function_status DECLSPECDLLEXPORT tng_frame_set_new
12479 (tng_trajectory_t tng_data
,
12480 const int64_t first_frame
,
12481 const int64_t n_frames
)
12483 tng_gen_block_t block
;
12484 tng_trajectory_frame_set_t frame_set
;
12485 FILE *temp
= tng_data
->input_file
;
12488 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12489 TNG_ASSERT(first_frame
>= 0, "TNG library: first_frame must be >= 0.");
12490 TNG_ASSERT(n_frames
>= 0, "TNG library: n_frames must be >= 0.");
12492 frame_set
= &tng_data
->current_trajectory_frame_set
;
12494 curr_pos
= ftell(tng_data
->output_file
);
12498 tng_file_headers_write(tng_data
, TNG_USE_HASH
);
12501 /* Set pointer to previous frame set to the one that was loaded
12503 * FIXME: This is a bit risky. If they are not added in order
12504 * it will be wrong. */
12505 if(tng_data
->n_trajectory_frame_sets
)
12507 frame_set
->prev_frame_set_file_pos
=
12508 tng_data
->current_trajectory_frame_set_output_file_pos
;
12511 tng_data
->current_trajectory_frame_set_output_file_pos
=
12512 ftell(tng_data
->output_file
);
12514 tng_data
->n_trajectory_frame_sets
++;
12516 /* Set the medium range pointers */
12517 if(tng_data
->n_trajectory_frame_sets
== tng_data
->medium_stride_length
+ 1)
12519 frame_set
->medium_stride_prev_frame_set_file_pos
=
12520 tng_data
->first_trajectory_frame_set_output_file_pos
;
12522 else if(tng_data
->n_trajectory_frame_sets
> tng_data
->medium_stride_length
+ 1)
12524 /* FIXME: Currently only working if the previous frame set has its
12525 * medium stride pointer already set. This might need some fixing. */
12526 if(frame_set
->medium_stride_prev_frame_set_file_pos
!= -1 &&
12527 frame_set
->medium_stride_prev_frame_set_file_pos
!= 0)
12529 tng_block_init(&block
);
12530 tng_data
->input_file
= tng_data
->output_file
;
12532 curr_pos
= ftell(tng_data
->output_file
);
12533 fseek(tng_data
->output_file
,
12534 (long)frame_set
->medium_stride_prev_frame_set_file_pos
,
12537 if(tng_block_header_read(tng_data
, block
) != TNG_SUCCESS
)
12539 fprintf(stderr
, "TNG library: Cannot read frame set header. %s: %d\n",
12540 __FILE__
, __LINE__
);
12541 tng_data
->input_file
= temp
;
12542 tng_block_destroy(&block
);
12543 return(TNG_CRITICAL
);
12546 /* Read the next frame set from the previous frame set and one
12547 * medium stride step back */
12548 fseek(tng_data
->output_file
, (long)block
->block_contents_size
- 6 *
12549 sizeof(int64_t), SEEK_CUR
);
12550 if(fread(&frame_set
->medium_stride_prev_frame_set_file_pos
,
12551 sizeof(frame_set
->medium_stride_prev_frame_set_file_pos
),
12552 1, tng_data
->output_file
) == 0)
12554 fprintf(stderr
, "TNG library: Cannot read block. %s: %d\n", __FILE__
, __LINE__
);
12555 tng_data
->input_file
= temp
;
12556 tng_block_destroy(&block
);
12557 return(TNG_CRITICAL
);
12560 if(tng_data
->input_endianness_swap_func_64
)
12562 if(tng_data
->input_endianness_swap_func_64(tng_data
,
12563 &frame_set
->medium_stride_prev_frame_set_file_pos
)
12566 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
12567 __FILE__
, __LINE__
);
12571 tng_block_destroy(&block
);
12573 /* Set the long range pointers */
12574 if(tng_data
->n_trajectory_frame_sets
== tng_data
->long_stride_length
+ 1)
12576 frame_set
->long_stride_prev_frame_set_file_pos
=
12577 tng_data
->first_trajectory_frame_set_output_file_pos
;
12579 else if(tng_data
->n_trajectory_frame_sets
> tng_data
->medium_stride_length
+ 1)
12581 /* FIXME: Currently only working if the previous frame set has its
12582 * long stride pointer already set. This might need some fixing. */
12583 if(frame_set
->long_stride_prev_frame_set_file_pos
!= -1 &&
12584 frame_set
->long_stride_prev_frame_set_file_pos
!= 0)
12586 tng_block_init(&block
);
12587 tng_data
->input_file
= tng_data
->output_file
;
12589 fseek(tng_data
->output_file
,
12590 (long)frame_set
->long_stride_prev_frame_set_file_pos
,
12593 if(tng_block_header_read(tng_data
, block
) != TNG_SUCCESS
)
12595 fprintf(stderr
, "TNG library: Cannot read frame set header. %s: %d\n",
12596 __FILE__
, __LINE__
);
12597 tng_data
->input_file
= temp
;
12598 tng_block_destroy(&block
);
12599 return(TNG_CRITICAL
);
12602 /* Read the next frame set from the previous frame set and one
12603 * long stride step back */
12604 fseek(tng_data
->output_file
, (long)block
->block_contents_size
- 6 *
12605 sizeof(int64_t), SEEK_CUR
);
12607 tng_block_destroy(&block
);
12609 if(fread(&frame_set
->long_stride_prev_frame_set_file_pos
,
12610 sizeof(frame_set
->long_stride_prev_frame_set_file_pos
),
12611 1, tng_data
->output_file
) == 0)
12613 fprintf(stderr
, "TNG library: Cannot read block. %s: %d\n", __FILE__
, __LINE__
);
12614 tng_data
->input_file
= temp
;
12615 return(TNG_CRITICAL
);
12618 if(tng_data
->input_endianness_swap_func_64
)
12620 if(tng_data
->input_endianness_swap_func_64(tng_data
,
12621 &frame_set
->long_stride_prev_frame_set_file_pos
)
12624 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
12625 __FILE__
, __LINE__
);
12632 tng_data
->input_file
= temp
;
12633 fseek(tng_data
->output_file
, (long)curr_pos
, SEEK_SET
);
12637 frame_set
->first_frame
= first_frame
;
12638 frame_set
->n_frames
= n_frames
;
12639 frame_set
->n_written_frames
= 0;
12640 frame_set
->n_unwritten_frames
= 0;
12641 frame_set
->first_frame_time
= -1;
12643 if(tng_data
->first_trajectory_frame_set_output_file_pos
== -1 ||
12644 tng_data
->first_trajectory_frame_set_output_file_pos
== 0)
12646 tng_data
->first_trajectory_frame_set_output_file_pos
=
12647 tng_data
->current_trajectory_frame_set_output_file_pos
;
12649 /* FIXME: Should check the frame number instead of the file_pos,
12650 * in case frame sets are not in order */
12651 if(tng_data
->last_trajectory_frame_set_output_file_pos
== -1 ||
12652 tng_data
->last_trajectory_frame_set_output_file_pos
== 0 ||
12653 tng_data
->last_trajectory_frame_set_output_file_pos
<
12654 tng_data
->current_trajectory_frame_set_output_file_pos
)
12656 tng_data
->last_trajectory_frame_set_output_file_pos
=
12657 tng_data
->current_trajectory_frame_set_output_file_pos
;
12660 return(TNG_SUCCESS
);
12663 tng_function_status DECLSPECDLLEXPORT tng_frame_set_with_time_new
12664 (tng_trajectory_t tng_data
,
12665 const int64_t first_frame
,
12666 const int64_t n_frames
,
12667 const double first_frame_time
)
12669 tng_function_status stat
;
12671 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12672 TNG_ASSERT(first_frame
>= 0, "TNG library: first_frame must be >= 0.");
12673 TNG_ASSERT(n_frames
>= 0, "TNG library: n_frames must be >= 0.");
12674 TNG_ASSERT(first_frame_time
>= 0, "TNG library: first_frame_time must be >= 0.");
12677 stat
= tng_frame_set_new(tng_data
, first_frame
, n_frames
);
12678 if(stat
!= TNG_SUCCESS
)
12682 stat
= tng_frame_set_first_frame_time_set(tng_data
, first_frame_time
);
12687 tng_function_status DECLSPECDLLEXPORT tng_frame_set_first_frame_time_set
12688 (tng_trajectory_t tng_data
,
12689 const double first_frame_time
)
12691 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12692 TNG_ASSERT(first_frame_time
>= 0, "TNG library: first_frame_time must be >= 0.");
12694 tng_data
->current_trajectory_frame_set
.first_frame_time
= first_frame_time
;
12696 return(TNG_SUCCESS
);
12699 tng_function_status DECLSPECDLLEXPORT tng_first_frame_nr_of_next_frame_set_get
12700 (const tng_trajectory_t tng_data
,
12703 long file_pos
, next_frame_set_file_pos
;
12704 tng_gen_block_t block
;
12705 tng_function_status stat
;
12707 tng_trajectory_frame_set_t frame_set
;
12709 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12710 TNG_ASSERT(tng_data
->input_file
, "TNG library: An input file must be open to find the next frame set");
12711 TNG_ASSERT(frame
, "TNG library: frame must not be a NULL pointer");
12713 file_pos
= ftell(tng_data
->input_file
);
12715 if(tng_data
->current_trajectory_frame_set_input_file_pos
<= 0)
12717 next_frame_set_file_pos
= (long)tng_data
->first_trajectory_frame_set_input_file_pos
;
12721 frame_set
= &tng_data
->current_trajectory_frame_set
;
12722 next_frame_set_file_pos
= (long)frame_set
->next_frame_set_file_pos
;
12725 if(next_frame_set_file_pos
<= 0)
12727 return(TNG_FAILURE
);
12730 fseek(tng_data
->input_file
, (long)next_frame_set_file_pos
, SEEK_SET
);
12731 /* Read block headers first to see that a frame set block is found. */
12732 tng_block_init(&block
);
12733 stat
= tng_block_header_read(tng_data
, block
);
12734 if(stat
== TNG_CRITICAL
|| block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
12736 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
12737 file_pos
, __FILE__
, __LINE__
);
12738 return(TNG_CRITICAL
);
12740 /* if(tng_data->current_trajectory_frame_set_input_file_pos <= 0)
12742 tng_block_read_next(tng_data, block, TNG_USE_HASH);
12744 tng_block_destroy(&block
);
12746 if(fread(frame
, sizeof(int64_t), 1, tng_data
->input_file
) == 0)
12748 fprintf(stderr
, "TNG library: Cannot read first frame of next frame set. %s: %d\n",
12749 __FILE__
, __LINE__
);
12750 return(TNG_CRITICAL
);
12752 fseek(tng_data
->input_file
, file_pos
, SEEK_SET
);
12754 return(TNG_SUCCESS
);
12757 tng_function_status DECLSPECDLLEXPORT tng_data_block_add
12758 (tng_trajectory_t tng_data
,
12760 const char *block_name
,
12761 const char datatype
,
12762 const char block_type_flag
,
12764 const int64_t n_values_per_frame
,
12765 int64_t stride_length
,
12766 const int64_t codec_id
,
12769 int i
, j
, size
, len
;
12770 tng_trajectory_frame_set_t frame_set
;
12771 tng_non_particle_data_t data
;
12772 char **first_dim_values
;
12773 char *new_data_c
=new_data
;
12774 int64_t n_frames_div
;
12776 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12777 TNG_ASSERT(block_name
, "TNG library: block_name must not be a NULL pointer.");
12778 TNG_ASSERT(n_values_per_frame
> 0, "TNG library: n_values_per_frame must be a positive integer.");
12780 frame_set
= &tng_data
->current_trajectory_frame_set
;
12782 if(stride_length
<= 0)
12787 /* If the block does not exist, create it */
12788 if(tng_data_find(tng_data
, id
, &data
) != TNG_SUCCESS
)
12790 if(tng_data_block_create(tng_data
, block_type_flag
) !=
12793 fprintf(stderr
, "TNG library: Cannot create data block. %s: %d\n",
12794 __FILE__
, __LINE__
);
12795 return(TNG_CRITICAL
);
12797 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
12799 data
= &frame_set
->tr_data
[frame_set
->n_data_blocks
- 1];
12803 data
= &tng_data
->non_tr_data
[tng_data
->n_data_blocks
- 1];
12805 data
->block_id
= id
;
12807 data
->block_name
= malloc(strlen(block_name
) + 1);
12808 if(!data
->block_name
)
12810 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
12811 (int)strlen(block_name
)+1, __FILE__
, __LINE__
);
12812 return(TNG_CRITICAL
);
12814 strncpy(data
->block_name
, block_name
, strlen(block_name
) + 1);
12817 /* FIXME: Memory leak from strings. */
12819 data
->last_retrieved_frame
= -1;
12822 data
->datatype
= datatype
;
12823 data
->stride_length
= tng_max_i64(stride_length
, 1);
12824 data
->n_values_per_frame
= n_values_per_frame
;
12825 data
->n_frames
= n_frames
;
12826 data
->codec_id
= codec_id
;
12827 data
->compression_multiplier
= 1.0;
12828 /* FIXME: This can cause problems. */
12829 data
->first_frame_with_data
= frame_set
->first_frame
;
12833 case TNG_FLOAT_DATA
:
12834 size
= sizeof(float);
12837 size
= sizeof(int64_t);
12839 case TNG_DOUBLE_DATA
:
12841 size
= sizeof(double);
12847 /* Allocate memory */
12848 if(tng_allocate_data_mem(tng_data
, data
, n_frames
, stride_length
,
12849 n_values_per_frame
) !=
12852 fprintf(stderr
, "TNG library: Cannot allocate data memory. %s: %d\n",
12853 __FILE__
, __LINE__
);
12854 return(TNG_CRITICAL
);
12857 if(n_frames
> frame_set
->n_unwritten_frames
)
12859 frame_set
->n_unwritten_frames
= n_frames
;
12862 n_frames_div
= (n_frames
% stride_length
) ?
12863 n_frames
/ stride_length
+ 1:
12864 n_frames
/ stride_length
;
12866 if(datatype
== TNG_CHAR_DATA
)
12868 for(i
= 0; i
< n_frames_div
; i
++)
12870 first_dim_values
= data
->strings
[i
];
12871 for(j
= 0; j
< n_values_per_frame
; j
++)
12873 len
= tng_min_i((int)strlen(new_data_c
) + 1,
12875 if(first_dim_values
[j
])
12877 free(first_dim_values
[j
]);
12879 first_dim_values
[j
] = malloc(len
);
12880 if(!first_dim_values
[j
])
12882 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
12883 len
, __FILE__
, __LINE__
);
12884 return(TNG_CRITICAL
);
12886 strncpy(first_dim_values
[j
],
12894 memcpy(data
->values
, new_data
, size
* n_frames_div
*
12895 n_values_per_frame
);
12899 return(TNG_SUCCESS
);
12902 tng_function_status DECLSPECDLLEXPORT tng_particle_data_block_add
12903 (tng_trajectory_t tng_data
,
12905 const char *block_name
,
12906 const char datatype
,
12907 const char block_type_flag
,
12909 const int64_t n_values_per_frame
,
12910 int64_t stride_length
,
12911 const int64_t num_first_particle
,
12912 const int64_t n_particles
,
12913 const int64_t codec_id
,
12918 int64_t tot_n_particles
, n_frames_div
;
12919 char ***first_dim_values
, **second_dim_values
;
12920 tng_trajectory_frame_set_t frame_set
;
12921 tng_particle_data_t data
;
12922 char *new_data_c
=new_data
;
12924 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
12925 TNG_ASSERT(block_name
, "TNG library: block_name mustnot be a NULL pointer.");
12926 TNG_ASSERT(n_values_per_frame
> 0, "TNG library: n_values_per_frame must be a positive integer.");
12927 TNG_ASSERT(num_first_particle
>= 0, "TNG library: num_first_particle must be >= 0.");
12928 TNG_ASSERT(n_particles
>= 0, "TNG library: n_particles must be >= 0.");
12931 frame_set
= &tng_data
->current_trajectory_frame_set
;
12933 if(stride_length
<= 0)
12938 /* If the block does not exist, create it */
12939 if(tng_particle_data_find(tng_data
, id
, &data
) != TNG_SUCCESS
)
12941 if(tng_particle_data_block_create(tng_data
, block_type_flag
) !=
12944 fprintf(stderr
, "TNG library: Cannot create particle data block. %s: %d\n",
12945 __FILE__
, __LINE__
);
12946 return(TNG_CRITICAL
);
12948 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
12950 data
= &frame_set
->tr_particle_data
[frame_set
->
12951 n_particle_data_blocks
- 1];
12955 data
= &tng_data
->non_tr_particle_data
[tng_data
->
12956 n_particle_data_blocks
- 1];
12958 data
->block_id
= id
;
12960 data
->block_name
= malloc(strlen(block_name
) + 1);
12961 if(!data
->block_name
)
12963 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
12964 (int)strlen(block_name
)+1, __FILE__
, __LINE__
);
12965 return(TNG_CRITICAL
);
12967 strncpy(data
->block_name
, block_name
, strlen(block_name
) + 1);
12969 data
->datatype
= datatype
;
12972 /* FIXME: Memory leak from strings. */
12974 data
->last_retrieved_frame
= -1;
12977 data
->stride_length
= tng_max_i64(stride_length
, 1);
12978 data
->n_values_per_frame
= n_values_per_frame
;
12979 data
->n_frames
= n_frames
;
12980 data
->codec_id
= codec_id
;
12981 data
->compression_multiplier
= 1.0;
12982 /* FIXME: This can cause problems. */
12983 data
->first_frame_with_data
= frame_set
->first_frame
;
12985 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
&& tng_data
->var_num_atoms_flag
)
12987 tot_n_particles
= frame_set
->n_particles
;
12991 tot_n_particles
= tng_data
->n_particles
;
12994 /* If data values are supplied add that data to the data block. */
12997 /* Allocate memory */
12998 if(tng_allocate_particle_data_mem(tng_data
, data
, n_frames
,
12999 stride_length
, tot_n_particles
,
13000 n_values_per_frame
) !=
13003 fprintf(stderr
, "TNG library: Cannot allocate particle data memory. %s: %d\n",
13004 __FILE__
, __LINE__
);
13005 return(TNG_CRITICAL
);
13008 if(n_frames
> frame_set
->n_unwritten_frames
)
13010 frame_set
->n_unwritten_frames
= n_frames
;
13013 n_frames_div
= (n_frames
% stride_length
) ?
13014 n_frames
/ stride_length
+ 1:
13015 n_frames
/ stride_length
;
13017 if(datatype
== TNG_CHAR_DATA
)
13019 for(i
= 0; i
< n_frames_div
; i
++)
13021 first_dim_values
= data
->strings
[i
];
13022 for(j
= num_first_particle
; j
< num_first_particle
+ n_particles
;
13025 second_dim_values
= first_dim_values
[j
];
13026 for(k
= 0; k
< n_values_per_frame
; k
++)
13028 len
= tng_min_i((int)strlen(new_data_c
) + 1,
13030 if(second_dim_values
[k
])
13032 free(second_dim_values
[k
]);
13034 second_dim_values
[k
] = malloc(len
);
13035 if(!second_dim_values
[k
])
13037 fprintf(stderr
, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
13038 len
, __FILE__
, __LINE__
);
13039 return(TNG_CRITICAL
);
13041 strncpy(second_dim_values
[k
],
13053 size
= sizeof(int64_t);
13055 case TNG_FLOAT_DATA
:
13056 size
= sizeof(float);
13058 case TNG_DOUBLE_DATA
:
13060 size
= sizeof(double);
13063 memcpy(data
->values
, new_data
, size
* n_frames_div
*
13064 n_particles
* n_values_per_frame
);
13068 return(TNG_SUCCESS
);
13071 tng_function_status DECLSPECDLLEXPORT tng_data_block_name_get
13072 (tng_trajectory_t tng_data
,
13078 tng_trajectory_frame_set_t frame_set
;
13079 tng_function_status stat
;
13080 tng_particle_data_t p_data
;
13081 tng_non_particle_data_t np_data
;
13082 int block_type
= -1;
13084 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
13085 TNG_ASSERT(name
, "TNG library: name must not be a NULL pointer.");
13087 for(i
= 0; i
< tng_data
->n_particle_data_blocks
; i
++)
13089 p_data
= &tng_data
->non_tr_particle_data
[i
];
13090 if(p_data
->block_id
== block_id
)
13092 strncpy(name
, p_data
->block_name
, max_len
);
13093 name
[max_len
- 1] = '\0';
13094 return(TNG_SUCCESS
);
13097 for(i
= 0; i
< tng_data
->n_data_blocks
; i
++)
13099 np_data
= &tng_data
->non_tr_data
[i
];
13100 if(np_data
->block_id
== block_id
)
13102 strncpy(name
, np_data
->block_name
, max_len
);
13103 name
[max_len
- 1] = '\0';
13104 return(TNG_SUCCESS
);
13108 frame_set
= &tng_data
->current_trajectory_frame_set
;
13110 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
13111 if(stat
== TNG_SUCCESS
)
13113 block_type
= TNG_PARTICLE_BLOCK_DATA
;
13117 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
13118 if(stat
== TNG_SUCCESS
)
13120 block_type
= TNG_NON_PARTICLE_BLOCK_DATA
;
13124 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
13125 if(stat
!= TNG_SUCCESS
)
13129 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
13130 if(stat
== TNG_SUCCESS
)
13132 block_type
= TNG_PARTICLE_BLOCK_DATA
;
13136 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
13137 if(stat
== TNG_SUCCESS
)
13139 block_type
= TNG_NON_PARTICLE_BLOCK_DATA
;
13144 if(block_type
== TNG_PARTICLE_BLOCK_DATA
)
13146 for(i
= 0; i
< frame_set
->n_particle_data_blocks
; i
++)
13148 p_data
= &frame_set
->tr_particle_data
[i
];
13149 if(p_data
->block_id
== block_id
)
13151 strncpy(name
, p_data
->block_name
, max_len
);
13152 name
[max_len
- 1] = '\0';
13153 return(TNG_SUCCESS
);
13157 else if(block_type
== TNG_NON_PARTICLE_BLOCK_DATA
)
13159 for(i
= 0; i
< frame_set
->n_data_blocks
; i
++)
13161 np_data
= &frame_set
->tr_data
[i
];
13162 if(np_data
->block_id
== block_id
)
13164 strncpy(name
, np_data
->block_name
, max_len
);
13165 name
[max_len
- 1] = '\0';
13166 return(TNG_SUCCESS
);
13171 return(TNG_FAILURE
);
13174 tng_function_status DECLSPECDLLEXPORT tng_data_block_dependency_get
13175 (const tng_trajectory_t tng_data
,
13177 int *block_dependency
)
13180 tng_function_status stat
;
13181 tng_particle_data_t p_data
;
13182 tng_non_particle_data_t np_data
;
13184 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
13185 TNG_ASSERT(block_dependency
, "TNG library: block_dependency must not be a NULL pointer.");
13187 for(i
= 0; i
< tng_data
->n_particle_data_blocks
; i
++)
13189 p_data
= &tng_data
->non_tr_particle_data
[i
];
13190 if(p_data
->block_id
== block_id
)
13192 *block_dependency
= TNG_PARTICLE_DEPENDENT
;
13193 return(TNG_SUCCESS
);
13196 for(i
= 0; i
< tng_data
->n_data_blocks
; i
++)
13198 np_data
= &tng_data
->non_tr_data
[i
];
13199 if(np_data
->block_id
== block_id
)
13201 *block_dependency
= 0;
13202 return(TNG_SUCCESS
);
13206 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
13207 if(stat
== TNG_SUCCESS
)
13209 *block_dependency
= TNG_PARTICLE_DEPENDENT
+ TNG_FRAME_DEPENDENT
;
13210 return(TNG_SUCCESS
);
13214 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
13215 if(stat
== TNG_SUCCESS
)
13217 *block_dependency
= TNG_FRAME_DEPENDENT
;
13218 return(TNG_SUCCESS
);
13222 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
13223 if(stat
!= TNG_SUCCESS
)
13227 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
13228 if(stat
== TNG_SUCCESS
)
13230 *block_dependency
= TNG_PARTICLE_DEPENDENT
+ TNG_FRAME_DEPENDENT
;
13231 return(TNG_SUCCESS
);
13235 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
13236 if(stat
== TNG_SUCCESS
)
13238 *block_dependency
= TNG_FRAME_DEPENDENT
;
13239 return(TNG_SUCCESS
);
13245 return(TNG_FAILURE
);
13248 tng_function_status DECLSPECDLLEXPORT tng_data_block_num_values_per_frame_get
13249 (const tng_trajectory_t tng_data
,
13251 int64_t *n_values_per_frame
)
13254 tng_function_status stat
;
13255 tng_particle_data_t p_data
;
13256 tng_non_particle_data_t np_data
;
13258 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
13259 TNG_ASSERT(n_values_per_frame
, "TNG library: n_values_per_frame must not be a NULL pointer.");
13261 for(i
= 0; i
< tng_data
->n_particle_data_blocks
; i
++)
13263 p_data
= &tng_data
->non_tr_particle_data
[i
];
13264 if(p_data
->block_id
== block_id
)
13266 *n_values_per_frame
= p_data
->n_values_per_frame
;
13267 return(TNG_SUCCESS
);
13270 for(i
= 0; i
< tng_data
->n_data_blocks
; i
++)
13272 np_data
= &tng_data
->non_tr_data
[i
];
13273 if(np_data
->block_id
== block_id
)
13275 *n_values_per_frame
= np_data
->n_values_per_frame
;
13276 return(TNG_SUCCESS
);
13280 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
13281 if(stat
== TNG_SUCCESS
)
13283 *n_values_per_frame
= p_data
->n_values_per_frame
;
13284 return(TNG_SUCCESS
);
13288 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
13289 if(stat
== TNG_SUCCESS
)
13291 *n_values_per_frame
= np_data
->n_values_per_frame
;
13292 return(TNG_SUCCESS
);
13296 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
13297 if(stat
!= TNG_SUCCESS
)
13301 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
13302 if(stat
== TNG_SUCCESS
)
13304 *n_values_per_frame
= p_data
->n_values_per_frame
;
13305 return(TNG_SUCCESS
);
13309 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
13310 if(stat
== TNG_SUCCESS
)
13312 *n_values_per_frame
= np_data
->n_values_per_frame
;
13313 return(TNG_SUCCESS
);
13319 return(TNG_FAILURE
);
13322 tng_function_status DECLSPECDLLEXPORT tng_frame_data_write
13323 (tng_trajectory_t tng_data
,
13324 const int64_t frame_nr
,
13325 const int64_t block_id
,
13326 const void *values
,
13327 const char hash_mode
)
13329 int64_t header_pos
, file_pos
;
13330 int64_t output_file_len
, n_values_per_frame
, size
, contents_size
;
13331 int64_t header_size
, temp_first
, temp_last
;
13332 int64_t i
, last_frame
;
13334 tng_gen_block_t block
;
13335 tng_trajectory_frame_set_t frame_set
;
13336 FILE *temp
= tng_data
->input_file
;
13337 struct tng_non_particle_data data
;
13338 tng_function_status stat
;
13339 char dependency
, sparse_data
, datatype
;
13342 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
13343 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
13344 TNG_ASSERT(values
, "TNG library: values must not be a NULL pointer.");
13346 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
13348 fprintf(stderr
, "TNG library: Cannot initialise destination file. %s: %d\n",
13349 __FILE__
, __LINE__
);
13350 return(TNG_CRITICAL
);
13353 temp_first
= tng_data
->first_trajectory_frame_set_input_file_pos
;
13354 temp_last
= tng_data
->last_trajectory_frame_set_input_file_pos
;
13355 temp_current
= tng_data
->current_trajectory_frame_set_input_file_pos
;
13356 tng_data
->first_trajectory_frame_set_input_file_pos
=
13357 tng_data
->first_trajectory_frame_set_output_file_pos
;
13358 tng_data
->last_trajectory_frame_set_input_file_pos
=
13359 tng_data
->last_trajectory_frame_set_output_file_pos
;
13360 tng_data
->current_trajectory_frame_set_input_file_pos
=
13361 tng_data
->current_trajectory_frame_set_output_file_pos
;
13363 tng_data
->input_file
= tng_data
->output_file
;
13365 stat
= tng_frame_set_of_frame_find(tng_data
, frame_nr
);
13367 frame_set
= &tng_data
->current_trajectory_frame_set
;
13369 if(stat
!= TNG_SUCCESS
)
13371 last_frame
= frame_set
->first_frame
+
13372 frame_set
->n_frames
- 1;
13373 /* If the wanted frame would be in the frame set after the last
13374 * frame set create a new frame set. */
13375 if(stat
== TNG_FAILURE
&&
13376 last_frame
< frame_nr
)
13377 /* (last_frame < frame_nr &&
13378 tng_data->current_trajectory_frame_set.first_frame +
13379 tng_data->frame_set_n_frames >= frame_nr))*/
13381 if(last_frame
+ tng_data
->frame_set_n_frames
< frame_nr
)
13383 last_frame
= frame_nr
- 1;
13385 tng_frame_set_new(tng_data
,
13387 tng_data
->frame_set_n_frames
);
13388 file_pos
= ftell(tng_data
->output_file
);
13389 fseek(tng_data
->output_file
, 0, SEEK_END
);
13390 output_file_len
= ftell(tng_data
->output_file
);
13391 fseek(tng_data
->output_file
, (long)file_pos
, SEEK_SET
);
13393 /* Read mapping blocks from the last frame set */
13394 tng_block_init(&block
);
13396 stat
= tng_block_header_read(tng_data
, block
);
13397 while(file_pos
< output_file_len
&&
13398 stat
!= TNG_CRITICAL
&&
13399 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
13401 if(block
->id
== TNG_PARTICLE_MAPPING
)
13403 tng_trajectory_mapping_block_read(tng_data
, block
,
13408 fseek(tng_data
->output_file
, (long)block
->block_contents_size
,
13411 file_pos
= ftell(tng_data
->output_file
);
13412 if(file_pos
< output_file_len
)
13414 stat
= tng_block_header_read(tng_data
, block
);
13418 tng_block_destroy(&block
);
13419 /* Write the frame set to disk */
13420 if(tng_frame_set_write(tng_data
, hash_mode
) != TNG_SUCCESS
)
13422 fprintf(stderr
, "TNG library: Error writing frame set. %s: %d\n", __FILE__
, __LINE__
);
13423 return(TNG_CRITICAL
);
13428 tng_data
->input_file
= temp
;
13429 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13430 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13431 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13436 tng_block_init(&block
);
13438 file_pos
= tng_data
->current_trajectory_frame_set_output_file_pos
;
13440 fseek(tng_data
->output_file
, 0, SEEK_END
);
13441 output_file_len
= ftell(tng_data
->output_file
);
13442 fseek(tng_data
->output_file
, (long)file_pos
, SEEK_SET
);
13444 /* Read past the frame set block first */
13445 stat
= tng_block_header_read(tng_data
, block
);
13446 if(stat
== TNG_CRITICAL
)
13448 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
13449 file_pos
, __FILE__
, __LINE__
);
13450 tng_block_destroy(&block
);
13451 tng_data
->input_file
= temp
;
13453 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13454 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13455 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13458 fseek(tng_data
->output_file
, (long)block
->block_contents_size
,
13461 /* Read all block headers until next frame set block or
13462 * until the wanted block id is found */
13463 stat
= tng_block_header_read(tng_data
, block
);
13464 while(file_pos
< output_file_len
&&
13465 stat
!= TNG_CRITICAL
&&
13466 block
->id
!= block_id
&&
13467 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
13469 fseek(tng_data
->output_file
, (long)block
->block_contents_size
, SEEK_CUR
);
13470 file_pos
= ftell(tng_data
->output_file
);
13471 if(file_pos
< output_file_len
)
13473 stat
= tng_block_header_read(tng_data
, block
);
13476 if(stat
== TNG_CRITICAL
)
13478 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
13479 file_pos
, __FILE__
, __LINE__
);
13480 tng_block_destroy(&block
);
13481 tng_data
->input_file
= temp
;
13482 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13483 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13484 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13488 contents_size
= block
->block_contents_size
;
13489 header_size
= block
->header_contents_size
;
13491 header_pos
= ftell(tng_data
->output_file
) - header_size
;
13492 frame_set
= &tng_data
->current_trajectory_frame_set
;
13494 if(fread(&datatype
, sizeof(datatype
), 1, tng_data
->input_file
) == 0)
13496 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13497 tng_block_destroy(&block
);
13498 return(TNG_CRITICAL
);
13500 if(fread(&dependency
, sizeof(dependency
), 1, tng_data
->input_file
) == 0)
13502 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13503 tng_block_destroy(&block
);
13504 return(TNG_CRITICAL
);
13506 data
.datatype
= datatype
;
13508 if(!(dependency
& TNG_FRAME_DEPENDENT
) ||
13509 (dependency
& TNG_PARTICLE_DEPENDENT
))
13511 tng_block_destroy(&block
);
13512 tng_data
->input_file
= temp
;
13514 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13515 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13516 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13517 return(TNG_FAILURE
);
13520 if(fread(&sparse_data
, sizeof(sparse_data
), 1, tng_data
->input_file
) == 0)
13522 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13523 tng_block_destroy(&block
);
13524 return(TNG_CRITICAL
);
13527 if(fread(&data
.n_values_per_frame
, sizeof(data
.n_values_per_frame
), 1,
13528 tng_data
->input_file
) == 0)
13530 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13531 tng_block_destroy(&block
);
13532 return(TNG_CRITICAL
);
13534 if(tng_data
->output_endianness_swap_func_64
)
13536 if(tng_data
->output_endianness_swap_func_64(tng_data
,
13537 &data
.n_values_per_frame
)
13540 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
13541 __FILE__
, __LINE__
);
13545 if(fread(&data
.codec_id
, sizeof(data
.codec_id
), 1,
13546 tng_data
->input_file
) == 0)
13548 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13549 tng_block_destroy(&block
);
13550 return(TNG_CRITICAL
);
13552 if(tng_data
->output_endianness_swap_func_64
)
13554 if(tng_data
->output_endianness_swap_func_64(tng_data
,
13558 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
13559 __FILE__
, __LINE__
);
13563 if(data
.codec_id
!= TNG_UNCOMPRESSED
)
13565 if(fread(&data
.compression_multiplier
,
13566 sizeof(data
.compression_multiplier
), 1, tng_data
->input_file
)
13569 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13570 tng_block_destroy(&block
);
13571 return(TNG_CRITICAL
);
13573 if(tng_data
->output_endianness_swap_func_64
)
13575 if(tng_data
->output_endianness_swap_func_64(tng_data
,
13576 (int64_t *)&data
.compression_multiplier
)
13579 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
13580 __FILE__
, __LINE__
);
13586 data
.compression_multiplier
= 1;
13591 if(fread(&data
.first_frame_with_data
, sizeof(data
.first_frame_with_data
),
13592 1, tng_data
->input_file
) == 0)
13594 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13595 tng_block_destroy(&block
);
13596 return(TNG_CRITICAL
);
13598 if(tng_data
->output_endianness_swap_func_64
)
13600 if(tng_data
->output_endianness_swap_func_64(tng_data
,
13601 &data
.first_frame_with_data
)
13604 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
13605 __FILE__
, __LINE__
);
13609 if(fread(&data
.stride_length
, sizeof(data
.stride_length
),
13610 1, tng_data
->input_file
) == 0)
13612 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13613 tng_block_destroy(&block
);
13614 return(TNG_CRITICAL
);
13616 if(tng_data
->output_endianness_swap_func_64
)
13618 if(tng_data
->output_endianness_swap_func_64(tng_data
,
13619 &data
.stride_length
)
13622 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
13623 __FILE__
, __LINE__
);
13629 data
.first_frame_with_data
= 0;
13630 data
.stride_length
= 1;
13632 data
.n_frames
= tng_data
->current_trajectory_frame_set
.n_frames
;
13634 tng_data
->input_file
= temp
;
13636 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13637 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13638 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13640 switch(data
.datatype
)
13642 case(TNG_INT_DATA
):
13643 size
= sizeof(int64_t);
13645 case(TNG_FLOAT_DATA
):
13646 size
= sizeof(float);
13648 case(TNG_DOUBLE_DATA
):
13649 size
= sizeof(double);
13652 fprintf(stderr
, "TNG library: Cannot calculate writing locations. %s: %d.\n", __FILE__
,
13654 tng_block_destroy(&block
);
13655 return(TNG_FAILURE
);
13658 n_values_per_frame
= data
.n_values_per_frame
;
13660 file_pos
= (frame_nr
- tng_max_i64(frame_set
->first_frame
,
13661 data
.first_frame_with_data
)) /
13662 data
.stride_length
;
13663 file_pos
*= size
* n_values_per_frame
;
13665 if(file_pos
> contents_size
)
13667 fprintf(stderr
, "TNG library: Attempting to write outside the block. %s: %d\n", __FILE__
,
13669 tng_block_destroy(&block
);
13670 return(TNG_FAILURE
);
13673 fseek(tng_data
->output_file
, (long)file_pos
, SEEK_CUR
);
13675 /* If the endianness is not big endian the data needs to be swapped */
13676 if((data
.datatype
== TNG_INT_DATA
||
13677 data
.datatype
== TNG_DOUBLE_DATA
) &&
13678 tng_data
->output_endianness_swap_func_64
)
13680 copy
= malloc(n_values_per_frame
* size
);
13681 memcpy(copy
, values
, n_values_per_frame
* size
);
13682 for(i
= 0; i
< n_values_per_frame
; i
++)
13684 if(tng_data
->output_endianness_swap_func_64(tng_data
,
13688 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
13689 __FILE__
, __LINE__
);
13692 fwrite(copy
, n_values_per_frame
, size
,
13693 tng_data
->output_file
);
13696 else if(data
.datatype
== TNG_FLOAT_DATA
&&
13697 tng_data
->output_endianness_swap_func_32
)
13699 copy
= malloc(n_values_per_frame
* size
);
13700 memcpy(copy
, values
, n_values_per_frame
* size
);
13701 for(i
= 0; i
< n_values_per_frame
; i
++)
13703 if(tng_data
->output_endianness_swap_func_32(tng_data
,
13707 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
13708 __FILE__
, __LINE__
);
13711 fwrite(copy
, n_values_per_frame
, size
,
13712 tng_data
->output_file
);
13718 fwrite(values
, n_values_per_frame
, size
, tng_data
->output_file
);
13721 fflush(tng_data
->output_file
);
13723 /* Update the number of written frames in the frame set. */
13724 if(frame_nr
- frame_set
->first_frame
+ 1 > frame_set
->n_written_frames
)
13726 frame_set
->n_written_frames
= frame_nr
- frame_set
->first_frame
+ 1;
13729 /* If the last frame has been written update the hash */
13730 if(hash_mode
== TNG_USE_HASH
&& (frame_nr
+ data
.stride_length
-
13731 data
.first_frame_with_data
) >=
13732 frame_set
->n_frames
)
13734 tng_md5_hash_update(tng_data
, block
, header_pos
, header_pos
+
13738 tng_block_destroy(&block
);
13740 return(TNG_SUCCESS
);
13743 tng_function_status DECLSPECDLLEXPORT tng_frame_particle_data_write
13744 (tng_trajectory_t tng_data
,
13745 const int64_t frame_nr
,
13746 const int64_t block_id
,
13747 const int64_t val_first_particle
,
13748 const int64_t val_n_particles
,
13749 const void *values
,
13750 const char hash_mode
)
13752 int64_t header_pos
, file_pos
, tot_n_particles
;
13753 int64_t output_file_len
, n_values_per_frame
, size
, contents_size
;
13754 int64_t header_size
, temp_first
, temp_last
;
13755 int64_t mapping_block_end_pos
, num_first_particle
, block_n_particles
;
13756 int64_t i
, last_frame
;
13758 tng_gen_block_t block
;
13759 tng_trajectory_frame_set_t frame_set
;
13760 FILE *temp
= tng_data
->input_file
;
13761 struct tng_particle_data data
;
13762 tng_function_status stat
;
13763 tng_particle_mapping_t mapping
;
13764 char dependency
, sparse_data
, datatype
;
13767 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
13768 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
13769 TNG_ASSERT(values
, "TNG library: values must not be a NULL pointer.");
13770 TNG_ASSERT(val_first_particle
>= 0, "TNG library: val_first_particle must be >= 0.");
13771 TNG_ASSERT(val_n_particles
>= 0, "TNG library: val_n_particles must be >= 0.");
13773 if(tng_output_file_init(tng_data
) != TNG_SUCCESS
)
13775 fprintf(stderr
, "TNG library: Cannot initialise destination file. %s: %d\n",
13776 __FILE__
, __LINE__
);
13777 return(TNG_CRITICAL
);
13780 temp_first
= tng_data
->first_trajectory_frame_set_input_file_pos
;
13781 temp_last
= tng_data
->last_trajectory_frame_set_input_file_pos
;
13782 temp_current
= tng_data
->current_trajectory_frame_set_input_file_pos
;
13783 tng_data
->first_trajectory_frame_set_input_file_pos
=
13784 tng_data
->first_trajectory_frame_set_output_file_pos
;
13785 tng_data
->last_trajectory_frame_set_input_file_pos
=
13786 tng_data
->last_trajectory_frame_set_output_file_pos
;
13787 tng_data
->current_trajectory_frame_set_input_file_pos
=
13788 tng_data
->current_trajectory_frame_set_output_file_pos
;
13790 tng_data
->input_file
= tng_data
->output_file
;
13792 stat
= tng_frame_set_of_frame_find(tng_data
, frame_nr
);
13794 frame_set
= &tng_data
->current_trajectory_frame_set
;
13796 if(stat
!= TNG_SUCCESS
)
13798 last_frame
= frame_set
->first_frame
+
13799 frame_set
->n_frames
- 1;
13800 /* fprintf(stderr, "TNG library: Frame %"PRId64" not found. Last frame: %"PRId64"\n", frame_nr,
13802 /* If the wanted frame would be in the frame set after the last
13803 * frame set create a new frame set. */
13804 if(stat
== TNG_FAILURE
&&
13805 (last_frame
< frame_nr
&&
13806 last_frame
+ tng_data
->frame_set_n_frames
>= frame_nr
))
13808 if(last_frame
+ tng_data
->frame_set_n_frames
< frame_nr
)
13810 last_frame
= frame_nr
- 1;
13812 tng_frame_set_new(tng_data
,
13814 tng_data
->frame_set_n_frames
);
13816 file_pos
= ftell(tng_data
->output_file
);
13817 fseek(tng_data
->output_file
, 0, SEEK_END
);
13818 output_file_len
= ftell(tng_data
->output_file
);
13819 fseek(tng_data
->output_file
, (long)file_pos
, SEEK_SET
);
13821 /* Read mapping blocks from the last frame set */
13822 tng_block_init(&block
);
13824 stat
= tng_block_header_read(tng_data
, block
);
13825 while(file_pos
< output_file_len
&&
13826 stat
!= TNG_CRITICAL
&&
13827 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
13829 if(block
->id
== TNG_PARTICLE_MAPPING
)
13831 tng_trajectory_mapping_block_read(tng_data
, block
,
13836 fseek(tng_data
->output_file
, (long)block
->block_contents_size
,
13839 file_pos
= ftell(tng_data
->output_file
);
13840 if(file_pos
< output_file_len
)
13842 stat
= tng_block_header_read(tng_data
, block
);
13846 tng_block_destroy(&block
);
13847 /* Write the frame set to disk */
13848 if(tng_frame_set_write(tng_data
, hash_mode
) != TNG_SUCCESS
)
13850 fprintf(stderr
, "TNG library: Error writing frame set. %s: %d\n", __FILE__
, __LINE__
);
13856 tng_data
->input_file
= temp
;
13857 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13858 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13859 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13865 tng_block_init(&block
);
13867 file_pos
= tng_data
->current_trajectory_frame_set_output_file_pos
;
13869 fseek(tng_data
->output_file
, 0, SEEK_END
);
13870 output_file_len
= ftell(tng_data
->output_file
);
13871 fseek(tng_data
->output_file
, (long)file_pos
, SEEK_SET
);
13873 /* Read past the frame set block first */
13874 stat
= tng_block_header_read(tng_data
, block
);
13875 if(stat
== TNG_CRITICAL
)
13877 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
13878 file_pos
, __FILE__
, __LINE__
);
13879 tng_block_destroy(&block
);
13880 tng_data
->input_file
= temp
;
13882 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13883 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13884 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13887 fseek(tng_data
->output_file
, (long)block
->block_contents_size
,
13890 if(tng_data
->var_num_atoms_flag
)
13892 tot_n_particles
= frame_set
->n_particles
;
13896 tot_n_particles
= tng_data
->n_particles
;
13899 if(val_n_particles
< tot_n_particles
)
13901 mapping_block_end_pos
= -1;
13902 /* Read all mapping blocks to find the right place to put the data */
13903 stat
= tng_block_header_read(tng_data
, block
);
13904 while(file_pos
< output_file_len
&&
13905 stat
!= TNG_CRITICAL
&&
13906 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
13908 if(block
->id
== TNG_PARTICLE_MAPPING
)
13910 tng_trajectory_mapping_block_read(tng_data
, block
, hash_mode
);
13914 fseek(tng_data
->output_file
, (long)block
->block_contents_size
,
13917 file_pos
= ftell(tng_data
->output_file
);
13918 if(block
->id
== TNG_PARTICLE_MAPPING
)
13920 mapping
= &frame_set
->mappings
[frame_set
->n_mapping_blocks
- 1];
13921 if(val_first_particle
>= mapping
->num_first_particle
&&
13922 val_first_particle
< mapping
->num_first_particle
+
13923 mapping
->n_particles
&&
13924 val_first_particle
+ val_n_particles
<=
13925 mapping
->num_first_particle
+ mapping
->n_particles
)
13927 mapping_block_end_pos
= file_pos
;
13930 if(file_pos
< output_file_len
)
13932 stat
= tng_block_header_read(tng_data
, block
);
13935 if(stat
== TNG_CRITICAL
)
13937 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
13938 file_pos
, __FILE__
, __LINE__
);
13939 tng_block_destroy(&block
);
13940 tng_data
->input_file
= temp
;
13942 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13943 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13944 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13947 if(mapping_block_end_pos
< 0)
13949 tng_block_destroy(&block
);
13950 tng_data
->input_file
= temp
;
13952 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13953 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13954 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13955 return(TNG_FAILURE
);
13957 fseek(tng_data
->output_file
, (long)mapping_block_end_pos
, SEEK_SET
);
13960 /* Read all block headers until next frame set block or
13961 * until the wanted block id is found */
13962 stat
= tng_block_header_read(tng_data
, block
);
13963 while(file_pos
< output_file_len
&&
13964 stat
!= TNG_CRITICAL
&&
13965 block
->id
!= block_id
&&
13966 block
->id
!= TNG_PARTICLE_MAPPING
&&
13967 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
13969 fseek(tng_data
->output_file
, (long)block
->block_contents_size
, SEEK_CUR
);
13970 file_pos
= ftell(tng_data
->output_file
);
13971 if(file_pos
< output_file_len
)
13973 stat
= tng_block_header_read(tng_data
, block
);
13976 if(stat
== TNG_CRITICAL
)
13978 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
13979 file_pos
, __FILE__
, __LINE__
);
13980 tng_block_destroy(&block
);
13981 tng_data
->input_file
= temp
;
13983 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
13984 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
13985 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
13989 contents_size
= block
->block_contents_size
;
13990 header_size
= block
->header_contents_size
;
13992 header_pos
= ftell(tng_data
->output_file
) - header_size
;
13993 frame_set
= &tng_data
->current_trajectory_frame_set
;
13995 if(fread(&datatype
, sizeof(datatype
), 1, tng_data
->input_file
) == 0)
13997 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
13998 tng_block_destroy(&block
);
13999 return(TNG_CRITICAL
);
14002 data
.datatype
= datatype
;
14004 if(fread(&dependency
, sizeof(dependency
), 1, tng_data
->input_file
) == 0)
14006 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
14007 tng_block_destroy(&block
);
14008 return(TNG_CRITICAL
);
14011 if(!(dependency
& TNG_FRAME_DEPENDENT
) ||
14012 !(dependency
& TNG_PARTICLE_DEPENDENT
))
14014 tng_block_destroy(&block
);
14015 tng_data
->input_file
= temp
;
14017 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
14018 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
14019 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
14020 return(TNG_FAILURE
);
14023 if(fread(&sparse_data
, sizeof(sparse_data
), 1, tng_data
->input_file
) == 0)
14025 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
14026 tng_block_destroy(&block
);
14027 return(TNG_CRITICAL
);
14030 if(fread(&data
.n_values_per_frame
, sizeof(data
.n_values_per_frame
), 1,
14031 tng_data
->input_file
) == 0)
14033 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
14034 tng_block_destroy(&block
);
14035 return(TNG_CRITICAL
);
14037 if(tng_data
->output_endianness_swap_func_64
)
14039 if(tng_data
->output_endianness_swap_func_64(tng_data
,
14040 &data
.n_values_per_frame
)
14043 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
14044 __FILE__
, __LINE__
);
14048 if(fread(&data
.codec_id
, sizeof(data
.codec_id
), 1,
14049 tng_data
->input_file
) == 0)
14051 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
14052 tng_block_destroy(&block
);
14053 return(TNG_CRITICAL
);
14055 if(tng_data
->output_endianness_swap_func_64
)
14057 if(tng_data
->output_endianness_swap_func_64(tng_data
,
14061 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
14062 __FILE__
, __LINE__
);
14066 if(data
.codec_id
!= TNG_UNCOMPRESSED
)
14068 if(fread(&data
.compression_multiplier
,
14069 sizeof(data
.compression_multiplier
), 1, tng_data
->input_file
)
14072 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
14073 tng_block_destroy(&block
);
14074 return(TNG_CRITICAL
);
14077 if(tng_data
->output_endianness_swap_func_64
)
14079 if(tng_data
->output_endianness_swap_func_64(tng_data
,
14080 (int64_t *)&data
.compression_multiplier
)
14083 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
14084 __FILE__
, __LINE__
);
14090 data
.compression_multiplier
= 1;
14095 if(fread(&data
.first_frame_with_data
,
14096 sizeof(data
.first_frame_with_data
),
14097 1, tng_data
->input_file
) == 0)
14099 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
14100 tng_block_destroy(&block
);
14101 return(TNG_CRITICAL
);
14103 if(tng_data
->output_endianness_swap_func_64
)
14105 if(tng_data
->output_endianness_swap_func_64(tng_data
,
14106 &data
.first_frame_with_data
)
14109 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
14110 __FILE__
, __LINE__
);
14114 if(fread(&data
.stride_length
, sizeof(data
.stride_length
),
14115 1, tng_data
->input_file
) == 0)
14117 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
14118 tng_block_destroy(&block
);
14119 return(TNG_CRITICAL
);
14121 if(tng_data
->output_endianness_swap_func_64
)
14123 if(tng_data
->output_endianness_swap_func_64(tng_data
,
14124 &data
.stride_length
)
14127 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
14128 __FILE__
, __LINE__
);
14134 data
.first_frame_with_data
= 0;
14135 data
.stride_length
= 1;
14137 data
.n_frames
= tng_data
->current_trajectory_frame_set
.n_frames
;
14139 if(fread(&num_first_particle
, sizeof(num_first_particle
), 1,
14140 tng_data
->input_file
) == 0)
14142 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
14143 tng_block_destroy(&block
);
14144 return(TNG_CRITICAL
);
14146 if(tng_data
->output_endianness_swap_func_64
)
14148 if(tng_data
->output_endianness_swap_func_64(tng_data
,
14149 &num_first_particle
)
14152 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
14153 __FILE__
, __LINE__
);
14157 if(fread(&block_n_particles
, sizeof(block_n_particles
), 1,
14158 tng_data
->input_file
) == 0)
14160 fprintf(stderr
, "TNG library: Error reading file. %s: %d\n", __FILE__
, __LINE__
);
14161 tng_block_destroy(&block
);
14162 return(TNG_CRITICAL
);
14164 if(tng_data
->output_endianness_swap_func_64
)
14166 if(tng_data
->output_endianness_swap_func_64(tng_data
,
14167 &block_n_particles
)
14170 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
14171 __FILE__
, __LINE__
);
14176 tng_data
->input_file
= temp
;
14178 tng_data
->first_trajectory_frame_set_input_file_pos
= temp_first
;
14179 tng_data
->last_trajectory_frame_set_input_file_pos
= temp_last
;
14180 tng_data
->current_trajectory_frame_set_input_file_pos
= temp_current
;
14183 switch(data
.datatype
)
14185 case(TNG_INT_DATA
):
14186 size
= sizeof(int64_t);
14188 case(TNG_FLOAT_DATA
):
14189 size
= sizeof(float);
14191 case(TNG_DOUBLE_DATA
):
14192 size
= sizeof(double);
14195 fprintf(stderr
, "TNG library: Cannot calculate writing locations. %s: %d.\n", __FILE__
,
14197 tng_block_destroy(&block
);
14198 return(TNG_FAILURE
);
14201 n_values_per_frame
= data
.n_values_per_frame
;
14203 file_pos
= (frame_nr
- tng_max_i64(frame_set
->first_frame
,
14204 data
.first_frame_with_data
)) /
14205 data
.stride_length
;
14206 file_pos
*= block_n_particles
* size
* n_values_per_frame
;
14208 if(file_pos
> contents_size
)
14210 fprintf(stderr
, "TNG library: Attempting to write outside the block. %s: %d\n", __FILE__
,
14212 tng_block_destroy(&block
);
14213 return(TNG_FAILURE
);
14216 fseek(tng_data
->output_file
, (long)file_pos
, SEEK_CUR
);
14218 /* If the endianness is not big endian the data needs to be swapped */
14219 if((data
.datatype
== TNG_INT_DATA
||
14220 data
.datatype
== TNG_DOUBLE_DATA
) &&
14221 tng_data
->output_endianness_swap_func_64
)
14223 copy
= malloc(val_n_particles
* n_values_per_frame
* size
);
14224 memcpy(copy
, values
, val_n_particles
* n_values_per_frame
* size
);
14225 for(i
= 0; i
< val_n_particles
* n_values_per_frame
; i
++)
14227 if(tng_data
->output_endianness_swap_func_64(tng_data
,
14228 (int64_t *) copy
+i
)
14231 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
14232 __FILE__
, __LINE__
);
14235 fwrite(copy
, val_n_particles
* n_values_per_frame
, size
,
14236 tng_data
->output_file
);
14239 else if(data
.datatype
== TNG_FLOAT_DATA
&&
14240 tng_data
->output_endianness_swap_func_32
)
14242 copy
= malloc(val_n_particles
* n_values_per_frame
* size
);
14243 memcpy(copy
, values
, val_n_particles
* n_values_per_frame
* size
);
14244 for(i
= 0; i
< val_n_particles
* n_values_per_frame
; i
++)
14246 if(tng_data
->output_endianness_swap_func_32(tng_data
,
14247 (int32_t *) copy
+i
)
14250 fprintf(stderr
, "TNG library: Cannot swap byte order. %s: %d\n",
14251 __FILE__
, __LINE__
);
14254 fwrite(copy
, val_n_particles
* n_values_per_frame
, size
,
14255 tng_data
->output_file
);
14261 fwrite(values
, val_n_particles
* n_values_per_frame
, size
,
14262 tng_data
->output_file
);
14264 fflush(tng_data
->output_file
);
14266 /* Update the number of written frames in the frame set. */
14267 if(frame_nr
- frame_set
->first_frame
+ 1 > frame_set
->n_written_frames
)
14269 frame_set
->n_written_frames
= frame_nr
- frame_set
->first_frame
+ 1;
14272 /* If the last frame has been written update the hash */
14273 if(hash_mode
== TNG_USE_HASH
&& (frame_nr
+ data
.stride_length
-
14274 data
.first_frame_with_data
) >=
14275 frame_set
->n_frames
)
14277 tng_md5_hash_update(tng_data
, block
, header_pos
, header_pos
+
14281 tng_block_destroy(&block
);
14282 return(TNG_SUCCESS
);
14285 static tng_function_status tng_data_values_alloc
14286 (const tng_trajectory_t tng_data
,
14287 union data_values
***values
,
14288 const int64_t n_frames
,
14289 const int64_t n_values_per_frame
,
14293 tng_function_status stat
;
14295 if(n_frames
<= 0 || n_values_per_frame
<= 0)
14297 return(TNG_FAILURE
);
14302 stat
= tng_data_values_free(tng_data
, *values
, n_frames
,
14303 n_values_per_frame
,
14305 if(stat
!= TNG_SUCCESS
)
14307 fprintf(stderr
, "TNG library: Cannot free particle data values. %s: %d\n",
14308 __FILE__
, __LINE__
);
14312 *values
= malloc(sizeof(union data_values
*) * n_frames
);
14315 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
14316 sizeof(union data_values
**) * n_frames
,
14317 __FILE__
, __LINE__
);
14318 return(TNG_CRITICAL
);
14322 for(i
= n_frames
; i
--;)
14324 (*values
)[i
] = malloc(sizeof(union data_values
) *
14325 n_values_per_frame
);
14328 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
14329 sizeof(union data_values
) * n_values_per_frame
,
14330 __FILE__
, __LINE__
);
14333 return(TNG_CRITICAL
);
14336 return(TNG_SUCCESS
);
14339 /* FIXME: This needs ***values */
14340 tng_function_status DECLSPECDLLEXPORT tng_data_values_free
14341 (const tng_trajectory_t tng_data
,
14342 union data_values
**values
,
14343 const int64_t n_frames
,
14344 const int64_t n_values_per_frame
,
14352 for(i
= 0; i
< n_frames
; i
++)
14356 if(type
== TNG_CHAR_DATA
)
14358 for(j
= n_values_per_frame
; j
--;)
14362 free(values
[i
][j
].c
);
14363 values
[i
][j
].c
= 0;
14375 return(TNG_SUCCESS
);
14378 static tng_function_status tng_particle_data_values_alloc
14379 (const tng_trajectory_t tng_data
,
14380 union data_values
****values
,
14381 const int64_t n_frames
,
14382 const int64_t n_particles
,
14383 const int64_t n_values_per_frame
,
14387 tng_function_status stat
;
14389 if(n_particles
== 0 || n_values_per_frame
== 0)
14391 return(TNG_FAILURE
);
14396 stat
= tng_particle_data_values_free(tng_data
, *values
, n_frames
,
14397 n_particles
, n_values_per_frame
,
14399 if(stat
!= TNG_SUCCESS
)
14401 fprintf(stderr
, "TNG library: Cannot free particle data values. %s: %d\n",
14402 __FILE__
, __LINE__
);
14406 *values
= malloc(sizeof(union data_values
**) * n_frames
);
14409 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
14410 sizeof(union data_values
**) * n_frames
,
14411 __FILE__
, __LINE__
);
14412 return(TNG_CRITICAL
);
14416 for(i
= n_frames
; i
--;)
14418 (*values
)[i
] = malloc(sizeof(union data_values
*) *
14422 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
14423 sizeof(union data_values
*) * n_particles
,
14424 __FILE__
, __LINE__
);
14427 return(TNG_CRITICAL
);
14429 for(j
= n_particles
; j
--;)
14431 (*values
)[i
][j
] = malloc(sizeof(union data_values
) *
14432 n_values_per_frame
);
14433 if(!(*values
)[i
][j
])
14435 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
14436 sizeof(union data_values
*) * n_particles
,
14437 __FILE__
, __LINE__
);
14438 tng_particle_data_values_free(tng_data
, *values
, n_frames
,
14439 n_particles
, n_values_per_frame
,
14442 return(TNG_CRITICAL
);
14446 return(TNG_SUCCESS
);
14449 /* FIXME: This needs ****values */
14450 tng_function_status DECLSPECDLLEXPORT tng_particle_data_values_free
14451 (const tng_trajectory_t tng_data
,
14452 union data_values
***values
,
14453 const int64_t n_frames
,
14454 const int64_t n_particles
,
14455 const int64_t n_values_per_frame
,
14463 for(i
= 0; i
< n_frames
; i
++)
14467 for(j
= 0; j
< n_particles
; j
++)
14469 if(type
== TNG_CHAR_DATA
)
14471 for(k
= n_values_per_frame
; k
--;)
14473 if(values
[i
][j
][k
].c
)
14475 free(values
[i
][j
][k
].c
);
14476 values
[i
][j
][k
].c
= 0;
14480 free(values
[i
][j
]);
14491 return(TNG_SUCCESS
);
14495 tng_function_status DECLSPECDLLEXPORT tng_data_get
14496 (tng_trajectory_t tng_data
,
14497 const int64_t block_id
,
14498 union data_values
***values
,
14500 int64_t *n_values_per_frame
,
14503 int64_t i
, j
, file_pos
, block_index
;
14506 tng_non_particle_data_t data
;
14507 tng_trajectory_frame_set_t frame_set
;
14508 tng_gen_block_t block
;
14509 tng_function_status stat
;
14511 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
14512 TNG_ASSERT(n_frames
, "TNG library: n_frames must not be a NULL pointer.");
14513 TNG_ASSERT(n_values_per_frame
, "TNG library: n_values_per_frame must not be a NULL pointer.");
14514 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer.");
14516 frame_set
= &tng_data
->current_trajectory_frame_set
;
14521 if(tng_data_find(tng_data
, block_id
, &data
) != TNG_SUCCESS
)
14523 tng_block_init(&block
);
14524 file_pos
= ftell(tng_data
->input_file
);
14525 /* Read all blocks until next frame set block */
14526 stat
= tng_block_header_read(tng_data
, block
);
14527 while(file_pos
< tng_data
->input_file_len
&&
14528 stat
!= TNG_CRITICAL
&&
14529 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
14531 /* Use hash by default */
14532 stat
= tng_block_read_next(tng_data
, block
,
14534 if(stat
!= TNG_CRITICAL
)
14536 file_pos
= ftell(tng_data
->input_file
);
14537 if(file_pos
< tng_data
->input_file_len
)
14539 stat
= tng_block_header_read(tng_data
, block
);
14543 tng_block_destroy(&block
);
14544 if(stat
== TNG_CRITICAL
)
14546 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
14547 file_pos
, __FILE__
, __LINE__
);
14551 for(i
= frame_set
->n_data_blocks
; i
-- ;)
14553 data
= &frame_set
->tr_data
[i
];
14554 if(data
->block_id
== block_id
)
14560 if(block_index
< 0)
14562 return(TNG_FAILURE
);
14566 *n_frames
= tng_max_i64(1, data
->n_frames
);
14567 *n_values_per_frame
= data
->n_values_per_frame
;
14568 *type
= data
->datatype
;
14572 if(tng_data_values_alloc(tng_data
, values
, *n_frames
,
14573 *n_values_per_frame
,
14577 return(TNG_CRITICAL
);
14583 case TNG_CHAR_DATA
:
14584 for(i
=*n_frames
; i
--;)
14586 for(j
=*n_values_per_frame
; j
--;)
14588 len
= strlen(data
->strings
[i
][j
]) + 1;
14589 (*values
)[i
][j
].c
= malloc(len
);
14590 strncpy((*values
)[i
][j
].c
, data
->strings
[i
][j
], len
);
14595 size
= sizeof(int);
14596 for(i
=*n_frames
; i
--;)
14598 for(j
=*n_values_per_frame
; j
--;)
14600 (*values
)[i
][j
].i
= *(int *)((char *)data
->values
+ size
*
14601 (i
*(*n_values_per_frame
) + j
));
14605 case TNG_FLOAT_DATA
:
14606 size
= sizeof(float);
14607 for(i
=*n_frames
; i
--;)
14609 for(j
=*n_values_per_frame
; j
--;)
14611 (*values
)[i
][j
].f
= *(float *)((char *)data
->values
+ size
*
14612 (i
*(*n_values_per_frame
) + j
));
14616 case TNG_DOUBLE_DATA
:
14618 size
= sizeof(double);
14619 for(i
=*n_frames
; i
--;)
14621 for(j
=*n_values_per_frame
; j
--;)
14623 (*values
)[i
][j
].d
= *(double *)((char *)data
->values
+ size
*
14624 (i
*(*n_values_per_frame
) + j
));
14629 data
->last_retrieved_frame
= frame_set
->first_frame
+ data
->n_frames
- 1;
14631 return(TNG_SUCCESS
);
14634 tng_function_status
tng_data_vector_get(tng_trajectory_t tng_data
,
14635 const int64_t block_id
,
14638 int64_t *stride_length
,
14639 int64_t *n_values_per_frame
,
14642 int64_t file_pos
, data_size
, n_frames_div
, block_index
;
14644 tng_non_particle_data_t data
;
14645 tng_trajectory_frame_set_t frame_set
;
14646 tng_gen_block_t block
;
14648 tng_function_status stat
;
14650 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
14651 TNG_ASSERT(n_frames
, "TNG library: n_frames must not be a NULL pointer.");
14652 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer.");
14653 TNG_ASSERT(n_values_per_frame
, "TNG library: n_values_per_frame must not be a NULL pointer.");
14654 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer.");
14656 frame_set
= &tng_data
->current_trajectory_frame_set
;
14661 if(tng_data_find(tng_data
, block_id
, &data
) != TNG_SUCCESS
)
14663 tng_block_init(&block
);
14664 file_pos
= ftell(tng_data
->input_file
);
14665 /* Read all blocks until next frame set block */
14666 stat
= tng_block_header_read(tng_data
, block
);
14667 while(file_pos
< tng_data
->input_file_len
&&
14668 stat
!= TNG_CRITICAL
&&
14669 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
14671 /* Use hash by default */
14672 stat
= tng_block_read_next(tng_data
, block
,
14674 if(stat
!= TNG_CRITICAL
)
14676 file_pos
= ftell(tng_data
->input_file
);
14677 if(file_pos
< tng_data
->input_file_len
)
14679 stat
= tng_block_header_read(tng_data
, block
);
14683 tng_block_destroy(&block
);
14684 if(stat
== TNG_CRITICAL
)
14686 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
14687 file_pos
, __FILE__
, __LINE__
);
14691 for(i
= frame_set
->n_data_blocks
; i
-- ;)
14693 data
= &frame_set
->tr_data
[i
];
14694 if(data
->block_id
== block_id
)
14700 if(block_index
< 0)
14702 return(TNG_FAILURE
);
14706 *type
= data
->datatype
;
14710 case TNG_CHAR_DATA
:
14711 return(TNG_FAILURE
);
14713 size
= sizeof(int64_t);
14715 case TNG_FLOAT_DATA
:
14716 size
= sizeof(float);
14718 case TNG_DOUBLE_DATA
:
14720 size
= sizeof(double);
14723 *n_frames
= data
->n_frames
;
14724 *n_values_per_frame
= data
->n_values_per_frame
;
14725 *stride_length
= data
->stride_length
;
14726 n_frames_div
= (*n_frames
% *stride_length
) ? *n_frames
/ *stride_length
+ 1:
14727 *n_frames
/ *stride_length
;
14729 data_size
= n_frames_div
* size
*
14730 *n_values_per_frame
;
14732 temp
= realloc(*values
, data_size
);
14735 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
14736 data_size
, __FILE__
, __LINE__
);
14739 return(TNG_CRITICAL
);
14744 memcpy(*values
, data
->values
, data_size
);
14746 data
->last_retrieved_frame
= frame_set
->first_frame
+ data
->n_frames
- 1;
14748 return(TNG_SUCCESS
);
14751 tng_function_status DECLSPECDLLEXPORT tng_data_interval_get
14752 (tng_trajectory_t tng_data
,
14753 const int64_t block_id
,
14754 const int64_t start_frame_nr
,
14755 const int64_t end_frame_nr
,
14756 const char hash_mode
,
14757 union data_values
***values
,
14758 int64_t *n_values_per_frame
,
14761 int64_t i
, j
, n_frames
, file_pos
, current_frame_pos
, first_frame
;
14762 int64_t block_index
;
14765 tng_non_particle_data_t data
;
14766 tng_trajectory_frame_set_t frame_set
;
14767 tng_gen_block_t block
;
14768 tng_function_status stat
;
14770 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
14771 TNG_ASSERT(start_frame_nr
<= end_frame_nr
, "TNG library: start_frame_nr must not be higher than tne end_frame_nr.");
14772 TNG_ASSERT(n_values_per_frame
, "TNG library: n_values_per_frame must not be a NULL pointer.");
14773 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer.");
14777 frame_set
= &tng_data
->current_trajectory_frame_set
;
14778 first_frame
= frame_set
->first_frame
;
14780 stat
= tng_frame_set_of_frame_find(tng_data
, start_frame_nr
);
14781 if(stat
!= TNG_SUCCESS
)
14787 /* Do not re-read the frame set. */
14788 if(first_frame
!= frame_set
->first_frame
||
14789 frame_set
->n_data_blocks
<= 0)
14791 tng_block_init(&block
);
14792 file_pos
= ftell(tng_data
->input_file
);
14793 /* Read all blocks until next frame set block */
14794 stat
= tng_block_header_read(tng_data
, block
);
14795 while(file_pos
< tng_data
->input_file_len
&&
14796 stat
!= TNG_CRITICAL
&&
14797 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
14799 stat
= tng_block_read_next(tng_data
, block
,
14801 if(stat
!= TNG_CRITICAL
)
14803 file_pos
= ftell(tng_data
->input_file
);
14804 if(file_pos
< tng_data
->input_file_len
)
14806 stat
= tng_block_header_read(tng_data
, block
);
14810 tng_block_destroy(&block
);
14811 if(stat
== TNG_CRITICAL
)
14813 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
14814 file_pos
, __FILE__
, __LINE__
);
14820 /* See if there is a data block of this ID.
14821 * Start checking the last read frame set */
14822 for(i
= frame_set
->n_data_blocks
; i
-- ;)
14824 data
= &frame_set
->tr_data
[i
];
14825 if(data
->block_id
== block_id
)
14832 if(block_index
< 0)
14834 fprintf(stderr
, "TNG library: Could not find non-particle data block with id %"PRId64
". %s: %d\n",
14835 block_id
, __FILE__
, __LINE__
);
14836 return(TNG_FAILURE
);
14839 n_frames
= end_frame_nr
- start_frame_nr
+ 1;
14840 *n_values_per_frame
= data
->n_values_per_frame
;
14841 *type
= data
->datatype
;
14845 if(tng_data_values_alloc(tng_data
, values
, n_frames
,
14846 *n_values_per_frame
,
14847 *type
) != TNG_SUCCESS
)
14849 return(TNG_CRITICAL
);
14853 current_frame_pos
= start_frame_nr
- frame_set
->first_frame
;
14854 /* It's not very elegant to reuse so much of the code in the different case
14855 * statements, but it's unnecessarily slow to have the switch-case block
14856 * inside the for loops. */
14859 case TNG_CHAR_DATA
:
14860 for(i
=0; i
<n_frames
; i
++)
14862 if(current_frame_pos
== frame_set
->n_frames
)
14864 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
14865 if(stat
!= TNG_SUCCESS
)
14869 current_frame_pos
= 0;
14871 for(j
=*n_values_per_frame
; j
--;)
14873 len
= strlen(data
->strings
[current_frame_pos
][j
]) + 1;
14874 (*values
)[i
][j
].c
= malloc(len
);
14875 strncpy((*values
)[i
][j
].c
, data
->strings
[current_frame_pos
][j
], len
);
14877 current_frame_pos
++;
14881 size
= sizeof(int);
14882 for(i
=0; i
<n_frames
; i
++)
14884 if(current_frame_pos
== frame_set
->n_frames
)
14886 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
14887 if(stat
!= TNG_SUCCESS
)
14891 current_frame_pos
= 0;
14893 for(j
=*n_values_per_frame
; j
--;)
14895 (*values
)[i
][j
].i
= *(int *)((char *)data
->values
+ size
*
14896 (current_frame_pos
*
14897 (*n_values_per_frame
) + j
));
14899 current_frame_pos
++;
14902 case TNG_FLOAT_DATA
:
14903 size
= sizeof(float);
14904 for(i
=0; i
<n_frames
; i
++)
14906 if(current_frame_pos
== frame_set
->n_frames
)
14908 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
14909 if(stat
!= TNG_SUCCESS
)
14913 current_frame_pos
= 0;
14915 for(j
=*n_values_per_frame
; j
--;)
14917 (*values
)[i
][j
].f
= *(float *)((char *)data
->values
+ size
*
14918 (current_frame_pos
*
14919 (*n_values_per_frame
) + j
));
14921 current_frame_pos
++;
14924 case TNG_DOUBLE_DATA
:
14926 size
= sizeof(double);
14927 for(i
=0; i
<n_frames
; i
++)
14929 if(current_frame_pos
== frame_set
->n_frames
)
14931 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
14932 if(stat
!= TNG_SUCCESS
)
14936 current_frame_pos
= 0;
14938 for(j
=*n_values_per_frame
; j
--;)
14940 (*values
)[i
][j
].d
= *(double *)((char *)data
->values
+ size
*
14941 (current_frame_pos
*
14942 (*n_values_per_frame
) + j
));
14944 current_frame_pos
++;
14948 data
->last_retrieved_frame
= end_frame_nr
;
14950 return(TNG_SUCCESS
);
14953 tng_function_status DECLSPECDLLEXPORT tng_data_vector_interval_get
14954 (tng_trajectory_t tng_data
,
14955 const int64_t block_id
,
14956 const int64_t start_frame_nr
,
14957 const int64_t end_frame_nr
,
14958 const char hash_mode
,
14960 int64_t *stride_length
,
14961 int64_t *n_values_per_frame
,
14964 int64_t n_frames
, tot_n_frames
, n_frames_div
, n_frames_div_2
, first_frame
;
14965 int64_t file_pos
, current_frame_pos
, data_size
, frame_size
;
14966 int64_t last_frame_pos
;
14968 tng_trajectory_frame_set_t frame_set
;
14969 tng_non_particle_data_t np_data
;
14970 tng_gen_block_t block
;
14971 void *current_values
= 0, *temp
;
14972 tng_function_status stat
;
14974 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
14975 TNG_ASSERT(start_frame_nr
<= end_frame_nr
, "TNG library: start_frame_nr must not be higher than the end_frame_nr.");
14976 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer.");
14977 TNG_ASSERT(n_values_per_frame
, "TNG library: n_values_per_frame must not be a NULL pointer.");
14978 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer.");
14980 frame_set
= &tng_data
->current_trajectory_frame_set
;
14981 first_frame
= frame_set
->first_frame
;
14983 stat
= tng_frame_set_of_frame_find(tng_data
, start_frame_nr
);
14984 if(stat
!= TNG_SUCCESS
)
14989 /* Do not re-read the frame set and only need the requested block. */
14990 /* TODO: Test that blocks are read correctly now that not all of them are read at the same time. */
14991 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
14992 if(first_frame
!= frame_set
->first_frame
||
14993 stat
!= TNG_SUCCESS
)
14995 tng_block_init(&block
);
14996 if(stat
!= TNG_SUCCESS
)
14998 fseek(tng_data
->input_file
,
14999 (long)tng_data
->current_trajectory_frame_set_input_file_pos
,
15001 stat
= tng_block_header_read(tng_data
, block
);
15002 if(stat
!= TNG_SUCCESS
)
15004 fprintf(stderr
, "TNG library: Cannot read block header. %s: %d\n",
15005 __FILE__
, __LINE__
);
15009 fseek(tng_data
->input_file
, (long)block
->block_contents_size
, SEEK_CUR
);
15011 file_pos
= ftell(tng_data
->input_file
);
15012 /* Read until next frame set block */
15013 stat
= tng_block_header_read(tng_data
, block
);
15014 while(file_pos
< tng_data
->input_file_len
&&
15015 stat
!= TNG_CRITICAL
&&
15016 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
15018 if(block
->id
== block_id
)
15020 stat
= tng_block_read_next(tng_data
, block
,
15022 if(stat
!= TNG_CRITICAL
)
15024 file_pos
= ftell(tng_data
->input_file
);
15025 if(file_pos
< tng_data
->input_file_len
)
15027 stat
= tng_block_header_read(tng_data
, block
);
15033 file_pos
+= block
->block_contents_size
+ block
->header_contents_size
;
15034 fseek(tng_data
->input_file
, (long)block
->block_contents_size
, SEEK_CUR
);
15035 if(file_pos
< tng_data
->input_file_len
)
15037 stat
= tng_block_header_read(tng_data
, block
);
15041 tng_block_destroy(&block
);
15042 if(stat
== TNG_CRITICAL
)
15044 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
15045 file_pos
, __FILE__
, __LINE__
);
15050 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
15051 if(stat
!= TNG_SUCCESS
)
15056 stat
= tng_data_vector_get(tng_data
, block_id
, ¤t_values
,
15057 &n_frames
, stride_length
,
15058 n_values_per_frame
, type
);
15060 if(stat
!= TNG_SUCCESS
)
15064 free(current_values
);
15069 if(n_frames
== 1 && n_frames
< frame_set
->n_frames
)
15075 tot_n_frames
= end_frame_nr
- start_frame_nr
+ 1;
15080 case TNG_CHAR_DATA
:
15081 return(TNG_FAILURE
);
15083 size
= sizeof(int64_t);
15085 case TNG_FLOAT_DATA
:
15086 size
= sizeof(float);
15088 case TNG_DOUBLE_DATA
:
15090 size
= sizeof(double);
15093 n_frames_div
= (tot_n_frames
% *stride_length
) ?
15094 tot_n_frames
/ *stride_length
+ 1:
15095 tot_n_frames
/ *stride_length
;
15096 data_size
= n_frames_div
* size
* (*n_values_per_frame
);
15098 /* fprintf(stderr, "TNG library: size: %d, n_frames_div: %"PRId64", data_size: %"PRId64"\n",
15099 size, n_frames_div, data_size);
15101 temp
= realloc(*values
, data_size
);
15104 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
15105 data_size
, __FILE__
, __LINE__
);
15108 return(TNG_CRITICAL
);
15113 if( n_frames
== 1 && n_frames
< frame_set
->n_frames
)
15115 memcpy(*values
, current_values
, size
* (*n_values_per_frame
));
15119 current_frame_pos
= start_frame_nr
- frame_set
->first_frame
;
15121 frame_size
= size
* (*n_values_per_frame
);
15123 last_frame_pos
= tng_min_i64(n_frames
,
15124 end_frame_nr
- start_frame_nr
);
15126 n_frames_div
= current_frame_pos
/ *stride_length
;
15127 n_frames_div_2
= (last_frame_pos
% *stride_length
) ?
15128 last_frame_pos
/ *stride_length
+ 1:
15129 last_frame_pos
/ *stride_length
;
15130 n_frames_div_2
= tng_max_i64(1, n_frames_div_2
);
15132 memcpy(*values
, (char *)current_values
+ n_frames_div
* frame_size
,
15133 n_frames_div_2
* frame_size
);
15135 current_frame_pos
+= n_frames
- current_frame_pos
;
15137 while(current_frame_pos
<= end_frame_nr
- start_frame_nr
)
15139 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
15140 if(stat
!= TNG_SUCCESS
)
15144 free(current_values
);
15151 stat
= tng_data_vector_get(tng_data
, block_id
, ¤t_values
,
15152 &n_frames
, stride_length
,
15153 n_values_per_frame
, type
);
15155 if(stat
!= TNG_SUCCESS
)
15159 free(current_values
);
15166 last_frame_pos
= tng_min_i64(n_frames
,
15167 end_frame_nr
- current_frame_pos
);
15169 n_frames_div
= current_frame_pos
/ *stride_length
;
15170 n_frames_div_2
= (last_frame_pos
% *stride_length
) ?
15171 last_frame_pos
/ *stride_length
+ 1:
15172 last_frame_pos
/ *stride_length
;
15173 n_frames_div_2
= tng_max_i64(1, n_frames_div_2
);
15175 memcpy(((char *)*values
) + n_frames_div
* frame_size
,
15177 n_frames_div_2
* frame_size
);
15179 current_frame_pos
+= n_frames
;
15185 free(current_values
);
15188 np_data
->last_retrieved_frame
= end_frame_nr
;
15190 return(TNG_SUCCESS
);
15193 tng_function_status DECLSPECDLLEXPORT tng_particle_data_get
15194 (tng_trajectory_t tng_data
,
15195 const int64_t block_id
,
15196 union data_values
****values
,
15198 int64_t *n_particles
,
15199 int64_t *n_values_per_frame
,
15202 int64_t i
, j
, k
, mapping
, file_pos
, i_step
, block_index
;
15205 tng_particle_data_t data
;
15206 tng_trajectory_frame_set_t frame_set
;
15207 tng_gen_block_t block
;
15208 char block_type_flag
;
15209 tng_function_status stat
;
15211 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
15212 TNG_ASSERT(n_frames
, "TNG library: n_frames must not be a NULL pointer.");
15213 TNG_ASSERT(n_particles
, "TNG library: n_particles must not be a NULL pointer.");
15214 TNG_ASSERT(n_values_per_frame
, "TNG library: n_values_per_frame must not be a NULL pointer.");
15215 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer.");
15217 frame_set
= &tng_data
->current_trajectory_frame_set
;
15222 if(tng_particle_data_find(tng_data
, block_id
, &data
) != TNG_SUCCESS
)
15224 if(tng_data
->current_trajectory_frame_set_input_file_pos
> 0)
15226 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
15230 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
15233 tng_block_init(&block
);
15234 file_pos
= ftell(tng_data
->input_file
);
15235 /* Read all blocks until next frame set block */
15236 stat
= tng_block_header_read(tng_data
, block
);
15237 while(file_pos
< tng_data
->input_file_len
&&
15238 stat
!= TNG_CRITICAL
&&
15239 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
15241 /* Use hash by default */
15242 stat
= tng_block_read_next(tng_data
, block
,
15244 if(stat
!= TNG_CRITICAL
)
15246 file_pos
= ftell(tng_data
->input_file
);
15247 if(file_pos
< tng_data
->input_file_len
)
15249 stat
= tng_block_header_read(tng_data
, block
);
15253 tng_block_destroy(&block
);
15254 if(stat
== TNG_CRITICAL
)
15256 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
15257 file_pos
, __FILE__
, __LINE__
);
15261 for(i
= frame_set
->n_particle_data_blocks
; i
-- ;)
15263 data
= &frame_set
->tr_particle_data
[i
];
15264 if(data
->block_id
== block_id
)
15267 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
15271 if(block_index
< 0)
15273 return(TNG_FAILURE
);
15278 if(tng_data
->current_trajectory_frame_set_input_file_pos
> 0)
15280 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
15284 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
15288 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
&&
15289 tng_data
->var_num_atoms_flag
)
15291 *n_particles
= frame_set
->n_particles
;
15295 *n_particles
= tng_data
->n_particles
;
15298 *n_frames
= tng_max_i64(1, data
->n_frames
);
15299 *n_values_per_frame
= data
->n_values_per_frame
;
15300 *type
= data
->datatype
;
15304 if(tng_particle_data_values_alloc(tng_data
, values
, *n_frames
,
15305 *n_particles
, *n_values_per_frame
,
15309 return(TNG_CRITICAL
);
15313 /* It's not very elegant to reuse so much of the code in the different case
15314 * statements, but it's unnecessarily slow to have the switch-case block
15315 * inside the for loops. */
15318 case TNG_CHAR_DATA
:
15319 for(i
=*n_frames
; i
--;)
15321 for(j
=*n_particles
; j
--;)
15323 tng_particle_mapping_get_real_particle(frame_set
, j
, &mapping
);
15324 for(k
=*n_values_per_frame
; k
--;)
15326 len
= strlen(data
->strings
[i
][j
][k
]) + 1;
15327 (*values
)[i
][mapping
][k
].c
= malloc(len
);
15328 strncpy((*values
)[i
][mapping
][k
].c
,
15329 data
->strings
[i
][j
][k
], len
);
15335 size
= sizeof(int);
15336 i_step
= (*n_particles
) * (*n_values_per_frame
);
15337 for(i
=*n_frames
; i
--;)
15339 for(j
=*n_particles
; j
--;)
15341 tng_particle_mapping_get_real_particle(frame_set
, j
, &mapping
);
15342 for(k
=*n_values_per_frame
; k
--;)
15344 (*values
)[i
][mapping
][k
].i
= *(int *)
15345 ((char *)data
->values
+ size
*
15347 (*n_values_per_frame
) + k
));
15352 case TNG_FLOAT_DATA
:
15353 size
= sizeof(float);
15354 i_step
= (*n_particles
) * (*n_values_per_frame
);
15355 for(i
=*n_frames
; i
--;)
15357 for(j
=*n_particles
; j
--;)
15359 tng_particle_mapping_get_real_particle(frame_set
, j
, &mapping
);
15360 for(k
=*n_values_per_frame
; k
--;)
15362 (*values
)[i
][mapping
][k
].f
= *(float *)
15363 ((char *)data
->values
+ size
*
15365 (*n_values_per_frame
) + k
));
15370 case TNG_DOUBLE_DATA
:
15372 size
= sizeof(double);
15373 i_step
= (*n_particles
) * (*n_values_per_frame
);
15374 for(i
=*n_frames
; i
--;)
15376 for(j
=*n_particles
; j
--;)
15378 tng_particle_mapping_get_real_particle(frame_set
, j
, &mapping
);
15379 for(k
=*n_values_per_frame
; k
--;)
15381 (*values
)[i
][mapping
][k
].d
= *(double *)
15382 ((char *)data
->values
+ size
*
15384 (*n_values_per_frame
) + k
));
15390 data
->last_retrieved_frame
= frame_set
->first_frame
+ data
->n_frames
- 1;
15392 return(TNG_SUCCESS
);
15395 tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_get
15396 (tng_trajectory_t tng_data
,
15397 const int64_t block_id
,
15400 int64_t *stride_length
,
15401 int64_t *n_particles
,
15402 int64_t *n_values_per_frame
,
15405 int64_t i
, j
, mapping
, file_pos
, i_step
, data_size
, n_frames_div
;
15406 int64_t block_index
;
15408 tng_particle_data_t data
;
15409 tng_trajectory_frame_set_t frame_set
;
15410 tng_gen_block_t block
;
15412 char block_type_flag
;
15413 tng_function_status stat
;
15415 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
15416 TNG_ASSERT(n_particles
, "TNG library: n_particles must not be a NULL pointer.");
15417 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer.");
15418 TNG_ASSERT(n_values_per_frame
, "TNG library: n_values_per_frame must not be a NULL pointer.");
15419 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer.");
15421 frame_set
= &tng_data
->current_trajectory_frame_set
;
15426 if(tng_particle_data_find(tng_data
, block_id
, &data
) != TNG_SUCCESS
)
15428 tng_block_init(&block
);
15429 file_pos
= ftell(tng_data
->input_file
);
15430 /* Read all blocks until next frame set block */
15431 stat
= tng_block_header_read(tng_data
, block
);
15432 while(file_pos
< tng_data
->input_file_len
&&
15433 stat
!= TNG_CRITICAL
&&
15434 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
15436 /* Use hash by default */
15437 stat
= tng_block_read_next(tng_data
, block
,
15439 if(stat
!= TNG_CRITICAL
)
15441 file_pos
= ftell(tng_data
->input_file
);
15442 if(file_pos
< tng_data
->input_file_len
)
15444 stat
= tng_block_header_read(tng_data
, block
);
15448 tng_block_destroy(&block
);
15449 if(stat
== TNG_CRITICAL
)
15451 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
15452 file_pos
, __FILE__
, __LINE__
);
15456 for(i
= frame_set
->n_particle_data_blocks
; i
-- ;)
15458 data
= &frame_set
->tr_particle_data
[i
];
15459 if(data
->block_id
== block_id
)
15465 if(block_index
< 0)
15467 return(TNG_FAILURE
);
15471 if(tng_data
->current_trajectory_frame_set_input_file_pos
> 0)
15473 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
15477 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
15480 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
&&
15481 tng_data
->var_num_atoms_flag
)
15483 *n_particles
= frame_set
->n_particles
;
15487 *n_particles
= tng_data
->n_particles
;
15490 *type
= data
->datatype
;
15494 case TNG_CHAR_DATA
:
15495 return(TNG_FAILURE
);
15497 size
= sizeof(int64_t);
15499 case TNG_FLOAT_DATA
:
15500 size
= sizeof(float);
15502 case TNG_DOUBLE_DATA
:
15504 size
= sizeof(double);
15507 *n_frames
= tng_max_i64(1, data
->n_frames
);
15508 *n_values_per_frame
= data
->n_values_per_frame
;
15509 *stride_length
= data
->stride_length
;
15511 n_frames_div
= (*n_frames
% *stride_length
) ?
15512 *n_frames
/ *stride_length
+ 1:
15513 *n_frames
/ *stride_length
;
15515 data_size
= n_frames_div
* size
* (*n_particles
) *
15516 (*n_values_per_frame
);
15518 temp
= realloc(*values
, data_size
);
15521 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
15522 data_size
, __FILE__
, __LINE__
);
15525 return(TNG_CRITICAL
);
15530 if(frame_set
->n_mapping_blocks
<= 0)
15532 memcpy(*values
, data
->values
, data_size
);
15536 i_step
= (*n_particles
) * (*n_values_per_frame
);
15537 for(i
= *n_frames
; i
--;)
15539 for(j
= *n_particles
; j
--;)
15541 tng_particle_mapping_get_real_particle(frame_set
, j
, &mapping
);
15542 memcpy(((char *)*values
) + size
* (i
* i_step
+ mapping
*
15543 (*n_values_per_frame
)),
15544 (char *)data
->values
+ size
*
15545 (i
* i_step
+ j
* (*n_values_per_frame
)),
15546 size
* (*n_values_per_frame
));
15551 data
->last_retrieved_frame
= frame_set
->first_frame
+ data
->n_frames
- 1;
15553 return(TNG_SUCCESS
);
15556 tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get
15557 (tng_trajectory_t tng_data
,
15558 const int64_t block_id
,
15559 const int64_t start_frame_nr
,
15560 const int64_t end_frame_nr
,
15561 const char hash_mode
,
15562 union data_values
****values
,
15563 int64_t *n_particles
,
15564 int64_t *n_values_per_frame
,
15567 int64_t i
, j
, k
, mapping
, n_frames
, file_pos
, current_frame_pos
, i_step
;
15568 int64_t first_frame
, block_index
;
15571 tng_particle_data_t data
;
15572 tng_trajectory_frame_set_t frame_set
;
15573 tng_gen_block_t block
;
15574 char block_type_flag
;
15575 tng_function_status stat
;
15577 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
15578 TNG_ASSERT(start_frame_nr
<= end_frame_nr
, "TNG library: start_frame_nr must not be higher than tne end_frame_nr.");
15579 TNG_ASSERT(n_particles
, "TNG library: n_particles must not be a NULL pointer.");
15580 TNG_ASSERT(n_values_per_frame
, "TNG library: n_values_per_frame must not be a NULL pointer.");
15581 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer.");
15585 frame_set
= &tng_data
->current_trajectory_frame_set
;
15586 first_frame
= frame_set
->first_frame
;
15588 stat
= tng_frame_set_of_frame_find(tng_data
, start_frame_nr
);
15589 if(stat
!= TNG_SUCCESS
)
15594 /* Do not re-read the frame set. */
15595 if(first_frame
!= frame_set
->first_frame
||
15596 frame_set
->n_particle_data_blocks
<= 0)
15598 tng_block_init(&block
);
15599 file_pos
= ftell(tng_data
->input_file
);
15600 /* Read all blocks until next frame set block */
15601 stat
= tng_block_header_read(tng_data
, block
);
15602 while(file_pos
< tng_data
->input_file_len
&&
15603 stat
!= TNG_CRITICAL
&&
15604 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
15606 stat
= tng_block_read_next(tng_data
, block
,
15608 if(stat
!= TNG_CRITICAL
)
15610 file_pos
= ftell(tng_data
->input_file
);
15611 if(file_pos
< tng_data
->input_file_len
)
15613 stat
= tng_block_header_read(tng_data
, block
);
15617 tng_block_destroy(&block
);
15618 if(stat
== TNG_CRITICAL
)
15620 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
15621 file_pos
, __FILE__
, __LINE__
);
15626 /* See if there is already a data block of this ID.
15627 * Start checking the last read frame set */
15628 for(i
= frame_set
->n_particle_data_blocks
; i
-- ;)
15630 data
= &frame_set
->tr_particle_data
[i
];
15631 if(data
->block_id
== block_id
)
15634 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
15639 if(block_index
< 0)
15641 fprintf(stderr
, "TNG library: Could not find particle data block with id %"PRId64
". %s: %d\n",
15642 block_id
, __FILE__
, __LINE__
);
15643 return(TNG_FAILURE
);
15646 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
&&
15647 tng_data
->var_num_atoms_flag
)
15649 *n_particles
= frame_set
->n_particles
;
15653 *n_particles
= tng_data
->n_particles
;
15656 n_frames
= end_frame_nr
- start_frame_nr
+ 1;
15657 *n_values_per_frame
= data
->n_values_per_frame
;
15658 *type
= data
->datatype
;
15662 if(tng_particle_data_values_alloc(tng_data
, values
, n_frames
,
15663 *n_particles
, *n_values_per_frame
,
15667 return(TNG_CRITICAL
);
15671 current_frame_pos
= start_frame_nr
- frame_set
->first_frame
;
15672 /* It's not very elegant to reuse so much of the code in the different case
15673 * statements, but it's unnecessarily slow to have the switch-case block
15674 * inside the for loops. */
15677 case TNG_CHAR_DATA
:
15678 for(i
=0; i
<n_frames
; i
++)
15680 if(current_frame_pos
== frame_set
->n_frames
)
15682 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
15683 if(stat
!= TNG_SUCCESS
)
15687 current_frame_pos
= 0;
15689 for(j
=*n_particles
; j
--;)
15691 tng_particle_mapping_get_real_particle(frame_set
, j
, &mapping
);
15692 for(k
=*n_values_per_frame
; k
--;)
15694 len
= strlen(data
->strings
[current_frame_pos
][j
][k
]) + 1;
15695 (*values
)[i
][mapping
][k
].c
= malloc(len
);
15696 strncpy((*values
)[i
][mapping
][k
].c
, data
->strings
[current_frame_pos
][j
][k
], len
);
15699 current_frame_pos
++;
15703 size
= sizeof(int);
15704 i_step
= (*n_particles
) * (*n_values_per_frame
);
15705 for(i
=0; i
<n_frames
; i
++)
15707 if(current_frame_pos
== frame_set
->n_frames
)
15709 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
15710 if(stat
!= TNG_SUCCESS
)
15714 current_frame_pos
= 0;
15716 for(j
=*n_particles
; j
--;)
15718 tng_particle_mapping_get_real_particle(frame_set
, j
, &mapping
);
15719 for(k
=*n_values_per_frame
; k
--;)
15721 (*values
)[i
][mapping
][k
].i
= *(int *)
15722 ((char *)data
->values
+ size
*
15723 (current_frame_pos
*
15725 (*n_values_per_frame
) + k
));
15728 current_frame_pos
++;
15731 case TNG_FLOAT_DATA
:
15732 size
= sizeof(float);
15733 i_step
= (*n_particles
) * (*n_values_per_frame
);
15734 for(i
=0; i
<n_frames
; i
++)
15736 if(current_frame_pos
== frame_set
->n_frames
)
15738 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
15739 if(stat
!= TNG_SUCCESS
)
15743 current_frame_pos
= 0;
15745 for(j
=*n_particles
; j
--;)
15747 tng_particle_mapping_get_real_particle(frame_set
, j
, &mapping
);
15748 for(k
=*n_values_per_frame
; k
--;)
15750 (*values
)[i
][mapping
][k
].f
= *(float *)
15751 ((char *)data
->values
+ size
*
15752 (current_frame_pos
*
15754 (*n_values_per_frame
) + k
));
15757 current_frame_pos
++;
15760 case TNG_DOUBLE_DATA
:
15762 size
= sizeof(double);
15763 i_step
= (*n_particles
) * (*n_values_per_frame
);
15764 for(i
=0; i
<n_frames
; i
++)
15766 if(current_frame_pos
== frame_set
->n_frames
)
15768 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
15769 if(stat
!= TNG_SUCCESS
)
15773 current_frame_pos
= 0;
15775 for(j
=*n_particles
; j
--;)
15777 tng_particle_mapping_get_real_particle(frame_set
, j
, &mapping
);
15778 for(k
=*n_values_per_frame
; k
--;)
15780 (*values
)[i
][mapping
][k
].d
= *(double *)
15781 ((char *)data
->values
+ size
*
15782 (current_frame_pos
*
15784 (*n_values_per_frame
) + k
));
15787 current_frame_pos
++;
15791 data
->last_retrieved_frame
= end_frame_nr
;
15793 return(TNG_SUCCESS
);
15796 tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_interval_get
15797 (tng_trajectory_t tng_data
,
15798 const int64_t block_id
,
15799 const int64_t start_frame_nr
,
15800 const int64_t end_frame_nr
,
15801 const char hash_mode
,
15803 int64_t *n_particles
,
15804 int64_t *stride_length
,
15805 int64_t *n_values_per_frame
,
15808 int64_t n_frames
, tot_n_frames
, n_frames_div
, n_frames_div_2
, first_frame
;
15809 int64_t file_pos
, current_frame_pos
, last_frame_pos
, data_size
, frame_size
;
15811 tng_trajectory_frame_set_t frame_set
;
15812 tng_particle_data_t p_data
;
15813 tng_gen_block_t block
;
15814 void *current_values
= 0, *temp
;
15815 tng_function_status stat
;
15817 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
15818 TNG_ASSERT(start_frame_nr
<= end_frame_nr
, "TNG library: start_frame_nr must not be higher than tne end_frame_nr.");
15819 TNG_ASSERT(n_particles
, "TNG library: n_particles must not be a NULL pointer.");
15820 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer.");
15821 TNG_ASSERT(n_values_per_frame
, "TNG library: n_values_per_frame must not be a NULL pointer.");
15822 TNG_ASSERT(type
, "TNG library: type must not be a NULL pointer.");
15824 frame_set
= &tng_data
->current_trajectory_frame_set
;
15825 first_frame
= frame_set
->first_frame
;
15827 stat
= tng_frame_set_of_frame_find(tng_data
, start_frame_nr
);
15828 if(stat
!= TNG_SUCCESS
)
15833 /* Do not re-read the frame set and only need the requested block + particle mapping blocks. */
15834 /* TODO: Test that blocks are read correctly now that now all of them are read at the same time. */
15835 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
15836 if(first_frame
!= frame_set
->first_frame
||
15837 stat
!= TNG_SUCCESS
)
15839 tng_block_init(&block
);
15840 if(stat
!= TNG_SUCCESS
)
15842 fseek(tng_data
->input_file
,
15843 (long)tng_data
->current_trajectory_frame_set_input_file_pos
,
15845 stat
= tng_block_header_read(tng_data
, block
);
15846 if(stat
!= TNG_SUCCESS
)
15848 fprintf(stderr
, "TNG library: Cannot read block header. %s: %d\n",
15849 __FILE__
, __LINE__
);
15853 fseek(tng_data
->input_file
, (long)block
->block_contents_size
, SEEK_CUR
);
15855 file_pos
= ftell(tng_data
->input_file
);
15856 /* Read until next frame set block */
15857 stat
= tng_block_header_read(tng_data
, block
);
15858 while(file_pos
< tng_data
->input_file_len
&&
15859 stat
!= TNG_CRITICAL
&&
15860 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
15862 if(block
->id
== block_id
|| block
->id
== TNG_PARTICLE_MAPPING
)
15864 stat
= tng_block_read_next(tng_data
, block
,
15866 if(stat
!= TNG_CRITICAL
)
15868 file_pos
= ftell(tng_data
->input_file
);
15869 if(file_pos
< tng_data
->input_file_len
)
15871 stat
= tng_block_header_read(tng_data
, block
);
15877 file_pos
+= block
->block_contents_size
+ block
->header_contents_size
;
15878 fseek(tng_data
->input_file
, (long)block
->block_contents_size
, SEEK_CUR
);
15879 if(file_pos
< tng_data
->input_file_len
)
15881 stat
= tng_block_header_read(tng_data
, block
);
15885 tng_block_destroy(&block
);
15886 if(stat
== TNG_CRITICAL
)
15888 fprintf(stderr
, "TNG library: Cannot read block header at pos %"PRId64
". %s: %d\n",
15889 file_pos
, __FILE__
, __LINE__
);
15893 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
15894 if(stat
!= TNG_SUCCESS
)
15899 stat
= tng_particle_data_vector_get(tng_data
, block_id
, ¤t_values
,
15900 &n_frames
, stride_length
, n_particles
,
15901 n_values_per_frame
, type
);
15903 if(stat
!= TNG_SUCCESS
|| *n_particles
== 0)
15907 free(current_values
);
15912 if(n_frames
== 1 && n_frames
< frame_set
->n_frames
)
15918 tot_n_frames
= end_frame_nr
- start_frame_nr
+ 1;
15923 case TNG_CHAR_DATA
:
15924 return(TNG_FAILURE
);
15926 size
= sizeof(int64_t);
15928 case TNG_FLOAT_DATA
:
15929 size
= sizeof(float);
15931 case TNG_DOUBLE_DATA
:
15933 size
= sizeof(double);
15936 n_frames_div
= (tot_n_frames
% *stride_length
) ?
15937 tot_n_frames
/ *stride_length
+ 1:
15938 tot_n_frames
/ *stride_length
;
15940 data_size
= n_frames_div
* size
* (*n_particles
) *
15941 (*n_values_per_frame
);
15943 temp
= realloc(*values
, data_size
);
15946 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
15947 data_size
, __FILE__
, __LINE__
);
15950 return(TNG_CRITICAL
);
15955 if( n_frames
== 1 && n_frames
< frame_set
->n_frames
)
15957 memcpy(*values
, current_values
, size
* (*n_particles
) *
15958 (*n_values_per_frame
));
15962 current_frame_pos
= start_frame_nr
- frame_set
->first_frame
;
15964 frame_size
= size
* (*n_particles
) * (*n_values_per_frame
);
15966 last_frame_pos
= tng_min_i64(n_frames
,
15967 end_frame_nr
- start_frame_nr
);
15969 n_frames_div
= current_frame_pos
/ *stride_length
;
15970 n_frames_div_2
= (last_frame_pos
% *stride_length
) ?
15971 last_frame_pos
/ *stride_length
+ 1:
15972 last_frame_pos
/ *stride_length
;
15973 n_frames_div_2
= tng_max_i64(1, n_frames_div_2
+ 1);
15975 memcpy(*values
, (char *)current_values
+ n_frames_div
* frame_size
,
15976 n_frames_div_2
* frame_size
);
15978 current_frame_pos
+= n_frames
- current_frame_pos
;
15980 while(current_frame_pos
<= end_frame_nr
- start_frame_nr
)
15982 stat
= tng_frame_set_read_next(tng_data
, hash_mode
);
15983 if(stat
!= TNG_SUCCESS
)
15987 free(current_values
);
15994 stat
= tng_particle_data_vector_get(tng_data
, block_id
, ¤t_values
,
15995 &n_frames
, stride_length
, n_particles
,
15996 n_values_per_frame
, type
);
15998 if(stat
!= TNG_SUCCESS
)
16002 free(current_values
);
16009 last_frame_pos
= tng_min_i64(n_frames
,
16010 end_frame_nr
- current_frame_pos
);
16012 n_frames_div
= current_frame_pos
/ *stride_length
;
16013 n_frames_div_2
= (last_frame_pos
% *stride_length
) ?
16014 last_frame_pos
/ *stride_length
+ 1:
16015 last_frame_pos
/ *stride_length
;
16016 n_frames_div_2
= tng_max_i64(1, n_frames_div_2
);
16018 memcpy(((char *)*values
) + n_frames_div
* frame_size
,
16020 n_frames_div_2
* frame_size
);
16022 current_frame_pos
+= n_frames
;
16028 free(current_values
);
16031 p_data
->last_retrieved_frame
= end_frame_nr
;
16033 return(TNG_SUCCESS
);
16036 tng_function_status DECLSPECDLLEXPORT tng_data_get_stride_length
16037 (const tng_trajectory_t tng_data
,
16038 const int64_t block_id
,
16040 int64_t *stride_length
)
16042 tng_function_status stat
;
16043 tng_non_particle_data_t np_data
;
16044 tng_particle_data_t p_data
;
16045 long orig_file_pos
, file_pos
;
16046 int is_particle_data
;
16048 if(tng_data
->current_trajectory_frame_set_input_file_pos
<= 0)
16055 stat
= tng_frame_set_of_frame_find(tng_data
, frame
);
16056 if(stat
!= TNG_SUCCESS
)
16061 orig_file_pos
= tng_data
->current_trajectory_frame_set_input_file_pos
;
16062 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
16063 if(stat
!= TNG_SUCCESS
)
16065 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
16066 if(stat
!= TNG_SUCCESS
)
16068 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16069 /* If no specific frame was required read until this data block is found */
16072 file_pos
= ftell(tng_data
->input_file
);
16073 while(stat
!= TNG_SUCCESS
&& file_pos
< tng_data
->input_file_len
)
16075 stat
= tng_frame_set_read_next_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16076 file_pos
= ftell(tng_data
->input_file
);
16079 if(stat
!= TNG_SUCCESS
)
16081 tng_reread_frame_set_at_file_pos(tng_data
, orig_file_pos
);
16085 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
16086 if(stat
!= TNG_SUCCESS
)
16088 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
16089 if(stat
!= TNG_SUCCESS
)
16091 tng_reread_frame_set_at_file_pos(tng_data
, orig_file_pos
);
16097 is_particle_data
= 1;
16102 is_particle_data
= 0;
16107 is_particle_data
= 1;
16112 is_particle_data
= 0;
16114 if(is_particle_data
)
16116 *stride_length
= p_data
->stride_length
;
16120 *stride_length
= np_data
->stride_length
;
16122 tng_reread_frame_set_at_file_pos(tng_data
, orig_file_pos
);
16124 return(TNG_SUCCESS
);
16127 tng_function_status DECLSPECDLLEXPORT tng_time_get_str
16128 (const tng_trajectory_t tng_data
,
16131 struct tm
*time_data
;
16134 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16135 TNG_ASSERT(time
, "TNG library: time must not be a NULL pointer");
16137 secs
= tng_data
->time
;
16139 time_data
= localtime(&secs
); /* Returns a statically allocated variable. */
16140 TNG_SNPRINTF(time
, TNG_MAX_DATE_STR_LEN
,
16141 "%4d-%02d-%02d %02d:%02d:%02d",
16142 time_data
->tm_year
+1900, time_data
->tm_mon
+1, time_data
->tm_mday
,
16143 time_data
->tm_hour
, time_data
->tm_min
, time_data
->tm_sec
);
16145 return(TNG_SUCCESS
);
16149 tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_open
16150 (const char *filename
,
16152 tng_trajectory_t
*tng_data_p
)
16154 tng_function_status stat
;
16156 TNG_ASSERT(filename
, "TNG library: filename must not be a NULL pointer.");
16158 if(mode
!= 'r' && mode
!= 'w' && mode
!= 'a')
16160 return(TNG_FAILURE
);
16163 if(tng_trajectory_init(tng_data_p
) != TNG_SUCCESS
)
16165 tng_trajectory_destroy(tng_data_p
);
16166 return(TNG_CRITICAL
);
16169 if(mode
== 'r' || mode
== 'a')
16171 tng_input_file_set(*tng_data_p
, filename
);
16173 /* Read the file headers */
16174 tng_file_headers_read(*tng_data_p
, TNG_USE_HASH
);
16176 tng_num_frame_sets_get(*tng_data_p
, &(*tng_data_p
)->n_trajectory_frame_sets
);
16181 tng_output_file_set(*tng_data_p
, filename
);
16183 else if(mode
== 'a')
16185 fseek((*tng_data_p
)->input_file
,
16186 (long)(*tng_data_p
)->last_trajectory_frame_set_input_file_pos
,
16189 stat
= tng_frame_set_read(*tng_data_p
, TNG_USE_HASH
);
16190 if(stat
!= TNG_SUCCESS
)
16192 fprintf(stderr
, "TNG library: Cannot read frame set and related blocks. %s: %d\n",
16193 __FILE__
, __LINE__
);
16196 (*tng_data_p
)->first_trajectory_frame_set_output_file_pos
=
16197 (*tng_data_p
)->first_trajectory_frame_set_input_file_pos
;
16198 (*tng_data_p
)->last_trajectory_frame_set_output_file_pos
=
16199 (*tng_data_p
)->last_trajectory_frame_set_input_file_pos
;
16200 (*tng_data_p
)->current_trajectory_frame_set_output_file_pos
=
16201 (*tng_data_p
)->current_trajectory_frame_set_input_file_pos
;
16202 (*tng_data_p
)->first_trajectory_frame_set_input_file_pos
= -1;
16203 (*tng_data_p
)->last_trajectory_frame_set_input_file_pos
= -1;
16204 (*tng_data_p
)->current_trajectory_frame_set_input_file_pos
= -1;
16205 if((*tng_data_p
)->input_file
)
16207 fclose((*tng_data_p
)->input_file
);
16208 (*tng_data_p
)->input_file
= 0;
16210 if((*tng_data_p
)->input_file_path
)
16212 free((*tng_data_p
)->input_file_path
);
16213 (*tng_data_p
)->input_file_path
= 0;
16215 tng_output_append_file_set(*tng_data_p
, filename
);
16217 fseek((*tng_data_p
)->output_file
, 0, SEEK_END
);
16220 return(TNG_SUCCESS
);
16223 tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_close
16224 (tng_trajectory_t
*tng_data_p
)
16226 tng_trajectory_frame_set_t frame_set
;
16228 if(tng_data_p
== 0)
16230 fprintf(stderr
, "TNG library: Empty pointer to trajectory when attempting to close. %s: %d\n",
16231 __FILE__
, __LINE__
);
16232 return(TNG_FAILURE
);
16235 if(*tng_data_p
== 0)
16237 return(TNG_SUCCESS
);
16240 frame_set
= &(*tng_data_p
)->current_trajectory_frame_set
;
16242 if(frame_set
->n_unwritten_frames
> 0)
16244 frame_set
->n_frames
= frame_set
->n_unwritten_frames
;
16245 tng_frame_set_write(*tng_data_p
, TNG_USE_HASH
);
16248 return(tng_trajectory_destroy(tng_data_p
));
16251 tng_function_status DECLSPECDLLEXPORT tng_util_time_of_frame_get
16252 (tng_trajectory_t tng_data
,
16253 const int64_t frame_nr
,
16256 int64_t first_frame
;
16257 tng_trajectory_frame_set_t frame_set
;
16258 tng_function_status stat
;
16260 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16261 TNG_ASSERT(time
, "TNG library: time must not be a NULL pointer");
16263 stat
= tng_frame_set_of_frame_find(tng_data
, frame_nr
);
16264 if(stat
!= TNG_SUCCESS
)
16266 fprintf(stderr
, "TNG library: Cannot find frame nr %"PRId64
". %s: %d\n",
16267 frame_nr
, __FILE__
, __LINE__
);
16271 frame_set
= &tng_data
->current_trajectory_frame_set
;
16272 first_frame
= frame_set
->first_frame
;
16274 if(tng_data
->time_per_frame
<= 0)
16276 return(TNG_FAILURE
);
16279 *time
= frame_set
->first_frame_time
+ (tng_data
->time_per_frame
* (frame_nr
- first_frame
));
16281 return(TNG_SUCCESS
);
16285 tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_molecules_get
16286 (tng_trajectory_t tng_data,
16288 int64_t **molecule_cnt_list,
16289 tng_molecule_t *mols)
16291 tng_trajectory_frame_set_t frame_set;
16293 TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
16294 TNG_ASSERT(n_mols, "TNG library: n_mols must not be a NULL pointer.");
16296 *n_mols = tng_data->n_molecules;
16298 frame_set = &tng_data->current_trajectory_frame_set;
16299 if(tng_data->var_num_atoms_flag && frame_set && frame_set->molecule_cnt_list)
16301 *molecule_cnt_list = frame_set->molecule_cnt_list;
16305 *molecule_cnt_list = tng_data->molecule_cnt_list;
16308 *mols = tng_data->molecules;
16310 return(TNG_SUCCESS);
16314 tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_molecule_add
16315 (tng_trajectory_t tng_data,
16318 tng_molecule_t *mol)
16320 tng_function_status stat;
16322 TNG_ASSERT(name, "TNG library: name must not be a NULL pointer");
16323 TNG_ASSERT(cnt>=0, "TNG library: cnt must be >= 0");
16325 stat = tng_molecule_add(tng_data, name, mol);
16326 if(stat != TNG_SUCCESS)
16330 stat = tng_molecule_cnt_set(tng_data, *mol, cnt);
16335 tng_function_status DECLSPECDLLEXPORT tng_util_molecule_particles_get
16336 (tng_trajectory_t tng_data
,
16337 const tng_molecule_t mol
,
16338 int64_t *n_particles
,
16343 char ***chain_names
,
16344 int64_t **chain_ids
)
16352 *n_particles
= mol
->n_atoms
;
16354 *names
= malloc(sizeof(char *) * *n_particles
);
16355 *types
= malloc(sizeof(char *) * *n_particles
);
16356 *res_names
= malloc(sizeof(char *) * *n_particles
);
16357 *chain_names
= malloc(sizeof(char *) * *n_particles
);
16358 *res_ids
= malloc(sizeof(int64_t) * *n_particles
);
16359 *chain_ids
= malloc(sizeof(int64_t) * *n_particles
);
16361 for(i
= 0; i
< *n_particles
; i
++)
16363 atom
= &mol
->atoms
[i
];
16364 res
= atom
->residue
;
16365 chain
= res
->chain
;
16366 (*names
)[i
] = malloc(strlen(atom
->name
));
16367 strcpy(*names
[i
], atom
->name
);
16368 (*types
)[i
] = malloc(strlen(atom
->atom_type
));
16369 strcpy(*types
[i
], atom
->atom_type
);
16370 (*res_names
)[i
] = malloc(strlen(res
->name
));
16371 strcpy(*res_names
[i
], res
->name
);
16372 (*chain_names
)[i
] = malloc(strlen(chain
->name
));
16373 strcpy(*chain_names
[i
], chain
->name
);
16374 (*res_ids
)[i
] = res
->id
;
16375 (*chain_ids
)[i
] = chain
->id
;
16378 return(TNG_SUCCESS
);
16381 tng_function_status DECLSPECDLLEXPORT tng_util_molecule_particles_set
16382 (tng_trajectory_t tng_data
,
16383 tng_molecule_t mol
,
16384 const int64_t n_particles
,
16385 const char **names
,
16386 const char **types
,
16387 const char **res_names
,
16388 const int64_t *res_ids
,
16389 const char **chain_names
,
16390 const int64_t *chain_ids
)
16394 tng_residue_t residue
;
16396 tng_function_status stat
;
16398 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16399 TNG_ASSERT(names
, "TNG library: names must not be a NULL pointer");
16400 TNG_ASSERT(types
, "TNG library: types must not be a NULL pointer");
16401 TNG_ASSERT(res_names
, "TNG library: res_names must not be a NULL pointer");
16402 TNG_ASSERT(res_ids
, "TNG library: res_ids must not be a NULL pointer");
16403 TNG_ASSERT(chain_names
, "TNG library: chain_names must not be a NULL pointer");
16404 TNG_ASSERT(chain_ids
, "TNG library: chain_ids must not be a NULL pointer");
16406 for(i
= 0; i
< n_particles
; i
++)
16408 if(tng_molecule_chain_find(tng_data
, mol
, chain_names
[i
], chain_ids
[i
],
16409 &chain
) == TNG_FAILURE
)
16411 stat
= tng_molecule_chain_add(tng_data
, mol
, chain_names
[i
],
16413 if(stat
!= TNG_SUCCESS
)
16418 if(tng_chain_residue_find(tng_data
, chain
, res_names
[i
], res_ids
[i
],
16419 &residue
) == TNG_FAILURE
)
16421 stat
= tng_chain_residue_add(tng_data
, chain
, res_names
[i
],
16423 if(stat
!= TNG_SUCCESS
)
16428 stat
= tng_residue_atom_add(tng_data
, residue
, names
[i
], types
[i
], &atom
);
16429 if(stat
!= TNG_SUCCESS
)
16434 return(TNG_SUCCESS
);
16437 tng_function_status DECLSPECDLLEXPORT tng_util_pos_read
16438 (tng_trajectory_t tng_data
,
16439 float **positions
, int64_t *stride_length
)
16441 int64_t n_frames
, n_particles
, n_values_per_frame
;
16443 tng_function_status stat
;
16445 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16446 TNG_ASSERT(positions
, "TNG library: positions must not be a NULL pointer");
16447 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer");
16449 stat
= tng_num_frames_get(tng_data
, &n_frames
);
16450 if(stat
!= TNG_SUCCESS
)
16455 stat
= tng_particle_data_vector_interval_get(tng_data
, TNG_TRAJ_POSITIONS
,
16456 0, n_frames
- 1, TNG_USE_HASH
,
16457 (void **)positions
,
16460 &n_values_per_frame
,
16466 tng_function_status DECLSPECDLLEXPORT tng_util_vel_read
16467 (tng_trajectory_t tng_data
,
16468 float **velocities
, int64_t *stride_length
)
16470 int64_t n_frames
, n_particles
, n_values_per_frame
;
16472 tng_function_status stat
;
16474 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16475 TNG_ASSERT(velocities
, "TNG library: velocities must not be a NULL pointer");
16476 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer");
16478 stat
= tng_num_frames_get(tng_data
, &n_frames
);
16479 if(stat
!= TNG_SUCCESS
)
16484 stat
= tng_particle_data_vector_interval_get(tng_data
, TNG_TRAJ_VELOCITIES
,
16485 0, n_frames
- 1, TNG_USE_HASH
,
16486 (void **)velocities
,
16489 &n_values_per_frame
,
16495 tng_function_status DECLSPECDLLEXPORT tng_util_force_read
16496 (tng_trajectory_t tng_data
,
16497 float **forces
, int64_t *stride_length
)
16499 int64_t n_frames
, n_particles
, n_values_per_frame
;
16501 tng_function_status stat
;
16503 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16504 TNG_ASSERT(forces
, "TNG library: forces must not be a NULL pointer");
16505 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer");
16507 stat
= tng_num_frames_get(tng_data
, &n_frames
);
16508 if(stat
!= TNG_SUCCESS
)
16513 stat
= tng_particle_data_vector_interval_get(tng_data
, TNG_TRAJ_FORCES
,
16514 0, n_frames
- 1, TNG_USE_HASH
,
16518 &n_values_per_frame
,
16524 tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_read
16525 (tng_trajectory_t tng_data
,
16527 int64_t *stride_length
)
16529 int64_t n_frames
, n_values_per_frame
;
16531 tng_function_status stat
;
16533 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16534 TNG_ASSERT(box_shape
, "TNG library: box_shape must not be a NULL pointer");
16535 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer");
16537 stat
= tng_num_frames_get(tng_data
, &n_frames
);
16538 if(stat
!= TNG_SUCCESS
)
16543 stat
= tng_data_vector_interval_get(tng_data
, TNG_TRAJ_BOX_SHAPE
,
16544 0, n_frames
- 1, TNG_USE_HASH
,
16545 (void **)box_shape
,
16547 &n_values_per_frame
,
16553 tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read
16554 (tng_trajectory_t tng_data
,
16555 const int64_t block_id
,
16558 int64_t *retrieved_frame_number
,
16559 double *retrieved_time
)
16561 tng_trajectory_frame_set_t frame_set
;
16562 tng_particle_data_t data
= 0;
16563 tng_function_status stat
;
16565 int64_t i
, data_size
, n_particles
;
16569 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16570 TNG_ASSERT(values
, "TNG library: The pointer to the values array must not be a NULL pointer");
16571 TNG_ASSERT(data_type
, "TNG library: The pointer to the data type of the returned data must not be a NULL pointer");
16572 TNG_ASSERT(retrieved_frame_number
, "TNG library: The pointer to the frame number of the returned data must not be a NULL pointer");
16573 TNG_ASSERT(retrieved_time
, "TNG library: The pointer to the time of the returned data must not be a NULL pointer");
16575 frame_set
= &tng_data
->current_trajectory_frame_set
;
16577 stat
= tng_particle_data_find(tng_data
, block_id
, &data
);
16578 if(stat
!= TNG_SUCCESS
)
16580 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16581 file_pos
= ftell(tng_data
->input_file
);
16582 while(stat
!= TNG_SUCCESS
&& file_pos
< tng_data
->input_file_len
)
16584 stat
= tng_frame_set_read_next_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16585 file_pos
= ftell(tng_data
->input_file
);
16587 if(stat
!= TNG_SUCCESS
)
16591 stat
= tng_particle_data_find(tng_data
, block_id
, &data
);
16592 if(stat
!= TNG_SUCCESS
)
16597 if(data
->last_retrieved_frame
< 0)
16599 fseek(tng_data
->input_file
,
16600 (long)tng_data
->first_trajectory_frame_set_input_file_pos
,
16602 stat
= tng_frame_set_read(tng_data
, TNG_USE_HASH
);
16603 if(stat
!= TNG_SUCCESS
)
16607 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16608 if(stat
!= TNG_SUCCESS
)
16613 i
= data
->first_frame_with_data
;
16617 if(data
->n_frames
== 1)
16619 i
= data
->last_retrieved_frame
+ 1;
16623 i
= data
->last_retrieved_frame
+ data
->stride_length
;
16625 if(i
< frame_set
->first_frame
|| i
>= frame_set
->first_frame
+ frame_set
->n_frames
)
16627 stat
= tng_frame_set_of_frame_find(tng_data
, i
);
16628 if(stat
!= TNG_SUCCESS
)
16630 /* If the frame set search found the frame set after the starting
16631 * frame set there is a gap in the frame sets. So, even if the frame
16632 * was not found the next frame with data is still in the found
16634 if(stat
== TNG_CRITICAL
)
16638 i
= frame_set
->first_frame
;
16641 if(data
->last_retrieved_frame
< frame_set
->first_frame
)
16643 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16644 if(stat
!= TNG_SUCCESS
)
16650 data
->last_retrieved_frame
= i
;
16651 *retrieved_frame_number
= i
;
16652 if(frame_set
->first_frame_time
>= 0 && tng_data
->time_per_frame
>= 0)
16654 *retrieved_time
= frame_set
->first_frame_time
+
16655 (i
- frame_set
->first_frame
) *
16656 tng_data
->time_per_frame
;
16660 *retrieved_time
= 0;
16663 if(data
->stride_length
> 1)
16665 i
= (i
- data
->first_frame_with_data
) / data
->stride_length
;
16669 i
= (i
- frame_set
->first_frame
);
16672 tng_num_particles_get(tng_data
, &n_particles
);
16674 *data_type
= data
->datatype
;
16678 case TNG_CHAR_DATA
:
16679 return(TNG_FAILURE
);
16681 size
= sizeof(int64_t);
16683 case TNG_FLOAT_DATA
:
16684 size
= sizeof(float);
16686 case TNG_DOUBLE_DATA
:
16688 size
= sizeof(double);
16691 data_size
= size
* n_particles
* data
->n_values_per_frame
;
16693 // fprintf(stderr, "TNG library: TEMP: i = %"PRId64", data_size = %"PRId64", size = %d, n_particles = %"PRId64", n_values_per_frame = %"PRId64"\n",
16694 // i, data_size, size, n_particles, data->n_values_per_frame);
16696 temp
= realloc(*values
, data_size
);
16699 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
16700 data_size
, __FILE__
, __LINE__
);
16703 return(TNG_CRITICAL
);
16708 memcpy(*values
, (char *)data
->values
+ i
* data_size
, data_size
);
16710 return(TNG_SUCCESS
);
16713 tng_function_status DECLSPECDLLEXPORT tng_util_non_particle_data_next_frame_read
16714 (tng_trajectory_t tng_data
,
16715 const int64_t block_id
,
16718 int64_t *retrieved_frame_number
,
16719 double *retrieved_time
)
16721 tng_trajectory_frame_set_t frame_set
;
16722 tng_non_particle_data_t data
= 0;
16723 tng_function_status stat
;
16725 int64_t i
, data_size
;
16729 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16730 TNG_ASSERT(values
, "TNG library: The pointer to the values array must not be a NULL pointer");
16731 TNG_ASSERT(data_type
, "TNG library: The pointer to the data type of the returned data must not be a NULL pointer");
16732 TNG_ASSERT(retrieved_frame_number
, "TNG library: The pointer to the frame number of the returned data must not be a NULL pointer");
16733 TNG_ASSERT(retrieved_time
, "TNG library: The pointer to the time of the returned data must not be a NULL pointer");
16735 frame_set
= &tng_data
->current_trajectory_frame_set
;
16737 stat
= tng_data_find(tng_data
, block_id
, &data
);
16738 if(stat
!= TNG_SUCCESS
)
16740 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16741 file_pos
= ftell(tng_data
->input_file
);
16742 while(stat
!= TNG_SUCCESS
&& file_pos
< tng_data
->input_file_len
)
16744 stat
= tng_frame_set_read_next_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16745 file_pos
= ftell(tng_data
->input_file
);
16747 if(stat
!= TNG_SUCCESS
)
16751 stat
= tng_data_find(tng_data
, block_id
, &data
);
16752 if(stat
!= TNG_SUCCESS
)
16757 if(data
->last_retrieved_frame
< 0)
16759 fseek(tng_data
->input_file
,
16760 (long)tng_data
->first_trajectory_frame_set_input_file_pos
,
16762 stat
= tng_frame_set_read(tng_data
, TNG_USE_HASH
);
16763 if(stat
!= TNG_SUCCESS
)
16767 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16768 if(stat
!= TNG_SUCCESS
)
16773 i
= data
->first_frame_with_data
;
16777 if(data
->n_frames
== 1)
16779 i
= data
->last_retrieved_frame
+ 1;
16783 i
= data
->last_retrieved_frame
+ data
->stride_length
;
16785 if(i
< frame_set
->first_frame
|| i
>= frame_set
->first_frame
+ frame_set
->n_frames
)
16787 stat
= tng_frame_set_of_frame_find(tng_data
, i
);
16788 if(stat
!= TNG_SUCCESS
)
16790 /* If the frame set search found the frame set after the starting
16791 * frame set there is a gap in the frame sets. So, even if the frame
16792 * was not found the next frame with data is still in the found
16794 if(stat
== TNG_CRITICAL
)
16798 i
= frame_set
->first_frame
;
16801 if(data
->last_retrieved_frame
< frame_set
->first_frame
)
16803 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
16804 if(stat
!= TNG_SUCCESS
)
16810 data
->last_retrieved_frame
= i
;
16811 *retrieved_frame_number
= i
;
16812 if(frame_set
->first_frame_time
>= 0 && tng_data
->time_per_frame
>= 0)
16814 *retrieved_time
= frame_set
->first_frame_time
+
16815 (i
- frame_set
->first_frame
) *
16816 tng_data
->time_per_frame
;
16820 *retrieved_time
= 0;
16823 if(data
->stride_length
> 1)
16825 i
= (i
- data
->first_frame_with_data
) / data
->stride_length
;
16829 i
= (i
- frame_set
->first_frame
);
16832 *data_type
= data
->datatype
;
16836 case TNG_CHAR_DATA
:
16837 return(TNG_FAILURE
);
16839 size
= sizeof(int64_t);
16841 case TNG_FLOAT_DATA
:
16842 size
= sizeof(float);
16844 case TNG_DOUBLE_DATA
:
16846 size
= sizeof(double);
16849 data_size
= size
* data
->n_values_per_frame
;
16851 temp
= realloc(*values
, data_size
);
16854 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
16855 data_size
, __FILE__
, __LINE__
);
16858 return(TNG_CRITICAL
);
16863 memcpy(*values
, (char *)data
->values
+ i
* data_size
, data_size
);
16865 return(TNG_SUCCESS
);
16868 tng_function_status DECLSPECDLLEXPORT tng_util_pos_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(positions
, "TNG library: positions 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_POSITIONS
,
16885 first_frame
, last_frame
,
16887 (void **)positions
,
16890 &n_values_per_frame
,
16896 tng_function_status DECLSPECDLLEXPORT tng_util_vel_read_range
16897 (tng_trajectory_t tng_data
,
16898 const int64_t first_frame
,
16899 const int64_t last_frame
,
16900 float **velocities
,
16901 int64_t *stride_length
)
16903 int64_t n_particles
, n_values_per_frame
;
16905 tng_function_status stat
;
16907 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16908 TNG_ASSERT(velocities
, "TNG library: velocities 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_particle_data_vector_interval_get(tng_data
, TNG_TRAJ_VELOCITIES
,
16913 first_frame
, last_frame
,
16915 (void **)velocities
,
16918 &n_values_per_frame
,
16924 tng_function_status DECLSPECDLLEXPORT tng_util_force_read_range
16925 (tng_trajectory_t tng_data
,
16926 const int64_t first_frame
,
16927 const int64_t last_frame
,
16929 int64_t *stride_length
)
16931 int64_t n_particles
, n_values_per_frame
;
16933 tng_function_status stat
;
16935 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16936 TNG_ASSERT(forces
, "TNG library: forces must not be a NULL pointer");
16937 TNG_ASSERT(first_frame
<= last_frame
, "TNG library: first_frame must be lower or equal to last_frame.");
16938 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer");
16940 stat
= tng_particle_data_vector_interval_get(tng_data
, TNG_TRAJ_FORCES
,
16941 first_frame
, last_frame
,
16946 &n_values_per_frame
,
16952 tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_read_range
16953 (tng_trajectory_t tng_data
,
16954 const int64_t first_frame
,
16955 const int64_t last_frame
,
16957 int64_t *stride_length
)
16959 int64_t n_values_per_frame
;
16961 tng_function_status stat
;
16963 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16964 TNG_ASSERT(box_shape
, "TNG library: box_shape must not be a NULL pointer");
16965 TNG_ASSERT(first_frame
<= last_frame
, "TNG library: first_frame must be lower or equal to last_frame.");
16966 TNG_ASSERT(stride_length
, "TNG library: stride_length must not be a NULL pointer");
16968 stat
= tng_data_vector_interval_get(tng_data
, TNG_TRAJ_BOX_SHAPE
,
16969 first_frame
, last_frame
,
16971 (void **)box_shape
,
16973 &n_values_per_frame
,
16979 tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_set
16980 (tng_trajectory_t tng_data
,
16982 const int64_t n_values_per_frame
,
16983 const int64_t block_id
,
16984 const char *block_name
,
16985 const char particle_dependency
,
16986 const char compression
)
16988 tng_trajectory_frame_set_t frame_set
;
16989 tng_particle_data_t p_data
;
16990 tng_non_particle_data_t np_data
;
16991 int64_t n_particles
, n_frames
;
16992 tng_function_status stat
;
16994 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
16995 TNG_ASSERT(i
>= 0, "TNG library: i (writing interval) must be >= 0.");
16999 fprintf(stderr
, "TNG library: Cannot set writing frequency to %"PRId64
". %s: %d\n",
17000 i
, __FILE__
, __LINE__
);
17001 return(TNG_FAILURE
);
17004 frame_set
= &tng_data
->current_trajectory_frame_set
;
17006 if(!frame_set
|| tng_data
->n_trajectory_frame_sets
<= 0)
17008 n_frames
= tng_data
->frame_set_n_frames
;
17010 stat
= tng_frame_set_new(tng_data
, 0, n_frames
);
17011 if(stat
!= TNG_SUCCESS
)
17013 fprintf(stderr
, "TNG library: Cannot create frame set. %s: %d\n", __FILE__
,
17020 n_frames
= frame_set
->n_frames
;
17023 if(particle_dependency
== TNG_PARTICLE_BLOCK_DATA
)
17025 tng_num_particles_get(tng_data
, &n_particles
);
17026 if(n_particles
<= 0)
17028 return(TNG_FAILURE
);
17031 if(tng_particle_data_find(tng_data
, block_id
, &p_data
)
17034 stat
= tng_particle_data_block_add(tng_data
, block_id
,
17037 TNG_TRAJECTORY_BLOCK
,
17038 n_frames
, n_values_per_frame
, i
,
17041 if(stat
!= TNG_SUCCESS
)
17043 fprintf(stderr
, "TNG library: Error %s adding data block. %s: %d\n", block_name
,
17044 __FILE__
, __LINE__
);
17047 p_data
= &frame_set
->tr_particle_data
[frame_set
->
17048 n_particle_data_blocks
- 1];
17049 stat
= tng_allocate_particle_data_mem(tng_data
, p_data
, n_frames
,
17051 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__
);
17061 if(p_data
->stride_length
!= i
)
17063 p_data
->stride_length
= i
;
17064 stat
= tng_allocate_particle_data_mem(tng_data
, p_data
, n_frames
,
17066 n_values_per_frame
);
17067 if(stat
!= TNG_SUCCESS
)
17069 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
17070 __FILE__
, __LINE__
);
17078 if(tng_data_find(tng_data
, block_id
, &np_data
) != TNG_SUCCESS
)
17080 stat
= tng_data_block_add(tng_data
, block_id
, block_name
,
17081 TNG_FLOAT_DATA
, TNG_TRAJECTORY_BLOCK
,
17082 n_frames
, n_values_per_frame
,
17083 i
, compression
, 0);
17084 if(stat
!= TNG_SUCCESS
)
17086 fprintf(stderr
, "TNG library: Error %s adding data block. %s: %d\n", block_name
,
17087 __FILE__
, __LINE__
);
17090 np_data
= &frame_set
->tr_data
[frame_set
->
17091 n_data_blocks
- 1];
17092 stat
= tng_allocate_data_mem(tng_data
, np_data
, n_frames
,
17093 i
, n_values_per_frame
);
17094 if(stat
!= TNG_SUCCESS
)
17096 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
17097 __FILE__
, __LINE__
);
17103 if(np_data
->stride_length
!= i
)
17105 np_data
->stride_length
= i
;
17106 stat
= tng_allocate_data_mem(tng_data
, np_data
, n_frames
,
17107 i
, n_values_per_frame
);
17108 if(stat
!= TNG_SUCCESS
)
17110 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
17111 __FILE__
, __LINE__
);
17118 return(TNG_SUCCESS
);
17121 tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_double_set
17122 (tng_trajectory_t tng_data
,
17124 const int64_t n_values_per_frame
,
17125 const int64_t block_id
,
17126 const char *block_name
,
17127 const char particle_dependency
,
17128 const char compression
)
17130 tng_trajectory_frame_set_t frame_set
;
17131 tng_particle_data_t p_data
;
17132 tng_non_particle_data_t np_data
;
17133 int64_t n_particles
, n_frames
;
17134 tng_function_status stat
;
17136 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17137 TNG_ASSERT(i
>= 0, "TNG library: i (writing interval) must be >= 0.");
17141 fprintf(stderr
, "TNG library: Cannot set writing frequency to %"PRId64
". %s: %d\n",
17142 i
, __FILE__
, __LINE__
);
17143 return(TNG_FAILURE
);
17146 frame_set
= &tng_data
->current_trajectory_frame_set
;
17148 if(!frame_set
|| tng_data
->n_trajectory_frame_sets
<= 0)
17150 n_frames
= tng_data
->frame_set_n_frames
;
17152 stat
= tng_frame_set_new(tng_data
, 0, n_frames
);
17153 if(stat
!= TNG_SUCCESS
)
17155 fprintf(stderr
, "TNG library: Cannot create frame set. %s: %d\n", __FILE__
,
17162 n_frames
= frame_set
->n_frames
;
17165 if(particle_dependency
== TNG_PARTICLE_BLOCK_DATA
)
17167 tng_num_particles_get(tng_data
, &n_particles
);
17169 if(n_particles
<= 0)
17171 return(TNG_FAILURE
);
17174 if(tng_particle_data_find(tng_data
, block_id
, &p_data
)
17177 stat
= tng_particle_data_block_add(tng_data
, block_id
,
17180 TNG_TRAJECTORY_BLOCK
,
17181 n_frames
, n_values_per_frame
, i
,
17184 if(stat
!= TNG_SUCCESS
)
17186 fprintf(stderr
, "TNG library: Error %s adding data block. %s: %d\n", block_name
,
17187 __FILE__
, __LINE__
);
17190 p_data
= &frame_set
->tr_particle_data
[frame_set
->
17191 n_particle_data_blocks
- 1];
17192 stat
= tng_allocate_particle_data_mem(tng_data
, p_data
, n_frames
,
17194 n_values_per_frame
);
17195 if(stat
!= TNG_SUCCESS
)
17197 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
17198 __FILE__
, __LINE__
);
17204 p_data
->stride_length
= i
;
17209 if(tng_data_find(tng_data
, block_id
, &np_data
) != TNG_SUCCESS
)
17211 stat
= tng_data_block_add(tng_data
, block_id
, block_name
,
17212 TNG_DOUBLE_DATA
, TNG_TRAJECTORY_BLOCK
,
17213 n_frames
, n_values_per_frame
,
17214 i
, compression
, 0);
17215 if(stat
!= TNG_SUCCESS
)
17217 fprintf(stderr
, "TNG library: Error %s adding data block. %s: %d\n", block_name
,
17218 __FILE__
, __LINE__
);
17221 np_data
= &frame_set
->tr_data
[frame_set
->
17222 n_data_blocks
- 1];
17223 stat
= tng_allocate_data_mem(tng_data
, np_data
, n_frames
,
17224 i
, n_values_per_frame
);
17225 if(stat
!= TNG_SUCCESS
)
17227 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
17228 __FILE__
, __LINE__
);
17234 np_data
->stride_length
= i
;
17238 return(TNG_SUCCESS
);
17241 tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_frequency_set
17242 (tng_trajectory_t tng_data
,
17244 const int64_t n_values_per_frame
,
17245 const int64_t block_id
,
17246 const char *block_name
,
17247 const char particle_dependency
,
17248 const char compression
)
17250 fprintf(stderr
, "TNG library: Using obsolete function tng_util_generic_write_frequency_set(). "
17251 "See documentation. %s: %d", __FILE__
, __LINE__
);
17252 return(tng_util_generic_write_interval_set(tng_data
, i
, n_values_per_frame
,
17253 block_id
, block_name
,
17254 particle_dependency
,
17257 tng_function_status DECLSPECDLLEXPORT tng_util_pos_write_interval_set
17258 (tng_trajectory_t tng_data
,
17261 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17262 TNG_ASSERT(i
> 0, "TNG library: i (writing interval) must be >= 0.");
17264 return(tng_util_generic_write_interval_set(tng_data
, i
, 3,
17265 TNG_TRAJ_POSITIONS
,
17267 TNG_PARTICLE_BLOCK_DATA
,
17268 TNG_TNG_COMPRESSION
));
17271 tng_function_status DECLSPECDLLEXPORT tng_util_pos_write_interval_double_set
17272 (tng_trajectory_t tng_data
,
17275 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17276 TNG_ASSERT(i
> 0, "TNG library: i (writing interval) must be >= 0.");
17278 return(tng_util_generic_write_interval_double_set(tng_data
, i
, 3,
17279 TNG_TRAJ_POSITIONS
,
17281 TNG_PARTICLE_BLOCK_DATA
,
17282 TNG_TNG_COMPRESSION
));
17285 tng_function_status DECLSPECDLLEXPORT tng_util_pos_write_frequency_set
17286 (tng_trajectory_t tng_data
,
17289 fprintf(stderr
, "TNG library: Using obsolete function tng_util_pos_write_frequency_set(). "
17290 "See documentation. %s: %d", __FILE__
, __LINE__
);
17291 return(tng_util_pos_write_interval_set(tng_data
, i
));
17294 tng_function_status DECLSPECDLLEXPORT tng_util_vel_write_interval_set
17295 (tng_trajectory_t tng_data
,
17298 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17299 TNG_ASSERT(i
> 0, "TNG library: i (writing interval) must be >= 0.");
17301 return(tng_util_generic_write_interval_set(tng_data
, i
, 3,
17302 TNG_TRAJ_VELOCITIES
,
17304 TNG_PARTICLE_BLOCK_DATA
,
17305 TNG_TNG_COMPRESSION
));
17308 tng_function_status DECLSPECDLLEXPORT tng_util_vel_write_interval_double_set
17309 (tng_trajectory_t tng_data
,
17312 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17313 TNG_ASSERT(i
> 0, "TNG library: i (writing interval) must be >= 0.");
17315 return(tng_util_generic_write_interval_double_set(tng_data
, i
, 3,
17316 TNG_TRAJ_VELOCITIES
,
17318 TNG_PARTICLE_BLOCK_DATA
,
17319 TNG_TNG_COMPRESSION
));
17322 tng_function_status DECLSPECDLLEXPORT tng_util_vel_write_frequency_set
17323 (tng_trajectory_t tng_data
,
17326 fprintf(stderr
, "TNG library: Using obsolete function tng_util_vel_write_frequency_set(). "
17327 "See documentation. %s: %d", __FILE__
, __LINE__
);
17328 return(tng_util_vel_write_interval_set(tng_data
, i
));
17331 tng_function_status DECLSPECDLLEXPORT tng_util_force_write_interval_set
17332 (tng_trajectory_t tng_data
,
17335 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17336 TNG_ASSERT(i
> 0, "TNG library: i (writing interval) must be >= 0.");
17338 return(tng_util_generic_write_interval_set(tng_data
, i
, 3,
17341 TNG_PARTICLE_BLOCK_DATA
,
17342 TNG_GZIP_COMPRESSION
));
17345 tng_function_status DECLSPECDLLEXPORT tng_util_force_write_interval_double_set
17346 (tng_trajectory_t tng_data
,
17349 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17350 TNG_ASSERT(i
> 0, "TNG library: i (writing interval) must be >= 0.");
17352 return(tng_util_generic_write_interval_double_set(tng_data
, i
, 3,
17355 TNG_PARTICLE_BLOCK_DATA
,
17356 TNG_GZIP_COMPRESSION
));
17359 tng_function_status DECLSPECDLLEXPORT tng_util_force_write_frequency_set
17360 (tng_trajectory_t tng_data
,
17363 fprintf(stderr
, "TNG library: Using obsolete function tng_util_force_write_frequency_set(). "
17364 "See documentation. %s: %d", __FILE__
, __LINE__
);
17365 return(tng_util_force_write_interval_set(tng_data
, i
));
17368 tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_interval_set
17369 (tng_trajectory_t tng_data
,
17372 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17373 TNG_ASSERT(i
> 0, "TNG library: i (writing interval) must be >= 0.");
17375 return(tng_util_generic_write_interval_set(tng_data
, i
, 9,
17376 TNG_TRAJ_BOX_SHAPE
,
17378 TNG_NON_PARTICLE_BLOCK_DATA
,
17379 TNG_GZIP_COMPRESSION
));
17382 tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_interval_double_set
17383 (tng_trajectory_t tng_data
,
17386 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17387 TNG_ASSERT(i
> 0, "TNG library: i (writing interval) must be >= 0.");
17389 return(tng_util_generic_write_interval_double_set(tng_data
, i
, 9,
17390 TNG_TRAJ_BOX_SHAPE
,
17392 TNG_NON_PARTICLE_BLOCK_DATA
,
17393 TNG_GZIP_COMPRESSION
));
17396 tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_frequency_set
17397 (tng_trajectory_t tng_data
,
17400 fprintf(stderr
, "TNG library: Using obsolete function tng_util_box_shape_write_frequency_set(). "
17401 "See documentation. %s: %d", __FILE__
, __LINE__
);
17402 return(tng_util_box_shape_write_interval_set(tng_data
, i
));
17405 tng_function_status DECLSPECDLLEXPORT tng_util_generic_write
17406 (tng_trajectory_t tng_data
,
17407 const int64_t frame_nr
,
17408 const float *values
,
17409 const int64_t n_values_per_frame
,
17410 const int64_t block_id
,
17411 const char *block_name
,
17412 const char particle_dependency
,
17413 const char compression
)
17415 tng_trajectory_frame_set_t frame_set
;
17416 tng_particle_data_t p_data
;
17417 tng_non_particle_data_t np_data
;
17418 int64_t n_particles
= 0, n_frames
, stride_length
= 100, frame_pos
;
17419 int64_t last_frame
;
17420 int is_first_frame_flag
= 0;
17421 char block_type_flag
;
17422 tng_function_status stat
;
17424 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17425 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17426 TNG_ASSERT(values
, "TNG library: values must not be a NULL pointer");
17428 if(particle_dependency
== TNG_PARTICLE_BLOCK_DATA
)
17430 tng_num_particles_get(tng_data
, &n_particles
);
17431 TNG_ASSERT(n_particles
> 0, "TNG library: There must be particles in the system to write particle data.");
17436 return(TNG_FAILURE
);
17439 frame_set
= &tng_data
->current_trajectory_frame_set
;
17443 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
17444 n_frames
= stride_length
= 1;
17448 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
17450 if(!frame_set
|| tng_data
->n_trajectory_frame_sets
<= 0)
17452 stat
= tng_frame_set_new(tng_data
, 0, tng_data
->frame_set_n_frames
);
17453 if(stat
!= TNG_SUCCESS
)
17455 fprintf(stderr
, "TNG library: Cannot create frame set. %s: %d\n", __FILE__
,
17460 last_frame
= frame_set
->first_frame
+
17461 frame_set
->n_frames
- 1;
17462 if(frame_nr
> last_frame
)
17464 stat
= tng_frame_set_write(tng_data
, TNG_USE_HASH
);
17465 if(stat
!= TNG_SUCCESS
)
17467 fprintf(stderr
, "TNG library: Cannot write frame set. %s: %d\n", __FILE__
,
17471 if(last_frame
+ tng_data
->frame_set_n_frames
< frame_nr
)
17473 last_frame
= frame_nr
- 1;
17475 stat
= tng_frame_set_new(tng_data
, last_frame
+ 1,
17476 tng_data
->frame_set_n_frames
);
17477 if(stat
!= TNG_SUCCESS
)
17479 fprintf(stderr
, "TNG library: Cannot create frame set. %s: %d\n", __FILE__
,
17484 if(frame_set
->n_unwritten_frames
== 0)
17486 is_first_frame_flag
= 1;
17488 frame_set
->n_unwritten_frames
= frame_nr
-
17489 frame_set
->first_frame
+ 1;
17491 n_frames
= frame_set
->n_frames
;
17494 if(particle_dependency
== TNG_PARTICLE_BLOCK_DATA
)
17496 if(tng_particle_data_find(tng_data
, block_id
, &p_data
)
17499 stat
= tng_particle_data_block_add(tng_data
, block_id
,
17503 n_frames
, n_values_per_frame
,
17507 if(stat
!= TNG_SUCCESS
)
17509 fprintf(stderr
, "TNG library: Error %s adding data block. %s: %d\n", block_name
,
17510 __FILE__
, __LINE__
);
17513 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
17515 p_data
= &frame_set
->tr_particle_data
[frame_set
->
17516 n_particle_data_blocks
- 1];
17520 p_data
= &tng_data
->non_tr_particle_data
[tng_data
->
17521 n_particle_data_blocks
- 1];
17523 stat
= tng_allocate_particle_data_mem(tng_data
, p_data
, n_frames
,
17524 stride_length
, n_particles
,
17525 n_values_per_frame
);
17526 if(stat
!= TNG_SUCCESS
)
17528 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
17529 __FILE__
, __LINE__
);
17534 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
17536 stride_length
= p_data
->stride_length
;
17538 if(is_first_frame_flag
|| p_data
->first_frame_with_data
< frame_set
->first_frame
)
17540 p_data
->first_frame_with_data
= frame_nr
;
17545 frame_pos
= (frame_nr
- frame_set
->first_frame
) / stride_length
;
17548 memcpy((char *)p_data
->values
+ sizeof(float) * frame_pos
* n_particles
*
17549 n_values_per_frame
, values
, sizeof(float) *
17550 n_particles
* n_values_per_frame
);
17554 memcpy(p_data
->values
, values
, sizeof(float) * n_particles
*
17555 n_values_per_frame
);
17560 if(tng_data_find(tng_data
, block_id
, &np_data
) != TNG_SUCCESS
)
17562 stat
= tng_data_block_add(tng_data
, block_id
, block_name
,
17563 TNG_FLOAT_DATA
, block_type_flag
,
17564 n_frames
, n_values_per_frame
,
17565 stride_length
, compression
, 0);
17566 if(stat
!= TNG_SUCCESS
)
17568 fprintf(stderr
, "TNG library: Error %s adding data block. %s: %d\n", block_name
,
17569 __FILE__
, __LINE__
);
17572 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
17574 np_data
= &frame_set
->tr_data
[frame_set
->
17575 n_data_blocks
- 1];
17579 np_data
= &tng_data
->non_tr_data
[tng_data
->
17580 n_data_blocks
- 1];
17582 stat
= tng_allocate_data_mem(tng_data
, np_data
, n_frames
,
17583 stride_length
, n_values_per_frame
);
17584 if(stat
!= TNG_SUCCESS
)
17586 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
17587 __FILE__
, __LINE__
);
17592 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
17594 stride_length
= np_data
->stride_length
;
17596 if(is_first_frame_flag
|| np_data
->first_frame_with_data
< frame_set
->first_frame
)
17598 np_data
->first_frame_with_data
= frame_nr
;
17603 frame_pos
= (frame_nr
- frame_set
->first_frame
) / stride_length
;
17606 memcpy((char *)np_data
->values
+ sizeof(float) * frame_pos
*
17607 n_values_per_frame
, values
, sizeof(float) *
17608 n_values_per_frame
);
17612 memcpy(np_data
->values
, values
, sizeof(float) * n_values_per_frame
);
17616 return(TNG_SUCCESS
);
17619 tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write
17620 (tng_trajectory_t tng_data
,
17621 const int64_t frame_nr
,
17622 const double *values
,
17623 const int64_t n_values_per_frame
,
17624 const int64_t block_id
,
17625 const char *block_name
,
17626 const char particle_dependency
,
17627 const char compression
)
17629 tng_trajectory_frame_set_t frame_set
;
17630 tng_particle_data_t p_data
;
17631 tng_non_particle_data_t np_data
;
17632 int64_t n_particles
= 0, n_frames
, stride_length
= 100, frame_pos
;
17633 int64_t last_frame
;
17634 int is_first_frame_flag
= 0;
17635 char block_type_flag
;
17636 tng_function_status stat
;
17638 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17639 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17640 TNG_ASSERT(values
, "TNG library: values must not be a NULL pointer");
17642 if(particle_dependency
== TNG_PARTICLE_BLOCK_DATA
)
17644 tng_num_particles_get(tng_data
, &n_particles
);
17645 TNG_ASSERT(n_particles
> 0, "TNG library: There must be particles in the system to write particle data.");
17650 return(TNG_FAILURE
);
17653 frame_set
= &tng_data
->current_trajectory_frame_set
;
17657 block_type_flag
= TNG_NON_TRAJECTORY_BLOCK
;
17658 n_frames
= stride_length
= 1;
17662 block_type_flag
= TNG_TRAJECTORY_BLOCK
;
17664 n_frames
= tng_data
->frame_set_n_frames
;
17666 if(!frame_set
|| tng_data
->n_trajectory_frame_sets
<= 0)
17668 stat
= tng_frame_set_new(tng_data
, 0, n_frames
);
17669 if(stat
!= TNG_SUCCESS
)
17671 fprintf(stderr
, "TNG library: Cannot create frame set. %s: %d\n", __FILE__
,
17678 n_frames
= frame_set
->n_frames
;
17680 last_frame
= frame_set
->first_frame
+
17681 frame_set
->n_frames
- 1;
17682 if(frame_nr
> last_frame
)
17684 stat
= tng_frame_set_write(tng_data
, TNG_USE_HASH
);
17685 if(stat
!= TNG_SUCCESS
)
17687 fprintf(stderr
, "TNG library: Cannot write frame set. %s: %d\n", __FILE__
,
17691 if(last_frame
+ tng_data
->frame_set_n_frames
< frame_nr
)
17693 last_frame
= frame_nr
- 1;
17695 stat
= tng_frame_set_new(tng_data
, last_frame
+ 1, n_frames
);
17696 if(stat
!= TNG_SUCCESS
)
17698 fprintf(stderr
, "TNG library: Cannot create frame set. %s: %d\n", __FILE__
,
17703 if(frame_set
->n_unwritten_frames
== 0)
17705 is_first_frame_flag
= 1;
17707 frame_set
->n_unwritten_frames
= frame_nr
-
17708 frame_set
->first_frame
+ 1;
17711 if(particle_dependency
== TNG_PARTICLE_BLOCK_DATA
)
17713 if(tng_particle_data_find(tng_data
, block_id
, &p_data
)
17716 stat
= tng_particle_data_block_add(tng_data
, block_id
,
17720 n_frames
, n_values_per_frame
,
17724 if(stat
!= TNG_SUCCESS
)
17726 fprintf(stderr
, "TNG library: Error %s adding data block. %s: %d\n", block_name
,
17727 __FILE__
, __LINE__
);
17730 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
17732 p_data
= &frame_set
->tr_particle_data
[frame_set
->
17733 n_particle_data_blocks
- 1];
17737 p_data
= &tng_data
->non_tr_particle_data
[tng_data
->
17738 n_particle_data_blocks
- 1];
17740 stat
= tng_allocate_particle_data_mem(tng_data
, p_data
, n_frames
,
17741 stride_length
, n_particles
,
17742 n_values_per_frame
);
17743 if(stat
!= TNG_SUCCESS
)
17745 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
17746 __FILE__
, __LINE__
);
17751 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
17753 stride_length
= p_data
->stride_length
;
17755 if(is_first_frame_flag
)
17757 p_data
->first_frame_with_data
= frame_nr
;
17762 frame_pos
= (frame_nr
- frame_set
->first_frame
) / stride_length
;
17765 memcpy((char *)p_data
->values
+ sizeof(double) * frame_pos
* n_particles
*
17766 n_values_per_frame
, values
, sizeof(double) *
17767 n_particles
* n_values_per_frame
);
17771 memcpy(p_data
->values
, values
, sizeof(double) * n_particles
*
17772 n_values_per_frame
);
17777 if(tng_data_find(tng_data
, block_id
, &np_data
) != TNG_SUCCESS
)
17779 stat
= tng_data_block_add(tng_data
, block_id
, block_name
,
17780 TNG_DOUBLE_DATA
, block_type_flag
,
17781 n_frames
, n_values_per_frame
,
17782 stride_length
, compression
, 0);
17783 if(stat
!= TNG_SUCCESS
)
17785 fprintf(stderr
, "TNG library: Error %s adding data block. %s: %d\n", block_name
,
17786 __FILE__
, __LINE__
);
17789 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
17791 np_data
= &frame_set
->tr_data
[frame_set
->
17792 n_data_blocks
- 1];
17796 np_data
= &tng_data
->non_tr_data
[tng_data
->
17797 n_data_blocks
- 1];
17799 stat
= tng_allocate_data_mem(tng_data
, np_data
, n_frames
,
17800 stride_length
, n_values_per_frame
);
17801 if(stat
!= TNG_SUCCESS
)
17803 fprintf(stderr
, "TNG library: Error allocating particle data memory. %s: %d\n",
17804 __FILE__
, __LINE__
);
17809 if(block_type_flag
== TNG_TRAJECTORY_BLOCK
)
17811 stride_length
= np_data
->stride_length
;
17813 if(is_first_frame_flag
)
17815 np_data
->first_frame_with_data
= frame_nr
;
17820 frame_pos
= (frame_nr
- frame_set
->first_frame
) / stride_length
;
17823 memcpy((char *)np_data
->values
+ sizeof(double) * frame_pos
*
17824 n_values_per_frame
, values
, sizeof(double) *
17825 n_values_per_frame
);
17829 memcpy(np_data
->values
, values
, sizeof(double) * n_values_per_frame
);
17833 return(TNG_SUCCESS
);
17836 tng_function_status DECLSPECDLLEXPORT tng_util_pos_write
17837 (tng_trajectory_t tng_data
,
17838 const int64_t frame_nr
,
17839 const float *positions
)
17841 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17842 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17843 TNG_ASSERT(positions
, "TNG library: positions must not be a NULL pointer");
17845 return(tng_util_generic_write(tng_data
, frame_nr
, positions
, 3,
17846 TNG_TRAJ_POSITIONS
, "POSITIONS",
17847 TNG_PARTICLE_BLOCK_DATA
,
17848 TNG_TNG_COMPRESSION
));
17851 tng_function_status DECLSPECDLLEXPORT tng_util_pos_double_write
17852 (tng_trajectory_t tng_data
,
17853 const int64_t frame_nr
,
17854 const double *positions
)
17856 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17857 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17858 TNG_ASSERT(positions
, "TNG library: positions must not be a NULL pointer");
17860 return(tng_util_generic_double_write(tng_data
, frame_nr
, positions
, 3,
17861 TNG_TRAJ_POSITIONS
, "POSITIONS",
17862 TNG_PARTICLE_BLOCK_DATA
,
17863 TNG_TNG_COMPRESSION
));
17866 tng_function_status DECLSPECDLLEXPORT tng_util_vel_write
17867 (tng_trajectory_t tng_data
,
17868 const int64_t frame_nr
,
17869 const float *velocities
)
17871 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17872 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17873 TNG_ASSERT(velocities
, "TNG library: velocities must not be a NULL pointer");
17875 return(tng_util_generic_write(tng_data
, frame_nr
, velocities
, 3,
17876 TNG_TRAJ_VELOCITIES
, "VELOCITIES",
17877 TNG_PARTICLE_BLOCK_DATA
,
17878 TNG_TNG_COMPRESSION
));
17881 tng_function_status DECLSPECDLLEXPORT tng_util_vel_double_write
17882 (tng_trajectory_t tng_data
,
17883 const int64_t frame_nr
,
17884 const double *velocities
)
17886 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17887 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17888 TNG_ASSERT(velocities
, "TNG library: velocities must not be a NULL pointer");
17890 return(tng_util_generic_double_write(tng_data
, frame_nr
, velocities
, 3,
17891 TNG_TRAJ_VELOCITIES
, "VELOCITIES",
17892 TNG_PARTICLE_BLOCK_DATA
,
17893 TNG_TNG_COMPRESSION
));
17896 tng_function_status DECLSPECDLLEXPORT tng_util_force_write
17897 (tng_trajectory_t tng_data
,
17898 const int64_t frame_nr
,
17899 const float *forces
)
17901 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17902 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17903 TNG_ASSERT(forces
, "TNG library: forces must not be a NULL pointer");
17905 return(tng_util_generic_write(tng_data
, frame_nr
, forces
, 3,
17906 TNG_TRAJ_FORCES
, "FORCES",
17907 TNG_PARTICLE_BLOCK_DATA
,
17908 TNG_GZIP_COMPRESSION
));
17911 tng_function_status DECLSPECDLLEXPORT tng_util_force_double_write
17912 (tng_trajectory_t tng_data
,
17913 const int64_t frame_nr
,
17914 const double *forces
)
17916 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17917 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17918 TNG_ASSERT(forces
, "TNG library: forces must not be a NULL pointer");
17920 return(tng_util_generic_double_write(tng_data
, frame_nr
, forces
, 3,
17921 TNG_TRAJ_FORCES
, "FORCES",
17922 TNG_PARTICLE_BLOCK_DATA
,
17923 TNG_GZIP_COMPRESSION
));
17926 tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write
17927 (tng_trajectory_t tng_data
,
17928 const int64_t frame_nr
,
17929 const float *box_shape
)
17931 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17932 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17933 TNG_ASSERT(box_shape
, "TNG library: box_shape must not be a NULL pointer");
17935 return(tng_util_generic_write(tng_data
, frame_nr
, box_shape
, 9,
17936 TNG_TRAJ_BOX_SHAPE
, "BOX SHAPE",
17937 TNG_NON_PARTICLE_BLOCK_DATA
,
17938 TNG_GZIP_COMPRESSION
));
17941 tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_double_write
17942 (tng_trajectory_t tng_data
,
17943 const int64_t frame_nr
,
17944 const double *box_shape
)
17946 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17947 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17948 TNG_ASSERT(box_shape
, "TNG library: box_shape must not be a NULL pointer");
17950 return(tng_util_generic_double_write(tng_data
, frame_nr
, box_shape
, 9,
17951 TNG_TRAJ_BOX_SHAPE
, "BOX SHAPE",
17952 TNG_NON_PARTICLE_BLOCK_DATA
,
17953 TNG_GZIP_COMPRESSION
));
17956 tng_function_status DECLSPECDLLEXPORT tng_util_generic_with_time_write
17957 (tng_trajectory_t tng_data
,
17958 const int64_t frame_nr
,
17960 const float *values
,
17961 const int64_t n_values_per_frame
,
17962 const int64_t block_id
,
17963 const char *block_name
,
17964 const char particle_dependency
,
17965 const char compression
)
17967 tng_trajectory_frame_set_t frame_set
;
17968 tng_function_status stat
;
17970 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
17971 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
17972 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
17973 TNG_ASSERT(values
, "TNG library: values must not be a NULL pointer");
17975 stat
= tng_util_generic_write(tng_data
, frame_nr
, values
, n_values_per_frame
,
17976 block_id
, block_name
,
17977 particle_dependency
,
17980 if(stat
!= TNG_SUCCESS
)
17985 frame_set
= &tng_data
->current_trajectory_frame_set
;
17987 /* first_frame_time is -1 when it is not yet set. */
17988 if(frame_set
->first_frame_time
< -0.1)
17990 if(frame_nr
> frame_set
->first_frame
)
17992 stat
= tng_frame_set_first_frame_time_set(tng_data
,
17995 frame_set
->first_frame
) *
17996 tng_data
->time_per_frame
);
18000 stat
= tng_frame_set_first_frame_time_set(tng_data
, time
);
18006 tng_function_status DECLSPECDLLEXPORT tng_util_generic_with_time_double_write
18007 (tng_trajectory_t tng_data
,
18008 const int64_t frame_nr
,
18010 const double *values
,
18011 const int64_t n_values_per_frame
,
18012 const int64_t block_id
,
18013 const char *block_name
,
18014 const char particle_dependency
,
18015 const char compression
)
18017 tng_trajectory_frame_set_t frame_set
;
18018 tng_function_status stat
;
18020 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18021 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
18022 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
18023 TNG_ASSERT(values
, "TNG library: values must not be a NULL pointer");
18025 stat
= tng_util_generic_double_write(tng_data
, frame_nr
, values
, n_values_per_frame
,
18026 block_id
, block_name
,
18027 particle_dependency
,
18030 if(stat
!= TNG_SUCCESS
)
18035 frame_set
= &tng_data
->current_trajectory_frame_set
;
18037 /* first_frame_time is -1 when it is not yet set. */
18038 if(frame_set
->first_frame_time
< -0.1)
18040 if(frame_nr
> frame_set
->first_frame
)
18042 stat
= tng_frame_set_first_frame_time_set(tng_data
,
18045 frame_set
->first_frame
) *
18046 tng_data
->time_per_frame
);
18050 stat
= tng_frame_set_first_frame_time_set(tng_data
, time
);
18056 tng_function_status DECLSPECDLLEXPORT tng_util_pos_with_time_write
18057 (tng_trajectory_t tng_data
,
18058 const int64_t frame_nr
,
18060 const float *positions
)
18062 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18063 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
18064 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
18065 TNG_ASSERT(positions
, "TNG library: positions must not be a NULL pointer");
18067 return(tng_util_generic_with_time_write(tng_data
, frame_nr
, time
, positions
,
18068 3, TNG_TRAJ_POSITIONS
, "POSITIONS",
18069 TNG_PARTICLE_BLOCK_DATA
,
18070 TNG_TNG_COMPRESSION
));
18073 tng_function_status DECLSPECDLLEXPORT tng_util_pos_with_time_double_write
18074 (tng_trajectory_t tng_data
,
18075 const int64_t frame_nr
,
18077 const double *positions
)
18079 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18080 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
18081 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
18082 TNG_ASSERT(positions
, "TNG library: positions must not be a NULL pointer");
18084 return(tng_util_generic_with_time_double_write(tng_data
, frame_nr
, time
,
18086 TNG_TRAJ_POSITIONS
,
18088 TNG_PARTICLE_BLOCK_DATA
,
18089 TNG_TNG_COMPRESSION
));
18092 tng_function_status DECLSPECDLLEXPORT tng_util_vel_with_time_write
18093 (tng_trajectory_t tng_data
,
18094 const int64_t frame_nr
,
18096 const float *velocities
)
18098 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18099 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
18100 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
18101 TNG_ASSERT(velocities
, "TNG library: velocities must not be a NULL pointer");
18103 return(tng_util_generic_with_time_write(tng_data
, frame_nr
, time
,
18105 TNG_TRAJ_VELOCITIES
,
18107 TNG_PARTICLE_BLOCK_DATA
,
18108 TNG_TNG_COMPRESSION
));
18111 tng_function_status DECLSPECDLLEXPORT tng_util_vel_with_time_double_write
18112 (tng_trajectory_t tng_data
,
18113 const int64_t frame_nr
,
18115 const double *velocities
)
18117 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18118 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
18119 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
18120 TNG_ASSERT(velocities
, "TNG library: velocities must not be a NULL pointer");
18122 return(tng_util_generic_with_time_double_write(tng_data
, frame_nr
, time
,
18124 TNG_TRAJ_VELOCITIES
,
18126 TNG_PARTICLE_BLOCK_DATA
,
18127 TNG_TNG_COMPRESSION
));
18130 tng_function_status DECLSPECDLLEXPORT tng_util_force_with_time_write
18131 (tng_trajectory_t tng_data
,
18132 const int64_t frame_nr
,
18134 const float *forces
)
18136 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18137 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
18138 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
18139 TNG_ASSERT(forces
, "TNG library: forces must not be a NULL pointer");
18141 return(tng_util_generic_with_time_write(tng_data
, frame_nr
, time
, forces
,
18142 3, TNG_TRAJ_FORCES
, "FORCES",
18143 TNG_PARTICLE_BLOCK_DATA
,
18144 TNG_GZIP_COMPRESSION
));
18147 tng_function_status DECLSPECDLLEXPORT tng_util_force_with_time_double_write
18148 (tng_trajectory_t tng_data
,
18149 const int64_t frame_nr
,
18151 const double *forces
)
18153 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18154 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
18155 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
18156 TNG_ASSERT(forces
, "TNG library: forces must not be a NULL pointer");
18158 return(tng_util_generic_with_time_double_write(tng_data
, frame_nr
, time
,
18160 TNG_TRAJ_FORCES
, "FORCES",
18161 TNG_PARTICLE_BLOCK_DATA
,
18162 TNG_GZIP_COMPRESSION
));
18165 tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_with_time_write
18166 (tng_trajectory_t tng_data
,
18167 const int64_t frame_nr
,
18169 const float *box_shape
)
18171 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18172 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
18173 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
18174 TNG_ASSERT(box_shape
, "TNG library: box_shape must not be a NULL pointer");
18176 return(tng_util_generic_with_time_write(tng_data
, frame_nr
, time
, box_shape
,
18177 9, TNG_TRAJ_BOX_SHAPE
, "BOX SHAPE",
18178 TNG_NON_PARTICLE_BLOCK_DATA
,
18179 TNG_GZIP_COMPRESSION
));
18182 tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_with_time_double_write
18183 (tng_trajectory_t tng_data
,
18184 const int64_t frame_nr
,
18186 const double *box_shape
)
18188 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18189 TNG_ASSERT(frame_nr
>= 0, "TNG library: frame_nr must be >= 0.");
18190 TNG_ASSERT(time
>= 0, "TNG library: time must be >= 0.");
18191 TNG_ASSERT(box_shape
, "TNG library: box_shape must not be a NULL pointer");
18193 return(tng_util_generic_with_time_double_write(tng_data
, frame_nr
,
18194 time
, box_shape
, 9,
18195 TNG_TRAJ_BOX_SHAPE
,
18197 TNG_NON_PARTICLE_BLOCK_DATA
,
18198 TNG_GZIP_COMPRESSION
));
18201 tng_function_status DECLSPECDLLEXPORT tng_util_frame_current_compression_get
18202 (tng_trajectory_t tng_data
,
18203 const int64_t block_id
,
18207 tng_trajectory_frame_set_t frame_set
;
18208 tng_particle_data_t p_data
= 0;
18209 tng_non_particle_data_t np_data
= 0;
18210 tng_function_status stat
;
18212 int block_type
= -1;
18214 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18215 TNG_ASSERT(codec_id
, "TNG library: The pointer to the returned codec id must not be a NULL pointer.");
18216 TNG_ASSERT(factor
, "TNG library: The pointer to the returned multiplication factor must not be a NULL pointer.");
18218 frame_set
= &tng_data
->current_trajectory_frame_set
;
18220 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
18221 if(stat
== TNG_SUCCESS
)
18223 block_type
= TNG_PARTICLE_BLOCK_DATA
;
18227 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
18228 if(stat
== TNG_SUCCESS
)
18230 block_type
= TNG_NON_PARTICLE_BLOCK_DATA
;
18234 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
18235 if(stat
!= TNG_SUCCESS
)
18239 stat
= tng_particle_data_find(tng_data
, block_id
, &p_data
);
18240 if(stat
== TNG_SUCCESS
)
18242 block_type
= TNG_PARTICLE_BLOCK_DATA
;
18246 stat
= tng_data_find(tng_data
, block_id
, &np_data
);
18247 if(stat
== TNG_SUCCESS
)
18249 block_type
= TNG_NON_PARTICLE_BLOCK_DATA
;
18258 if(block_type
== TNG_PARTICLE_BLOCK_DATA
)
18260 if(p_data
->last_retrieved_frame
< 0)
18262 i
= p_data
->first_frame_with_data
;
18266 i
= p_data
->last_retrieved_frame
;
18269 else if(block_type
== TNG_NON_PARTICLE_BLOCK_DATA
)
18271 if(np_data
->last_retrieved_frame
< 0)
18273 i
= np_data
->first_frame_with_data
;
18277 i
= np_data
->last_retrieved_frame
;
18282 return(TNG_FAILURE
);
18284 if(i
< frame_set
->first_frame
|| i
>= frame_set
->first_frame
+ frame_set
->n_frames
)
18286 stat
= tng_frame_set_of_frame_find(tng_data
, i
);
18287 if(stat
!= TNG_SUCCESS
)
18291 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
, TNG_USE_HASH
, block_id
);
18292 if(stat
!= TNG_SUCCESS
)
18294 fprintf(stderr
, "TNG library: Cannot read data block of frame set. %s: %d\n",
18295 __FILE__
, __LINE__
);
18299 if(block_type
== TNG_PARTICLE_BLOCK_DATA
)
18301 *codec_id
= p_data
->codec_id
;
18302 *factor
= (float)p_data
->compression_multiplier
;
18304 else if(block_type
== TNG_NON_PARTICLE_BLOCK_DATA
)
18306 *codec_id
= np_data
->codec_id
;
18307 *factor
= (float)np_data
->compression_multiplier
;
18309 return(TNG_SUCCESS
);
18312 tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_data_blocks_find
18313 (tng_trajectory_t tng_data
,
18314 int64_t current_frame
,
18315 const int64_t n_requested_data_block_ids
,
18316 const int64_t *requested_data_block_ids
,
18317 int64_t *next_frame
,
18318 int64_t *n_data_blocks_in_next_frame
,
18319 int64_t **data_block_ids_in_next_frame
)
18321 tng_trajectory_frame_set_t frame_set
;
18322 tng_function_status stat
;
18323 tng_particle_data_t p_data
;
18324 tng_non_particle_data_t np_data
;
18325 tng_gen_block_t block
;
18326 int64_t i
, j
, block_id
, *temp
;
18327 int64_t data_frame
, frame_diff
, min_diff
;
18328 int64_t size
, frame_set_file_pos
;
18329 int found
, read_all
= 0;
18332 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18333 TNG_ASSERT(next_frame
, "TNG library: The pointer to the next frame must not be NULL.");
18334 TNG_ASSERT(n_data_blocks_in_next_frame
, "TNG library: The pointer to n_data_blocks_in_next_frame must not be NULL.");
18335 TNG_ASSERT(data_block_ids_in_next_frame
, "TNG library: The pointer to the list of data block IDs must not be NULL.");
18337 if(n_requested_data_block_ids
)
18339 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.");
18340 size
= sizeof(int64_t) * n_requested_data_block_ids
;
18341 temp
= realloc(*data_block_ids_in_next_frame
, size
);
18344 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
18345 sizeof(int64_t) * (*n_data_blocks_in_next_frame
),
18346 __FILE__
, __LINE__
);
18347 free(*data_block_ids_in_next_frame
);
18348 *data_block_ids_in_next_frame
= 0;
18349 return(TNG_CRITICAL
);
18351 *data_block_ids_in_next_frame
= temp
;
18354 frame_set
= &tng_data
->current_trajectory_frame_set
;
18356 current_frame
+= 1;
18358 if(current_frame
< frame_set
->first_frame
||
18359 current_frame
>= frame_set
->first_frame
+ frame_set
->n_frames
)
18361 frame_set_file_pos
= tng_data
->current_trajectory_frame_set_input_file_pos
;
18362 stat
= tng_frame_set_of_frame_find(tng_data
, current_frame
);
18363 if(stat
!= TNG_SUCCESS
)
18365 /* If the frame set search found the frame set after the starting
18366 * frame set there is a gap in the frame sets. So, even if the frame
18367 * was not found the next frame with data is still in the found
18369 if(stat
== TNG_CRITICAL
|| frame_set
->prev_frame_set_file_pos
!=
18370 frame_set_file_pos
)
18374 current_frame
= frame_set
->first_frame
;
18378 /* If no data blocks have been found in the frame set check what data blocks
18379 * are present. If they have already been found do not read them again. */
18380 if(frame_set
->n_particle_data_blocks
<= 0 && frame_set
->n_data_blocks
<= 0)
18382 file_pos
= ftell(tng_data
->input_file
);
18383 /* Read all blocks until next frame set block */
18384 if(file_pos
< tng_data
->input_file_len
)
18386 tng_block_init(&block
);
18387 stat
= tng_block_header_read(tng_data
, block
);
18388 while(file_pos
< tng_data
->input_file_len
&&
18389 stat
!= TNG_CRITICAL
&&
18390 block
->id
!= TNG_TRAJECTORY_FRAME_SET
)
18392 stat
= tng_block_read_next(tng_data
, block
,
18394 if(stat
!= TNG_CRITICAL
)
18396 file_pos
= ftell(tng_data
->input_file
);
18397 if(file_pos
< tng_data
->input_file_len
)
18399 stat
= tng_block_header_read(tng_data
, block
);
18403 tng_block_destroy(&block
);
18404 if(stat
== TNG_CRITICAL
)
18406 fprintf(stderr
, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
18407 file_pos
, __FILE__
, __LINE__
);
18416 *n_data_blocks_in_next_frame
= 0;
18418 for(i
= 0; i
< frame_set
->n_particle_data_blocks
; i
++)
18420 p_data
= &frame_set
->tr_particle_data
[i
];
18421 block_id
= p_data
->block_id
;
18423 if(n_requested_data_block_ids
> 0)
18426 for(j
= 0; j
< n_requested_data_block_ids
; j
++)
18428 if(block_id
== requested_data_block_ids
[j
])
18440 if(!read_all
&& (p_data
->last_retrieved_frame
< frame_set
->first_frame
||
18441 p_data
->last_retrieved_frame
>=
18442 frame_set
->first_frame
+ frame_set
->n_frames
))
18444 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
,
18445 TNG_USE_HASH
, block_id
);
18446 if(stat
== TNG_CRITICAL
)
18448 fprintf(stderr
, "TNG library: Cannot read data block of frame set. %s: %d\n",
18449 __FILE__
, __LINE__
);
18452 if(stat
== TNG_FAILURE
)
18457 if(frame_set
->first_frame
!= current_frame
&&
18458 p_data
->last_retrieved_frame
>= 0)
18460 data_frame
= p_data
->last_retrieved_frame
+ p_data
->stride_length
;
18464 data_frame
= p_data
->first_frame_with_data
;
18466 frame_diff
= data_frame
- current_frame
;
18471 if(min_diff
== -1 || frame_diff
<= min_diff
)
18473 if(frame_diff
< min_diff
)
18475 *n_data_blocks_in_next_frame
= 1;
18479 *n_data_blocks_in_next_frame
+= 1;
18481 if(n_requested_data_block_ids
<= 0)
18483 size
= sizeof(int64_t) * (*n_data_blocks_in_next_frame
);
18484 temp
= realloc(*data_block_ids_in_next_frame
, size
);
18487 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
18488 sizeof(int64_t) * (*n_data_blocks_in_next_frame
),
18489 __FILE__
, __LINE__
);
18490 free(*data_block_ids_in_next_frame
);
18491 *data_block_ids_in_next_frame
= 0;
18492 return(TNG_CRITICAL
);
18494 *data_block_ids_in_next_frame
= temp
;
18498 TNG_ASSERT(*n_data_blocks_in_next_frame
<= n_requested_data_block_ids
, "TNG library: Array of data block IDs out of bounds");
18500 (*data_block_ids_in_next_frame
)[(*n_data_blocks_in_next_frame
) - 1] = block_id
;
18502 min_diff
= frame_diff
;
18505 for(i
= 0; i
< frame_set
->n_data_blocks
; i
++)
18507 np_data
= &frame_set
->tr_data
[i
];
18508 block_id
= np_data
->block_id
;
18510 if(n_requested_data_block_ids
> 0)
18513 for(j
= 0; j
< n_requested_data_block_ids
; j
++)
18515 if(block_id
== requested_data_block_ids
[j
])
18527 if(!read_all
&& (np_data
->last_retrieved_frame
< frame_set
->first_frame
||
18528 np_data
->last_retrieved_frame
>=
18529 frame_set
->first_frame
+ frame_set
->n_frames
))
18531 stat
= tng_frame_set_read_current_only_data_from_block_id(tng_data
,
18532 TNG_USE_HASH
, block_id
);
18533 if(stat
== TNG_CRITICAL
)
18535 fprintf(stderr
, "TNG library: Cannot read data block of frame set. %s: %d\n",
18536 __FILE__
, __LINE__
);
18539 if(stat
== TNG_FAILURE
)
18544 if(frame_set
->first_frame
!= current_frame
&&
18545 np_data
->last_retrieved_frame
>= 0)
18547 data_frame
= np_data
->last_retrieved_frame
+ np_data
->stride_length
;
18551 data_frame
= np_data
->first_frame_with_data
;
18553 frame_diff
= data_frame
- current_frame
;
18558 if(min_diff
== -1 || frame_diff
<= min_diff
)
18560 if(frame_diff
< min_diff
)
18562 *n_data_blocks_in_next_frame
= 1;
18566 *n_data_blocks_in_next_frame
+= 1;
18568 if(n_requested_data_block_ids
<= 0)
18570 size
= sizeof(int64_t) * (*n_data_blocks_in_next_frame
);
18571 temp
= realloc(*data_block_ids_in_next_frame
, size
);
18574 fprintf(stderr
, "TNG library: Cannot allocate memory (%"PRId64
" bytes). %s: %d\n",
18575 sizeof(int64_t) * (*n_data_blocks_in_next_frame
),
18576 __FILE__
, __LINE__
);
18577 free(*data_block_ids_in_next_frame
);
18578 *data_block_ids_in_next_frame
= 0;
18579 return(TNG_CRITICAL
);
18581 *data_block_ids_in_next_frame
= temp
;
18585 TNG_ASSERT(*n_data_blocks_in_next_frame
<= n_requested_data_block_ids
, "TNG library: Array of data block IDs out of bounds");
18587 (*data_block_ids_in_next_frame
)[(*n_data_blocks_in_next_frame
) - 1] = block_id
;
18589 min_diff
= frame_diff
;
18594 return(TNG_FAILURE
);
18596 *next_frame
= current_frame
+ min_diff
;
18598 return(TNG_SUCCESS
);
18602 tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_all_data_block_types_get
18603 (tng_trajectory_t tng_data,
18604 int64_t *n_data_blocks,
18605 int64_t **data_block_ids,
18606 char ***data_block_names,
18607 int64_t **stride_lengths,
18608 int64_t **n_values_per_frame,
18609 char **block_types,
18610 char **dependencies,
18611 char **compressions)
18613 tng_gen_block_t block;
18614 long orig_file_pos, file_pos;
18616 TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
18617 TNG_ASSERT(n_data_blocks, "TNG library: The pointer to n_data_blocks must not be NULL.");
18618 TNG_ASSERT(data_block_ids, "TNG library: The pointer to the list of data block IDs must not be NULL.");
18619 TNG_ASSERT(data_block_names, "TNG library: The pointer to the list of data block names must not be NULL.");
18620 TNG_ASSERT(stride_lengths, "TNG library: The pointer to the list of stride lengths must not be NULL.");
18622 orig_file_pos = ftell(tng_data->input_file);
18624 if(!tng_data->input_file_len)
18626 fseek(tng_data->input_file, 0, SEEK_END);
18627 tng_data->input_file_len = ftell(tng_data->input_file);
18630 fseek(tng_data->input_file, 0, SEEK_SET);
18633 *n_data_blocks = 0;
18635 tng_block_init(&block);
18637 while(file_pos < tng_data->input_file_len &&
18638 tng_block_header_read(tng_data, block) != TNG_CRITICAL)
18640 if(block->id > TNG_TRAJECTORY_FRAME_SET)
18644 file_pos += (long)(block->block_contents_size + block->header_contents_size);
18645 fseek(tng_data->input_file, (long)block->block_contents_size, SEEK_CUR);
18648 fseek(tng_data->input_file, orig_file_pos, SEEK_SET);
18650 return(TNG_SUCCESS);
18653 tng_function_status DECLSPECDLLEXPORT tng_util_prepare_append_after_frame
18654 (tng_trajectory_t tng_data
,
18655 const int64_t prev_frame
)
18657 tng_function_status stat
;
18658 FILE *temp
= tng_data
->input_file
;
18660 TNG_ASSERT(tng_data
, "TNG library: Trajectory container not properly setup.");
18661 TNG_ASSERT(prev_frame
>= 0, "TNG library: The previous frame must not be negative.");
18663 tng_data
->input_file
= tng_data
->output_file
;
18665 stat
= tng_frame_set_of_frame_find(tng_data
, prev_frame
);
18666 if(stat
!= TNG_SUCCESS
)
18671 tng_data
->current_trajectory_frame_set_output_file_pos
=
18672 tng_data
->current_trajectory_frame_set_input_file_pos
;
18674 tng_data
->input_file
= temp
;
18676 return(TNG_SUCCESS
);