diff --git a/src/defs.h b/src/defs.h index 707a5ab..26da14c 100644 --- a/src/defs.h +++ b/src/defs.h @@ -67,11 +67,12 @@ class idx2; #define SWITCHTYPE_FLIP 0 #define SWITCHTYPE_SWITCH 1 -#define SWITCHTYPE_SWITCH_ERR 2 -#define SWITCHTYPE_FLIP_BEG 3 -#define SWITCHTYPE_FLIP_END 4 -#define SWITCHTYPE_NONE 5 -#define SWITCHTYPES 6 +#define SWITCHTYPE_SWITCH_AND_FLIP 2 +#define SWITCHTYPE_SWITCH_ERR 3 +#define SWITCHTYPE_FLIP_BEG 4 +#define SWITCHTYPE_FLIP_END 5 +#define SWITCHTYPE_NONE 6 +#define SWITCHTYPES 7 // runtime timers #define TIME_READ 0 diff --git a/src/main.cpp b/src/main.cpp index 74b3634..a286f86 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,7 +23,7 @@ std::vector callset_strs = {"QUERY", "TRUTH"}; std::vector phase_strs = {"=", "X", "?"}; std::vector timer_strs = {"reading", "clustering", "realigning", "reclustering", "superclustering", "precision/recall", "edit distance", "phasing", "writing", "total"}; -std::vector switch_strs = {"FLIP", "SWITCH", "SWITCH_ERR", "FLIP_BEG", "FLIP_END", "NONE"}; +std::vector switch_strs = {"FLIP", "SWITCH", "SWITCH+FLIP", "SWITCH_ERR", "FLIP_BEG", "FLIP_END", "NONE"}; int main(int argc, char **argv) { diff --git a/src/phase.cpp b/src/phase.cpp index c946f19..45f255f 100644 --- a/src/phase.cpp +++ b/src/phase.cpp @@ -426,27 +426,30 @@ void phaseblockData::write_switchflips() { while (true) { // get type and supercluster of next switch/flip/phaseset - // check flip first because it will cause a second switch - if (flip_idx < ctg_pbs->nflips && ctg_pbs->flips[flip_idx] < next_sc) { - type = SWITCHTYPE_FLIP; - next_sc = ctg_pbs->flips[flip_idx]; - } - if (pb_idx < ctg_pbs->n && ctg_pbs->phase_blocks[pb_idx] < next_sc) { + if (pb_idx < ctg_pbs->n && ctg_pbs->phase_blocks[pb_idx] <= next_sc) { type = SWITCHTYPE_SWITCH; next_sc = ctg_pbs->phase_blocks[pb_idx]; } - if (switch_idx < ctg_pbs->nswitches && ctg_pbs->switches[switch_idx] < next_sc) { + if (switch_idx < ctg_pbs->nswitches && ctg_pbs->switches[switch_idx] <= next_sc) { type = SWITCHTYPE_SWITCH_ERR; next_sc = ctg_pbs->switches[switch_idx]; } + // check flip last because it will cause a second switch + if (flip_idx < ctg_pbs->nflips && ctg_pbs->flips[flip_idx] <= next_sc) { + if (type == SWITCHTYPE_SWITCH) + type = SWITCHTYPE_SWITCH_AND_FLIP; + else + type = SWITCHTYPE_FLIP; + next_sc = ctg_pbs->flips[flip_idx]; + } if (type == SWITCHTYPE_NONE) { // all out-of-bounds break; } - if (next_sc <= sc) ERROR("Next SC is not after current SC"); + if (next_sc <= sc) ERROR("Next supercluster (%d) is not after current supercluster (%d) in write_switchflips()", next_sc, sc); // get block(s) - if (type == SWITCHTYPE_FLIP) { + if (type == SWITCHTYPE_FLIP || type == SWITCHTYPE_SWITCH_AND_FLIP) { // switch could have occurred anywhere after last phased supercluster int left = next_sc-1; while (left > 0 && ctg_scs->sc_phase[left] == PHASE_NONE) @@ -469,9 +472,12 @@ void phaseblockData::write_switchflips() { switch_strs[SWITCHTYPE_FLIP_END].data(), next_sc, pb_idx-1); } flip_idx++; + if (type == SWITCHTYPE_SWITCH_AND_FLIP) pb_idx++; + } else if (type == SWITCHTYPE_SWITCH) { // end of phase block, don't print anything since not an error pb_idx++; + } else if (type == SWITCHTYPE_SWITCH_ERR) { // expand left/right from in between these clusters int left = next_sc-1; @@ -549,27 +555,31 @@ int phaseblockData::calculate_ng50(bool break_on_switch, bool break_on_flip) { while (true) { // get type and supercluster of next switch/flip/phaseset - // check flip first because it will cause a second switch - if (break_on_flip && flip_idx < ctg_pbs->nflips && ctg_pbs->flips[flip_idx] < next_sc) { - type = SWITCHTYPE_FLIP; - next_sc = ctg_pbs->flips[flip_idx]; - } - if (pb_idx < ctg_pbs->n && ctg_pbs->phase_blocks[pb_idx] < next_sc) { + if (pb_idx < ctg_pbs->n && ctg_pbs->phase_blocks[pb_idx] <= next_sc) { type = SWITCHTYPE_SWITCH; next_sc = ctg_pbs->phase_blocks[pb_idx]; } - if (break_on_switch && switch_idx < ctg_pbs->nswitches && ctg_pbs->switches[switch_idx] < next_sc) { + if (break_on_switch && switch_idx < ctg_pbs->nswitches && ctg_pbs->switches[switch_idx] <= next_sc) { type = SWITCHTYPE_SWITCH_ERR; next_sc = ctg_pbs->switches[switch_idx]; } + // check flip last (takes preference due to <=) because it can cause two breaks (before/after) + // NOTE: is is possible for one supercluster to have both a switch (new PS) and flip + if (break_on_flip && flip_idx < ctg_pbs->nflips && ctg_pbs->flips[flip_idx] <= next_sc) { + if (type == SWITCHTYPE_SWITCH) + type = SWITCHTYPE_SWITCH_AND_FLIP; + else + type = SWITCHTYPE_FLIP; + next_sc = ctg_pbs->flips[flip_idx]; + } if (type == SWITCHTYPE_NONE) { // all out-of-bounds break; } - if (next_sc <= sc) ERROR("Next SC is not after current SC"); + if (next_sc <= sc) ERROR("Next supercluster (%d) is not after current supercluster (%d) in calc_ng50()", next_sc, sc); // get block(s) - if (type == SWITCHTYPE_FLIP) { + if (type == SWITCHTYPE_FLIP || type == SWITCHTYPE_SWITCH_AND_FLIP) { end = ctg_scs->ends[next_sc-1]; correct_blocks.push_back(end-beg); beg = ctg_scs->begs[next_sc]; @@ -578,6 +588,7 @@ int phaseblockData::calculate_ng50(bool break_on_switch, bool break_on_flip) { correct_blocks.push_back(end-beg); beg = ctg_scs->begs[next_sc+1]; flip_idx++; + if (type == SWITCHTYPE_SWITCH_AND_FLIP) pb_idx++; } else if (type == SWITCHTYPE_SWITCH) { end = ctg_scs->ends[next_sc-1]; correct_blocks.push_back(end-beg);