wiki:BossaExampleOne

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

--

Bossa tutorial

Create a Bossa server

Install the BOINC software on a Linux system (or run the BOINC virtual server in a VMWare player on any computer).

Use make_project to create a BOINC project named "test":

> cd boinc/tools
> make_project --web_only test

Read ~/projects/test/test.readme and do what it says.

Let's say your server's domain name is "a.b.c".

Example application

We'll create an application in which volunteers view images, looking for ellipses on a noisy background. Their task is to click on the center of the ellipse, or to indicate that there is no ellipse. Here's an example:

(this has an ellipse slightly below/left of center).

Visit http://a.b.c/test_ops/bossa_ops.php, and create an application with short name "bossa_example".

The application is define by three scripts in ~/projects/test/html/:

  • ops/bossa_example_make_files.php: this creates image files.
  • ops/bossa_example_make_jobs.php: this creates jobs.
  • inc/bossa_example.inc: display jobs and handle completed jobs.

We'll go through these scripts and explain how they work. To develop your own Bossa applications you'll need to write corresponding scripts.

Creating jobs

To create some jobs, first we'll create some image files using the script html/ops/bossa_example_make_files.php.

cd ~/projects/test/html/ops
mkdir ../user/example
php bossa_example_make_files.php --nfiles 10 --dir example

This creates (in the examples/ directory) 10 image files 0.png to 9.png, and corresponding "answer" files 0.ans to 9.ans. Roughly half the images will have ellipses (you can specify this probability with --ellipse_frac x).

Now, create jobs using html/ops/bossa_example_make_jobs.php.

php bossa_example_make_jobs --app_name bossa_example --dir example

This makes 10 jobs (one for each image in the directory) and collects them into a "batch".

Displaying jobs

Next we'll explain the script that displays a job to a volunteer and handles their response: bossa_example_display.php.

function show_job($bj, $bji) {
    $info = json_decode($bj->info);
    $img_url = $info->url;
    echo "
        <form method=get action='bossa_example_display.php'>
        Click on the center of the ellipse.
        If you don't see one, click here:
        <br><br><input type=submit name=submit value=None>
        <input type=hidden name=bji value=$bji->id>
        <input type=hidden name=completion value=1>
        <input type=image name=pic src='$img_url'>
        </form>
    ";
}

function handle_job_completion($bj, $bji) {
    $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');
    }
    $bji->info = json_encode($response);
    $bji->completed($bj);
    Bossa::show_next_job($bj);    // show another job immediately
}

Bossa::script_init($user, $bj, $bji);

if (isset($_GET['completion'])) {
    handle_job_completion($bj, $bji);
} else {
    show_job($bj, $bji);
}

The script calls Bossa::script_init() to get PHP objects describing the user, the job, and the job instance.

show_job() decodes the job description to get the image URL, and displays the image in an HTML page that lets the user click on the image or on a "No ellipse" button.

handle_job_completion() gets the user's response (from form variables). It calls the completed() method of the job, passing it a JSON encoding of the response. I then calls Bossa::show_next_job() to immediately display another job.

Handling completed results

Finally, we need to specify how results are handled. This is specified in bossa_example_backend.inc.

This defines two functions, which must have names X_compare and X_handle where X is the application's short name.

The first function compares two instances and decides if they are compatible:

function bossa_example_compare($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;
    }
}

In this case, two instances are considered compatible if either

  • neither of them found an ellipse, or
  • they both found an ellipse and the centers are within 20 pixels

The second function specifies what happens when a job has been completed, i.e. a consensus set has been found:

function bossa_example_handle($bj, $c) {
    $res = $c[0];
    if ($res->have_ellipse) {
        $res->cx = 0;
        $res->cy = 0;
        foreach ($c as $r) {
            $res->cx += $r->cx;
            $res->cy += $r->cy;
        }
        $res->cx /= count($c);
        $res->cy /= count($c);
    }

    $info = json_decode[$bj->info);
    $info->result = $res;
    $i = json_encode($info);
    $bj->update("info='$i'");
}

This function is called with the BossaJob? record ($bj) and an array of job instances in the consensus set ($c). In this case, we average the center positions (if an ellipse was found) and store the JSON-encoded result in the info field of the job record.

Attachments (1)

Download all attachments as: .zip