public static void CreateDemoJob_OBJECT_COUNTING_IN_VIDEO() { SatyamJob job = new SatyamJob(); AzureInformation AzureInfo = new AzureInformation(); AzureInfo.AzureBlobStorageConnectionString = SatyamJobStorageAccountAccess.connection_string; AzureInfo.AzureBlobStorageContainerName = "demo"; AzureInfo.AzureBlobStorageContainerDirectoryName = "PedestrianCountingDemo"; AmazonMTurkHITInformation AmazonInfo = new AmazonMTurkHITInformation(); ObjectCountingSubmittedJob template = new ObjectCountingSubmittedJob(); template.ObjectName = "pedestrian"; template.Description = "By pedestrians we mean people walking or on wheel chairs not cyclists."; job.JobGUIDString = "OBJECT_COUNTING_IN_VIDEO_DEMO"; job.amazonHITInformation = AmazonInfo; job.azureInformation = AzureInfo; job.JobSubmitTime = DateTime.Now; job.JobTemplateType = "OBJECT_COUNTING_IN_VIDEO_DEMO"; job.UserID = TaskConstants.AdminName; job.JobParameters = JSonUtils.ConvertObjectToJSon <ObjectCountingSubmittedJob>(template); string JobParametersString = JSonUtils.ConvertObjectToJSon <SatyamJob>(job); SatyamJobSubmissionsTableAccess jobDB = new SatyamJobSubmissionsTableAccess(); jobDB.AddEntry(job.JobTemplateType, job.UserID, job.JobGUIDString, JobParametersString, job.JobSubmitTime); jobDB.close(); }
public static void PopulateTasksIntoTaskTable(SatyamJobSubmissionsTableAccessEntry job) { List <SatyamTask> tasks = generate(job); if (tasks == null) { return; } SatyamTaskTableAccess dbAccess = new SatyamTaskTableAccess(); foreach (SatyamTask task in tasks) { String JobTemplateType = job.JobTemplateType; String UserID = job.UserID; String JobGUID = job.JobGUID; String JsonString = JSonUtils.ConvertObjectToJSon <SatyamTask>(task); DateTime SubmitTime = job.JobSubmitTime; double price = task.jobEntry.amazonHITInformation.Price; dbAccess.AddEntry(JobTemplateType, UserID, JobGUID, JsonString, SubmitTime, price); } dbAccess.close(); // add the total task number to job submission table SatyamJobSubmissionsTableAccess jobDB = new SatyamJobSubmissionsTableAccess(); jobDB.UpdateEntryProgress(job.JobGUID, tasks.Count.ToString()); jobDB.close(); }
//ready to Launched status change happens by the AmazonHITTableManager //Completed tasks are removed from the TaskTable //Thus, we check if tasks are still pernding //if not tasks for a GUID are pending its deemed as complete //then save the results and chnage status to completed public static void processLaunchedJobs() { SatyamJobSubmissionsTableAccess jobDB = new SatyamJobSubmissionsTableAccess(); List <string> guidList = jobDB.getAllJobGUIDSByStatus(JobStatus.launched); List <string> readyList = jobDB.getAllJobGUIDSByStatus(JobStatus.ready); guidList.AddRange(readyList); SatyamTaskTableAccess taskDB = new SatyamTaskTableAccess(); foreach (String GUID in guidList) { if (GUID == "SINGLE_OBJECT_LABLING_DEMO") { continue; } List <int> IDList = taskDB.getAllIDsByGUID(GUID); if (IDList.Count == 0) { SatyamSaveResults.SaveByGUIDRequester(GUID); SatyamSaveResults.SaveByGUIDSatyam(GUID); SatyamSaveAggregatedResult.SaveByGUIDRequester(GUID); SatyamSaveAggregatedResult.SaveByGUIDSatyam(GUID); jobDB.UpdateEntryStatus(GUID, JobStatus.completed); } } jobDB.close(); taskDB.close(); }
public static string getJobStatus(string request) { SatyamJobSubmissionsTableAccess dbaccess = new SatyamJobSubmissionsTableAccess(); List <SatyamJobSubmissionsTableAccessEntry> entries = dbaccess.getAllEntriesByUserID(request); string JsonString = JSonUtils.ConvertObjectToJSon(entries); dbaccess.close(); return(JsonString); }
//goes through the jobDB and finds submitted jobs //uses the TaskGenerator to populate the taskTable //public static string processSubmittedJobsDebug() //{ // string debugString = "Entered the Function\n"; // SatyamJobSubmissionsTableAccess jobDB = new SatyamJobSubmissionsTableAccess(); // List<SatyamJobSubmissionsTableAccessEntry> jobEntries = jobDB.getAllEntriesByStatus(JobStatus.submitted); // debugString += "got the job entries, there are " + jobEntries.Count + "\n"; // if (jobEntries.Count == 0) // { // debugString += "No new Entries in the DB\n"; // return debugString; // } // int noEntries = 0; // foreach (SatyamJobSubmissionsTableAccessEntry entry in jobEntries) // { // debugString += "About To Populate Entry " + noEntries + "\n"; // //SatyamTaskGenerator.PopulateTasksIntoTaskTable(entry); // debugString += SatyamTaskGenerator.PopulateTasksIntoTaskTableDebug(entry); // return debugString; // if (TaskConstants.MTurkTaskTemplates.Contains(entry.JobTemplateType)) // { // jobDB.UpdateEntryStatus(entry.JobGUID, JobStatus.ready); // } // else // { // jobDB.UpdateEntryStatus(entry.JobGUID, JobStatus.launched); // } // noEntries++; // } // return debugString; //} public static void preprocessSubmittedData() { SatyamJobSubmissionsTableAccess jobDB = new SatyamJobSubmissionsTableAccess(); List <SatyamJobSubmissionsTableAccessEntry> jobEntries = jobDB.getAllEntriesByStatus(JobStatus.submitted); foreach (SatyamJobSubmissionsTableAccessEntry entry in jobEntries) { if (SatyamTaskGenerator.PreprocessSubmittedData(entry)) { jobDB.UpdateEntryStatus(entry.JobGUID, JobStatus.preprocessed); } } jobDB.close(); }
private void populateRows() { SatyamJobSubmissionsTableAccess dbaccess = new SatyamJobSubmissionsTableAccess(); List <SatyamJobSubmissionsTableAccessEntry> entries = dbaccess.getAllEntriesByUserID(UserId); dbaccess.close(); List <TableRow> rows = new List <TableRow>(); int maxShow = 10; for (int i = entries.Count - 1; i >= Math.Max(0, entries.Count - 1 - maxShow); i--) { TableRow row = new TableRow(); row.JobGUID = entries[i].JobGUID; row.JobTemplateType = entries[i].JobTemplateType; row.JobSubmitTime = entries[i].JobSubmitTime.ToLocalTime().ToString(); row.JobStatus = entries[i].JobStatus; SatyamTaskTableAccess taskDB = new SatyamTaskTableAccess(); int remainingTasks = taskDB.getTasksCountByGUID(row.JobGUID); taskDB.close(); row.TaskPending = remainingTasks.ToString(); if (entries[i].JobProgress == "") { row.JobProgress = "1"; } else { row.JobProgress = (1 - (double)remainingTasks / Convert.ToDouble(entries[i].JobProgress)).ToString("0.000"); } int totalResults, totalAggregated; row.ApprovalRate = SatyamResultsAnalysis.getPaymentRateByGUID(row.JobGUID, out totalResults, out totalAggregated).ToString("0.000"); row.TotalResults = totalResults.ToString(); row.TotalAggregated = totalAggregated.ToString(); rows.Add(row); } rpt.DataSource = rows; rpt.DataBind(); }
public static void CreateDemoJob_SINGLE_OBJECT_LABLING() { SatyamJob job = new SatyamJob(); Console.WriteLine("here 1"); AzureInformation AzureInfo = new AzureInformation(); AzureInfo.AzureBlobStorageConnectionString = SatyamJobStorageAccountAccess.connection_string; AzureInfo.AzureBlobStorageContainerName = "demo"; AzureInfo.AzureBlobStorageContainerDirectoryName = "testSingleObjectLabelingImages"; AmazonMTurkHITInformation AmazonInfo = new AmazonMTurkHITInformation(); SingleObjectLabelingSubmittedJob template = new SingleObjectLabelingSubmittedJob(); List <string> categories = new List <string>() { "Car", "Bus" }; template.Categories = categories; template.Description = "Car: Includes SUV's, Vans with upto 6 passengers, Jeeps and Pickcups. Click <a href=\"http://satyamtaskpages.azurewebsites.net/CategoryExamplesPageForDemo.aspx\"> here</a> to see examples of the various categories."; job.JobGUIDString = "SINGLE_OBJECT_LABLING_DEMO"; job.amazonHITInformation = AmazonInfo; job.azureInformation = AzureInfo; job.JobSubmitTime = DateTime.Now; job.JobTemplateType = "SINGLE_OBJECT_LABLING_DEMO"; job.UserID = TaskConstants.AdminName; job.JobParameters = JSonUtils.ConvertObjectToJSon <SingleObjectLabelingSubmittedJob>(template); string JobParametersString = JSonUtils.ConvertObjectToJSon <SatyamJob>(job); SatyamJobSubmissionsTableAccess jobDB = new SatyamJobSubmissionsTableAccess(); jobDB.AddEntry(job.JobTemplateType, job.UserID, job.JobGUIDString, JobParametersString, job.JobSubmitTime); jobDB.close(); }
public static void processPreprocessedJobs() { SatyamJobSubmissionsTableAccess jobDB = new SatyamJobSubmissionsTableAccess(); List <SatyamJobSubmissionsTableAccessEntry> jobEntries = jobDB.getAllEntriesByStatus(JobStatus.preprocessed); foreach (SatyamJobSubmissionsTableAccessEntry entry in jobEntries) { SatyamTaskGenerator.PopulateTasksIntoTaskTable(entry); if (TaskConstants.MTurkTaskTemplates.Contains(entry.JobTemplateType)) { jobDB.UpdateEntryStatus(entry.JobGUID, JobStatus.ready); } else { jobDB.UpdateEntryStatus(entry.JobGUID, JobStatus.launched); } } jobDB.close(); }
public static void CreateDemoJob_SINGLE_OBJECT_LABLING_IN_VIDEO() { SatyamJob job = new SatyamJob(); AzureInformation AzureInfo = new AzureInformation(); AzureInfo.AzureBlobStorageConnectionString = SatyamJobStorageAccountAccess.connection_string; AzureInfo.AzureBlobStorageContainerName = "demo"; AzureInfo.AzureBlobStorageContainerDirectoryName = "TestVideoClassificationMP4"; AmazonMTurkHITInformation AmazonInfo = new AmazonMTurkHITInformation(); SingleObjectLabelingSubmittedJob template = new SingleObjectLabelingSubmittedJob(); List <string> categories = new List <string>() { "Biking", "HorseRiding", "SkateBoarding" }; template.Categories = categories; template.Description = ""; job.JobGUIDString = "SINGLE_OBJECT_LABLING_IN_VIDEO_DEMO"; job.amazonHITInformation = AmazonInfo; job.azureInformation = AzureInfo; job.JobSubmitTime = DateTime.Now; job.JobTemplateType = "SINGLE_OBJECT_LABLING_IN_VIDEO_DEMO"; job.UserID = TaskConstants.AdminName; job.JobParameters = JSonUtils.ConvertObjectToJSon <SingleObjectLabelingSubmittedJob>(template); string JobParametersString = JSonUtils.ConvertObjectToJSon <SatyamJob>(job); SatyamJobSubmissionsTableAccess jobDB = new SatyamJobSubmissionsTableAccess(); jobDB.AddEntry(job.JobTemplateType, job.UserID, job.JobGUIDString, JobParametersString, job.JobSubmitTime); jobDB.close(); }
public static void CreateDemoJob_OBJECT_COUNTING_IN_IMAGE() { SatyamJob job = new SatyamJob(); Console.WriteLine("here 1"); AzureInformation AzureInfo = new AzureInformation(); AzureInfo.AzureBlobStorageConnectionString = SatyamJobStorageAccountAccess.connection_string; AzureInfo.AzureBlobStorageContainerName = "demo"; AzureInfo.AzureBlobStorageContainerDirectoryName = "catsCount"; AmazonMTurkHITInformation AmazonInfo = new AmazonMTurkHITInformation(); ObjectCountingSubmittedJob template = new ObjectCountingSubmittedJob(); template.ObjectName = "cat"; template.Description = "By cat we mean house cat and not the general category of cat family like lions or tigers."; job.JobGUIDString = "OBJECT_COUNTING_IN_IMAGE_DEMO"; job.amazonHITInformation = AmazonInfo; job.azureInformation = AzureInfo; job.JobSubmitTime = DateTime.Now; job.JobTemplateType = "OBJECT_COUNTING_IN_IMAGE_DEMO"; job.UserID = TaskConstants.AdminName; job.JobParameters = JSonUtils.ConvertObjectToJSon <ObjectCountingSubmittedJob>(template); string JobParametersString = JSonUtils.ConvertObjectToJSon <SatyamJob>(job); SatyamJobSubmissionsTableAccess jobDB = new SatyamJobSubmissionsTableAccess(); jobDB.AddEntry(job.JobTemplateType, job.UserID, job.JobGUIDString, JobParametersString, job.JobSubmitTime); jobDB.close(); }
// If the results were not good enough, or aggregation method changed, retargeted, users might want to reopen the job // All we need to do: (IN STRICT ORDER) // clear all results back to inconclusive, // remove all aggregated results // restore the task table as it was for the guid, // change the job status back to launched, and // WARNING: // for safety, this has to be run atomically synchronously, without any parallel process. for now. public static void reopenJobForMoreResults(string guid) { SatyamJobSubmissionsTableAccess jobDB = new SatyamJobSubmissionsTableAccess(); SatyamJobSubmissionsTableAccessEntry jobEntry = jobDB.getEntryByJobGIUD(guid); jobDB.close(); if (jobEntry.JobStatus != JobStatus.completed) { Console.WriteLine("Job not completed yet!"); return; } SatyamAggregatedResultsTableAccess aggResultDB = new SatyamAggregatedResultsTableAccess(); bool delSuccess = aggResultDB.DeleteEntriesByGUID(guid); aggResultDB.close(); if (!delSuccess) { Console.WriteLine("Delete Agg Result DB Failed"); return; } SatyamResultsTableAccess resultDB = new SatyamResultsTableAccess(); if (!resultDB.UpdateStatusByGUID(guid, ResultStatus.inconclusive)) { Console.WriteLine("Update Result DB Failed"); //resultDB.close(); //return; } List <SatyamResultsTableEntry> results = resultDB.getEntriesByGUID(guid); resultDB.close(); Dictionary <int, SatyamTask> taskParamsByTaskID = new Dictionary <int, SatyamTask>(); foreach (SatyamResultsTableEntry result in results) { if (taskParamsByTaskID.ContainsKey(result.SatyamTaskTableEntryID)) { continue; } SatyamResult satyamRes = JSonUtils.ConvertJSonToObject <SatyamResult>(result.ResultString); SatyamTask task = JSonUtils.ConvertJSonToObject <SatyamTask>(satyamRes.TaskParametersString); taskParamsByTaskID.Add(result.SatyamTaskTableEntryID, task); } SatyamTaskTableAccess taskDB = new SatyamTaskTableAccess(); foreach (int taskID in taskParamsByTaskID.Keys) { SatyamTask task = taskParamsByTaskID[taskID]; SatyamJob job = task.jobEntry; bool suc = taskDB.AddEntryWithSpecificID(taskID, job.JobTemplateType, job.UserID, job.JobGUIDString, JSonUtils.ConvertObjectToJSon(task), job.JobSubmitTime, job.amazonHITInformation.Price); if (!suc) { Console.WriteLine("Update Task Table Failed"); taskDB.close(); return; } } taskDB.close(); jobDB = new SatyamJobSubmissionsTableAccess(); bool success = jobDB.UpdateEntryStatus(guid, JobStatus.launched); jobDB.close(); if (!success) { Console.WriteLine("Update Job Entry Failed"); return; } }
//protected void CategoryListBox_SelectedIndexChanged(object sender, EventArgs e) //{ // SubCategoryListBox.Items.Clear(); // string selectedItem = CategoryListBox.SelectedValue; // List<string> items = subCategories[selectedItem]; // for (int i = 0; i < items.Count; i++) // { // ListItem item = new ListItem(items[i]); // SubCategoryListBox.Items.Add(item); // } //} //protected void AddSubCategoryButton_Click(object sender, EventArgs e) //{ // string category = CategoryListBox.SelectedValue; // string newSubCategory = AddSubCategoryTextBox.Text; // if (newSubCategory == "") // { // return; // } // else if (subCategories[category].Contains(newSubCategory)) // { // return; // } // ListItem item = new ListItem(newSubCategory); // SubCategoryListBox.Items.Add(item); // AddSubCategoryTextBox.Text = ""; // subCategories[category].Add(newSubCategory); // Hidden_SubCategories.Value = JSonUtils.ConvertObjectToJSon<Dictionary<String, List<String>>>(subCategories); //} //protected void DeleteSubCategoryButton_Click(object sender, EventArgs e) //{ // string category = CategoryListBox.SelectedValue; // List<ListItem> subcategoriesToBeDeleted = new List<ListItem>(); // for (int i = 0; i < SubCategoryListBox.Items.Count; i++) // { // if (SubCategoryListBox.Items[i].Selected) // { // subcategoriesToBeDeleted.Add(SubCategoryListBox.Items[i]); // } // } // for (int i = 0; i < subcategoriesToBeDeleted.Count; i++) // { // subCategories[category].Remove(subcategoriesToBeDeleted[i].Text); // SubCategoryListBox.Items.Remove(subcategoriesToBeDeleted[i]); // } // Hidden_SubCategories.Value = JSonUtils.ConvertObjectToJSon<Dictionary<String, List<String>>>(subCategories); //} protected void JobSubmitButton_Click(object sender, EventArgs e) { string AzureBlobStorageConnectionString = AzureBlobStorageConnectionStringTextBox.Text; string AzureContainer = AzureBlobStorageContainerNameTextBox.Text; string AzureContainerDirectory = AzureBlobStorageContainerDirectoryNameTextBox.Text; string AmazonAccessKeyIDValue = AmazonAccessKeyID.Text; string AmazonSecretAccessKeyIDValue = AmazonSecretAccessKeyID.Text; string Description = CategoryDescription.Text; string jobGuid = NewJobGUID.Text; string AmazonTaskTitle = AmazonTaskTitleTextBox.Text; string AmazonTaskDescription = AmazonTaskDescriptionTextBox.Text; string AmazonTaskKeywords = AmazonTaskKeywordsTextBox.Text; double pricePerObjectPerChunk = 0; int noObjectsPerChunk = 0; string FrameRate = TargetFrameRate.Text; string chunkLength = ChunkDuration.Text; string chunkOverlap = ChunkOverlap.Text; if (AzureBlobStorageConnectionString == "" || AzureContainer == "") { Template_ErrorMessageLabel.Text = "Error : Azure Connection String and Container are mandatory fields."; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } AzureConnectionInfo connectionInfo = new AzureConnectionInfo(AzureBlobStorageConnectionString, AzureContainer, AzureContainerDirectory); int noFiles = connectionInfo.getNoFiles(); if (noFiles == -1) { Template_ErrorMessageLabel.Text = "Error : Invalid Azure Location"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } else if (noFiles == 0) { Template_ErrorMessageLabel.Text = "Error : There are 0 files at the Azure Location"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } if (Hidden_MechanicalTurk.Value == "true") { AmazonMTurkHIT hit = new AmazonMTurkHIT(); bool success = hit.setAccount(AmazonAccessKeyIDValue, AmazonSecretAccessKeyIDValue, false); if (!success) { Template_ErrorMessageLabel.Text = "Error : Invalid Amazon Turk Account"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } double balance = hit.getAccountBalance(); if (balance < 0) { Template_ErrorMessageLabel.Text = "Error : Invalid Amazon Turk Account"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } if (balance < 0.1) { Template_ErrorMessageLabel.Text = "Error : Insufficient money in Amazon Turk Account"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } } if (subCategories.Count == 0) { Template_ErrorMessageLabel.Text = "Error : There are no Categories"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } List <LineSegment> BoundaryLines = new List <LineSegment>(); if (BoundaryString.Text != "") { bool error = false; string errorMessage = ""; string[] boundaryFields = BoundaryString.Text.Split(','); for (int i = 0; i < boundaryFields.Length; i++) { string[] coords = boundaryFields[i].Split('-'); if (coords.Length != 4) { errorMessage = "In Boundary String, Line No " + (i + 1) + " " + boundaryFields[i] + " : does not have 4 values."; error = true; break; } int x1, y1, x2, y2; bool success = int.TryParse(coords[0], out x1); if (!success) { errorMessage = "In Boundary String, Line No " + (i + 1) + " " + boundaryFields[i] + " : " + coords[0] + " must be an integer"; error = true; break; } success = int.TryParse(coords[1], out y1); if (!success) { errorMessage = "In Boundary String, Line No " + (i + 1) + " " + boundaryFields[i] + " : " + coords[1] + " must be an integer"; error = true; break; } success = int.TryParse(coords[2], out x2); if (!success) { errorMessage = "In Boundary String, Line No " + (i + 1) + " " + boundaryFields[i] + " : " + coords[2] + " must be an integer"; error = true; break; } success = int.TryParse(coords[3], out y2); if (!success) { errorMessage = "In Boundary String, Line No " + (i + 1) + " " + boundaryFields[i] + " : " + coords[3] + " must be an integer"; error = true; break; } LineSegment ls = new LineSegment(x1, y1, x2, y2); BoundaryLines.Add(ls); } if (error) { Template_ErrorMessageLabel.Text = errorMessage; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } } if (Hidden_MechanicalTurk.Value == "true") { bool success = Double.TryParse(PriceTextBox.Text, out pricePerObjectPerChunk); if (!success) { Template_ErrorMessageLabel.Text = "Error : Non-numerical price entered"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } pricePerObjectPerChunk = pricePerObjectPerChunk / 100; //covert to dollars success = Int32.TryParse(NoObjectsPerChunkTextBox.Text, out noObjectsPerChunk); if (!success) { Template_ErrorMessageLabel.Text = "Error : Non-numerical number of objects per image entered"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } if (pricePerObjectPerChunk <= 0.0) { Template_ErrorMessageLabel.Text = "Error : Illegal Price"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } if (noObjectsPerChunk <= 0.0) { Template_ErrorMessageLabel.Text = "Error : Illegal number of objects"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } } if (!InputFormatImage.Checked && !InputFormatVideo.Checked) { Template_ErrorMessageLabel.Text = "Error : Please select input format"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } if (Convert.ToDouble(FrameRate) <= 0) { Template_ErrorMessageLabel.Text = "Error : Invalid Target Frame Rate"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } if (Convert.ToInt32(chunkLength) <= 0) { Template_ErrorMessageLabel.Text = "Error : Invalid Chunk Duration"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } if (Convert.ToDouble(chunkOverlap) <= 0 || Convert.ToDouble(chunkOverlap) > Convert.ToInt32(chunkLength) / 2) { Template_ErrorMessageLabel.Text = "Error : Invalid Chunk Overlap, must be in (0,Chunk/2]"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } AzureInformation AzureInfo = new AzureInformation(); AzureInfo.AzureBlobStorageConnectionString = AzureBlobStorageConnectionString; AzureInfo.AzureBlobStorageContainerName = AzureContainer; AzureInfo.AzureBlobStorageContainerDirectoryName = AzureContainerDirectory; AmazonMTurkHITInformation AmazonInfo = new AmazonMTurkHITInformation(); if (Hidden_MechanicalTurk.Value == "true") { AmazonInfo.AmazonAccessKeyID = AmazonAccessKeyIDValue; AmazonInfo.AmazonSecretAccessKeyID = AmazonSecretAccessKeyIDValue; AmazonInfo.Price = Math.Floor(pricePerObjectPerChunk * (double)noObjectsPerChunk * 100) / 100; AmazonInfo.AmazonMTurkTaskTitle = AmazonTaskTitle; AmazonInfo.AmazonMTurkTaskDescription = AmazonTaskDescription; AmazonInfo.AmazonMTurkTaskKeywords = AmazonTaskKeywords; } else { AmazonInfo.AmazonAccessKeyID = ""; AmazonInfo.AmazonSecretAccessKeyID = ""; AmazonInfo.Price = 0; AmazonInfo.AmazonMTurkTaskTitle = ""; AmazonInfo.AmazonMTurkTaskDescription = ""; AmazonInfo.AmazonMTurkTaskKeywords = ""; } MultiObjectTrackingSubmittedJob jobParameters = new MultiObjectTrackingSubmittedJob(); jobParameters.Categories = subCategories; jobParameters.Description = Description; jobParameters.BoundaryLines = BoundaryLines; jobParameters.FrameRate = Convert.ToInt32(FrameRate); jobParameters.ChunkDuration = Convert.ToInt32(chunkLength); jobParameters.ChunkOverlap = Convert.ToDouble(chunkOverlap); if (InputFormatVideo.Checked) { jobParameters.DataSrcFormat = Constants.DataFormat.Video; } else if (InputFormatImage.Checked) { jobParameters.DataSrcFormat = Constants.DataFormat.VideoFrame; } SatyamJob job = new SatyamJob(); job.UserID = userName; job.amazonHITInformation = AmazonInfo; job.azureInformation = AzureInfo; job.JobGUIDString = jobGuid; if (Hidden_MechanicalTurk.Value == "true") { job.JobTemplateType = TaskConstants.Tracking_MTurk; job.TasksPerJob = 1; } else { job.JobTemplateType = TaskConstants.Tracking; job.TasksPerJob = 0; } job.JobSubmitTime = DateTime.Now; job.JobParameters = JSonUtils.ConvertObjectToJSon <MultiObjectTrackingSubmittedJob>(jobParameters); string jobDefinition = JSonUtils.ConvertObjectToJSon <SatyamJob>(job); SatyamJobSubmissionsTableAccess dbAccess = new SatyamJobSubmissionsTableAccess(); dbAccess.AddEntry(job.JobTemplateType, job.UserID, job.JobGUIDString, jobDefinition, job.JobSubmitTime); dbAccess.close(); Response.Redirect("NewJobSubmitted.aspx"); }
//public static Dictionary<string, int> getRemainingHITsFinishedTasksFromResultDB(string guid, int taskPerHIT) //{ // SatyamResultsTableAccess resultDB = new SatyamResultsTableAccess(); // List<SatyamResultsTableEntry> entries = resultDB.getEntriesByGUID(guid); // Dictionary<string, int> noResultPerHITID = new Dictionary<string, int>(); // //int noFinishedHIT = 0; // foreach (SatyamResultsTableEntry entry in entries) // { // string HITId = JSonUtils.ConvertJSonToObject<SatyamResult>(entry.ResultString).amazonInfo.HITID; // if (!noResultPerHITID.ContainsKey(HITId)) // { // noResultPerHITID.Add(HITId,1); // } // else // { // noResultPerHITID[HITId]++; // //if (noResultPerHITID[HITId] == taskPerHIT) // //{ // // noFinishedHIT++; // //} // } // } // return noResultPerHITID; //} //makes sure that there are enough HITS in Amazon to ensure that jobs will be done public static void LaunchAmazonHITsFromTaskTable(int max = int.MaxValue) { //Group them by jobguids since each job can have many tasks Dictionary <string, List <SatyamTaskTableEntry> > TasksByGUID = OrganizeMTurkTasksByGUID(); if (TasksByGUID == null) //there is nothing to do!! { return; } //after running the aggregator, the number of tasks in each guid <= no of HITS pending //so if there are less HITS pending we launch more and if there are more we leave them alone until the job is done SatyamAmazonHITTableAccess hitDB = new SatyamAmazonHITTableAccess(); SatyamJobSubmissionsTableAccess jobDB = new SatyamJobSubmissionsTableAccess(); //now check how manyy hits are pending and launch to ensure that there are enough hits in amazon foreach (KeyValuePair <string, List <SatyamTaskTableEntry> > entry in TasksByGUID) { String jobGUID = entry.Key; SatyamTask task = JSonUtils.ConvertJSonToObject <SatyamTask>(entry.Value[0].TaskParametersString); SatyamJob job = task.jobEntry; //// filter task templates -- temporary filter //if (job.JobTemplateType == TaskConstants.Segmentation_Image_MTurk) continue; string AmazonAccessKeyID = job.amazonHITInformation.AmazonAccessKeyID; string AmazonSecretAccessKeyID = job.amazonHITInformation.AmazonSecretAccessKeyID; string JobTemplateType = entry.Value[0].JobTemplateType; Dictionary <string, Object> hitParams = new Dictionary <string, object>(); hitParams.Add("Title", job.amazonHITInformation.AmazonMTurkTaskTitle); hitParams.Add("TaskDescription", job.amazonHITInformation.AmazonMTurkTaskDescription); hitParams.Add("KeyWords", job.amazonHITInformation.AmazonMTurkTaskKeywords); hitParams.Add("Reward", job.amazonHITInformation.Price); //convert cents to dollars if (TaskConstants.masterGUIDs.Contains(job.JobGUIDString)) { hitParams.Add("Masters", true); } int tasksPerHIT = job.TasksPerJob; List <SatyamAmazonHITTableAccessEntry> hitEntries = hitDB.getAllEntriesByJobGUIDAndStatus(jobGUID, HitStatus.pending); // the task will be marked as submitted when the webpage exit int noHITsRemaining = hitEntries.Count; ////////////////////////// check and deal with pending stragglers, the actual hit might have expired. //int noStragglers = 0; //foreach (SatyamAmazonHITTableAccessEntry pendingEntry in hitEntries) //{ // if ((DateTime.Now - pendingEntry.CreationTime).TotalHours > 1) // { // // the hit will be finished in 1hr if taken by a user, // // there is a higher chance that this hit have already been expired // // launch more for stragglers // noStragglers++; // } //} //noHITsRemaining -= noStragglers; /////////////////////////////// //////////////////////////////////// the query amazon way //AmazonMTurkHIT hit = new AmazonMTurkHIT(); //hit.setAccount(AmazonAccessKeyID, AmazonSecretAccessKeyID, false); ////an alternative without querying amazon ////Dictionary<string, int> noHITsFinishedTasks = getRemainingHITsFinishedTasksFromResultDB(jobGUID, tasksPerHIT); ////int noHITsRemaining = 0; //noHITsRemaining = 0; //int noPendingHITDone = 0; //foreach (SatyamAmazonHITTableAccessEntry hitEntry in hitEntries) //{ // int noTasksPending = hit.getNumTasksRemaining(hitEntry.HITID); // noHITsRemaining += noTasksPending; // //an alternative without querying amazon // //if (noHITsFinishedTasks.ContainsKey(hitEntry.HITID) && noHITsFinishedTasks[hitEntry.HITID] == tasksPerHIT) // //{ // // //HIT done // // noPendingHITDone++; // //} //} ////int noHITsRemainingFromResultDB = hitEntries.Count - noPendingHITDone; ////Console.WriteLine("Job {0}, HITS Remaining/fromDB/Pending/noTasks: {1}/{2}/{3}", //// jobGUID, noHITsRemaining, noHITsRemainingFromResultDB, hitEntries.Count, TasksByGUID[jobGUID].Count); ////if (noHITsRemainingFromResultDB!= noHITsRemaining) ////{ //// // not gonna work, what is the hit has less tasks than tasksPerHIT?? //// Console.WriteLine("Database method is wrong"); ////} ///////////////////////////////////////////////////////// int NoParallelTurker = 3; // too large will make the task stale on AMT, too small will hurt latency int difference = (int)Math.Ceiling((double)(TasksByGUID[jobGUID].Count * NoParallelTurker - noHITsRemaining * tasksPerHIT) / (double)tasksPerHIT); //int difference = 50; //difference *= 2; // boost for parallelism //difference = 10; //difference = Math.Min(difference, max) * NoParallelTurker; if (difference > 0) { AmazonMTurkHITBatchLauncher hitLauncher = new AmazonMTurkHITBatchLauncher(AmazonAccessKeyID, AmazonSecretAccessKeyID); string url = TaskConstants.JobTemplateTypeToTaskURI[JobTemplateType]; double reward = job.amazonHITInformation.Price; url = url + "?reward=" + reward; List <string> hitIDs = null; string hitParametersString = JSonUtils.ConvertObjectToJSon <Dictionary <string, object> >(hitParams); hitLauncher.LaunchBatches(url, hitParams, difference, out hitIDs); if (hitIDs != null) { foreach (string hitID in hitIDs) { hitDB.AddEntry(JobTemplateType, job.UserID, hitID, job.JobGUIDString, DateTime.Now, hitParametersString, AmazonAccessKeyID, AmazonSecretAccessKeyID); } jobDB.UpdateEntryStatus(entry.Key, JobStatus.launched); } } } jobDB.close(); hitDB.close(); }
protected void JobSubmitButton_Click(object sender, EventArgs e) { string AzureBlobStorageConnectionString = AzureBlobStorageConnectionStringTextBox.Text; string AzureContainer = AzureBlobStorageContainerNameTextBox.Text; string AzureContainerDirectory = AzureBlobStorageContainerDirectoryNameTextBox.Text; string AmazonAccessKeyIDValue = AmazonAccessKeyID.Text; string AmazonSecretAccessKeyIDValue = AmazonSecretAccessKeyID.Text; string Description = CategoryDescription.Text; string jobGuid = NewJobGUID.Text; string AmazonTaskTitle = AmazonTaskTitleTextBox.Text; string AmazonTaskDescription = AmazonTaskDescriptionTextBox.Text; string AmazonTaskKeywords = AmazonTaskKeywordsTextBox.Text; double pricePerObject = 0; //default int numObjectPerImage = 0; //default double price = 0; //default int tasksPerHIT = 1; //defuault if (AzureBlobStorageConnectionString == "" || AzureContainer == "") { Template_ErrorMessageLabel.Text = "Error : Azure Connection String and Container are mandatory fields."; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } AzureConnectionInfo connectionInfo = new AzureConnectionInfo(AzureBlobStorageConnectionString, AzureContainer, AzureContainerDirectory); int noFiles = connectionInfo.getNoFiles(); if (noFiles == -1) { Template_ErrorMessageLabel.Text = "Error : Invalid Azure Location"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } else if (noFiles == 0) { Template_ErrorMessageLabel.Text = "Error : There are 0 files at the Azure Location"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } if (Hidden_MechanicalTurk.Value == "true") { AmazonMTurkHIT hit = new AmazonMTurkHIT(); bool success = hit.setAccount(AmazonAccessKeyIDValue, AmazonSecretAccessKeyIDValue, false); if (!success) { Template_ErrorMessageLabel.Text = "Error : Invalid Amazon Turk Account"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } double balance = hit.getAccountBalance(); if (balance < 0) { Template_ErrorMessageLabel.Text = "Error : Invalid Amazon Turk Account"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } if (balance < 0.1) { Template_ErrorMessageLabel.Text = "Error : Insufficient money in Amazon Turk Account"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } } if (categories.Count == 0) { Template_ErrorMessageLabel.Text = "Error : There are no Categories"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } List <LineSegment> BoundaryLines = new List <LineSegment>(); if (BoundaryTextBox.Text != "") { bool error = false; string errorMessage = ""; string[] boundaryFields = BoundaryTextBox.Text.Split(','); for (int i = 0; i < boundaryFields.Length; i++) { string[] coords = boundaryFields[i].Split('-'); if (coords.Length != 4) { errorMessage = "In Boundary String, Line No " + (i + 1) + " " + boundaryFields[i] + " : does not have 4 values."; error = true; break; } int x1, y1, x2, y2; bool success = int.TryParse(coords[0], out x1); if (!success) { errorMessage = "In Boundary String, Line No " + (i + 1) + " " + boundaryFields[i] + " : " + coords[0] + " must be an integer"; error = true; break; } success = int.TryParse(coords[1], out y1); if (!success) { errorMessage = "In Boundary String, Line No " + (i + 1) + " " + boundaryFields[i] + " : " + coords[1] + " must be an integer"; error = true; break; } success = int.TryParse(coords[2], out x2); if (!success) { errorMessage = "In Boundary String, Line No " + (i + 1) + " " + boundaryFields[i] + " : " + coords[2] + " must be an integer"; error = true; break; } success = int.TryParse(coords[3], out y2); if (!success) { errorMessage = "In Boundary String, Line No " + (i + 1) + " " + boundaryFields[i] + " : " + coords[3] + " must be an integer"; error = true; break; } LineSegment ls = new LineSegment(x1, y1, x2, y2); BoundaryLines.Add(ls); } if (error) { Template_ErrorMessageLabel.Text = errorMessage; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } } if (Hidden_MechanicalTurk.Value == "true") { bool success = Double.TryParse(PriceTextBox.Text, out pricePerObject); if (!success) { Template_ErrorMessageLabel.Text = "Error : Non-numerical price entered"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } pricePerObject = pricePerObject / 100; //covert to dollars success = Int32.TryParse(NoObjectsPerImageTextBox.Text, out numObjectPerImage); if (!success) { Template_ErrorMessageLabel.Text = "Error : Non-numerical number of objects per image entered"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } price = pricePerObject * numObjectPerImage; if (price <= 0.0) { Template_ErrorMessageLabel.Text = "Error : The Price is Zero"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } //need to round to cents price = Math.Floor(price * 100) / 100; AmazonMTurkHIT hit = new AmazonMTurkHIT(); success = hit.setAccount(AmazonAccessKeyIDValue, AmazonSecretAccessKeyIDValue, false); if (!success) { Template_ErrorMessageLabel.Text = "Error : Invalid Amazon Turk Account"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } double balance = hit.getAccountBalance(); if (balance < 0) { Template_ErrorMessageLabel.Text = "Error : Invalid Amazon Turk Account"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } double moneyNeeded = 4 * price * noFiles / tasksPerHIT; if (balance < moneyNeeded) { Template_ErrorMessageLabel.Text = "Error : Insufficient money in Amazon Turk Account, you will need atleast " + moneyNeeded + "$."; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } if (AmazonTaskTitle == "") { Template_ErrorMessageLabel.Text = "Image Segmentation"; } if (AmazonTaskTitle == "") { Template_ErrorMessageLabel.Text = "Earn money quickly by drawing polygons around objects of interest in an image!"; } if (AmazonTaskKeywords == "Image Segmentation") { Template_ErrorMessageLabel.Text = ""; } } AzureInformation AzureInfo = new AzureInformation(); AzureInfo.AzureBlobStorageConnectionString = AzureBlobStorageConnectionString; AzureInfo.AzureBlobStorageContainerName = AzureContainer; AzureInfo.AzureBlobStorageContainerDirectoryName = AzureContainerDirectory; AmazonMTurkHITInformation AmazonInfo = new AmazonMTurkHITInformation(); if (Hidden_MechanicalTurk.Value == "true") { AmazonInfo.AmazonAccessKeyID = AmazonAccessKeyIDValue; AmazonInfo.AmazonSecretAccessKeyID = AmazonSecretAccessKeyIDValue; AmazonInfo.Price = price; AmazonInfo.AmazonMTurkTaskTitle = AmazonTaskTitle; AmazonInfo.AmazonMTurkTaskDescription = AmazonTaskDescription; AmazonInfo.AmazonMTurkTaskKeywords = AmazonTaskKeywords; } else { AmazonInfo.AmazonAccessKeyID = ""; AmazonInfo.AmazonSecretAccessKeyID = ""; AmazonInfo.Price = 0; AmazonInfo.AmazonMTurkTaskTitle = ""; AmazonInfo.AmazonMTurkTaskDescription = ""; AmazonInfo.AmazonMTurkTaskKeywords = ""; } ImageSegmentationSubmittedJob jobParameters = new ImageSegmentationSubmittedJob(); jobParameters.Categories = categories; jobParameters.Description = Description; jobParameters.BoundaryLines = BoundaryLines; SatyamJob job = new SatyamJob(); job.UserID = userName; job.amazonHITInformation = AmazonInfo; job.azureInformation = AzureInfo; job.JobGUIDString = jobGuid; if (Hidden_MechanicalTurk.Value == "true") { job.JobTemplateType = TaskConstants.Segmentation_Image_MTurk; job.TasksPerJob = tasksPerHIT; } else { job.JobTemplateType = TaskConstants.Segmentation_Image; job.TasksPerJob = 0; } job.JobSubmitTime = DateTime.Now; job.JobParameters = JSonUtils.ConvertObjectToJSon <ImageSegmentationSubmittedJob>(jobParameters); string jobDefinition = JSonUtils.ConvertObjectToJSon <SatyamJob>(job); SatyamJobSubmissionsTableAccess dbAccess = new SatyamJobSubmissionsTableAccess(); dbAccess.AddEntry(job.JobTemplateType, job.UserID, job.JobGUIDString, jobDefinition, job.JobSubmitTime); dbAccess.close(); Response.Redirect("NewJobSubmitted.aspx"); }
protected void Object_Counting_JobSubmitButton_Click(object sender, EventArgs e) { string AzureBlobStorageConnectionString = AzureBlobStorageConnectionStringTextBox.Text; string AzureContainer = AzureBlobStorageContainerNameTextBox.Text; string AzureContainerDirectory = AzureBlobStorageContainerDirectoryNameTextBox.Text; string AmazonAccessKeyIDValue = AmazonAccessKeyID.Text; string AmazonSecretAccessKeyIDValue = AmazonSecretAccessKeyID.Text; string Description = CategoryDescription.Text; double pricePerImage = 0; double price = 0; string jobGuid = NewJobGUID.Text; string AmazonTaskTitle = AmazonTaskTitleTextBox.Text; string AmazonTaskDescription = AmazonTaskDescriptionTextBox.Text; string AmazonTaskKeywords = AmazonTaskKeywordsTextBox.Text; if (AzureBlobStorageConnectionString == "" || AzureContainer == "") { Template_ErrorMessageLabel.Text = "Error : Azure Connection String and Container are mandatory fields."; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } AzureConnectionInfo connectionInfo = new AzureConnectionInfo(AzureBlobStorageConnectionString, AzureContainer, AzureContainerDirectory); int noFiles = connectionInfo.getNoFiles(); if (noFiles == -1) { Template_ErrorMessageLabel.Text = "Error : Invalid Azure Location"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } else if (noFiles == 0) { Template_ErrorMessageLabel.Text = "Error : There are 0 files at the Azure Location"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } if (Hidden_MechanicalTurk.Value == "true") { bool success = Double.TryParse(PriceTextBox.Text, out pricePerImage); if (!success) { Template_ErrorMessageLabel.Text = "Error : Non-numerical price entered"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } pricePerImage = pricePerImage / 100; //convert to dollars price = pricePerImage * TaskConstants.OBJECT_COUNTING_MTURK_MAX_IMAGES_PER_TASK; //need to round to cents price = Math.Floor(price * 100) / 100; if (price <= 0.0) { Template_ErrorMessageLabel.Text = "Error : The Price is Zero"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } AmazonMTurkHIT hit = new AmazonMTurkHIT(); success = hit.setAccount(AmazonAccessKeyIDValue, AmazonSecretAccessKeyIDValue, false); if (!success) { Template_ErrorMessageLabel.Text = "Error : Invalid Amazon Turk Account"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } double balance = hit.getAccountBalance(); if (balance < 0) { Template_ErrorMessageLabel.Text = "Error : Invalid Amazon Turk Account"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } double moneyNeeded = 4 * price * noFiles / TaskConstants.OBJECT_COUNTING_MTURK_MAX_IMAGES_PER_TASK; if (balance < moneyNeeded) { Template_ErrorMessageLabel.Text = "Error : Insufficient money in Amazon Turk Account. You will need at least " + moneyNeeded + "$."; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } if (AmazonTaskTitle == "") { Template_ErrorMessageLabel.Text = "Counting Objects in an Image"; } if (AmazonTaskTitle == "") { Template_ErrorMessageLabel.Text = "Earn money quickly by simply counting the number of objects of interest in an image!"; } if (AmazonTaskKeywords == "Object Counting") { Template_ErrorMessageLabel.Text = ""; } } string objectName = ObjectNameTextBox.Text; if (objectName == "") { Template_ErrorMessageLabel.Text = "Error : No Object Name Entered"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } AzureInformation AzureInfo = new AzureInformation(); AzureInfo.AzureBlobStorageConnectionString = AzureBlobStorageConnectionString; AzureInfo.AzureBlobStorageContainerName = AzureContainer; AzureInfo.AzureBlobStorageContainerDirectoryName = AzureContainerDirectory; AmazonMTurkHITInformation AmazonInfo = new AmazonMTurkHITInformation(); if (Hidden_MechanicalTurk.Value == "true") { AmazonInfo.AmazonAccessKeyID = AmazonAccessKeyIDValue; AmazonInfo.AmazonSecretAccessKeyID = AmazonSecretAccessKeyIDValue; AmazonInfo.Price = price; //in dollars AmazonInfo.AmazonMTurkTaskTitle = AmazonTaskTitle; AmazonInfo.AmazonMTurkTaskDescription = AmazonTaskDescription; AmazonInfo.AmazonMTurkTaskKeywords = AmazonTaskKeywords; } else { AmazonInfo.AmazonAccessKeyID = ""; AmazonInfo.AmazonSecretAccessKeyID = ""; AmazonInfo.Price = 0; AmazonInfo.AmazonMTurkTaskTitle = ""; AmazonInfo.AmazonMTurkTaskDescription = ""; AmazonInfo.AmazonMTurkTaskKeywords = ""; } ObjectCountingSubmittedJob jobParameters = new ObjectCountingSubmittedJob(); jobParameters.ObjectName = objectName; jobParameters.Description = Description; SatyamJob job = new SatyamJob(); job.UserID = userName; job.amazonHITInformation = AmazonInfo; job.azureInformation = AzureInfo; job.JobGUIDString = jobGuid; if (Hidden_MechanicalTurk.Value == "true") { job.JobTemplateType = TaskConstants.Counting_Image_MTurk; job.TasksPerJob = TaskConstants.OBJECT_COUNTING_MTURK_MAX_IMAGES_PER_TASK; } else { job.JobTemplateType = TaskConstants.Counting_Image; job.TasksPerJob = 0; } job.JobSubmitTime = DateTime.Now; job.JobParameters = JSonUtils.ConvertObjectToJSon <ObjectCountingSubmittedJob>(jobParameters); if (Hidden_AdaptivePricing.Value == "true") { job.AdaptivePricing = true; bool success = Double.TryParse(TargetPricePerHourTextBox.Text, out job.TargetPricePerTask); if (!success) { job.TargetPricePerTask = 13.56; // default for now } success = Double.TryParse(BudgetTextBox.Text, out job.TotalBudget); if (!success) { job.TotalBudget = -1; //default } } else { job.AdaptivePricing = false; job.TargetPricePerTask = -1; job.TotalBudget = -1; } string jobDefinition = JSonUtils.ConvertObjectToJSon <SatyamJob>(job); SatyamJobSubmissionsTableAccess dbAccess = new SatyamJobSubmissionsTableAccess(); dbAccess.AddEntry(job.JobTemplateType, job.UserID, job.JobGUIDString, jobDefinition, job.JobSubmitTime); dbAccess.close(); Response.Redirect("NewJobSubmitted.aspx"); }
//go through all the inconclusive results and aggregate them if they are not aggregated already public static void AggregateResults() { //first get all the results that are not aggregated SatyamResultsTableAccess resultsDB = new SatyamResultsTableAccess(); List <SatyamResultsTableEntry> results = resultsDB.getEntriesByStatus(ResultStatus.inconclusive); if (results.Count == 0) //there is nothing to do { resultsDB.close(); return; } //first group all the results by the tasks since wach task may have multiple entries Dictionary <int, List <SatyamResultsTableEntry> > collectedResults = new Dictionary <int, List <SatyamResultsTableEntry> >(); List <string> pendingGUID = new List <string>(); foreach (SatyamResultsTableEntry entry in results) { int taskID = entry.SatyamTaskTableEntryID; if (!collectedResults.ContainsKey(taskID)) { collectedResults.Add(taskID, new List <SatyamResultsTableEntry>()); } collectedResults[taskID].Add(entry); if (!pendingGUID.Contains(entry.JobGUID)) { pendingGUID.Add(entry.JobGUID); } } List <int> taskIDList = collectedResults.Keys.ToList(); taskIDList.Sort(); //check if guid is still pending SatyamJobSubmissionsTableAccess jobDB = new SatyamJobSubmissionsTableAccess(); List <string> completedGUIDs = jobDB.getAllJobGUIDSByStatus(JobStatus.completed); jobDB.close(); //check if this taskID has already been aggregated and exists int he aggregationDB Dictionary <string, Dictionary <int, SatyamAggregatedResultsTableEntry> > ExistingAggEntriesPerTaskPerGUID = SatyamAggregatedResultManagement.getAggregatedEntriesPerTaskByGuidList(pendingGUID); Console.WriteLine("Aggregating {0} Tasks", taskIDList.Count); List <SatyamAggregatedResultsTableEntry> aggEntries = new List <SatyamAggregatedResultsTableEntry>(); //foreach (int taskId in taskIDList) for (int i = 0; i < taskIDList.Count; i++) { //int taskId = taskIDList[taskIDList.Count - i - 1]; int taskId = taskIDList[i]; string guid = collectedResults[taskId][0].JobGUID; if (completedGUIDs.Contains(guid)) { // Hit Completed, mark results outdated. resultsDB.UpdateStatusByTaskID(taskId, ResultStatus.outdated); continue; } //SatyamAggregatedResultsTableAccess aggDB = new SatyamAggregatedResultsTableAccess(); //int LatestResultsAggregated = aggDB.getLatestNoResultsAggregatedByTaskID(taskId); //aggDB.close(); if (ExistingAggEntriesPerTaskPerGUID.ContainsKey(guid) && ExistingAggEntriesPerTaskPerGUID[guid].ContainsKey(taskId)) { continue; //int MinResults = TaskConstants.getMinResultsByTemplate(ExistingAggEntriesPerTaskPerGUID[guid][taskId].JobTemplateType); //if (LatestResultsAggregated >= MinResults) //{ // continue; //} // already aggregated to MinResult Request, but leftover results will be judged. So do nothing } //if it does not exist only then aggregate Console.WriteLine("Task Type: {2}({3}), Task ID: {0}, # of Results: {1}", taskId, collectedResults[taskId].Count, collectedResults[taskId][0].JobTemplateType, collectedResults[taskId][0].JobGUID); //if (collectedResults[taskId].Count != LatestResultsAggregated) //{ SatyamAggregatedResultsTableEntry aggEntry = ResultsTableAggregator.GetAggregatedResultString(taskId, collectedResults[taskId]); if (aggEntry != null) { //aggEntries.Add(aggEntry); SatyamAggregatedResultsTableAccess aggDB = new SatyamAggregatedResultsTableAccess(); aggDB.AddEntry(aggEntry, collectedResults[taskId].Count); aggDB.close(); } //} //else //{ // Console.WriteLine("No New Results"); //} } resultsDB.close(); }
public static void CreateDemoJob_MULTI_OBJECT_LOCALIZATION_AND_LABLING() { //first Job SatyamJob job = new SatyamJob(); AzureInformation AzureInfo = new AzureInformation(); AzureInfo.AzureBlobStorageConnectionString = SatyamJobStorageAccountAccess.connection_string; AzureInfo.AzureBlobStorageContainerName = "demo"; AzureInfo.AzureBlobStorageContainerDirectoryName = "catsAndDogs"; AmazonMTurkHITInformation AmazonInfo = new AmazonMTurkHITInformation(); MultiObjectLocalizationAndLabelingSubmittedJob template = new MultiObjectLocalizationAndLabelingSubmittedJob(); List <string> categories = new List <string>() { "Cat", "Dog" }; template.Categories = categories; template.Description = ""; template.BoundaryLines = new List <LineSegment>(); job.JobGUIDString = "MULTI_OBJECT_LOCALIZATION_AND_LABLING_DEMO"; job.amazonHITInformation = AmazonInfo; job.azureInformation = AzureInfo; job.JobSubmitTime = DateTime.Now; job.JobTemplateType = "MULTI_OBJECT_LOCALIZATION_AND_LABLING_DEMO"; job.UserID = TaskConstants.AdminName; job.JobParameters = JSonUtils.ConvertObjectToJSon <MultiObjectLocalizationAndLabelingSubmittedJob>(template); string JobParametersString = JSonUtils.ConvertObjectToJSon <SatyamJob>(job); SatyamJobSubmissionsTableAccess jobDB = new SatyamJobSubmissionsTableAccess(); jobDB.AddEntry(job.JobTemplateType, job.UserID, job.JobGUIDString, JobParametersString, job.JobSubmitTime); //second job SatyamJob job1 = new SatyamJob(); AzureInformation AzureInfo1 = new AzureInformation(); AzureInfo1.AzureBlobStorageConnectionString = SatyamJobStorageAccountAccess.connection_string; AzureInfo1.AzureBlobStorageContainerName = "demo"; AzureInfo1.AzureBlobStorageContainerDirectoryName = "TrafficExample-EastGate"; AmazonMTurkHITInformation AmazonInfo1 = new AmazonMTurkHITInformation(); MultiObjectLocalizationAndLabelingSubmittedJob template1 = new MultiObjectLocalizationAndLabelingSubmittedJob(); List <string> categories1 = new List <string>() { "Vehicle", "Person" }; template1.Categories = categories1; template1.Description = "Vehicles can be buses, cars, trucks, motorbikes but not bi-cylces or wheelchairs. Person can be pedestrian or a cylist."; template1.BoundaryLines = new List <LineSegment>(); template1.BoundaryLines.Add(new LineSegment(1, 489, 291, 191)); template1.BoundaryLines.Add(new LineSegment(291, 191, 435, 103)); template1.BoundaryLines.Add(new LineSegment(435, 103, 664, 68)); template1.BoundaryLines.Add(new LineSegment(664, 68, 883, 127)); template1.BoundaryLines.Add(new LineSegment(883, 127, 915, 205)); template1.BoundaryLines.Add(new LineSegment(915, 205, 1276, 497)); template1.BoundaryLines.Add(new LineSegment(1276, 497, 1276, 694)); template1.BoundaryLines.Add(new LineSegment(1276, 694, 1, 696)); template1.BoundaryLines.Add(new LineSegment(1, 696, 1, 489)); job1.JobGUIDString = "MULTI_OBJECT_LOCALIZATION_AND_LABLING_DEMO"; job1.amazonHITInformation = AmazonInfo1; job1.azureInformation = AzureInfo1; job1.JobSubmitTime = DateTime.Now; job1.JobTemplateType = "MULTI_OBJECT_LOCALIZATION_AND_LABLING_DEMO"; job1.UserID = TaskConstants.AdminName; job1.JobParameters = JSonUtils.ConvertObjectToJSon <MultiObjectLocalizationAndLabelingSubmittedJob>(template1); string JobParametersString1 = JSonUtils.ConvertObjectToJSon <SatyamJob>(job1); jobDB.AddEntry(job1.JobTemplateType, job1.UserID, job1.JobGUIDString, JobParametersString1, job1.JobSubmitTime); jobDB.close(); }
protected void JobSubmitButton_Click(object sender, EventArgs e) { string AzureBlobStorageConnectionString = AzureBlobStorageConnectionStringTextBox.Text; string AzureContainer = AzureBlobStorageContainerNameTextBox.Text; string AzureContainerDirectory = AzureBlobStorageContainerDirectoryNameTextBox.Text; string AmazonAccessKeyIDValue = AmazonAccessKeyID.Text; string AmazonSecretAccessKeyIDValue = AmazonSecretAccessKeyID.Text; string Description = CategoryDescription.Text; double pricePerImage = 0; double price = 0; string jobGuid = NewJobGUID.Text; string AmazonTaskTitle = AmazonTaskTitleTextBox.Text; string AmazonTaskDescription = AmazonTaskDescriptionTextBox.Text; string AmazonTaskKeywords = AmazonTaskKeywordsTextBox.Text; if (AzureBlobStorageConnectionString == "" || AzureContainer == "") { Template_ErrorMessageLabel.Text = "Error : Azure Connection String and Container are mandatory fields."; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } AzureConnectionInfo connectionInfo = new AzureConnectionInfo(AzureBlobStorageConnectionString, AzureContainer, AzureContainerDirectory); int noFiles = connectionInfo.getNoFiles(); if (noFiles == -1) { Template_ErrorMessageLabel.Text = "Error : Invalid Azure Location"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } else if (noFiles == 0) { Template_ErrorMessageLabel.Text = "Error : There are 0 files at the Azure Location"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } if (Hidden_MechanicalTurk.Value == "true") { bool success = Double.TryParse(PriceTextBox.Text, out pricePerImage); if (!success) { Template_ErrorMessageLabel.Text = "Error : Non-numerical price entered"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } pricePerImage = pricePerImage / 100; //convert to dollars price = pricePerImage; //need to round to cents price = Math.Floor(price * 100) / 100; if (price <= 0) { Template_ErrorMessageLabel.Text = "Error : The Price is Zero"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } AmazonMTurkHIT hit = new AmazonMTurkHIT(); success = hit.setAccount(AmazonAccessKeyIDValue, AmazonSecretAccessKeyIDValue, false); if (!success) { Template_ErrorMessageLabel.Text = "Error : Invalid Amazon Turk Account"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } double balance = hit.getAccountBalance(); if (balance < 0) { Template_ErrorMessageLabel.Text = "Error : Invalid Amazon Turk Account"; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } double moneyNeeded = 4 * price * noFiles / TaskConstants.SINGLE_OBJECT_LABLING_MTURK_MAX_IMAGES_PER_TASK; if (balance < moneyNeeded) { Template_ErrorMessageLabel.Text = "Error : Insufficient money in Amazon Turk Account. You will need at least " + moneyNeeded + "$."; Template_ErrorMessageLabel.ForeColor = System.Drawing.Color.Red; Template_ErrorMessageLabel.Font.Bold = true; return; } if (AmazonTaskTitle == "") { Template_ErrorMessageLabel.Text = "Image Classification Task"; } if (AmazonTaskTitle == "") { Template_ErrorMessageLabel.Text = "Quickly earn money by simply selecting what an image looks like!"; } if (AmazonTaskKeywords == "Pictures, Classify, Categorize") { Template_ErrorMessageLabel.Text = ""; } } AzureInformation AzureInfo = new AzureInformation(); AzureInfo.AzureBlobStorageConnectionString = AzureBlobStorageConnectionString; AzureInfo.AzureBlobStorageContainerName = AzureContainer; AzureInfo.AzureBlobStorageContainerDirectoryName = AzureContainerDirectory; AmazonMTurkHITInformation AmazonInfo = new AmazonMTurkHITInformation(); if (Hidden_MechanicalTurk.Value == "true") { AmazonInfo.AmazonAccessKeyID = AmazonAccessKeyIDValue; AmazonInfo.AmazonSecretAccessKeyID = AmazonSecretAccessKeyIDValue; AmazonInfo.Price = price; //in dollars AmazonInfo.AmazonMTurkTaskTitle = AmazonTaskTitle; AmazonInfo.AmazonMTurkTaskDescription = AmazonTaskDescription; AmazonInfo.AmazonMTurkTaskKeywords = AmazonTaskKeywords; } else { AmazonInfo.AmazonAccessKeyID = ""; AmazonInfo.AmazonSecretAccessKeyID = ""; AmazonInfo.Price = 0; AmazonInfo.AmazonMTurkTaskTitle = ""; AmazonInfo.AmazonMTurkTaskDescription = ""; AmazonInfo.AmazonMTurkTaskKeywords = ""; } SingleObjectLabelingSubmittedJob jobParameters = new SingleObjectLabelingSubmittedJob(); jobParameters.Description = Description; SatyamJob job = new SatyamJob(); job.UserID = userName; job.amazonHITInformation = AmazonInfo; job.azureInformation = AzureInfo; job.JobGUIDString = jobGuid; if (Hidden_MechanicalTurk.Value == "true") { job.JobTemplateType = TaskConstants.CameraPoseEsitmation_MTurk; job.TasksPerJob = 1; } else { job.JobTemplateType = TaskConstants.CameraPoseEsitmation; job.TasksPerJob = 0; //does not matter } job.JobSubmitTime = DateTime.Now; job.JobParameters = JSonUtils.ConvertObjectToJSon <SingleObjectLabelingSubmittedJob>(jobParameters); string jobDefinition = JSonUtils.ConvertObjectToJSon <SatyamJob>(job); SatyamJobSubmissionsTableAccess dbAccess = new SatyamJobSubmissionsTableAccess(); dbAccess.AddEntry(job.JobTemplateType, job.UserID, job.JobGUIDString, jobDefinition, job.JobSubmitTime); dbAccess.close(); Response.Redirect("NewJobSubmitted.aspx"); }
public static void Run([TimerTrigger("0 */5 * * * *")] TimerInfo myTimer, TraceWriter log) { DateTime start = DateTime.Now; bool logging = false; if (logging) { log.Info($"Aggregation Dispatch executed at: {DateTime.Now}"); } //first get all the results that are not aggregated SatyamResultsTableAccess resultsDB = new SatyamResultsTableAccess(); List <SatyamResultsTableEntry> results = resultsDB.getEntriesByStatus(ResultStatus.inconclusive); resultsDB.close(); if (results.Count == 0) //there is nothing to do { return; } //first group all the results by the guids, and then by tasks since wach task may have multiple entries // organize by guid, so when polling, each guid will get a chance. SortedDictionary <string, SortedDictionary <int, List <SatyamResultsTableEntry> > > ResultsByGUID = new SortedDictionary <string, SortedDictionary <int, List <SatyamResultsTableEntry> > >(); List <string> pendingGUID = new List <string>(); foreach (SatyamResultsTableEntry entry in results) { string guid = entry.JobGUID; if (!ResultsByGUID.ContainsKey(guid)) { ResultsByGUID.Add(guid, new SortedDictionary <int, List <SatyamResultsTableEntry> >()); } int taskID = entry.SatyamTaskTableEntryID; if (!ResultsByGUID[guid].ContainsKey(taskID)) { ResultsByGUID[guid].Add(taskID, new List <SatyamResultsTableEntry>()); } ResultsByGUID[guid][taskID].Add(entry); if (!pendingGUID.Contains(entry.JobGUID)) { pendingGUID.Add(entry.JobGUID); } } List <string> guidList = ResultsByGUID.Keys.ToList(); if (logging) { log.Info($"Aggregation Dispatch: Results Collected at: {DateTime.Now}"); } //check if guid is still pending SatyamJobSubmissionsTableAccess jobDB = new SatyamJobSubmissionsTableAccess(); List <string> completedGUIDs = jobDB.getAllJobGUIDSByStatus(JobStatus.completed); jobDB.close(); //check if this taskID has already been aggregated and exists int he aggregationDB Dictionary <string, Dictionary <int, SatyamAggregatedResultsTableEntry> > ExistingAggEntriesPerTaskPerGUID = SatyamAggregatedResultManagement.getAggregatedEntriesPerTaskByGuidList(pendingGUID); //Console.WriteLine("Aggregating {0} Tasks", taskIDList.Count); List <SatyamAggregatedResultsTableEntry> aggEntries = new List <SatyamAggregatedResultsTableEntry>(); SatyamDispatchStorageAccountAccess satyamQueue = new SatyamDispatchStorageAccountAccess(); int i = -1; int count = 0; while (true) { i++; bool Done = true; for (int j = 0; j < guidList.Count; j++) { string guid = guidList[j]; List <int> taskIDList = ResultsByGUID[guid].Keys.ToList(); if (taskIDList.Count <= i) { continue; } Done = false; int taskId = taskIDList[i]; if (completedGUIDs.Contains(guid)) { // Hit Completed, mark results outdated. resultsDB = new SatyamResultsTableAccess(); resultsDB.UpdateStatusByTaskID(taskId, ResultStatus.outdated); resultsDB.close(); continue; } //SatyamAggregatedResultsTableAccess aggDB = new SatyamAggregatedResultsTableAccess(); //int LatestResultsAggregated = aggDB.getLatestNoResultsAggregatedByTaskID(taskId); //aggDB.close(); if (ExistingAggEntriesPerTaskPerGUID.ContainsKey(guid) && ExistingAggEntriesPerTaskPerGUID[guid].ContainsKey(taskId)) { continue; //int MinResults = TaskConstants.getMinResultsByTemplate(ExistingAggEntriesPerTaskPerGUID[guid][taskId].JobTemplateType); //if (LatestResultsAggregated >= MinResults) //{ // continue; //} // already aggregated to MinResult request, but leftover results will be judged. So do nothing } //if it does not exist only then aggregate if (logging) { log.Info($"{(DateTime.Now - start).TotalSeconds} Dispatching aggregation for guid {guid} task {taskId}"); } string queueName = "aggregation"; string m = guid + "_" + taskId; satyamQueue.Enqueue(queueName, m); count++; } if (Done) { break; } // emergency break if ((DateTime.Now - start).TotalSeconds > 280) { break; } } if (logging) { log.Info($"Aggregation Dispatch finished at: {DateTime.Now}, dispatched {count} aggregations"); } }