Get Time
long_comps_topcoder  Problem Statement
Contest: Cassini Imagery
Problem: PropellerDetector

Problem Statement



Image Credit: NASA/JPL/SSI

The Cassini spacecraft has returned thousands of images from its orbit around Saturn. Scientists have discovered giant propeller-shaped objects in the rings of Saturn. These propellers are quite unique in their shape and effect on the rings, so the scientists currently use a combination of processing and manual inspection to determine the location of these propeller objects. However, with thousands of images returned from Cassini, manually inspecting each image would take a large amount of time.

Our goal is to automate the process of identifying propeller objects in Saturn’s rings as much as possible. The propeller objects’ locations must be determined and propellers which appear in multiple images must be flagged as the same object.

The propellers travel around Saturn in a circular Keplerian orbit. These orbits are highly predictable and the future position can be predicted accurately even over long periods of time. For reasons not completely understood, the propellers also make small chaotic jumps over time. These jumps slightly change the radius of the orbit. These small chaotic jumps have a very low probability of occurring over a short time span.

Contest Format

This is a re-release of a contest that was originally done in a two-part format. Submissions and results from the previous contests is available for research related to this new round. Our primary goal this time around is to reduce false positives.


The original run of this contest had prizes for both rounds it was run, however, the re-running will not have cash prizes, but will include a collection of NASA-related swag and goodies.


There are 643 images in the complete data set that will be used for this competition. Approximately 30% of these images will be used for system testing, 20% for provisional testing, and 50% for local testing. The local test images can be downloaded here (~1GB). The images can be viewed using the NASAView program. Most images contain only 1 propeller, but some images contain as many as 5 propellers. The ground truth .csv file for the local test images can be downloaded here. The ground truth contains one line per propeller appearance with the following values, comma separated.

  1. Image - Unique string assigned to this image.
  2. Line - Propeller pixel coordinate Y.
  3. Sample - Propeller pixel coordinate X.
  4. Radius - Orbital radius with respect to Saturn.
  5. delta
  6. Longitude - Longitudinal coordinate with respect to Saturn.
  7. delta
  8. a
  9. delta
  10. b
  11. delta
  12. dx
  13. delta
  14. dy
  15. delta
  16. Nickname - Name assigned to this propeller.
a, b, dx, and dy represent size measurements estimated by the observer. The delta entries are measures of uncertainty.

For each image in the local training set, your trainingData method will be called with the current image data. The following parameters are supplied to your testingData method.

Parameters 4 through 9 can be used to convert from pixel location to space coordinates using the provided Transformer class.

  1. imageData - Decimal format image array in horizontal scan lines. Single value per pixel. Image size can be determined from the instrumentModeId parameter (see Transformer class).
  2. imageId - Unique string assigned to this image.
  3. startTime - Time the image was taken. Format: yyyy-dddTHH:mm:ss.SSS (Example: 2005-138T17:33:19.842)
  4. declination - Camera posture declination
  5. rightAscension - Camera posture right ascension
  6. twistAngle - Camera posture twist angle
  7. scPlanetPositionVector - Vector from the Cassini spacecraft to Saturn in J2000 coordinates.
  8. instrumentId - Camera instrument ID
  9. instrumentModeId - Camera operating mode ID
  10. imageGroundTruth - String array of lines from the ground truth file associated with this image. Comma separated format with same values as the supplied local ground truth .csv file.

For each image in the testing set, your testingData method will be called with the current image data. The following parameters are supplied to your testingData method.

Finally, your getAnswer method will be called. This method should return all of the identified propeller objects in order from "most sure" to "least sure". You may not return more than 10,000 objects. Each element should contain the following information in comma delimited format.

  1. ImageID – ImageID associated with image containing this object
  2. Line – Pixel coordinate Y
  3. Sample – Pixel coordinate X
  4. ObjectID - User defined ID# identifying this object (integer from 1 to 10000)

