func (lhs *LiquidHandlingService) MakeMixRequest(solution *wtype.LHSolution) *liquidhandling.LHRequest { lhs.lock.Lock() defer lhs.lock.Unlock() rq, ok := lhs.RequestQueue[execute.ThreadID(solution.BlockID)] if !ok { // if we don't have a request with this ID, make a new one rq = liquidhandling.NewLHRequest() rq = initRequest(rq, execute.ThreadID(solution.BlockID)) } if solution.Platetype != "" { rq.Output_platetype = factory.GetPlateByType(solution.Platetype) } rq.Output_solutions[solution.ID] = solution lhs.RequestQueue[execute.ThreadID(rq.BlockID)] = rq return rq }
// Runs a workflow for one sample func (w *Workflow) Run(cf *Config) ([]interface{}, error) { id, err := uuid.NewV4() if err != nil { return nil, err } tid := execute.ThreadID(id.String()) ctx := execution.GetContext() ctx.ConfigService.SetConfig(tid, cf.Config) wr, err := NewWorkflowRun(*id, w, cf) if err != nil { return nil, err } var errors []error go func() { for v := range wr.Errors { if v != nil { errors = append(errors, v) } } }() var messages []interface{} go func() { for v := range wr.Messages { // messages = append(messages, fmt.Sprintf("%v", v.Value)) messages = append(messages, v.Value) } }() <-wr.Done if len(errors) > 0 { return messages, Errors(errors) } return messages, nil }
func main() { eid, _ := uuid.NewV4() em := equipmentManager.NewAnthaEquipmentManager(eid.String()) defer em.Shutdown() eem := equipmentManager.EquipmentManager(em) equipmentManager.SetEquipmentManager(&eem) //manual driver equipment mid, _ := uuid.NewV4() var mde equipment.Equipment var amd manual.AnthaManual amd = *manual.NewAnthaManual(mid.String()) mde = amd em.RegisterEquipment(&mde) //cui logger middleware cmw := middleware.NewLogToCui(&amd.Cui) log_id, _ := uuid.NewV4() l := logger.NewAnthaFileLogger(log_id.String()) l.RegisterMiddleware(cmw) var params Parameters var inputs Inputs // give this thing an arbitrary ID for testing id := execute.ThreadID(fmt.Sprintf("EXPERIMENT_1_%s", string(eid.String()[1:5]))) fmt.Println(id) // set up parameters and inputs params.Reactionvolume = wunit.NewVolume(20, "ul") params.Partconc = wunit.NewConcentration(0.0001, "g/l") params.Vectorconc = wunit.NewConcentration(0.001, "g/l") params.Atpvol = wunit.NewVolume(1, "ul") params.Revol = wunit.NewVolume(1, "ul") params.Ligvol = wunit.NewVolume(1, "ul") params.Reactiontemp = wunit.NewTemperature(25, "C") params.Reactiontime = wunit.NewTime(1800, "s") params.Inactivationtemp = wunit.NewTemperature(40, "C") params.Inactivationtime = wunit.NewTime(60, "s") params.BlockID = id inputs.Parts = make([]*wtype.LHComponent, 4) for i := 0; i < 4; i++ { inputs.Parts[i] = factory.GetComponentByType("dna_part") inputs.Parts[i].CName = inputs.Parts[i].CName + "_" + strconv.Itoa(i+1) } inputs.Vector = factory.GetComponentByType("standard_cloning_vector_mark_1") inputs.RestrictionEnzyme = factory.GetComponentByType("SapI") inputs.Ligase = factory.GetComponentByType("T4Ligase") inputs.Buffer = factory.GetComponentByType("CutsmartBuffer") inputs.ATP = factory.GetComponentByType("ATP") inputs.Outplate = factory.GetPlateByType("pcrplate") inputs.TipType = factory.GetTipboxByType("Gilson50") ctx := execution.GetContext() conf := make(map[string]interface{}) conf["MAX_N_PLATES"] = 1.5 conf["MAX_N_WELLS"] = 12.0 conf["RESIDUAL_VOLUME_WEIGHT"] = 1.0 conf["SQLITE_FILE_IN"] = "/Users/msadowski/synthace/protocol_language/checkout/synthace-antha/anthalib/driver/liquidhandling/pm_driver/default.sqlite" conf["SQLITE_FILE_OUT"] = "/tmp/output_file.sqlite" ctx.ConfigService.SetConfig(id, conf) outputs := Steps(params, inputs) fmt.Println(outputs.Reaction) }
func NewWorkflowRun(id uuid.UUID, wf *Workflow, cf *Config) (*WorkflowRun, error) { params := make(map[flow.FullPortName]interface{}) for _, port := range wf.InPorts { param, ok := cf.Parameters[port.Proc] if !ok { return nil, fmt.Errorf("required parameter not found %v", port) } // Need to unpack fields to map entries; use reflection to avoid // copying pointer based structures pv := reflect.ValueOf(param) fv := pv.Elem().FieldByName(port.Port) if !fv.IsValid() { return nil, fmt.Errorf("required parameter not found %v", port) } reflect.ValueOf(params).SetMapIndex(reflect.ValueOf(port), fv) } ins := make(map[flow.FullPortName]chan execute.ThreadParam) outs := make(map[flow.FullPortName]chan execute.ThreadParam) for _, port := range wf.InPorts { ins[port] = make(chan execute.ThreadParam) wf.Graph.SetInPort(fmt.Sprintf("%s.%s", port.Proc, port.Port), ins[port]) } for _, port := range wf.OutPorts { outs[port] = make(chan execute.ThreadParam) wf.Graph.SetOutPort(fmt.Sprintf("%s.%s", port.Proc, port.Port), outs[port]) } messages := make(chan execute.ThreadParam) errors := make(chan error) done := make(chan bool) // Point of no return... start running workflow flow.RunNet(&wf.Graph) for _, ch := range outs { go func(ch chan execute.ThreadParam) { for v := range ch { messages <- v } }(ch) } tid := execute.ThreadID(id.String()) go func() { defer func() { for _, ch := range ins { close(ch) } }() for port, v := range params { param := execute.ThreadParam{ Value: v, ID: tid, } ins[port] <- param } }() go func() { <-wf.Graph.Wait() close(errors) close(messages) done <- true }() return &WorkflowRun{ ID: id, Outs: outs, Ins: ins, Messages: messages, Errors: errors, Done: done, }, nil }