#include "sctk.h" /* This variable is used to set the sequence number in the path structure */ static int PATH_sequence_number = 0; void PATH_add_utt_id(PATH *path, char *utt_id){ path->id = (char *)TEXT_strdup((TEXT *)utt_id); } void PATH_add_label(PATH *path, char *label){ if (label != (char *)0) path->labels = (char *)TEXT_strdup((TEXT *)label); } void PATH_add_file(PATH *path, char *file){ if (file != (char *)0) path->file = (char *)TEXT_strdup((TEXT *)file); } void PATH_add_channel(PATH *path, char *channel){ if (channel != (char *)0) path->channel = (char *)TEXT_strdup((TEXT *)channel); } void PATH_set_sequence(PATH *path){ path->sequence = PATH_sequence_number++; } PATH *PATH_alloc(int s){ PATH *tp; /* Set a minimum size for the maximum number of items */ if (s < 4) s=5; alloc_singarr(tp,1,PATH); tp->max = s; tp->num = 0; tp->id = (char *)0; tp->labels = (char *)0; tp->file = (char *)0; tp->channel = (char *)0; tp->attrib = PA_NONE; tp->sequence = -1; tp->ref_t1 = tp->ref_t2 = 0.0; tp->hyp_t1 = tp->hyp_t2 = 0.0; alloc_singarr(tp->pset,tp->max,PATH_SET); return tp; } void check_space_in_PATH(PATH *path){ if (path->num >= path->max) expand_singarr(path->pset,path->num,path->max,2,PATH_SET); } void PATH_print(PATH *path, FILE *fp, int max){ PATH_n_print(path, fp, 0, path->num, max); } void PATH_n_print(PATH *path, FILE *fp, int from, int to, int max){ int i, lena, lenb, alen=40, plen=0, endpass, used; int c,s,d,n,u,aux_max=0,line=0,wmax; char fmt[30]; TEXT *astr, *bstr, *aster=(TEXT *) "****************************************", buf[100]; if (to > path->num) to = path->num; used = (from >= 0 && from < to) ? from : 0; c = s = d = n = u = 0; /* collect preliminary info */ for (i=used; ipset[i].eval & P_CORR) != 0) c++; else if ((path->pset[i].eval & P_SUB) != 0) s++; else if ((path->pset[i].eval & P_INS) != 0) n++; else if ((path->pset[i].eval & P_DEL) != 0) d++; else u ++; /* compute the max of the auxillary info */ if (BF_isSET(path->attrib,PA_HYP_CONF)) aux_max = (aux_max < 7) ? 7 : aux_max; if (BF_isSET(path->attrib,PA_REF_CONF)) aux_max = (aux_max < 7) ? 7 : aux_max; if (BF_isSET(path->attrib,PA_HYP_WTIMES)) aux_max = (aux_max < 7) ? 7 : aux_max; if (BF_isSET(path->attrib,PA_REF_WTIMES)) aux_max = (aux_max < 7) ? 7 : aux_max; if (BF_isSET(path->attrib,PA_HYP_WEIGHT)) aux_max = (aux_max < 7) ? 7 : aux_max; if (BF_isSET(path->attrib,PA_REF_WEIGHT)) aux_max = (aux_max < 7) ? 7 : aux_max; fprintf(fp,"id: %s\n",(path->id == (char *)0) ? "" : path->id); if (from != 0 || to != path->num) fprintf(fp,"Range: %d-%d of %d words\n",from,to,path->num); if (path->labels != (char *)0) fprintf(fp,"Labels: %s\n",path->labels); if (path->file != (char *)0) fprintf(fp,"File: %s\n",path->file); if (path->channel != (char *)0) fprintf(fp,"Channel: %s\n",path->channel); if (u > 0) fprintf(fp,"Scores: (#C #S #D #I #UNK) %d %d %d %d %d\n",c,s,d,n,u); else fprintf(fp,"Scores: (#C #S #D #I) %d %d %d %d\n",c,s,d,n); if (BF_isSET(path->attrib,PA_CHAR_ALIGN) || BF_isSET(path->attrib,PA_CASE_SENSE) || BF_isSET(path->attrib,PA_REF_WEIGHT) || BF_isSET(path->attrib,PA_HYP_WEIGHT)){ fprintf(fp,"Attributes: "); if (BF_isSET(path->attrib,PA_CHAR_ALIGN)) fprintf(fp,"Character_align "); if (BF_isSET(path->attrib,PA_CASE_SENSE)) fprintf(fp,"Case_sensitve "); if (BF_isSET(path->attrib,PA_REF_WEIGHT)) fprintf(fp,"Ref_weight "); if (BF_isSET(path->attrib,PA_HYP_WEIGHT)) fprintf(fp,"Hyp_weight "); fprintf(fp,"\n"); } if (BF_isSET(path->attrib,PA_REF_TIMES)) fprintf(fp,"Ref times: t1= %.2f t2= %.2f\n",path->ref_t1,path->ref_t2); if (BF_isSET(path->attrib,PA_HYP_TIMES)) fprintf(fp,"Hyp times: t1= %.2f t2= %.2f\n",path->hyp_t1,path->hyp_t2); while (used < to){ /* calculate the max words for this pass */ plen = (used > 0) ? 9 : 6; for (i=used; plen < max && ipset[i].eval == P_INS) ? 1 : TEXT_strlen(((WORD *)(path->pset[i].a_ptr))->value); lenb = (path->pset[i].eval == P_DEL) ? 1 : TEXT_strlen(((WORD *)(path->pset[i].b_ptr))->value); plen += 1 + MAX3(aux_max,lena,lenb); } if (used > 0) fprintf(fp,"\n"); endpass = i - ((i < to) ? 1 : 0); for (line=0; line<11; line++){ switch(line) { case 0: { if (used > 0) fprintf(fp,">> "); fprintf(fp,"REF: "); break; } case 1: case 2: { if (BF_notSET(path->attrib,PA_REF_WTIMES)) continue; if (used > 0) fprintf(fp,">> "); if (line == 1) fprintf(fp,"R_T1: "); if (line == 2) fprintf(fp,"R_T2: "); break; } case 3: { if (BF_notSET(path->attrib,PA_REF_CONF)) continue; if (used > 0) fprintf(fp,">> "); fprintf(fp,"RCNF: "); break; } case 4: { if (used > 0) fprintf(fp,">> "); fprintf(fp,"HYP: "); break; } case 5: case 6: { if (BF_notSET(path->attrib,PA_HYP_WTIMES)) continue; if (used > 0) fprintf(fp,">> "); if (line == 5) fprintf(fp,"H_T1: "); if (line == 6) fprintf(fp,"H_T2: "); break; } case 7: { if (BF_notSET(path->attrib,PA_HYP_CONF)) continue; if (used > 0) fprintf(fp,">> "); fprintf(fp,"CONF: "); break; } case 8: { if (BF_notSET(path->attrib,PA_REF_WEIGHT)) continue; if (used > 0) fprintf(fp,">> "); fprintf(fp,"R_WE: "); break; } case 9: { if (BF_notSET(path->attrib,PA_HYP_WEIGHT)) continue; if (used > 0) fprintf(fp,">> "); fprintf(fp,"H_WE: "); break; } case 10: { if (used > 0) fprintf(fp,">> "); fprintf(fp,"Eval: "); break; } } /* loop through the words */ for (i=used; ipset[i].eval == P_INS) lena = 1, astr = aster; else { astr = ((WORD *)(path->pset[i].a_ptr))->value; lena = TEXT_strlen(astr); } if (path->pset[i].eval == P_DEL) lenb = 1, bstr = aster; else { bstr = ((WORD *)(path->pset[i].b_ptr))->value; lenb = TEXT_strlen(bstr); } wmax = MAX3(aux_max,lena,lenb); /* set the format statement and print the word */ switch(line) { case 0: { sprintf(fmt,"%%-%ds ",wmax); if (astr == aster) astr = aster + (alen - lenb); else { if (BF_notSET(path->attrib,PA_CASE_SENSE) && path->pset[i].eval != P_CORR) { astr = TEXT_str_to_master(astr, 0); } } fprintf(fp,fmt,astr); break; } case 1: case 2: { if ((line == 1) && (path->pset[i].eval != P_INS)){ sprintf(fmt,"%%-%d.2f ",wmax); fprintf(fp,fmt,((WORD *)(path->pset[i].a_ptr))->T1); } else if ((line == 2) && (path->pset[i].eval != P_INS)){ sprintf(fmt,"%%-%d.2f ",wmax); fprintf(fp,fmt,((WORD *)(path->pset[i].a_ptr))->T2); } else { sprintf(fmt,"%%%ds ",wmax); fprintf(fp,fmt,""); } break; } case 3: { if (path->pset[i].eval != P_INS){ sprintf(fmt,"%%-%d.4f ",wmax); fprintf(fp,fmt,((WORD *)(path->pset[i].a_ptr))->conf); } else { sprintf(fmt,"%%%ds ",wmax); fprintf(fp,fmt,""); } break; } case 4: { sprintf(fmt,"%%-%ds ",wmax); if (bstr == aster) bstr = aster + (alen - lena); else { if (BF_notSET(path->attrib,PA_CASE_SENSE) && path->pset[i].eval != P_CORR){ bstr = TEXT_str_to_master(bstr, 0); } } fprintf(fp,fmt,bstr); break; } case 5: case 6: { if ((line == 5) && (path->pset[i].eval != P_DEL)){ sprintf(fmt,"%%-%d.2f ",wmax); fprintf(fp,fmt,((WORD *)(path->pset[i].b_ptr))->T1); } else if ((line == 6) && (path->pset[i].eval != P_DEL)){ sprintf(fmt,"%%-%d.2f ",wmax); fprintf(fp,fmt,((WORD *)(path->pset[i].b_ptr))->T2); } else { sprintf(fmt,"%%%ds ",wmax); fprintf(fp,fmt,""); } break; } case 7: { if (path->pset[i].eval != P_DEL){ sprintf(fmt,"%%-%d.4f ",wmax); fprintf(fp,fmt,((WORD *)(path->pset[i].b_ptr))->conf); } else { sprintf(fmt,"%%%ds ",wmax); fprintf(fp,fmt,""); } break; } case 8: { if (path->pset[i].eval != P_INS){ sprintf(fmt,"%%-%d.4f ",wmax); fprintf(fp,fmt,((WORD *)(path->pset[i].a_ptr))->weight); } else { sprintf(fmt,"%%%ds ",wmax); fprintf(fp,fmt,""); } break; } case 9: { if (path->pset[i].eval != P_DEL){ sprintf(fmt,"%%-%d.4f ",wmax); fprintf(fp,fmt,((WORD *)(path->pset[i].b_ptr))->weight); } else { sprintf(fmt,"%%%ds ",wmax); fprintf(fp,fmt,""); } break; } case 10: { sprintf(fmt,"%%-%ds ",wmax); fprintf(fp,fmt,(astr == aster) ? "I" : ((bstr == aster) ? "D" : ((path->pset[i].eval != P_CORR) ? "S" : ""))); break; } } } fprintf(fp,"\n"); } used = endpass; } } void PATH_print_html(PATH *path, FILE *fp, int max, int header){ PATH_n_print_html(path, fp, 0, path->num, max, header); } void PATH_n_print_html(PATH *path, FILE *fp, int from, int to, int max, int header){ int i, lena, lenb, alen=40, plen=0, endpass, used; int c,s,d,n,u,aux_max=0,line=0,wmax; char fmt[30]; TEXT *astr, *bstr, *aster=(TEXT *) "****************************************"; if (to > path->num) to = path->num; used = (from >= 0 && from < to) ? from : 0; c = s = d = n = u = 0; /* collect preliminary info */ for (i=used; ipset[i].eval & P_CORR) != 0) c++; else if ((path->pset[i].eval & P_SUB) != 0) s++; else if ((path->pset[i].eval & P_INS) != 0) n++; else if ((path->pset[i].eval & P_DEL) != 0) d++; else u ++; /* compute the max of the auxillary info */ if (BF_isSET(path->attrib,PA_HYP_CONF)) aux_max = (aux_max < 7) ? 7 : aux_max; if (BF_isSET(path->attrib,PA_REF_CONF)) aux_max = (aux_max < 7) ? 7 : aux_max; if (BF_isSET(path->attrib,PA_HYP_WTIMES)) aux_max = (aux_max < 7) ? 7 : aux_max; if (BF_isSET(path->attrib,PA_REF_WTIMES)) aux_max = (aux_max < 7) ? 7 : aux_max; if (header){ fprintf(fp,"\n"); fprintf(fp,"id: %s
\n",(path->id == (char *)0) ? "" : path->id); if (from != 0 || to != path->num) fprintf(fp,"Range: %d-%d of %d words
\n",from,to,path->num); if (path->labels != (char *)0) fprintf(fp,"Labels: %s
\n",path->labels); if (u > 0) fprintf(fp,"Scores: (#C #S #D #I #UNK) %d %d %d %d %d
\n", c,s,d,n,u); else fprintf(fp,"Scores: (#C #S #D #I) %d %d %d %d
\n",c,s,d,n); if (BF_isSET(path->attrib,PA_CHAR_ALIGN) || BF_isSET(path->attrib,PA_CASE_SENSE)){ fprintf(fp,"Attributes: "); fprintf(fp,"
    \n"); if (BF_isSET(path->attrib,PA_CHAR_ALIGN)) fprintf(fp,"Character_align "); if (BF_isSET(path->attrib,PA_CASE_SENSE)) fprintf(fp,"Case_sensitve "); fprintf(fp,"\n"); fprintf(fp,"
\n"); } if (BF_isSET(path->attrib,PA_REF_TIMES)) fprintf(fp,"Ref times: t1= %.2f t2= %.2f
\n", path->ref_t1,path->ref_t2); if (BF_isSET(path->attrib,PA_HYP_TIMES)) fprintf(fp,"Hyp times: t1= %.2f t2= %.2f
\n", path->hyp_t1,path->hyp_t2); fprintf(fp,"
\n"); } while (used < to){ /* calculate the max words for this pass */ plen = (used > 0) ? 9 : 6; for (i=used; plen < max && ipset[i].eval == P_INS) ? 1 : TEXT_strlen(((WORD *)(path->pset[i].a_ptr))->value); lenb = (path->pset[i].eval == P_DEL) ? 1 : TEXT_strlen(((WORD *)(path->pset[i].b_ptr))->value); plen += 1 + MAX3(aux_max,lena,lenb); } if (used > 0) fprintf(fp,"\n"); endpass = i - ((i < to) ? 1 : 0); fprintf(fp,"\n"); for (line=0; line<9; line++){ fprintf(fp,"\n"); /* write the header */ switch(line) { case 0: { fprintf(fp,"\n"); break; } case 1: case 2: { if (BF_notSET(path->attrib,PA_REF_WTIMES)) continue; fprintf(fp,"\n"); break; } case 3: { if (BF_notSET(path->attrib,PA_REF_CONF)) continue; fprintf(fp,"\n"); break; } case 4: { fprintf(fp,"\n"); break; } case 5: case 6: { if (BF_notSET(path->attrib,PA_HYP_WTIMES)) continue; fprintf(fp,"\n"); break; } case 7: { if (BF_notSET(path->attrib,PA_HYP_CONF)) continue; fprintf(fp,"\n"); break; } case 8: { fprintf(fp,"\n"); break; } } /* loop through the words */ for (i=used; ipset[i].eval == P_INS) lena = 1, astr = aster; else { astr = ((WORD *)(path->pset[i].a_ptr))->value; lena = TEXT_strlen(astr); } if (path->pset[i].eval == P_DEL) lenb = 1, bstr = aster; else { bstr = ((WORD *)(path->pset[i].b_ptr))->value; lenb = TEXT_strlen(bstr); } wmax = MAX3(aux_max,lena,lenb); /* set the format statement and print the word */ switch(line) { case 0: { sprintf(fmt,"",wmax); if (astr == aster) astr = aster + (alen - lenb); else { if (BF_notSET(path->attrib,PA_CASE_SENSE) && path->pset[i].eval != P_CORR) { astr = TEXT_str_to_master(astr, 0); } } fprintf(fp,fmt,astr); break; } case 1: case 2: { sprintf(fmt,""); if ((line == 1) && (path->pset[i].eval != P_INS)){ fprintf(fp,fmt,((WORD *)(path->pset[i].a_ptr))->T1); } else if ((line == 2) && (path->pset[i].eval != P_INS)){ fprintf(fp,fmt,((WORD *)(path->pset[i].a_ptr))->T2); } else { sprintf(fmt,""); } break; } case 3: { if (path->pset[i].eval != P_INS){ fprintf(fp,"", ((WORD *)(path->pset[i].a_ptr))->conf); } else fprintf(fp,""); break; } case 4: { sprintf(fmt,""); if (bstr == aster) bstr = aster + (alen - lena); else { if (BF_notSET(path->attrib,PA_CASE_SENSE) && path->pset[i].eval != P_CORR){ bstr = TEXT_str_to_master(bstr, 0); } } fprintf(fp,fmt,bstr); break; } case 5: case 6: { sprintf(fmt,""); if ((line == 5) && (path->pset[i].eval != P_DEL)){ fprintf(fp,fmt,((WORD *)(path->pset[i].b_ptr))->T1); } else if ((line == 6) && (path->pset[i].eval != P_DEL)){ fprintf(fp,fmt,((WORD *)(path->pset[i].b_ptr))->T2); } else { fprintf(fp,""); } break; } case 7: { if (path->pset[i].eval != P_DEL){ fprintf(fp,"", ((WORD *)(path->pset[i].b_ptr))->conf); } else { fprintf(fp,""); } break; } case 8: { fprintf(fp,"",(astr == aster) ? "I" : ((bstr == aster) ? "D" : ((path->pset[i].eval != P_CORR) ? "S" : ""))); break; } } } fprintf(fp,"\n"); } fprintf(fp,"
"); if (used > 0) fprintf(fp,">> "); fprintf(fp,"REF:"); fprintf(fp,""); if (used > 0) fprintf(fp,">> "); if (line == 1) fprintf(fp,"R_T1:"); if (line == 2) fprintf(fp,"R_T2:"); fprintf(fp,""); if (used > 0) fprintf(fp,">> "); fprintf(fp,"RCNF:"); fprintf(fp,""); if (used > 0) fprintf(fp,">> "); fprintf(fp,"HYP:"); fprintf(fp,""); if (used > 0) fprintf(fp,">> "); if (line == 5) fprintf(fp,"H_T1:"); if (line == 6) fprintf(fp,"H_T2:"); fprintf(fp,""); if (used > 0) fprintf(fp,">> "); fprintf(fp,"CONF:"); fprintf(fp,""); if (used > 0) fprintf(fp,">> "); fprintf(fp,"Eval: "); fprintf(fp,"%%-%ds%%.2f%.4f%%s%%.2f%.4f%s
\n"); used = endpass; } } void PATH_print_wt(PATH *path, FILE *fp){ int w; fprintf(fp,"Path dump id: %s Labels: %s\n", path->id, (path->labels!=(char*)0)?path->labels:""); for (w=0; wnum; w++){ fprintf(fp,"%4d: ",w); print_2_WORD_wt(path->pset[w].a_ptr,path->pset[w].b_ptr,fp); } } void PATH_increment_WORD_use(PATH *path){ int i; for (i=0; inum; i++){ if (path->pset[i].a_ptr != (void *)0) ((WORD *)(path->pset[i].a_ptr))->use ++; if (path->pset[i].b_ptr != (void *)0) ((WORD *)(path->pset[i].b_ptr))->use ++; } } void PATH_free(PATH *path){ int i; for (i=0; inum; i++){ if (path->pset[i].a_ptr != (void *)0) release_WORD((WORD *)(path->pset[i].a_ptr)); if (path->pset[i].b_ptr != (void *)0) release_WORD((WORD *)(path->pset[i].b_ptr)); } if (path->id != (char *)0) free_singarr(path->id,char); if (path->labels != (char *)0) free_singarr(path->labels,char); if (path->file != (char *)0) free_singarr(path->file,char); if (path->channel != (char *)0) free_singarr(path->channel,char); free_singarr(path->pset,PATH_SET); free_singarr(path, PATH); } void PATH_append(PATH *path, void *ap, void *bp, int eval) { check_space_in_PATH(path); path->pset[path->num].a_ptr = ap; path->pset[path->num].b_ptr = bp; path->pset[path->num].eval = eval; path->num++; } void PATH_remove(PATH *path) { if (path->num > 0) path->num--; } /******************************************************/ /* sort the Insertions and Deletions in the sentence */ /* by the time in which they occure. */ /******************************************************/ #define SW(_a1,_a2,_tt) {_tt _t=_a1; _a1=_a2; _a2=_t;} void sort_PATH_time_marks(PATH *path) { int x=0, tx, change; double tb, ta; /* Sort the insertions and deletions, so that later down the */ /* road split and merges are properly done. */ while (x < path->num){ while (x < path->num && (! ((path->pset[x].eval == P_DEL) || (path->pset[x].eval == P_INS)))) x++; /* printf("Located In/Del %d\n",x); */ /* word at x is either EOF or INS or del */ change = TRUE; while ( x < path->num && change){ change = FALSE; tx = x+1; while (tx < path->num && (path->pset[tx].eval == P_DEL || path->pset[tx].eval == P_INS)){ /* printf("inner loop\n"); */ ta = (path->pset[tx-1].eval == P_DEL) ? ((WORD *)(path->pset[tx-1].a_ptr))->T1 : ((WORD *)(path->pset[tx-1].b_ptr))->T1; tb = (path->pset[tx].eval == P_DEL) ? ((WORD *)(path->pset[tx].a_ptr))->T1 : ((WORD *)(path->pset[tx].b_ptr))->T1; /* printf("ta=%f tb=%f\n",ta,tb); */ if (ta > tb) { /* printf("Swapping \n"); */ /* I need to swap */ SW(path->pset[tx],path->pset[tx-1],PATH_SET); change = TRUE; } tx++; } } while (x < path->num && (path->pset[x].eval == P_DEL || path->pset[x].eval == P_INS)) x++; } /* printf("Sort done\n"); */ }