wiki:BossaExampleTwo

Version 4 (modified by davea, 16 years ago) (diff)

--

Example two: replication

This example uses the same type of jobs as the previous example, but does replication to increase the accuracy of results. Every job is sent to at least two different volunteers. A job is considered finished if either

  • Two volunteers reported "no ellipse found";
  • Two volunteers found ellipses, and their centers are within 20 pixels;

If ten instances have been performed and neither condition holds, the job is marked as "inconclusive" and no further instances are issued.

The following When the first instance of a job is issued, its priority is left at 1; this allows another instance to be issued immediately.

function job_issued($job, $inst, $user) {
    $insts = $job->get_instances();
    if (count($insts) > 1) {
        $job->set_priority(0);
    }
}

When an instance is finished, we check whether

function job_finished($job, $inst) {
    $response = null;
    if (get_str('submit', true)) {
        $response->have_ellipse = 0;
    } else {
        $response->have_ellipse = 1;
        $response->cx = get_int('pic_x');
        $response->cy = get_int('pic_y');
    }
    $inst->update_info($response);

    // see if job is done
    //
    $insts = $job->get_finished_instances();
    $n = count($insts);

    $results = null;
    foreach ($insts as $inst) {
        $results[] = $inst->get_info();
    }
    for ($i=0; $i<$n-1; $i++) {
        $r1 = $results[$i];
        for ($j=$i+1; $j<$n; $j++) {
            $r2 = $results[$j];
            if (compatible($r1, $r2)) {
                $job->update_state(BOSSA_JOB_DONE);
                return;
            }
        }
    }
    if ($n >= 10) {
        $job->update_state(BOSSA_JOB_INCONCLUSIVE);
        return;
    }
}

// two results are compatible if neither found an ellipse,
// or they both did and centers are within 20 pixels
//
function compatible($r1, $r2) {
    if ($r1->have_ellipse) {
        if ($r2->have_ellipse) {
            $dx = ($r1->cx - $r2->cx);
            $dy = ($r1->cy - $r2->cy);
            $dsq = $dx*$dx + $dy*$dy;
            return ($dsq < 400);
        } else return false;
    } else {
        return !$r2->have_ellipse;
    }
}