]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RALICE/icepack/iceconvert/amanda.c
10-may-2006 NvE Distance determination between tracks and/or jets introduced in
[u/mrichter/AliRoot.git] / RALICE / icepack / iceconvert / amanda.c
CommitLineData
f67e2651 1/*
2 * Read/write files in the oncoming Standard AMANDA format - "format 2000"
3 */
4#if 0 /******* TODO *********/
5/* skip event gets array as parameter */
6/* level 4 event types in mevt */
7/* end of file, tend */
8/******************************/
9#endif
10
11
12char *amanda_rdmc_cvsid =
13"$Header: /net/local/cvsroot/siegmund/rdmc/amanda.c,v 1.81 2004/02/19 17:10:08 wiebusch Exp $";
14
15#include <stdlib.h>
16#include <ctype.h>
17
18#include "rdmc.h"
19#ifdef AMANDA_ASCII_F
20
21#include "rdmc_local.h"
22
23#include "amanda.h"
24#include "f2k.h"
25
26/****************************************************************************/
27/* rdmc_nint(double a) */
28/* converts a to the nearest integer */
29/* but also takes care on the sign */
30/****************************************************************************/
31long rdmc_nint(double a)
32{ long i;
33 i = (a >= 0.) ? (long) (a + 0.5 ) : (long) (a - 0.5);
34 return i;
35}
36
37/*******************************/
38/* Work around missing isnan() */
39/*******************************/
f60271ca 40int isnan(double r)
f67e2651 41{
42 return 0;
43}
44
45/******************************************************/
46/*** Definitions of f2k blocks struture in memory ***/
47/******************************************************/
48
49
50/* check if line is in buffer or read a new one */
51/* returns 0 if OK */
52static int amanda_readline(mcfile *fp);
53
54/* dump a line back into the buffer if it is empty */
55/* returns 0 if OK */
56static int amanda_unreadline(mcfile *fp);
57
58/* read the next block according to a list of allowed lines into the buffer */
59/* returns 0 if OK */
60static int amanda_read_block(mcfile *fp ,const f2000_event_t *def);
61
62/* try to decode a given line according to line_def */
63/* store if OK */
64/* returns RDMC_IO_OK or RDMC_LINE_EMPTY or RDMC_EVENT_NOT_RECOGNIZED */
65static int amanda_lex_line(mcfile *fp, const f2000_line_t * const line_def[F2K_MAX_LINETYPES] );
66
67/* compares each byte of key to the first no white exam until lngth of key*/
68/* -1 if line is empty, 0 on no and 1 on succes */
69static int tokencmp(const char *key, char *exam);
70
71/* same with no trailing chars */
72static int tokencmp_notrail(const char *key, char *exam);
73
74/* checks if the first non-white char in exam is in keys */
75/* if a line is only whitespace ot empty -1 is returned */
76/* 0: if the char is not found */
77/* 1: if the char is not found */
78static int tokenchr(const char *keys, char *exam);
79/* same as above but chars are not alnum (ispunct()) */
80static int tokenchrpunct(const char *keys, char *exam);
81
82/***************************************************************************/
83/***************************************************************************/
84/*** ***/
85/*** Read functions follow ***/
86/*** ***/
87/***************************************************************************/
88
89
90/****************************************************************************
91 * read the F2000 "V" line (the first one) and put it into fp
92 ****************************************************************************/
93/******* This is the only parswer routine, which is different !!! */
94/* it reads directly from fp, instead of the readline mode */
95int rdmc_amanda_V(const char *s, mcfile *fp)
96{
97 int major = 0, minor = 0;
98 if(sscanf(s,"V 2000.%i.%i",&major, &minor) != 2)
99 return RDMC_LINE_NOT_PARSED;
100 if (rdmc_is_f2000_supported(major, minor) == 0)
101 return RDMC_UNKNOWN_FORMAT_VERSION;
102 fp->fmajor = major;
103 fp->fminor = minor;
104 return RDMC_IO_OK;
105
106} /* amanda_rdmc_V() */
107
108int rdmc_rhd_amanda(mcfile *fp){
109 const f2000_event_t *ev_def;
110 int ret;
111
112 /* get the config def for the right format*/
113 switch( 100*fp->fmajor + fp->fminor ){
114 case 101:
115 case 102:
116 case 200401:
117 ev_def=&f2000_preamble_1x1;
118 break;
119 default:
120 return RDMC_UNKNOWN_FORMAT_VERSION;
121 }
122
123 /* read the block acordng to the def */
124 if ((ret = amanda_read_block(fp, ev_def)) != RDMC_IO_OK)
125 return ret;
126
127 /* use the pointer from the event definition and scan*/
128 return ev_def->reader(fp, NULL, NULL);
129}
130
131
132int rdmc_rarr_amanda(mcfile *fp, array *ar)
133{
134 const f2000_event_t *ev_def;
135 int ret;
136
137 /* get the config def for the right format*/
138 switch( 100*fp->fmajor + fp->fminor ){
139 case 101:
140 case 102:
141 case 200401:
142 ev_def=&f2000_mhead_1x1;
143 break;
144 default:
145 return RDMC_UNKNOWN_FORMAT_VERSION;
146 }
147
148 /* read the block acordng to the def */
149 if ((ret = amanda_read_block(fp, ev_def)) != RDMC_IO_OK)
150 return ret;
151
152 /* use the pointer from the event definition and scan*/
153 return ev_def->reader(fp, ar, NULL);
154
155}
156
157int rdmc_revt_amanda(mcfile *fp, mevt *ev, array *ar){
158 const f2000_event_t **ev_def,*foot_def;
159
160 int ret = RDMC_ILF;
161 int ret2 = RDMC_ILF;
162
163 /* get the config def for the right format*/
164 /* get the config def for the right format*/
165 switch( 100*fp->fmajor + fp->fminor ){
166 case 101:
167 ev_def = f2000_events_1x1;
168 foot_def = &f2000_mfoot_1x1 ;
169 break;
170 case 102:
171 ev_def =f2000_events_1x2;
172 foot_def = &f2000_mfoot_1x1 ;
173 break;
174 case 200401:
175 ev_def =f2000_events_2004x1;
176 foot_def = &f2000_mfoot_1x1 ;
177 break;
178 default:
179 return RDMC_UNKNOWN_FORMAT_VERSION;
180 }
181
182 while( *ev_def !=NULL ){
183 /* read the block acordng to the def */
184 ret = amanda_read_block(fp, *ev_def);
185 if ( ret == RDMC_IO_OK)
186 break;
187 ++ev_def;
188 }
189 if ( ret == RDMC_IO_OK){
190 rdmc_clear_mevt(ev); /* reset the event */
191 /* use the pointer from the event definition and scan*/
192 if (fp->info.f2000.nolex)
193 return RDMC_IO_OK;
194 else
195 return (*ev_def)->reader(fp, ar, ev);
196 }else{ /* test footer */
197 if ( ret == RDMC_EVENT_NOT_RECOGNIZED) {
198 ret2 = amanda_read_block(fp, foot_def);
199 if (ret2 == RDMC_IO_OK)
200 return RDMC_EOF;
201 else
202 return ret2;
203 }else{
204 return ret;
205 }
206 }
207}
208
209int rdmc_skipevt_amanda(mcfile *fp)
210{
211 int ret;
212#if 0
213 array ar;
214#endif
215 mevt ev;
216#if 0 /* this is the proper, presently slow version */
217 rdmc_init_array(&ar);
218 rdmc_init_mevt(&ev);
219 fp->info.f2000.nolex=1;
220 ret = rdmc_revt_amanda(fp, &ev, &ar);
221 fp->info.f2000.nolex=0;
222 rdmc_clear_array(&ar);
223 rdmc_clear_mevt(&ev);
224#else /* presently no array is needed -> dirty patch ! */
225 rdmc_init_mevt(&ev);
226 fp->info.f2000.nolex=1;
227 ret = rdmc_revt_amanda(fp, &ev, NULL);
228 fp->info.f2000.nolex=0;
229 rdmc_clear_mevt(&ev);
230#endif
231 return ret;
232}
233
234
235
236/****************************************************************************
237 * Reads a nonempty line
238 ****************************************************************************/
239static int amanda_readline(mcfile *fp){
240
241 char *s = fp->last_line;
242 do {
243 if (fp->info.f2000.unread != 0 ) { /* line in buffer */
244 fp->info.f2000.unread = 0;
245 } else{ /* no line in buffer - read from file */
246 if (fgets(s, RDMC_MAXLINE-1, fp->fp) == NULL)/*fgets includes the '\n'*/
247 return EOF;
248 }
249 } while (*s == '\0'); /* look for a not-empty line */
250 /* increment the counter line */
251 fp->fpos++;
252 return RDMC_IO_OK;
253
254} /* amanda_readline() */
255
256/****************************************************************************
257 * "unread" an amanda F2000 format line
258 ****************************************************************************/
259
260static int amanda_unreadline(mcfile *fp){
261 if (fp->info.f2000.unread != 0)
262 return EOF; /* only one line allowed */
263 else
264 fp->info.f2000.unread = 1;
265 fp->fpos--;
266 return RDMC_IO_OK;
267} /* amanda_unreadline() */
268
269
270static int amanda_read_block(mcfile *fp ,const f2000_event_t *def){
271 int r;
272 int ret=RDMC_ILF;
273 int do_reading;
274 rdmc_clear_f2k_buffer(fp->info.f2000.f2k_buffer);
275 fp->errline = 0;
276
277 /* test if the block starts with the right line */
278 do_reading=1;
279 do {
280 if (def->opener[0]){ /* yes there is one needed ! */
281 if ( (r=amanda_readline(fp)) != RDMC_IO_OK)
282 ret=r;
283 else /* analyse if this line matches and store it then */
284 ret = amanda_lex_line(fp, def->opener);
285 } else{ /* no opener needed -> OK */
286 ret = RDMC_IO_OK;
287 break;
288 }
289 if( ret != RDMC_LINE_EMPTY ){ /* something happende */
290 do_reading=0;
291 if ( ret == RDMC_EVENT_NOT_RECOGNIZED){
292 amanda_unreadline(fp); /* we have read one line to much */
293 return ret;
294 }
295 }
296 } while(do_reading);
297
298 /* keep on reading body lines */
299 do_reading=1;
300 do {
301 /* analyse if this line matches and store it then */
302 if (def->inner[0]){ /* yes there are some ! */
303 if ( (r=amanda_readline(fp)) != RDMC_IO_OK)
304 ret =r;
305 else
306 ret = amanda_lex_line(fp, def->inner);
307 } else{
308 ret = RDMC_IO_OK;
309 do_reading=0;
310 break;
311 }
312
313 if( ret != RDMC_LINE_EMPTY ){ /* something happend */
314 if (ret == RDMC_IO_OK) /* line OK -> next one */
315 continue;
316 else{ /* line is not parsed -> check if an end marker appeared */
317 amanda_unreadline(fp); /* we have read one line to much */
318 do_reading = 0; /* this is no error since the body may be empty */
319 ret = RDMC_IO_OK; /* this is no error but maybe the next event */
320 break; /* ok we end here */
321 }
322 }
323 } while(do_reading);
324
325 /* check the end marker */
326 do_reading=1;
327 do {
328 /* analyse if this line matches and store it then */
329 if (def->closer[0]){ /* yes there are some needed ! */
330 if ( (r=amanda_readline(fp)) != RDMC_IO_OK)
331 ret=r;
332 else
333 ret = amanda_lex_line(fp, def->closer);
334 } else{
335 ret = RDMC_IO_OK;
336 do_reading=0;
337 break;
338 }
339
340 if( ret != RDMC_LINE_EMPTY ){ /* something happend */
341 if (ret == RDMC_IO_OK){ /* line OK -> finish */
342 do_reading=0;
343 break;
344 }
345 else{ /* line is not parsed */
346 amanda_unreadline(fp); /* we have read one line to much */
347 do_reading = 0; /* this is no error since the body may be empty */
348 break; /* ok we end here */
349 }
350 }
351 } while(do_reading);
352
353 return ret;
354}
355
356
357static int amanda_lex_line(mcfile *fp, const f2000_line_t * const line_def[F2K_MAX_LINETYPES] ){
358 int ptindex , cres = 0;
359 const f2000_line_t *opt;
360
361 if ( !(line_def[0]) ) /* no match actually needed */
362 return RDMC_EVENT_NOT_RECOGNIZED;
363
364 for(ptindex=0 , cres=0, opt = line_def[0]
365 ; opt
366 ; opt = line_def[++ptindex]
367 ){
368
369 switch (opt->searchtype){
370 case COMP_STRINGWISE:
371 cres = tokencmp(opt->tag,fp->last_line);
372 break;
373 case COMP_STRINGWISE_NOTRAIL:
374 cres = tokencmp_notrail(opt->tag,fp->last_line);
375 break;
376 case COMP_CHARWISE:
377 cres = tokenchr(opt->tag,fp->last_line);
378 break;
379 case COMP_CHARPUNCT:
380 cres = tokenchrpunct(opt->tag,fp->last_line);
381 break;
382#if 0
383 case COMP_DUMMY: /* no token is needed so stop parsing */
384 /* trap to finish here */
385 return RDMC_EVENT_NOT_RECOGNIZED;
386 break;
387#endif
388 default:
389 return RDMC_LIBRARY_ERROR;
390 } /* switch */
391 if (cres < 0){ /* empty line */
392 return RDMC_LINE_EMPTY;
393 } else if(cres == 0){ /* no match found */
394 /* needed but not found -> try the next */
395 continue;
396 }else{ /* ok tag is found */
397 rdmc_push_f2k_buffer(fp->info.f2000.f2k_buffer, fp->last_line,line_def[ptindex]);
398 return RDMC_IO_OK;
399 } /* check cres */
400 } /*for */
401 return RDMC_EVENT_NOT_RECOGNIZED;
402}
403
404/* compares each byte of key to exam until th lngth of key */
405/* leading whitespaces are ignored */
406static int tokencmp(const char *key, char *exam){
407 int r = -1;
408 const char *k = key;
409 const char *e = exam;
410 while(*e){
411 if (isspace(*e))
412 ++e;
413 else { /* this is the first non white */
414 r=0;
415 while (*k){ /* now check key */
416 if (!(*e)) /* if e ends before key */
417 return r=0;
418 if( *e == *k ) /* stil agreement ? */
419 r=1;
420 else
421 return r=0; /* break if not */
422 ++e; /* next char */
423 ++k;
424 } /* while k */
425 return r; /* exit here likely with r==1 */
426 }
427 } /* while e */
428
429 return r;
430}
431/* compares each byte of key to exam until the lngth of key */
432/* trailing chars are ignored */
433static int tokencmp_notrail(const char *key, char *exam){
434 int r = -1;
435 const char *k = key;
436 const char *e = exam;
437 while(*e){
438 if (isspace(*e))
439 ++e;
440 else { /* this is the first non white */
441 r=0;
442 while (*k){ /* now check key */
443 if (!(*e)) /* if e ends before key */
444 return r=0;
445 if( *e == *k ) /* stil agreement ? */
446 r=1;
447 else
448 return r=0; /* break if not */
449 ++e; /* next char */
450 ++k;
451 } /* while k */
452 return r; /* exit here likely with r==1 */
453 }
454 } /* while e */
455 return r;
456}
457
458/* checks if the first non-white char in exam is in keys */
459/* if a line is only whitespace ot empty -1 is returned */
460/* 0: if the char is not found */
461/* 1: if the char is found */
462static int tokenchr(const char *keys, char *exam){
463 int r = -1;
464 const char *k=keys;
465 const char *e=exam;
466 while(*e){
467 if (isspace(*e))
468 ++e;
469 else { /* this is the first non white */
470 r=0;
471 while (*k){ /* now check key */
472 if( *e == *k ) /* agreement ? */
473 return r=1;
474 else
475 ++k;
476 } /* while k */
477 return r=0; /* exit here likely with r==1 */
478 }
479 } /* while e */
480 return r;
481}
482
483static int tokenchrpunct(const char *keys, char *exam){
484 int r = -1;
485 const char *k=keys;
486 const char *e=exam;
487 while(*e){
488 if (isspace(*e))
489 ++e;
490 else if (!ispunct(*e))
491 return r=0;
492 else { /* this is the first non white */
493 r=0;
494 while (*k){ /* now check key */
495 if( *e == *k ) /* agreement ? */
496 return r=1;
497 else
498 ++k;
499 } /* while k */
500 return r=0; /* exit here likely */
501 }
502 } /* while e */
503 return r;
504}
505
506
507/***************************************************************************/
508/*** ***/
509/*** Write functions follow ***/
510/*** ***/
511/***************************************************************************/
512/***************************************************************************/
513
514
515
516
517/***************************************************************************/
518/* write end of file (F2000 format) */
519int rdmc_wrend_amanda(const mcfile *fp)
520{
521 const f2000_event_t *ev_def;
522
523 /* get the config def for the right format*/
524 switch( 100*fp->fmajor + fp->fminor ){
525 case 101:
526 case 102:
527 case 200401:
528 ev_def=&f2000_mfoot_1x1;
529 break;
530 default:
531 return RDMC_UNKNOWN_FORMAT_VERSION;
532 }
533
534 /* use the pointer from the event definition and scan*/
535 return ev_def->writer(fp, NULL, NULL);
536} /* wrend_amanda() */
537
538/****************************************************************************
539 * function warr_amanda() writes the array info to a amanda-like file
540 * This function writes out the head of a AMANDA ascii file
541 * opposite to reading the input file it writes not only
542 * the Geometry banks ('G', 'P') , but also the ('V' and 'M' flags)
543 * so the function whd_amanda does not exist
544 ****************************************************************************/
545
546int rdmc_warr_amanda(const mcfile *fp,const array *geo)
547{
548 const f2000_event_t *ev_def;
549
550 /* get the config def for the right format*/
551 switch( 100*fp->fmajor + fp->fminor ){
552 default:
553 ev_def=&f2000_mhead_1x1;
554 break;
555 }
556
557 /* use the pointer from the event definition and scan*/
558 return ev_def->writer(fp, geo, NULL);
559}
560
561/****************************************************************************
562 * function wevt_amanda() writes an event to a amanda-like file
563 ****************************************************************************/
564
565int rdmc_wevt_amanda(const mcfile *fp,const mevt *event, const array *ar)
566{
567 const f2000_event_t *ev_def;
568
569 /* get the config def for the right format*/
570 switch( 100*fp->fmajor + fp->fminor ){
571 case 101:
572 ev_def=f2000_events_1x1[0]; /* take first array element */
573 break;
574 case 102:
575 ev_def=f2000_events_1x2[0]; /* take first array element */
576 break;
577 case 200401:
578 ev_def=f2000_events_2004x1[0]; /* take first array element */
579 break;
580 default:
581 return RDMC_UNKNOWN_FORMAT_VERSION;
582 }
583
584 /* use the pointer from the event definition and scan*/
585 return ev_def->writer(fp, ar, event);
586
587}
588
589#if 0
590/****************************************************************************
591 * wrhist_amanda() writes history lines to an ASCII file
592 ****************************************************************************/
593
594int rdmc_wrhist_amanda(const mcfile *fp, const char *s, const char *pre)
595{
596 return rdmc_wrhist_f2k_1x1(fp, s, pre);
597}
598
599/****************************************************************************
600 * wrcomment_amanda() writes a comment line to an ASCII file
601 ****************************************************************************/
602
603int rdmc_wrcomment_amanda(const mcfile *fp, const char *s)
604{
605 return rdmc_wrcomment_f2k_1x1(fp, s);
606}
607#endif
608
609#endif /* AMANDA_ASCII_F */
610
611/****************************************************************************
612 ********************************** E O F ***********************************
613 ****************************************************************************/
614/*
615 This is just for EMACS:
616 Local Variables:
617 compile-command: "cd .. ; make -k rdmc"
618 End:
619*/
620
621
622
623
624
625
626
627
628
629
630
631