/* Compares files of "found" and "ideal" candidates, writes diff and inter. */ /* Last edited on 2015-01-20 16:43:50 by stolfilocal */ #include #include #include #include #include TYPE options_t = struct ??? { char *found; /* Input file name of "found" candidates. */ char *ideal; /* Input file name of "ideal" candidates. */ char *good; /* Output file name of "good" candidates. */ char *missing; /* Output file name of "missing" candidates. */ char *bogus; /* Output file name of "bogus" candidates. */ double step; /* Nominal sampling step (pixels). */ bool_t printGood; /* TRUE prints candidates that are in both sets. */ bool_t printMissing; /* TRUE prints ideal cands that aren't found cands. */ bool_t printBogus; /* TRUE prints found cands that aren't ideal cands. */ bool_t printChainPairs; /* TRUE prints summary line per matched chain pair. */ bool_t printCandPairs; /* TRUE prints every pairing candidate pair. */ /* Criteria for ideal candidate selection: */ double minIdealLength; /* Min length (pixels) for ideal cands. */ double blurFactor; /* Corner broadening factor. */ /* Criteria for equality of candidates: */ double minCompOverlap; /* Minimum overlap (pixels). */ double maxCompShift; /* Maximum displacement on each chain (pixels). */ } ???; int main(int argc, char **argv ) { { /* with */ ??? o = pz_get_options(int argc, char **argv); ??? fData = ReadFoundCandidates(o.found); ??? fCand = fData.c^; ??? fOK = NEW(REF bool_vec_t, (fCand.ne))^; ??? lambda = fData.lambda; iData = ReadIdealCandidates( name := o.ideal; minLength := o.minIdealLength; blurFactor := o.blurFactor; lambda := lambda; step := o.step ); ??? iCand = iData.c^; ??? iOK = NEW(REF bool_vec_t, (iCand.ne))^; /* do */ CompareCandSets( fData, iData, fOK, iOK, minCompOverlap = o.minCompOverlap, maxCompShift = o.maxCompShift, step = o.step, printGood = o.printGood, printMissing = o.printMissing, printBogus = o.printBogus, printChainPairs = o.printChainPairs, printCandPairs = o.printCandPairs ); { /* with */ ??? gCand = ExtractCands(fCand, fOK, TRUE)^; /* do */ WriteCandidateSubset( o.good, gCand, "found candidates that match some ideal candidate", fData.cmt, fData.lambda ); }; { /* with */ ??? bCand = ExtractCands(fCand, fOK, FALSE)^; /* do */ WriteCandidateSubset( o.bogus, bCand, "found candidates that don't match any ideal candidates", fData.cmt, fData.lambda ); }; { /* with */ ??? mCand = ExtractCands(iCand, iOK, FALSE)^; /* do */ WriteCandidateSubset( o.missing, mCand, "ideal candidates that don't match any found candidates", iData.cmt, iData.lambda ); };; }; } /* Main */ options_t pz_get_options(int argc, char **argv ) VAR o: options_t; { argparser_t *pp = argparser_new(stderr, argc, argv); argparser_set_help(pp, PROG_NAME " version " PROG_VERS ", usage:\n" PROG_HELP); argparser_set_info(pp, PROG_INFO); argparser_process_help_info_options(pp); { /* with */ /* do */ TRY argparser_get_keyword(pp, "-found"); o.found = argparser_get_next(pp); argparser_get_keyword(pp, "-ideal"); o.ideal = argparser_get_next(pp); if (( argparser_keyword_present(pp, "-good") )){ o.good = argparser_get_next(pp) }else{ o.good = ""; }; if (( argparser_keyword_present(pp, "-missing") )){ o.missing = argparser_get_next(pp) }else{ o.missing = ""; }; if (( argparser_keyword_present(pp, "-bogus") )){ o.bogus = argparser_get_next(pp) }else{ o.bogus = ""; }; argparser_get_keyword(pp, "-step"); o.step = argparser_get_next_double(pp, 0.0e0, 1024.0e0); if (( argparser_keyword_present(pp, "-minIdealLength") )){ o.minIdealLength = argparser_get_next_double(pp, 0.0e0) }else{ o.minIdealLength = 0.0e0; }; argparser_get_keyword(pp, "-blurFactor"); o.blurFactor = argparser_get_next_double(pp, 0.01e0, 100.0e0); argparser_get_keyword(pp, "-minCompOverlap"); o.minCompOverlap = argparser_get_next_double(pp, 0.0e0); argparser_get_keyword(pp, "-maxCompShift"); o.maxCompShift = argparser_get_next_double(pp, 0.0e0); o.printGood = argparser_keyword_present(pp, "-printGood"); o.printMissing = argparser_keyword_present(pp, "-printMissing"); o.printBogus = argparser_keyword_present(pp, "-printBogus"); o.printChainPairs = argparser_keyword_present(pp, "-printChainPairs"); o.printCandPairs = argparser_keyword_present(pp, "-printCandPairs"); argparser_finish(pp); EXCEPT | ParseParams.Error ==> fprintf(stderr, "Usage: pz_comp_cands \\\n"); fprintf(stderr, " -found NAME \\\n"); fprintf(stderr, " -ideal NAME \\\n"); fprintf(stderr, " -good NAME \\\n"); fprintf(stderr, " -missing NAME \\\n"); fprintf(stderr, " -step PIXELS \\\n"); fprintf(stderr, " [ -minIdealLength PIXELS ] \\\n"); fprintf(stderr, " -blurFactor PIXELS \\\n"); fprintf(stderr, " -minCompOverlap PIXELS -maxCompShift PIXELS \\\n"); fprintf(stderr, " [ -printGood ] [ -printMissing ] [ -printBogus ] \\\n"); fprintf(stderr, " [ -printChainPairs ] [ -printCandPairs ]\n"); Process.Exit(1);; };; }; return o } /* GetOptions */ pz_candidate_read_data ReadFoundCandidates( char *name ) /* Reads a candidate list. */ { return pz_candidate_read(open_read(name & ".can"), TRUE) } /* ReadFoundCandidates */ pz_candidate_read_data ReadIdealCandidates( char *name, double minLength, double blurFactor, double lambda, double step ) /* Reads a candidate list, and removes entries with less than "minLength" (minus corner blurring) on either segment. */ VAR nCands: unsigned; cData: pz_candidate_read_data; { if (( step == 0.0e0 )){ minLength = 0.0e0; step = 1.0e0 ;}; cData = pz_candidate_read(open_read(name & ".can"), TRUE); { /* with */ ??? c = cData.c^; ??? minCorrLength = MAX(0.0e0, minLength - 2.0e0*blurFactor*cData.lambda); ??? minSteps = FLOOR(minCorrLength/step); /* do */ affirm(cData.lambda == lambda ); fprintf(stderr, "ignoring ideal cands that cover less than " & FI(minSteps,1) & " sampling steps\n" ); nCands = (c.ne); pz_candidate_remove_short(&(cData.c), nCands, minSteps); { int diff = nCands - (cData.ne); txt = "pz_comp_cands: removed candidates with less than " & FI(minSteps,5) & " steps\n"; /* do */ if (diff > 0) { fprintf(stderr, txt & "\n") ;}; cData.cmt = txtcat(cData.cmt & "\n" , txt); }; }; return cData } /* ReadIdealCandidates */ void CompareCandSets( pz_candidate_read_data *fData, pz_candidate_read_data *iData, bool_vec_t *fOK, /* (OUT) */ bool_vec_t *iOK, /* (OUT) */ double minCompOverlap, double maxCompShift, double step, bool_t printGood, bool_t printMissing, bool_t printBogus, bool_t printChainPairs, bool_t printCandPairs ) { if (( (iData.c^.ne) > 0 )){ affirm(fData.lambda == iData.lambda );; }; /* Hack to avoid overflow when "step" is zero. */ if (( step == 0.0e0 )){ step = minCompOverlap; if (( step == 0.0e0 )){ step = 1.0e0 ;};; }; { /* with */ ??? fCand = fData.c^; ??? iCand = iData.c^; ??? minSteps = FLOOR(minCompOverlap / step + 0.0001e0); ??? maxAdjust = CEILING(maxCompShift / step - 0.0001e0); /* do */ fprintf(stderr, "Candidate comparison parameters:\n"); fprintf(stderr, " overlap minSteps == %s\n", Fmt.Int(minSteps) ); fprintf(stderr, " alignment maxAdjust == %s\n", Fmt.Int(maxAdjust) ); pz_candidate_find_similar_cands( aCand = fCand, bCand = iCand, minSteps = minSteps, maxAdjust = maxAdjust, aOK = fOK, bOK = iOK, printAMatched = printGood, printBMatched = printGood, printAUnmatched = printBogus, printBUnmatched = printMissing, printMatchedCands = printCandPairs, printMatchedChains = printChainPairs ); pz_candidate_print_similarity_statistics( stderr, fOK, "found", iOK, "ideal" );; } } /* CompareCandSets */ pz_candidate.List *ExtractCands( pz_candidate.List *oldCand, bool_vec_t *mark /* Marks on each candidate. */ bool_t which, /* Extract candidates whose "mark" has this value. */ ) VAR nCands: unsigned := 0; { affirm((mark.ne) == (oldCand.ne) ); for (i = 0; i < (oldCand.ne ) ; i++){ if (( mark[i] == which )){ nCands++ ;}; }; { /* with */ ??? rc = NEW(REF pz_candidate.List, nCands), newCand = rc^; /* do */ nCands = 0; for (i = 0; i < (oldCand.ne ) ; i++){ if (( mark[i] == which )){ newCand[nCands] = oldCand[i]; nCands++; }; }; return rc; }; } /* ExtractCands */ void WriteCandidateSubset( char *name /* File name prefix. */ pz_candidate.List *cand, /* The candidate subset. */ char *desc, /* Description of the subset. */ char *cmt, /* Original dataset comments. */ double lambda, /* Filtering scale. */ ) /* Writes the specified candidates to disk, as "fname.can", provided "fname" is not the empty string. NOTE: Will also reorder the candidates. */ { if (( NOT Text.Empty(name) )){ { /* with */ ??? wr = open_write(name & ".can", TRUE); ??? cmt = txtcat(cmt & "\n\nPZCompCands: " , desc); /* do */ pz_candidate_sort(cand, pz_candidate_mismatch_better); pz_candidate_write(wr, cmt, cand, lambda); }; }; } /* WriteCandidateSubset */ <*UNUSED); char *FLR( double x, unsigned w, unsigned p ) { return Fmt.Pad(Fmt.LongReal(x, Fmt.Style.Fix, prec = p), w) } /* FLR */ char *FI( unsigned x, unsigned w ) { return Fmt.Pad(Fmt.Int(x), w) } /* FI */ <*UNUSED); void DebugIntPair( char *title, int r, int s ) { fprintf(stderr, title); fprintf(stderr, " "); fprintf(stderr, Fmt.Int(r)); fprintf(stderr, " "); fprintf(stderr, Fmt.Int(s)); fprintf(stderr, "\n"); } /* DebugIntPair */ { /* Copyright © 2001 Universidade Estadual de Campinas (UNICAMP). Authors: Helena C. G. Leitão and Jorge Stolfi. This file can be freely distributed, used, and modified, provided that this copyright and authorship notice is preserved, and that any modified versions are clearly marked as such. This software has NO WARRANTY of correctness or applicability for any purpose. Neither the authors nor their employers chall be held responsible for any losses or damages that may result from its use. */