| Version 9 (modified by , 18 years ago) (diff) |
|---|
Bossa tutorial
Create a Bossa server
Install the BOINC software on a Linux system (or run the BOINC server virtual machine 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
Edit httpd.conf as directed (you'll need root access to do this). Let's say your server's domain name is "a.b.c".
Visit http://a.b.c/test/create_account.php and create an account for yourself.
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 "ellipse".
A script to generate jobs
First, let's generate some jobs. We'll do this with a PHP script, html/ops/bossa_test.php: copy this from html/ops/bossa_test.php.
The first part of this script is code for generating an image; the key functions are make_test_case(), which generates a structure saying if and where there's an ellipse, and make_image(), which generates an image given this info.
Next we have
function make_job($app, $batch, $i, $config) {
// create the image file;
// store it in the download directory hierarchy
//
$jobname = "job_$batch_$i";
$case = make_test_case();
$filename = "$jobname.png";
$path = dir_hier_path(
$filename, $config->download_dir, $config->uldl_dir_fanout
);
$url = dir_hier_url(
$filename, $config->download_url, $config->uldl_dir_fanout
);
imagepng(make_image($case), $path);
$case->url = $url;
// make a job record in the Bossa database
//
$job = new BossaJob;
$job->app_id = $app->id;
$job->batch = $batch;
$job->time_estimate = 30;
$job->time_limit = 600;
$job->name = $jobname;
$job->info = json_encode($case);
if (!$job->insert()) {
echo "BossaJob::insert failed: ", mysql_error(), "\n";
exit(1);
}
}
This function creates one job. It does the following:
- Choose a name for the job, and a name for the corresponding image file.
- Decide where the file goes in the project's download hierarchy.
- Generate a random case (ellipse presence and position)
- Create the image file.
- Create a job record in the Bossa database. Assign a time estimate (in seconds) and a time limit. Store a description of the job, encoded in JSON, in the job record.
Finally we have:
function make_jobs($njobs) {
$c = get_config();
$config = null;
$config->download_dir = parse_config($c, "<download_dir>");
$config->download_url = parse_config($c, "<download_url>");
$config->uldl_dir_fanout = parse_config($c, "<uldl_dir_fanout>");
$app = BossaApp::lookup_name("Find the ellipse");
if (!$app) {
echo "Application $appname not found\n";
exit(1);
}
$batch = time();
for ($i=0; $i<$njobs; $i++) {
make_job($app, $batch, $i, $config);
}
echo "Created $njobs jobs";
}
$njobs = get_int('make_jobs', true);
if ($njobs) {
make_jobs($njobs);
} else {
header ("Content-type: image/png");
imagepng(make_image(make_test_case()));
}
make_jobs() parses the project configuration file, looks up the application in the database, and creates some jobs. You can invoke this by visiting http://a.b.c/test_ops/bossa_test.php?make_jobs=10.
Displaying jobs
Next we'll need a script that displays a job to a volunteer, and handles their response. This uses a PHP script, html/user/ellipse_display.php: copy this from html/user/bossa_example.php.
function show_job($bj, $bji) {
$info = json_decode($bj->info);
$img_url = $info.url;
echo "
<form method=get action=ellipse_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 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 "html/inc/ellipse_handler.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 ellipse_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 ellipse_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)
- bossa_test.png (3.1 KB) - added by 18 years ago.
Download all attachments as: .zip