For the example test case, only the first 50 local images will be used in the testing set and the next 50 images will be used for the training. Provisional and system tests will contain propellers which do not exist at all in the local test set. The example case will be different because propellers appear in both the training and testing sets.

Scoring and Testing

Two criteria are used to determine your final score: accurately determining propeller positions and linking propellers between images. Your final score will be the sum of these two scores.

  • Position Scoring: Scored used average precision. Items closer to the front of the answer list will affect the score more than those further away. Maximum position score: 1,000,000
  • Linking Scoring: Compares and attempts to match the correctly positioned answers' ObjectID's with the ground truth nicknames. Maximum linking score: 200,000
Scoring Pseudocode:
numFound := 0
aIndex := 0
matched[] := all false
baskets[][] := all 0

for all(a in answers)
	for all(b in groundTruth)
		if(a.imageID == b.imageID AND matched[b] == false)
			if(distance from a to the center of b is less than 10 pixels)
				numFound = numFound + 1
				//Position score
				score = score + (1,000,000 / groundTruth.length) * (numFound / (aIndex + 1))
				matched[b] = true
				baskets[a.objectId][b.nickname] = baskets[a.objectId][b.nickname] + 1
	aIndex = aIndex + 1;

for all(B = 0 to baskets.length - 1)
	maxN = nickname N with maximum value of baskets[B][N]
	//Linking score
	score = score + (200,000 / groundTruth.length) * (baskets[B][maxN] - 1) * (baskets[B][maxN] - 1) / (baskets[B].length - 1)

Local Tester

A local tester has been provided for Java solutions. The tester files can be downloaded here and here. The local_ground_truth.csv, local_index.lbl, and files must be placed in the program's directory. The extracted image and label files from the local data set must also be placed in a folder "local/" in the program's directory. Your solution is placed in the PropellerDetectorLocal class file.

Current Algorithm

In this competition, you may use and modify the provided code from the current algorithm.

The Transformer class and RingSubtractor class from the current algorithm can be downloaded here with example usage.

The current feature extraction and linking algorithms can be downloaded here, here, and here. The current linking algorithm finds features in each of the images and cross correlates these features by comparing their radius, longitude, and time values.

Special Rules and Conditions

  • You are not allowed to hard code values of known objects into your code, you are expected to process the images in order to detect the propellers.
  • In order to receive the prize money, you will need to fully document your code and explain your algorithm. If any parameters were obtained from the training data set, you will also need to provide the program used to generate these parameters. There is no restriction on the programming language used to generate these training parameters. Note that all this documentation should not be submitted anywhere during the coding phase. Instead, if you win a prize, a TopCoder representative will contact you directly in order to collect this data.


Parameters:double[], String, String, double, double, double, double[], String, String, String[]
Method signature:int trainingData(double[] imageData, String imageId, String startTime, double declination, double rightAscension, double twistAngle, double[] scPlanetPositionVector, String instrumentId, String instrumentModeId, String[] imageGroundTruth)
Parameters:double[], String, String, double, double, double, double[], String, String
Method signature:int testingData(double[] imageData, String imageId, String startTime, double declination, double rightAscension, double twistAngle, double[] scPlanetPositionVector, String instrumentId, String instrumentModeId)
Method signature:String[] getAnswer()
(be sure your methods are public)


-Memory limit is 4096MB. Time limit is 60 minutes. Solutions are executed on VMs. Therefore, the amount of CPU resources may vary to some degree. The time limit is set to a large value in order to help you deal with this. Given this variability, we recommend that you design your solution so that its runtime does not exceed 45 minutes.
-There is no explicit code size limit. The implicit source code size limit is around 1 MB (it is not advisable to submit codes of size close to that or larger).
-The compilation time limit is 60 seconds. You can find information about compilers that we use, compilation options and processing server specifications here


Seed: 10

This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2010, TopCoder, Inc. All rights reserved.