/// <summary> /// Removes the seal pierce or spin operations dynamically. Useful for protocols that will utilize virtual plates and /// it is undesirable for the same physical piece of labware to be sealed and peeled multiple times. /// </summary> /// <remarks>Method called during Cellario protocol execution when a sample arrives at the scripting step.</remarks> /// <param name="api">Access to properties and methods for interacting with the Cellario run-time scheduler, /// samples, resources and devices operations.</param> public override void Execute(IScriptingApi api) { //only execute this script once -- when the first plate in the thread is introduced if (api.CurrentPlate.PlateNumber != 1) { return; } var plates = api.GetPlatesForCurrentThread(); foreach (var plate in plates) { if (plates.Any(p => p.StartingLocation.ResourceName == plate.StartingLocation.ResourceName && p.StartingLocation.Stack == plate.StartingLocation.Stack && p.StartingLocation.Position == plate.StartingLocation.Position && p.PlateNumber < plate.PlateNumber)) { RemoveStep(plate, "SPIN"); RemoveStep(plate, "PIERCE"); } if (plates.Any(p => p.StartingLocation.ResourceName == plate.StartingLocation.ResourceName && p.StartingLocation.Stack == plate.StartingLocation.Stack && p.StartingLocation.Position == plate.StartingLocation.Position && p.PlateNumber > plate.PlateNumber)) { RemoveStep(plate, "SEAL"); } } }
/// <summary> /// Changes the times used parameter on the transfer step to be the same as the number of plates in the other thread. /// Useful for Echo transfers from a single plate to a variable number of destinations. When using virtual plates the /// physical plate is moved in and out of the Echo repeatedly. This script will use a single labware (no virtual labware) /// and it stays in the Echo for the entire run. Script only runs on the first plate. /// </summary> public override void Execute(IScriptingApi api) { // Only execute this script once -- when the first plate in the thread is introduced if (api.CurrentPlate.PlateNumber != 1) { return; } // Get the number of plates in the other Thread. Raise error if more than 2 threads exist. var threads = api.CurrentPlate.CurrentProtocol.Threads; // Throw an error if the thread count does not equal 2. if (threads.Count() != 2) { try { throw new Exception("This protocol does not have two threads. Only protocols with exactly two threads are supported."); } catch (Exception ex) { // Show exception to the user // Message severity is serious => the user may elect to shut down. api.Messaging.Notify("Unsupported Thread Count", null, ex, ScriptMessageSeverity.Serious); } } int otherThreadPlateCount = api.GetPlates().Count(p => p.CurrentThread.ThreadName != api.CurrentPlate.CurrentThread.ThreadName); // Rebuild the plates array from the current thread var plates = api.GetPlatesForCurrentThread(); var cumulativeUsage = 0; // Calculate the new timesused value int newTimesUsed = Convert.ToInt16(Math.Ceiling(((double)otherThreadPlateCount / (double)plates.Length))); foreach (var plate in plates) { // Change the newTimesUsed value if the cumulative usage does not equal the number of plates in the other thread if ((cumulativeUsage + newTimesUsed) > otherThreadPlateCount) { newTimesUsed = otherThreadPlateCount - cumulativeUsage; } cumulativeUsage = cumulativeUsage + newTimesUsed; // Modify operation parameter TimesUsed in all transfer steps var transfer = plate.RemainingSteps.FirstOrDefault(s => s.StepName.Contains("Transfer")); if (transfer != null) { transfer.TimesUsed = newTimesUsed; } } }
public ElsaClient( IActivitiesApi activities, IWorkflowDefinitionsApi workflowDefinitions, IWorkflowRegistryApi workflowRegistry, IWorkflowInstancesApi workflowInstances, IWebhookDefinitionsApi webhookDefinitions, IScriptingApi scriptingApi) { Activities = activities; WorkflowDefinitions = workflowDefinitions; WorkflowRegistry = workflowRegistry; WorkflowInstances = workflowInstances; WebhookDefinitions = webhookDefinitions; Scripting = scriptingApi; }
/// <summary> /// Look at the script name in the Echo transfer step for this thread and verify that the plate type matches. /// </summary> /// <remarks>This script will need to be edited if any Echo Source plate types are added or names changed</remarks> public override void Execute(IScriptingApi api) { // Only execute this script once -- when the first plate in the thread is introduced if (api.CurrentPlate.PlateNumber != 1) { return; } // Get Current Thread Plates var plates = api.GetPlatesForCurrentThread(); foreach (var plate in plates) { // Get Steps remaining in thread var steps = plate.RemainingSteps.ToList(); foreach (var step in steps) { // Check parameters for LIQUIDTRANSFER steps if (step.StepName.ToUpper().Contains("LIQUIDTRANSFER")) { // Check Script Name matches Labware // PP = LABCYTE_POLYPROPYLENE if (step.OperationParameters["Script Name"].ToString().Contains("PP") && !plate.Labware.Name.ToUpper().Contains("LABCYTE_POLYPROPYLENE")) { api.Messaging.WriteError(ScriptErrorSeverity.Error, string.Format("Stopping system due to labware mismatch. Echo script indicates PP source ({0}), but labware supplied is {1}.", step.OperationParameters["Script Name"].ToString(), plate.Labware.Name)); api.System.Stop(); } // LDV = LABCYTE_DIAMOND if (step.OperationParameters["Script Name"].ToString().Contains("LDV") && !plate.Labware.Name.ToUpper().Contains("LABCYTE_DIAMOND")) { api.Messaging.WriteError(ScriptErrorSeverity.Error, string.Format("Stopping system due to labware mismatch. Echo script indicates LDV source ({0}), but labware supplied is {1}.", step.OperationParameters["Script Name"].ToString(), plate.Labware.Name)); api.System.Stop(); } } } } }
/// <summary> /// Method called during Cellario protocol execution when a sample arrives at the scripting step. /// </summary> /// <remarks>Executes synchronously with the run scheduler. Device operation results not available /// until <see cref="ReleaseResources"/> method is called.</remarks> /// <param name="api">Access to properties and methods for interacting with the Cellario run-time scheduler, /// samples, resources and devices operations.</param> public override void Execute(IScriptingApi api) { foreach (var ResourceName in ResourceNames) { if (api.CurrentPlate.PlateNumber != (api.GetPlatesForCurrentThread().Count())) { return; } if (!(api.Resources.ContainsKey(ResourceName))) { return; } // Log the Empty Operation api.Messaging.WriteDiagnostic(ScriptLogLevel.Normal, "Empty {0}.", ResourceName); // Do the Empty Operation var operation = api.Resources[ResourceName].Operations["Empty"]; operation.OperationParameters["Volume"] = 1200; operation.Execute(); } }