Update TNG build system
[gromacs.git] / src / external / tng_io / src / tests / compression / testsuite.c
blobe266c110b8b43995e56ef63ab34f165dfe163eff
1 /* tng compression routines */
3 /* Only modify testsuite.c
4 *Then* run testsuite.sh to perform the test.
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <math.h>
11 #include "compression/tng_compress.h"
12 #include TESTPARAM
14 #ifdef TEST_FLOAT
15 #define REAL float
16 #else
17 #define REAL double
18 #endif
20 #ifndef TNG_COMPRESS_FILES_DIR
21 #define TNG_COMPRESS_FILES_DIR ""
22 #endif
24 #define FUDGE 1.1 /* 10% off target precision is acceptable */
26 static void keepinbox(int *val)
28 while (val[0]>INTMAX1)
29 val[0]-=(INTMAX1-INTMIN1+1);
30 while (val[0]<INTMIN1)
31 val[0]+=(INTMAX1-INTMIN1+1);
32 while (val[1]>INTMAX2)
33 val[1]-=(INTMAX2-INTMIN2+1);
34 while (val[1]<INTMIN2)
35 val[1]+=(INTMAX2-INTMIN2+1);
36 while (val[2]>INTMAX3)
37 val[2]-=(INTMAX3-INTMIN3+1);
38 while (val[2]<INTMIN3)
39 val[2]+=(INTMAX3-INTMIN3+1);
42 static int intsintable[128]={
43 0 , 3215 , 6423 , 9615 , 12785 , 15923 , 19023 , 22078 ,
44 25079 , 28019 , 30892 , 33691 , 36409 , 39039 , 41574 , 44010 ,
45 46340 , 48558 , 50659 , 52638 , 54490 , 56211 , 57796 , 59242 ,
46 60546 , 61704 , 62713 , 63570 , 64275 , 64825 , 65219 , 65456 ,
47 65535 , 65456 , 65219 , 64825 , 64275 , 63570 , 62713 , 61704 ,
48 60546 , 59242 , 57796 , 56211 , 54490 , 52638 , 50659 , 48558 ,
49 46340 , 44010 , 41574 , 39039 , 36409 , 33691 , 30892 , 28019 ,
50 25079 , 22078 , 19023 , 15923 , 12785 , 9615 , 6423 , 3215 ,
51 0 , -3215 , -6423 , -9615 , -12785 , -15923 , -19023 , -22078 ,
52 -25079 , -28019 , -30892 , -33691 , -36409 , -39039 , -41574 , -44010 ,
53 -46340 , -48558 , -50659 , -52638 , -54490 , -56211 , -57796 , -59242 ,
54 -60546 , -61704 , -62713 , -63570 , -64275 , -64825 , -65219 , -65456 ,
55 -65535 , -65456 , -65219 , -64825 , -64275 , -63570 , -62713 , -61704 ,
56 -60546 , -59242 , -57796 , -56211 , -54490 , -52638 , -50659 , -48558 ,
57 -46340 , -44010 , -41574 , -39039 , -36409 , -33691 , -30892 , -28019 ,
58 -25079 , -22078 , -19023 , -15923 , -12785 , -9615 , -6423 , -3215 ,
61 static int intsin(int i)
63 int sign=1;
64 if (i<0)
66 i=0;
67 sign=-1;
69 return sign*intsintable[i%128];
72 static int intcos(int i)
74 if (i<0)
75 i=0;
76 return intsin(i+32);
79 static void molecule(int *target,
80 int *base,
81 int length,
82 int scale, int *direction,
83 int flip,
84 int iframe)
86 int i;
87 for (i=0; i<length; i++)
89 int ifl=i;
90 if ((i==0) && (flip) && (length>1))
91 ifl=1;
92 else if ((i==1) && (flip) && (length>1))
93 ifl=0;
94 target[ifl*3]=base[0]+(intsin((i+iframe)*direction[0])*scale)/256;
95 target[ifl*3+1]=base[1]+(intcos((i+iframe)*direction[1])*scale)/256;
96 target[ifl*3+2]=base[2]+(intcos((i+iframe)*direction[2])*scale)/256;
97 keepinbox(target+ifl*3);
101 #ifndef FRAMESCALE
102 #define FRAMESCALE 1
103 #endif
105 static void genibox(int *intbox, int iframe)
107 int molecule_length=1;
108 int molpos[3];
109 int direction[3]={1,1,1};
110 int scale=1;
111 int flip=0;
112 int i=0;
113 molpos[0]=intsin(iframe*FRAMESCALE)/32;
114 molpos[1]=1+intcos(iframe*FRAMESCALE)/32;
115 molpos[2]=2+intsin(iframe*FRAMESCALE)/16;
116 keepinbox(molpos);
117 while (i<NATOMS)
119 int this_mol_length=molecule_length;
120 int dir;
121 #ifdef REGULAR
122 this_mol_length=4;
123 flip=0;
124 scale=1;
125 #endif
126 if (i+this_mol_length>NATOMS)
127 this_mol_length=NATOMS-i;
128 /* We must test the large rle as well. This requires special
129 sequencies to get triggered. So insert these from time to
130 time */
131 #ifndef REGULAR
132 if ((i%10)==0)
134 int j;
135 intbox[i*3]=molpos[0];
136 intbox[i*3+1]=molpos[1];
137 intbox[i*3+2]=molpos[2];
138 for (j=1; j<this_mol_length; j++)
140 intbox[(i+j)*3]=intbox[(i+j-1)*3]+(INTMAX1-INTMIN1+1)/5;
141 intbox[(i+j)*3+1]=intbox[(i+j-1)*3+1]+(INTMAX2-INTMIN2+1)/5;
142 intbox[(i+j)*3+2]=intbox[(i+j-1)*3+2]+(INTMAX3-INTMIN3+1)/5;
143 keepinbox(intbox+(i+j)*3);
146 else
147 #endif
148 molecule(intbox+i*3,molpos,this_mol_length,scale,direction,flip,iframe*FRAMESCALE);
149 i+=this_mol_length;
150 dir=1;
151 if (intsin(i*3)<0)
152 dir=-1;
153 molpos[0]+=dir*(INTMAX1-INTMIN1+1)/20;
154 dir=1;
155 if (intsin(i*5)<0)
156 dir=-1;
157 molpos[1]+=dir*(INTMAX2-INTMIN2+1)/20;
158 dir=1;
159 if (intsin(i*7)<0)
160 dir=-1;
161 molpos[2]+=dir*(INTMAX3-INTMIN3+1)/20;
162 keepinbox(molpos);
164 direction[0]=((direction[0]+1)%7)+1;
165 direction[1]=((direction[1]+1)%3)+1;
166 direction[2]=((direction[2]+1)%6)+1;
168 scale++;
169 if (scale>5)
170 scale=1;
172 molecule_length++;
173 if (molecule_length>30)
174 molecule_length=1;
175 if (i%9)
176 flip=1-flip;
180 static void genivelbox(int *intvelbox, int iframe)
182 int i;
183 for (i=0; i<NATOMS; i++)
185 #ifdef VELINTMUL
186 intvelbox[i*3]=((intsin((i+iframe*FRAMESCALE)*3))/10)*VELINTMUL+i;
187 intvelbox[i*3+1]=1+((intcos((i+iframe*FRAMESCALE)*5))/10)*VELINTMUL+i;
188 intvelbox[i*3+2]=2+((intsin((i+iframe*FRAMESCALE)*7)+intcos((i+iframe*FRAMESCALE)*9))/20)*VELINTMUL+i;
189 #else
190 intvelbox[i*3]=((intsin((i+iframe*FRAMESCALE)*3))/10);
191 intvelbox[i*3+1]=1+((intcos((i+iframe*FRAMESCALE)*5))/10);
192 intvelbox[i*3+2]=2+((intsin((i+iframe*FRAMESCALE)*7)+intcos((i+iframe*FRAMESCALE)*9))/20);
193 #endif
197 #ifndef STRIDE1
198 #define STRIDE1 3
199 #endif
201 #ifndef STRIDE2
202 #define STRIDE2 3
203 #endif
205 #ifndef GENPRECISION
206 #define GENPRECISION PRECISION
207 #endif
209 #ifndef GENVELPRECISION
210 #define GENVELPRECISION VELPRECISION
211 #endif
213 static void realbox(int *intbox, REAL *realbox, int stride)
215 int i,j;
216 for (i=0; i<NATOMS; i++)
218 for (j=0; j<3; j++)
219 realbox[i*stride+j]=(REAL)(intbox[i*3+j]*GENPRECISION*SCALE);
220 for (j=3; j<stride; j++)
221 realbox[i*stride+j]=0.;
225 static void realvelbox(int *intbox, REAL *realbox, int stride)
227 int i,j;
228 for (i=0; i<NATOMS; i++)
230 for (j=0; j<3; j++)
231 realbox[i*stride+j]=(REAL)(intbox[i*3+j]*GENVELPRECISION*SCALE);
232 for (j=3; j<stride; j++)
233 realbox[i*stride+j]=0.;
237 static int equalarr(REAL *arr1, REAL *arr2, REAL prec, int len, int itemlen, int stride1, int stride2)
239 REAL maxdiff=0.;
240 int i,j;
241 for (i=0; i<len; i++)
243 for (j=0; j<itemlen; j++)
244 if (fabs(arr1[i*stride1+j]-arr2[i*stride2+j])>maxdiff)
245 maxdiff=(REAL)fabs(arr1[i*stride1+j]-arr2[i*stride2+j]);
247 #if 0
248 for (i=0; i<len; i++)
250 for (j=0; j<itemlen; j++)
251 printf("%d %d: %g %g\n",i,j,arr1[i*stride1+j],arr2[i*stride2+j]);
253 #endif
254 #if 0
255 fprintf(stderr,"Error is %g. Acceptable error is %g.\n",maxdiff,prec*0.5*FUDGE);
256 #endif
257 if (maxdiff>prec*0.5*FUDGE)
259 return 0;
261 else
262 return 1;
265 struct tng_file
267 FILE *f;
268 int natoms;
269 int chunky;
270 REAL precision;
271 REAL velprecision;
272 int initial_coding;
273 int initial_coding_parameter;
274 int coding;
275 int coding_parameter;
276 int initial_velcoding;
277 int initial_velcoding_parameter;
278 int velcoding;
279 int velcoding_parameter;
280 int speed;
281 int nframes;
282 int nframes_delivered;
283 int writevel;
284 REAL *pos;
285 REAL *vel;
286 int *ipos;
287 int *ivel;
288 unsigned int prec_hi, prec_lo;
289 unsigned int velprec_hi, velprec_lo;
292 static size_t fwrite_int_le(int *x,FILE *f)
294 unsigned char c[4];
295 unsigned int i=(unsigned int)*x;
296 c[0]=(unsigned char)(i&0xFFU);
297 c[1]=(unsigned char)((i>>8)&0xFFU);
298 c[2]=(unsigned char)((i>>16)&0xFFU);
299 c[3]=(unsigned char)((i>>24)&0xFFU);
300 return fwrite(c,1,4,f);
303 static size_t fread_int_le(int *x,FILE *f)
305 unsigned char c[4];
306 unsigned int i;
307 size_t n=fread(c,1,4,f);
308 if (n)
310 i=(((unsigned int)c[3])<<24)|(((unsigned int)c[2])<<16)|(((unsigned int)c[1])<<8)|((unsigned int)c[0]);
311 *x=(int)i;
313 return n;
316 static struct tng_file *open_tng_file_write(char *filename,
317 int natoms,int chunky,
318 REAL precision,
319 int writevel,
320 REAL velprecision,
321 int initial_coding,
322 int initial_coding_parameter,
323 int coding,
324 int coding_parameter,
325 int initial_velcoding,
326 int initial_velcoding_parameter,
327 int velcoding,
328 int velcoding_parameter,
329 int speed)
331 struct tng_file *tng_file=malloc(sizeof *tng_file);
332 tng_file->pos=NULL;
333 tng_file->vel=NULL;
334 tng_file->ipos=NULL;
335 tng_file->ivel=NULL;
336 tng_file->nframes=0;
337 tng_file->chunky=chunky;
338 tng_file->precision=precision;
339 tng_file->natoms=natoms;
340 tng_file->writevel=writevel;
341 tng_file->velprecision=velprecision;
342 tng_file->initial_coding=initial_coding;
343 tng_file->initial_coding_parameter=initial_coding_parameter;
344 tng_file->coding=coding;
345 tng_file->coding_parameter=coding_parameter;
346 tng_file->initial_velcoding=initial_velcoding;
347 tng_file->initial_velcoding_parameter=initial_velcoding_parameter;
348 tng_file->velcoding=velcoding;
349 tng_file->velcoding_parameter=velcoding_parameter;
350 tng_file->speed=speed;
351 tng_file->pos=malloc(natoms*chunky*3*sizeof *tng_file->pos);
352 tng_file->f=fopen(filename,"wb");
353 if (writevel)
354 tng_file->vel=malloc(natoms*chunky*3*sizeof *tng_file->vel);
355 fwrite_int_le(&natoms,tng_file->f);
356 return tng_file;
359 static struct tng_file *open_tng_file_write_int(char *filename,
360 int natoms,int chunky,
361 int writevel,
362 int initial_coding,
363 int initial_coding_parameter,
364 int coding,
365 int coding_parameter,
366 int initial_velcoding,
367 int initial_velcoding_parameter,
368 int velcoding,
369 int velcoding_parameter,
370 int speed)
372 struct tng_file *tng_file=malloc(sizeof *tng_file);
373 tng_file->pos=NULL;
374 tng_file->vel=NULL;
375 tng_file->ipos=NULL;
376 tng_file->ivel=NULL;
377 tng_file->nframes=0;
378 tng_file->chunky=chunky;
379 tng_file->natoms=natoms;
380 tng_file->writevel=writevel;
381 tng_file->initial_coding=initial_coding;
382 tng_file->initial_coding_parameter=initial_coding_parameter;
383 tng_file->coding=coding;
384 tng_file->coding_parameter=coding_parameter;
385 tng_file->initial_velcoding=initial_velcoding;
386 tng_file->initial_velcoding_parameter=initial_velcoding_parameter;
387 tng_file->velcoding=velcoding;
388 tng_file->velcoding_parameter=velcoding_parameter;
389 tng_file->speed=speed;
390 tng_file->ipos=malloc(natoms*chunky*3*sizeof *tng_file->ipos);
391 tng_file->f=fopen(filename,"wb");
392 if (writevel)
393 tng_file->ivel=malloc(natoms*chunky*3*sizeof *tng_file->ivel);
394 fwrite_int_le(&natoms,tng_file->f);
395 return tng_file;
398 static void flush_tng_frames(struct tng_file *tng_file,
399 unsigned long prec_hi, unsigned long prec_lo,
400 unsigned long velprec_hi, unsigned long velprec_lo)
402 int algo[4];
403 char *buf;
404 int nitems;
406 /* Make sure these variables are used to avoid compilation warnings */
407 (void)prec_hi;
408 (void)prec_lo;
409 (void)velprec_hi;
410 (void)velprec_lo;
412 fwrite_int_le(&tng_file->nframes,tng_file->f);
413 algo[0]=tng_file->initial_coding;
414 algo[1]=tng_file->initial_coding_parameter;
415 algo[2]=tng_file->coding;
416 algo[3]=tng_file->coding_parameter;
417 #ifdef RECOMPRESS
418 buf=tng_compress_pos_int(tng_file->ipos,
419 tng_file->natoms,
420 tng_file->nframes,
421 prec_hi,prec_lo,
422 tng_file->speed,algo,&nitems);
423 #else /* RECOMPRESS */
424 #ifdef TEST_FLOAT
425 buf=tng_compress_pos_float(tng_file->pos,
426 tng_file->natoms,
427 tng_file->nframes,
428 tng_file->precision,
429 tng_file->speed,algo,&nitems);
430 #else /* TEST_FLOAT */
431 buf=tng_compress_pos(tng_file->pos,
432 tng_file->natoms,
433 tng_file->nframes,
434 tng_file->precision,
435 tng_file->speed,algo,&nitems);
436 #endif /* TEST_FLOAT */
437 #endif /* RECOMPRESS */
438 tng_file->initial_coding=algo[0];
439 tng_file->initial_coding_parameter=algo[1];
440 tng_file->coding=algo[2];
441 tng_file->coding_parameter=algo[3];
442 fwrite_int_le(&nitems,tng_file->f);
443 fwrite(buf,1,nitems,tng_file->f);
444 free(buf);
445 if (tng_file->writevel)
447 algo[0]=tng_file->initial_velcoding;
448 algo[1]=tng_file->initial_velcoding_parameter;
449 algo[2]=tng_file->velcoding;
450 algo[3]=tng_file->velcoding_parameter;
451 #ifdef RECOMPRESS
452 buf=tng_compress_vel_int(tng_file->ivel,
453 tng_file->natoms,
454 tng_file->nframes,
455 velprec_hi,velprec_lo,
456 tng_file->speed,algo,&nitems);
457 #else /* RECOMPRESS */
458 #ifdef TEST_FLOAT
459 buf=tng_compress_vel_float(tng_file->vel,
460 tng_file->natoms,
461 tng_file->nframes,
462 tng_file->velprecision,
463 tng_file->speed,algo,&nitems);
464 #else /* TEST_FLOAT */
465 buf=tng_compress_vel(tng_file->vel,
466 tng_file->natoms,
467 tng_file->nframes,
468 tng_file->velprecision,
469 tng_file->speed,algo,&nitems);
470 #endif /* TEST_FLOAT */
471 #endif /* RECOMPRESS */
472 tng_file->initial_velcoding=algo[0];
473 tng_file->initial_velcoding_parameter=algo[1];
474 tng_file->velcoding=algo[2];
475 tng_file->velcoding_parameter=algo[3];
476 fwrite_int_le(&nitems,tng_file->f);
477 fwrite(buf,1,nitems,tng_file->f);
478 free(buf);
480 tng_file->nframes=0;
483 static void write_tng_file(struct tng_file *tng_file,
484 REAL *pos,REAL *vel)
486 memcpy(tng_file->pos+tng_file->nframes*tng_file->natoms*3,pos,tng_file->natoms*3*sizeof *tng_file->pos);
487 if (tng_file->writevel)
488 memcpy(tng_file->vel+tng_file->nframes*tng_file->natoms*3,vel,tng_file->natoms*3*sizeof *tng_file->vel);
489 tng_file->nframes++;
490 if (tng_file->nframes==tng_file->chunky)
491 flush_tng_frames(tng_file,0,0,0,0);
494 static void write_tng_file_int(struct tng_file *tng_file,
495 int *ipos,int *ivel,
496 unsigned long prec_hi, unsigned long prec_lo,
497 unsigned long velprec_hi, unsigned long velprec_lo)
499 memcpy(tng_file->ipos+tng_file->nframes*tng_file->natoms*3,ipos,tng_file->natoms*3*sizeof *tng_file->ipos);
500 if (tng_file->writevel)
501 memcpy(tng_file->ivel+tng_file->nframes*tng_file->natoms*3,ivel,tng_file->natoms*3*sizeof *tng_file->ivel);
502 tng_file->nframes++;
503 if (tng_file->nframes==tng_file->chunky)
504 flush_tng_frames(tng_file,prec_hi,prec_lo,velprec_hi,velprec_lo);
505 tng_file->prec_hi=prec_hi;
506 tng_file->prec_lo=prec_lo;
507 tng_file->velprec_hi=velprec_hi;
508 tng_file->velprec_lo=velprec_lo;
511 static void close_tng_file_write(struct tng_file *tng_file)
513 if (tng_file->nframes)
514 flush_tng_frames(tng_file,tng_file->prec_hi,tng_file->prec_lo,tng_file->velprec_hi,tng_file->velprec_lo);
515 fclose(tng_file->f);
516 free(tng_file->pos);
517 free(tng_file->vel);
518 free(tng_file->ipos);
519 free(tng_file->ivel);
520 free(tng_file);
523 static struct tng_file *open_tng_file_read(char *filename, int writevel)
525 struct tng_file *tng_file=malloc(sizeof *tng_file);
526 tng_file->pos=NULL;
527 tng_file->vel=NULL;
528 tng_file->ipos=NULL;
529 tng_file->ivel=NULL;
530 tng_file->f=fopen(filename,"rb");
531 tng_file->nframes=0;
532 tng_file->nframes_delivered=0;
533 tng_file->writevel=writevel;
534 if (tng_file->f)
535 fread_int_le(&tng_file->natoms,tng_file->f);
536 else
538 free(tng_file);
539 tng_file=NULL;
541 return tng_file;
544 static struct tng_file *open_tng_file_read_int(char *filename, int writevel)
546 struct tng_file *tng_file=malloc(sizeof *tng_file);
547 tng_file->pos=NULL;
548 tng_file->vel=NULL;
549 tng_file->ipos=NULL;
550 tng_file->ivel=NULL;
551 tng_file->f=fopen(filename,"rb");
552 tng_file->nframes=0;
553 tng_file->nframes_delivered=0;
554 tng_file->writevel=writevel;
555 if (tng_file->f)
556 fread_int_le(&tng_file->natoms,tng_file->f);
557 else
559 free(tng_file);
560 tng_file=NULL;
562 return tng_file;
565 static int read_tng_file(struct tng_file *tng_file,
566 REAL *pos,
567 REAL *vel)
569 if (tng_file->nframes==tng_file->nframes_delivered)
571 int nitems;
572 char *buf;
573 free(tng_file->pos);
574 free(tng_file->vel);
575 if (!fread_int_le(&tng_file->nframes,tng_file->f))
576 return 1;
577 if (!fread_int_le(&nitems,tng_file->f))
578 return 1;
579 buf=malloc(nitems);
580 if (!fread(buf,1,nitems,tng_file->f))
582 free(buf);
583 return 1;
585 tng_file->pos=malloc(tng_file->natoms*tng_file->nframes*3*sizeof *tng_file->pos);
586 if (tng_file->writevel)
587 tng_file->vel=malloc(tng_file->natoms*tng_file->nframes*3*sizeof *tng_file->vel);
588 #if 0
590 int natoms, nframes, algo[4];
591 double precision;
592 int ivel;
593 char *initial_coding, *coding;
594 tng_compress_inquire(buf,&ivel,&natoms,&nframes,&precision,algo);
595 initial_coding=tng_compress_initial_pos_algo(algo);
596 coding=tng_compress_pos_algo(algo);
597 printf("ivel=%d natoms=%d nframes=%d precision=%g initial pos=%s pos=%s\n",ivel,natoms,nframes,precision,initial_coding,coding);
599 #endif
600 #ifdef TEST_FLOAT
601 tng_compress_uncompress_float(buf,tng_file->pos);
602 #else
603 tng_compress_uncompress(buf,tng_file->pos);
604 #endif
605 free(buf);
606 if (tng_file->writevel)
608 if (!fread_int_le(&nitems,tng_file->f))
609 return 1;
610 buf=malloc(nitems);
611 if (!fread(buf,1,nitems,tng_file->f))
613 free(buf);
614 return 1;
616 #if 0
618 int natoms, nframes, algo[4];
619 double precision;
620 int ivel;
621 char *initial_coding, *coding;
622 tng_compress_inquire(buf,&ivel,&natoms,&nframes,&precision,algo);
623 initial_coding=tng_compress_initial_vel_algo(algo);
624 coding=tng_compress_vel_algo(algo);
625 printf("ivel=%d natoms=%d nframes=%d precision=%g initial vel=%s vel=%s\n",ivel,natoms,nframes,precision,initial_coding,coding);
627 #endif
628 #ifdef TEST_FLOAT
629 tng_compress_uncompress_float(buf,tng_file->vel);
630 #else
631 tng_compress_uncompress(buf,tng_file->vel);
632 #endif
633 free(buf);
635 tng_file->nframes_delivered=0;
637 memcpy(pos,tng_file->pos+tng_file->nframes_delivered*tng_file->natoms*3,tng_file->natoms*3*sizeof *pos);
638 if (tng_file->writevel)
639 memcpy(vel,tng_file->vel+tng_file->nframes_delivered*tng_file->natoms*3,tng_file->natoms*3*sizeof *vel);
640 tng_file->nframes_delivered++;
641 return 0;
644 static int read_tng_file_int(struct tng_file *tng_file,
645 int *ipos,
646 int *ivel,
647 unsigned long *prec_hi, unsigned long *prec_lo,
648 unsigned long *velprec_hi, unsigned long *velprec_lo)
650 if (tng_file->nframes==tng_file->nframes_delivered)
652 int nitems;
653 char *buf;
654 free(tng_file->ipos);
655 free(tng_file->ivel);
656 if (!fread_int_le(&tng_file->nframes,tng_file->f))
657 return 1;
658 if (!fread_int_le(&nitems,tng_file->f))
659 return 1;
660 buf=malloc(nitems);
661 if (!fread(buf,1,nitems,tng_file->f))
663 free(buf);
664 return 1;
666 tng_file->ipos=malloc(tng_file->natoms*tng_file->nframes*3*sizeof *tng_file->ipos);
667 if (tng_file->writevel)
668 tng_file->ivel=malloc(tng_file->natoms*tng_file->nframes*3*sizeof *tng_file->ivel);
669 tng_compress_uncompress_int(buf,tng_file->ipos,prec_hi,prec_lo);
670 free(buf);
671 if (tng_file->writevel)
673 if (!fread_int_le(&nitems,tng_file->f))
674 return 1;
675 buf=malloc(nitems);
676 if (!fread(buf,1,nitems,tng_file->f))
678 free(buf);
679 return 1;
681 tng_compress_uncompress_int(buf,tng_file->ivel,velprec_hi,velprec_lo);
682 free(buf);
684 tng_file->nframes_delivered=0;
686 memcpy(ipos,tng_file->ipos+tng_file->nframes_delivered*tng_file->natoms*3,tng_file->natoms*3*sizeof *ipos);
687 if (tng_file->writevel)
688 memcpy(ivel,tng_file->ivel+tng_file->nframes_delivered*tng_file->natoms*3,tng_file->natoms*3*sizeof *ivel);
689 tng_file->nframes_delivered++;
690 return 0;
693 static void close_tng_file_read(struct tng_file *tng_file)
695 free(tng_file->vel);
696 free(tng_file->pos);
697 free(tng_file->ivel);
698 free(tng_file->ipos);
699 fclose(tng_file->f);
700 free(tng_file);
705 #ifndef EXPECTED_FILESIZE
706 #define EXPECTED_FILESIZE 1
707 #endif
709 #ifndef INITIALVELCODING
710 #define INITIALVELCODING -1
711 #endif
712 #ifndef INITIALVELCODINGPARAMETER
713 #define INITIALVELCODINGPARAMETER -1
714 #endif
716 #ifndef SPEED
717 #define SPEED 5
718 #endif
720 /* Return value 1 means file error.
721 Return value 4 means coding error in coordinates.
722 Return value 5 means coding error in velocities.
723 Return value 9 means filesize seems too off.
725 Return value 100+ means test specific error.
727 static int algotest()
729 int i;
730 int *intbox=malloc(NATOMS*3*sizeof *intbox);
731 int *intvelbox=malloc(NATOMS*3*sizeof *intvelbox);
732 #ifdef RECOMPRESS
733 unsigned long pos_prec_hi,pos_prec_lo;
734 unsigned long vel_prec_hi,vel_prec_lo;
735 #endif
736 REAL *box1=malloc(NATOMS*STRIDE1*sizeof *box1);
737 REAL *velbox1=malloc(NATOMS*STRIDE1*sizeof *velbox1);
738 int startframe=0;
739 int endframe=NFRAMES;
740 #ifdef GEN
741 FILE *file;
742 REAL filesize;
743 REAL *box2=0;
744 REAL *velbox2=0;
745 #else
746 int readreturn;
747 REAL *box2=malloc(NATOMS*STRIDE2*sizeof *box2);
748 REAL *velbox2=malloc(NATOMS*STRIDE2*sizeof *velbox2);
749 #endif
750 #ifdef RECOMPRESS
751 void *dumpfile=open_tng_file_write_int(TNG_COMPRESS_FILES_DIR FILENAME,NATOMS,CHUNKY,
752 WRITEVEL,
753 INITIALCODING,
754 INITIALCODINGPARAMETER,CODING,CODINGPARAMETER,
755 INITIALVELCODING,INITIALVELCODINGPARAMETER,
756 VELCODING,VELCODINGPARAMETER,SPEED);
757 void *dumpfile_recompress=open_tng_file_read_int(TNG_COMPRESS_FILES_DIR RECOMPRESS,WRITEVEL);
758 if (!dumpfile_recompress)
760 free(intbox);
761 free(intvelbox);
762 free(box1);
763 free(velbox1);
764 if(box2)
765 free(box2);
766 if(velbox2)
767 free(velbox2);
768 return 1;
770 #else /* RECOMPRESS */
771 #ifdef GEN
772 void *dumpfile=open_tng_file_write(TNG_COMPRESS_FILES_DIR FILENAME,NATOMS,CHUNKY,
773 PRECISION,WRITEVEL,VELPRECISION,
774 INITIALCODING,
775 INITIALCODINGPARAMETER,CODING,CODINGPARAMETER,
776 INITIALVELCODING,INITIALVELCODINGPARAMETER,
777 VELCODING,VELCODINGPARAMETER,SPEED);
778 #else
779 void *dumpfile=open_tng_file_read(TNG_COMPRESS_FILES_DIR FILENAME,WRITEVEL);
780 #endif
781 #endif /* RECOMPRESS */
782 if (!dumpfile)
784 free(intbox);
785 free(intvelbox);
786 free(box1);
787 free(velbox1);
788 if(box2)
789 free(box2);
790 if(velbox2)
791 free(velbox2);
792 return 1;
794 for (i=startframe; i<endframe; i++)
796 #ifdef RECOMPRESS
797 unsigned long prec_hi, prec_lo;
798 unsigned long velprec_hi, velprec_lo;
799 if (read_tng_file_int(dumpfile_recompress,intbox,intvelbox,&prec_hi,&prec_lo,&velprec_hi,&velprec_lo))
800 return 1;
801 write_tng_file_int(dumpfile,intbox,intvelbox,prec_hi,prec_lo,velprec_hi,velprec_lo);
802 #else /* RECOMPRESS */
803 genibox(intbox,i);
804 realbox(intbox,box1,STRIDE1);
805 #if WRITEVEL
806 genivelbox(intvelbox,i);
807 realvelbox(intvelbox,velbox1,STRIDE1);
808 #endif
809 #ifdef GEN
810 write_tng_file(dumpfile,box1,velbox1);
811 #else /* GEN */
812 #ifdef INTTOFLOAT
814 unsigned long prec_hi, prec_lo;
815 unsigned long velprec_hi, velprec_lo;
816 readreturn=read_tng_file_int(dumpfile,intbox,intvelbox,&prec_hi,&prec_lo,&velprec_hi,&velprec_lo);
817 if (!readreturn)
819 tng_compress_int_to_float(intbox,prec_hi,prec_lo,NATOMS,1,box2);
820 #if WRITEVEL
821 tng_compress_int_to_float(intvelbox,velprec_hi,velprec_lo,NATOMS,1,velbox2);
822 #endif
825 #else /* INTTOFLOAT */
826 #ifdef INTTODOUBLE
828 unsigned long prec_hi, prec_lo;
829 unsigned long velprec_hi, velprec_lo;
830 readreturn=read_tng_file_int(dumpfile,intbox,intvelbox,&prec_hi,&prec_lo,&velprec_hi,&velprec_lo);
831 if (!readreturn)
833 tng_compress_int_to_double(intbox,prec_hi,prec_lo,NATOMS,1,box2);
834 #if WRITEVEL
835 tng_compress_int_to_double(intvelbox,velprec_hi,velprec_lo,NATOMS,1,velbox2);
836 #endif
839 #else /* INTTODOUBLE */
840 readreturn=read_tng_file(dumpfile,box2,velbox2);
841 #endif /* INTTODOUBLE */
842 #endif /* INTTOFLOAT */
843 if (readreturn==1) /* general read error */
845 free(intbox);
846 free(intvelbox);
847 free(box1);
848 free(velbox1);
849 if(box2)
850 free(box2);
851 if(velbox2)
852 free(velbox2);
853 return 1;
855 #endif /* GEN */
856 #ifndef GEN
857 /* Check for equality of boxes. */
858 if (!equalarr(box1,box2,(REAL)PRECISION,NATOMS,3,STRIDE1,STRIDE2))
860 free(intbox);
861 free(intvelbox);
862 free(box1);
863 free(velbox1);
864 if(box2)
865 free(box2);
866 if(velbox2)
867 free(velbox2);
868 return 4;
870 #if WRITEVEL
871 if (!equalarr(velbox1,velbox2,(REAL)VELPRECISION,NATOMS,3,STRIDE1,STRIDE2))
873 free(intbox);
874 free(intvelbox);
875 free(box1);
876 free(velbox1);
877 if(box2)
878 free(box2);
879 if(velbox2)
880 free(velbox2);
881 return 5;
883 #endif
884 #endif /* GEN */
885 #endif /* RECOMPRESS */
887 #ifdef GEN
888 close_tng_file_write(dumpfile);
889 #else
890 close_tng_file_read(dumpfile);
891 #endif
892 #ifdef RECOMPRESS
893 close_tng_file_read(dumpfile_recompress);
894 #endif
895 #ifdef GEN
896 /* Check against expected filesize for this test. */
897 if (!(file=fopen(TNG_COMPRESS_FILES_DIR FILENAME,"rb")))
899 fprintf(stderr,"ERROR: Cannot open file "TNG_COMPRESS_FILES_DIR FILENAME"\n");
900 exit(EXIT_FAILURE);
902 filesize=0;
903 while(1)
905 char b;
906 if (!fread(&b,1,1,file))
907 break;
908 filesize++;
910 fclose(file);
911 if (filesize>0)
913 if ((fabs(filesize-EXPECTED_FILESIZE)/EXPECTED_FILESIZE)>0.05)
915 free(intvelbox);
916 free(box1);
917 free(velbox1);
918 if(box2)
919 free(box2);
920 if(velbox2)
921 free(velbox2);
922 return 9;
925 #endif
926 free(intvelbox);
927 free(box1);
928 free(velbox1);
929 if(box2)
930 free(box2);
931 if(velbox2)
932 free(velbox2);
933 return 0;
936 int main()
938 int testval;
939 if (sizeof(int)<4)
941 fprintf(stderr,"ERROR: sizeof(int) is too small: %d<4\n",(int)sizeof(int));
942 exit(EXIT_FAILURE);
944 #ifdef GEN
945 printf("Tng compress testsuite generating (writing) test: %s\n",TESTNAME);
946 #else
947 printf("Tng compress testsuite running (reading) test: %s\n",TESTNAME);
948 #endif
949 testval=algotest();
950 if (testval==0)
951 printf("Passed.\n");
952 else if (testval==1)
954 printf("ERROR: File error.\n");
955 exit(EXIT_FAILURE);
957 else if (testval==4)
959 printf("ERROR: Read coding error in coordinates.\n");
960 exit(EXIT_FAILURE);
962 else if (testval==5)
964 printf("ERROR: Read coding error in velocities.\n");
965 exit(EXIT_FAILURE);
967 else if (testval==9)
969 printf("ERROR: Generated filesize differs too much.\n");
970 exit(EXIT_FAILURE);
972 else
974 printf("ERROR: Unknown error.\n");
975 exit(EXIT_FAILURE);
977 return 0;