2 /* implement functions that help with the f2k format */
13 /* copies the string src to dest and removes inline coments, leading blanks */
14 /* returns the number of characters copied */
15 static int rdmc_f2k_strcleancpy(char *dest, char *src);
19 /****************************************************************************/
20 int rdmc_f2k_dummy_parser(mcfile *fp, array *a, mevt *e, void *misc){
23 /****************************************************************************/
24 int rdmc_f2k_dummy_event_writer(const mcfile *fp, const array *a, const mevt *e){
27 /****************************************************************************/
29 /****************************************************************************/
30 /* returns 1 if the format version is supportet */
31 int rdmc_is_f2000_supported(int major, int minor){
36 { {1,1} ,{1,2} , {2004,1}, {0,0} };
39 while (( supportet[i].major != 0) && ( supportet[i].minor != 0)){
40 if (supportet[i].major == major){
41 if (supportet[i].minor == minor){
50 /* stores specific error information int f2k file pointer for print */
51 void rdmc_f2k_errorlog(mcfile *fp){
52 rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
53 int iline= f2k_buff->iline;
54 char *token_pt = f2k_buff->line_pt[iline];
55 char *target_pt = fp->info.f2000.parse_line;
59 return; /* already one error */
61 fp->info.f2000.errline = fp->fpos - f2k_buff->lines + iline +1;
62 /* try to recover the tokenized line arghhhh */
63 if (iline+1 >= f2k_buff->lines)
64 end_pt = &(f2k_buff->buff[f2k_buff->used-1]);
66 end_pt = f2k_buff->line_pt[iline+1];
67 while (token_pt < end_pt ){
71 *target_pt = *token_pt;
79 /****************************************************************************/
80 /****************************************************************************/
81 /* text buffer functions *********************/
82 void rdmc_push_f2k_buffer(rdmc_f2k_buffer_t *b, char *s,
83 const f2000_line_t * type_def){
86 /* check the size and increase it if necessary */
87 while ( (b->used + RDMC_MAXLINE + 1) >= b->ntot){
90 char* bsave = b->buff; /* is needed to save the former location */
93 fprintf(stderr,"bused=%i lused=%i btot=%i ltot=%i %.10s\n",b->used, b->lines, b->ntot,b->lines_tot,s);
96 b->ntot += F2K_BUFFERSIZE;
97 b->buff = realloc(b->buff,b->ntot*sizeof(char));
99 /* now correct the line_pointer pointers */
100 pedestal = (long int ) (b->buff - bsave); /* amount buffer was mooved */
102 fprintf(stderr," %p %p %p %i %p\n",bsave,b->buff,b->line_pt[0],pedestal,b->line_pt[0]+pedestal);
104 for(i=0 ; i< b-> lines; i++){
105 b->line_pt[i] += pedestal; /* only line pointers have to be cotrected */
110 while( (b->lines+1) >= b->lines_tot){
111 b->lines_tot += F2K_LINE_BUFFERSIZE;
112 b->line_pt = realloc(b->line_pt,b->lines_tot*sizeof(char *));
113 b->type_def = realloc(b->type_def
114 ,b->lines_tot*sizeof(const f2000_line_t *));
117 /* copy the string */
118 nnew = rdmc_f2k_strcleancpy(&(b->buff[b->used]),s);
120 b->type_def[b->lines] = type_def;
121 b->line_pt[b->lines] = &(b->buff[b->used]);
124 b->line_pt[b->lines] = NULL; /* flag the last line to NULL */
128 void rdmc_init_f2k_buffer(rdmc_f2k_buffer_t *b){
129 b->buff = NULL; b->line_pt = NULL ; b->type_def = NULL;
130 b->ntot = b->lines_tot = 0;
131 rdmc_reset_f2k_buffer(b);
134 void rdmc_reset_f2k_buffer(rdmc_f2k_buffer_t *b){
135 b->used = b->lines = b->iline = 0;
137 b->ntot=F2K_BUFFERSIZE;
138 b->buff = realloc(b->buff,b->ntot*sizeof(char));
140 b->lines_tot = F2K_LINE_BUFFERSIZE;
141 b->line_pt = realloc(b->line_pt,b->lines_tot*sizeof(char *));
142 b->type_def = realloc(b->type_def,b->lines_tot*sizeof(f2000_line_t *));
146 void rdmc_clear_f2k_buffer(rdmc_f2k_buffer_t *b){
147 b->used = b->lines = b->iline = 0;
150 void rdmc_unlink_f2k_buffer(rdmc_f2k_buffer_t *b){
154 b->ntot = b->lines_tot = 0;
155 b->buff = NULL; b->line_pt = NULL ; b->type_def = NULL;
158 /*********************************************/
159 static int rdmc_f2k_strcleancpy(char *dest, char *src){
160 int ncp=0; /* number of chars copied to dest */
163 int leading_space=1; /* flag to mark the begining of parsing */
165 /* copy the string */
167 if (leading_space){ /* scip leading spaces */
175 /* now we are pointing to the first non-white */
176 /* kill inline comments */
183 /* append a \0 terminator */
190 /***************************************************************************/
192 /**********************************************************************
193 * scans a nonempty line into tokens
194 **********************************************************************/
195 char ** rdmc_f2k_tokenize(char *s, int *nargs) {
196 static char ** f2k_tokens = NULL; /* buffer for tokens */
197 static int f2k_maxtoken =0; /* buffer for tokens */
198 const char delim[]=" \t\n";
202 tok_pt = strtok(s,delim); /* find first non-whitespace char */
204 if (*nargs >= f2k_maxtoken ){
205 f2k_maxtoken += RDMC_MAXTOKEN_PER_LINE + 1;
206 f2k_tokens = realloc(f2k_tokens,f2k_maxtoken*sizeof(char *));
208 f2k_tokens[*nargs] = tok_pt;
210 tok_pt = strtok(NULL,delim); /* find first non-whitespace char */
212 f2k_tokens[*nargs + 1] = NULL;
215 } /* amanda_tokenize() */
219 /****************************************************************************/
220 /****************************************************************************/
221 /** string conversion functions */
223 /****************************************************************************
224 * return the OM id, with the experiment prefix (see siegmund format
225 * description about these ids)
226 ****************************************************************************/
227 int rdmc_amanda_iomid(const char *str,int array_id){
228 return rdmc_amanda_ipmtid(str)
229 + 100000*(array_id / 100);
232 const char * rdmc_amanda_somid(int id){
233 return rdmc_amanda_spmtid(id);
236 /****************************************************************************
237 * return the OM id, with the experiment prefix (see siegmund format
238 * description about these ids)
239 ****************************************************************************/
240 const char *rdmc_amanda_spmtid(int type)
242 int pmtid, sphereid, dataid;
244 static char typestring[RDMC_MAXTOKENLENGTH];
245 char *sphere, *pmt, *data;
248 dataid = (type/100)%100;
249 sphereid = (type/10000)%10;
252 for (i = 0; rdmc_pmt_idtable[i].name != NULL; i++)
253 if (rdmc_pmt_idtable[i].id == pmtid) {
254 pmt = rdmc_pmt_idtable[i].name;
259 for (i = 0; rdmc_sphere_idtable[i].name != NULL; i++)
260 if (rdmc_sphere_idtable[i].id == sphereid) {
261 sphere = rdmc_sphere_idtable[i].name;
266 for (i = 0; rdmc_datatrans_idtable[i].name != NULL; i++)
267 if (rdmc_datatrans_idtable[i].id == dataid) {
268 data = rdmc_datatrans_idtable[i].name;
272 sprintf(typestring, "%s-%s-%s", pmt, sphere, data);
276 } /* rdmc_amanda_spmtid */
279 /****************************************************************************
280 * return the OM id, without the experiment prefix (see siegmund format
281 * description about these ids)
282 ****************************************************************************/
283 int rdmc_amanda_ipmtid(const char *str)
287 int pmtid, dataid, sphereid;
289 char s1[RDMC_MAXTOKENLENGTH];
293 tok = strtok(s1, "-");
294 if (tok == NULL) return 0;
295 for (c=tok ; *c ; c++)
296 *c=tolower((int) *c);
299 for (i = 0; rdmc_pmt_idtable[i].name != NULL; i++)
300 if (strcmp(rdmc_pmt_idtable[i].name, tok) == 0) {
301 pmtid = rdmc_pmt_idtable[i].id;
305 tok = strtok(NULL, "-");
306 if (tok == NULL) return pmtid;
307 for (c=tok ; *c ; c++)
308 *c=tolower((int) *c);
311 for (i = 0; rdmc_sphere_idtable[i].name != NULL; i++)
312 if (strcmp(rdmc_sphere_idtable[i].name, tok) == 0) {
313 sphereid = rdmc_sphere_idtable[i].id;
317 tok = strtok(NULL, "-");
318 if (tok == NULL) return 10000*sphereid + pmtid;
319 for (c=tok ; *c ; c++)
320 *c=tolower((int) *c);
323 for (i = 0; rdmc_datatrans_idtable[i].name != NULL; i++)
324 if (strcmp(rdmc_datatrans_idtable[i].name, tok) == 0) {
325 dataid = rdmc_datatrans_idtable[i].id;
329 return 10000*sphereid + 100*dataid + pmtid;
331 } /* rdmc_amanda_ipmtid() */
333 /****************************************************************************
334 * build a string containing the Detector name, or "Neutrino_telescope" if
336 ****************************************************************************/
338 const char *rdmc_amanda_sdet(int geoid)
341 for (i = 0; rdmc_detector_idtable[i].name != NULL; i++)
342 if (rdmc_detector_idtable[i].id == geoid)
343 return rdmc_detector_idtable[i].name;
344 return rdmc_detector_idtable[0].name;
345 } /* rdmc_amanda_sdet() */
347 int rdmc_amanda_idet(const char *detnam)
350 char tmp_detnam[RDMC_MAXTOKENLENGTH];
353 strncpy(tmp_detnam,detnam,RDMC_MAXTOKENLENGTH-1);
354 tmp_detnam[RDMC_MAXTOKENLENGTH-1]='\0';
358 *c = tolower((int) *c);
362 for (i = 0; rdmc_detector_idtable[i].name != NULL; i++)
363 if (strcmp(rdmc_detector_idtable[i].name, tmp_detnam) == 0)
364 return rdmc_detector_idtable[i].id;
366 /* maybe, we find a substring? */
367 for (i = 0; rdmc_detector_idtable[i].name != NULL; i++)
368 if (strstr(rdmc_detector_idtable[i].name, tmp_detnam) != NULL)
369 return rdmc_detector_idtable[i].id;
370 return rdmc_detector_idtable[0].id;
372 } /* rdmc_amanda_detid() */
375 /****************************************************************************
376 * build a string containing the particle name
377 ****************************************************************************/
378 const char *rdmc_amanda_spartid(int id)
381 static char a_primary[]="Axxx";
382 static char z_primary[]="Zxxx";
384 if ((id>=Z_PRIMARY) && (id < (Z_PRIMARY+200))){ /* primary Zxx */
385 int idd=id-Z_PRIMARY;
388 sprintf(z_primary,"Z00%1i",idd);
390 sprintf(z_primary,"Z0%2i",idd);
392 sprintf(z_primary,"Z%3i",idd);
394 sprintf(z_primary,"Z%i",idd);
398 }else if ((id>=A_PRIMARY) && (id < A_PRIMARY+500)){ /* primary Axxx undocumented !! */
399 int idd=id-A_PRIMARY;
402 sprintf(a_primary,"A00%1i",idd);
404 sprintf(a_primary,"A0%2i",idd);
406 sprintf(a_primary,"A%3i",idd);
408 sprintf(a_primary,"A%i",idd);
413 for (i = 0; rdmc_particle_idtable[i].name != NULL; i++)
414 if (rdmc_particle_idtable[i].id == id)
415 return rdmc_particle_idtable[i].name;
417 return rdmc_amanda_spartid(0); /* return unknown */
419 } /* rdmc_amanda_spartid */
422 int rdmc_amanda_ipartid(const char *s)
426 char name[RDMC_MAXTOKENLENGTH];
433 *c=tolower((int) *sp);
445 for (i = 0; rdmc_particle_idtable[i].name != NULL; i++)
446 if (strcmp(rdmc_particle_idtable[i].name, name) == 0)
447 return rdmc_particle_idtable[i].id;
449 if (name[0] == 'z'){ /* CR primary charge Z */
451 if( 1 != sscanf(name,"z%d",&idd))
456 if ( (idd < Z_PRIMARY) && (idd >= Z_PRIMARY+200) )
460 }else if (name[0] == 'a'){ /* CR primary mass A */
462 if( 1 != sscanf(name,"a%d",&idd))
467 if ( (idd < A_PRIMARY) && (idd >= A_PRIMARY+500) )
474 } /* rdmc_amanda_ipartid() */
476 int rdmc_amanda_mhit_stat(mhit_stat_t *hstat, char *stat_s){
486 iedges = strtol(cpt, (char **)NULL, 10);
487 if ((iedges == LONG_MIN )|| (iedges == LONG_MAX ))
490 hstat->n_tdc_edges = iedges;
496 /****************************************************************************/
497 /****************************************************************************/
498 /** value conversion functions */
499 /****************************************************************************
500 * make an integer from a string. If "na" or "?" return RDMC_NA
501 ****************************************************************************/
503 int rdmc_amanda_strtoi(const char *str, int default_na)
506 /* f2000 writes not na, but ? for NA */
507 if (strstr(str,"?") != NULL)
509 if (strstr(str,"na") != NULL) /* old rdmc specific value */
511 if (strstr(str,"*") !=NULL)
512 return RDMC_REPEAT_CH;
513 if (strstr(str,"-inf") !=NULL)
515 if (strstr(str,"inf") !=NULL)
517 if (strstr(str,"N") !=NULL)
518 return RDMC_PARENT_NOISE;
519 if (strstr(str,"A") !=NULL)
520 return RDMC_PARENT_AFPULS;
524 if (isnan( (float) r ))
529 } /* rdmc_amanda_strtoi() */
531 /****************************************************************************
532 * make a float from a string. If "na" return default_na
533 ****************************************************************************/
534 double rdmc_amanda_strtof(char *str, double default_na)
537 /* f2000 writes not na, but ? for NA */
538 if (strstr(str,"?") != NULL)
540 if (strstr(str,"na") != NULL) /* old rdmc specific value */
542 if (strstr(str,"*") !=NULL)
543 return RDMC_REPEAT_CH;
544 if (strstr(str,"-inf") !=NULL)
546 if (strstr(str,"inf") !=NULL)
548 #if 0 /* parent is never a float but an int */
549 if (strstr(str,"N") !=NULL)
550 return RDMC_PARENT_NOISE;
551 if (strstr(str,"A") !=NULL)
552 return RDMC_PARENT_AFPULS;
554 // r=strtof(str,NULL);
556 if (isnan( (float) r ))
561 } /* rdmc_amanda_strtof() */
563 /****************************************************************************
564 * make a float to a string.
565 ****************************************************************************/
566 char * rdmc_amanda_ftostr(double f, double default_na)
568 static char str[RDMC_MAXTOKENLENGTH];
569 /* f2000 writes not na, but ? for NA */
570 if (isnan(f)) return "NaN";
571 if ( fabs(f - default_na) < 1.e-5 )
573 if (f >= RDMC_FINFTY/2)
575 if (f <= -RDMC_FINFTY/2)
579 } /* rdmc_amanda_ftostr() */
581 /****************************************************************************
582 * make a int to a string.
583 ****************************************************************************/
584 char * rdmc_amanda_itostr(int i, int default_na)
586 static char str[RDMC_MAXTOKENLENGTH];
587 /* f2000 writes not na, but ? for NA */
589 if (isnan(i)) return "NaN";
593 if (i >= RDMC_IINFTY)
595 if (i <= -RDMC_IINFTY)
600 } /* rdmc_amanda_itostr() */
602 /****************************************************************************
603 * make a time string sec.nsec.
604 ****************************************************************************/
605 char * rdmc_amanda_itimetostr(int sec, int nsec){
606 static char str[RDMC_MAXTOKENLENGTH];
607 static char s1[RDMC_MAXTOKENLENGTH];
608 static char s2[RDMC_MAXTOKENLENGTH];
610 if (isnan(sec) || (sec<0) )
613 sprintf(s1,"%i.",sec);
615 if (isnan(nsec) || (nsec<0) || (nsec>= 1e9 ) )
618 sprintf(s2,"%09i",nsec);
623 } /* rdmc_amanda_timestr() */
625 /* returns 0 on succes */
626 int rdmc_amanda_strtimetoi(const char *stime, int *sec, int *nsec){
629 if ( (spt = strchr(stime,'.')) != NULL){
631 *sec = rdmc_amanda_strtoi(stime,0); /* test only if a valid number */
632 *nsec = rdmc_amanda_strtoi(spt+1,0); /* test only if a valid number */
634 slen = strlen(spt+1) - 9;
643 *sec = rdmc_amanda_strtoi(stime,0); /* test only if a valid number */
644 *sec %= 86400 ; /* seconds of begin of day only is mod(sec,86400)*/
645 *nsec = rdmc_amanda_strtoi("?",0); /* test only if a valid number */
650 int rdmc_f2k_y2k(int year){
651 year = (year > 0 ) ? year : 1970;
659 /****************************************************************************
660 * return the orientation (cosinus theta) as a float
661 ****************************************************************************/
662 static const struct {
667 } rdmc_updown_table[] = {
668 {"hr", 0.0 , 0.5 , -0.5 },
669 {"HR", 0.0 , 0.5 , -0.5 },
670 {"Hr", 0.0 , 0.5 , -0.5 },
671 {"up", 1.0 , 1.1 , 0.5 },
672 {"UP", 1.0 , 1.1 , 0.5 },
673 {"Up", 1.0 , 1.1 , 0.5 },
674 {"dn", -1.0, -0.5 , -1.1 },
675 {"DN", -1.0, -0.5 , -1.1 },
676 {"Dn", -1.0, -0.5 , -1.1 },
677 {"down", -1.0, -0.5 , -1.1 },
678 {"DOWN", -1.0, -0.5 , -1.1 },
679 {"Down", -1.0, -0.5 , -1.1 },
680 {NULL , 0.0 , 0.0 , 0.0 }
683 char *rdmc_amanda_sori(float ori){
685 for (i=0 ; rdmc_updown_table[i].str != NULL ; i++ ){
686 if ( (ori > rdmc_updown_table[i].lower)
687 && ( ori < rdmc_updown_table[i].upper) ){
688 return rdmc_updown_table[i].str;
691 return rdmc_updown_table[0].str;
694 float rdmc_amanda_fori(char *ori)
697 for (i=0 ; rdmc_updown_table[i].str != NULL ; i++ ){
698 if (strcmp(ori,rdmc_updown_table[i].str) == 0)
699 return rdmc_updown_table[i].fori;
701 return rdmc_updown_table[0].fori;
702 } /* rdmc_amanda_ori() */
705 static const struct {
709 } rdmc_sp_ftable[] = {
714 { RDMC_NA, RDMC_NA, "nan" },
715 { RDMC_NA, RDMC_NA, "na" },
719 /* catch some special values */
720 double rdmc_amanda_sptof(char *str){
722 int ir=RDMC_NA,i,slen;
724 /* now check for hex numbers */
725 if (strstr(str,"0x") == str){
726 if ( 1 == sscanf(str,"%i",&ir)){
732 /* try to decode directly first */
733 if (sscanf(str,"%lg",&r) == 1){
734 /* rdmc_msgprintf("%.18g %s %i",r,str,DBL_DIG); */
738 /* make a local copy and tronspose to lower */
740 char t[RDMC_MAXTOKENLENGTH];
742 slen = (slen < (RDMC_MAXTOKENLENGTH-1)) ? slen : RDMC_MAXTOKENLENGTH-1;
743 for (i=0 ; i <= slen ; i++){
744 t[i] = tolower((int) str[i]);
748 /* check special values */
749 for (i=0; rdmc_sp_ftable[i].name != NULL ; i++){
750 if( strcmp(rdmc_sp_ftable[i].name,t) == 0){
751 return rdmc_sp_ftable[i].val;
754 } /* check for special values */
756 /* now try a last decode: */
758 return RDMC_SPECIAL_NA;
762 /* create a string the USES lines for itoken */
763 char * rdmc_amanda_uses_to_str(int n_uses, mevt_uses_t *uses, int id){
764 static char *buffer = NULL;
765 static int bsize = 0;
768 int char_in_line,token_in_line,last_hid;
769 char tbuff[RDMC_MAXTOKENLENGTH];
774 rdmc_sort_uses(uses, n_uses);
777 /* init the buffer */
779 bsize += RDMC_MAXLINE;
780 buffer = malloc(bsize*sizeof(char));
783 bused = char_in_line = token_in_line = 0 ;
785 last_hid = RDMC_NA; /* the last seen OM */
788 /* now loop and look */
789 for (i_uses = 0 ; i_uses < n_uses ; i_uses++){
790 if ( uses[i_uses].useid == id ){ /*** ahh there is one ***/
792 /* check buffersize large enough */
793 /* 2* -> save space for USES and \n */
794 while ( (bused + 2*RDMC_MAXTOKENLENGTH) > bsize){
795 bsize += RDMC_MAXLINE;
796 buffer = (char *) realloc(buffer,bsize*sizeof(char));
799 /* check the current lenght */
800 if ( ( (char_in_line+RDMC_MAXTOKENLENGTH) >= F2000_MAXLINE )
801 || (token_in_line >= RDMC_MAXTOKEN_PER_LINE ) ){
803 bused += sprintf(&(buffer[bused]),"-%i",last_hid);
806 bused += sprintf(&(buffer[bused]),"\n");
807 char_in_line = token_in_line = 0 ;
811 if (char_in_line == 0 ){
812 char_in_line = strlen("USES");
813 bused += sprintf(&(buffer[bused]),"USES");
816 /* now print this channel */
817 if ((last_hid == RDMC_NA ) ||
818 (uses[i_uses].hitid > last_hid+1 )){
820 t_len = sprintf(&(buffer[bused]),"-%i",last_hid);
823 char_in_line += t_len;
827 t_len = sprintf(&(buffer[bused])," %i",uses[i_uses].hitid);
828 last_hid=uses[i_uses].hitid;
830 char_in_line += t_len;
834 last_hid=uses[i_uses].hitid;
838 } else if ( uses[i_uses].useid > id ){
840 break; /* break to improve speed since the uses array is sorted */
846 if(buffer[bused-1] != '\n'){
848 bused += sprintf(&(buffer[bused]),"-%i",last_hid);
851 strcpy(&(buffer[bused]),"\n");
856 #if 0 /* desireble later */
857 if (buffer[0] == '\0')
858 strcpy(buffer,"USES all\n");
864 /****************************************************************************
865 ********************************** E O F ***********************************
866 ****************************************************************************/