// TASK: define output plates // INPUT: "output_platetype", "outputs" //OUTPUT: "output_plates" -- these each have components in wells // "output_assignments" -- map with arrays of assignment strings, i.e. {tea: [plate1:A:1, plate1:A:2...] }etc. func output_plate_setup(request *LHRequest) *LHRequest { //(map[string]*wtype.LHPlate, map[string][]string) { output_platetype := (*request).Output_platetype if output_platetype == nil || output_platetype.ID == "" { wutil.Error(errors.New("plate_setup: No output plate type defined")) } if (*request).Output_major_group_layouts == nil { wutil.Error(errors.New("plate setup: Output major groups undefined")) } output_plates := (*request).Output_plates if len(output_plates) == 0 { output_plates = make(map[string]*wtype.LHPlate, len(request.Output_major_group_layouts)) } // just assign based on number of groups opl := request.Output_plate_layout for i := 0; i < len(request.Output_major_group_layouts); i++ { //p := wtype.New_Plate(request.Output_platetype) p := factory.GetPlateByType(request.Output_platetype.Type) output_plates[p.ID] = p opl[i] = p.ID name := fmt.Sprintf("Output_plate_%d", i+1) p.PlateName = name } (*request).Output_plate_layout = opl (*request).Output_plates = output_plates return request }
func TestIPLinear(*testing.T) { // get component library ctypes := factory.GetComponentList() // make components cmps := make(map[string]wunit.Volume) for _, cmpn := range ctypes { vf := rand.Float64() * 10000.0 vol := wunit.NewVolume(vf, "ul") cmps[cmpn] = vol } // get plate library plist := factory.GetPlateList() // no need to subselect just stick em all in plates := make([]*wtype.LHPlate, 0) for _, p := range plist { plates = append(plates, factory.GetPlateByType(p)) } // we need a map between components and volumes // an array of plates // and a map of weights and constraints wtc := make(map[string]float64, 3) wtc["MAX_N_PLATES"] = 2.0 wtc["MAX_N_WELLS"] = 96.0 wtc["RESIDUAL_VOLUME_WEIGHT"] = 1.0 ass := choose_plate_assignments(cmps, plates, wtc) ass = ass /* for component, cmap := range ass { for plt, nw := range cmap { volreq := cmps[component] fmt.Println("\t", nw, " wells of ", plt.Type, " total volume ", float64(nw)*(plt.Welltype.Vol-plt.Welltype.Rvol), " residual volume ", float64(nw)*plt.Welltype.Rvol, " volume required: ", volreq.RawValue()) } } */ }
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 }
// define which labware to use // and request specific instances func (this *Liquidhandler) GetPlates(plates map[string]*wtype.LHPlate, major_layouts map[int][]string, ptype *wtype.LHPlate) map[string]*wtype.LHPlate { if plates == nil { plates = make(map[string]*wtype.LHPlate, len(major_layouts)) // assign new plates for i := 0; i < len(major_layouts); i++ { //newplate := wtype.New_Plate(ptype) newplate := factory.GetPlateByType(ptype.Type) plates[newplate.ID] = newplate } } // we should know how many plates we need for k, plate := range plates { if plate.Inst == "" { //stockrequest := execution.GetContext().StockMgr.RequestStock(makePlateStockRequest(plate)) //plate.Inst = stockrequest["inst"].(string) } plates[k] = plate } return plates }
// Transfer fields from conf to params instantiating certain fields from a // factory. conf is like the type of params but with wtype.FromFactory entries // for certain fields/elements. Assign values of conf to params. Use // factory.GetComponentByType to instantiate FromFactory instances and assign // them to the appropriate entry in params. // // Assumes that params is a nil instance and conf is like type of params but // with some values as FromFactory rather than the appropriate interface type func (p *Config) transfer(cv reflect.Value, pv reflect.Value) error { factoryType := reflect.TypeOf(wtype.FromFactory{}) ct := cv.Type() pt := pv.Type() switch { case ct.AssignableTo(pt): pv.Set(cv) case ct == factoryType: v := cv.Interface().(wtype.FromFactory) terms := strings.Split(v.String, ":") if len(terms) != 2 { return fmt.Errorf("cannot parse factory string: %s", v.String) } var newV interface{} switch terms[0] { case "component": newV = factory.GetComponentByType(terms[1]) case "tipbox": newV = factory.GetTipboxByType(terms[1]) case "plate": newV = factory.GetPlateByType(terms[1]) default: return fmt.Errorf("cannot parse factory string: %s", v.String) } nv := reflect.ValueOf(newV) nt := nv.Type() if !nt.AssignableTo(pt) { return fmt.Errorf("cannot convert %v to %v", nt, pt) } pv.Set(nv) default: pk := pt.Kind() ck := ct.Kind() if pk != ck { return fmt.Errorf("cannot convert %v to %v", ct, pt) } switch ck { case reflect.Slice: cvl := cv.Len() newSlice := reflect.MakeSlice(pt, cvl, cvl) pv.Set(newSlice) for i := 0; i < cvl; i += 1 { if err := p.transfer(cv.Index(i), pv.Index(i)); err != nil { return err } } case reflect.Map: newMap := reflect.MakeMap(pt) pv.Set(newMap) for _, key := range cv.MapKeys() { if err := p.transfer(pv.MapIndex(key), pv.MapIndex(key)); err != nil { return err } } case reflect.Struct: ctn := ct.NumField() for i := 0; i < ctn; i += 1 { if err := p.transfer(cv.Field(i), pv.Field(i)); err != nil { return err } } case reflect.Ptr: if err := p.transfer(cv.Elem(), pv.Elem()); err != nil { return err } default: return fmt.Errorf("cannot convert %v to %v", ct, pt) } } return nil }
// TASK: Map inputs to input plates // INPUT: "input_platetype", "inputs" //OUTPUT: "input_plates" -- these each have components in wells // "input_assignments" -- map with arrays of assignment strings, i.e. {tea: [plate1:A:1, plate1:A:2...] }etc. func input_plate_setup(request *LHRequest) *LHRequest { input_platetypes := (*request).Input_platetypes if input_platetypes == nil || len(input_platetypes) == 0 { // this configuration needs to happen outside but for now... list := factory.GetPlateList() input_platetypes = make([]*wtype.LHPlate, len(list)) for i, platetype := range list { input_platetypes[i] = factory.GetPlateByType(platetype) } (*request).Input_platetypes = input_platetypes } input_plates := (*request).Input_plates if len(input_plates) == 0 { input_plates = make(map[string]*wtype.LHPlate, 3) } // need to fill each plate type var curr_plate *wtype.LHPlate inputs := (*request).Input_solutions input_volumes := make(map[string]wunit.Volume, len(inputs)) // aggregate the volumes for the inputs for k, v := range inputs { v2 := v[0].Volume() vol := &v2 for i := 1; i < len(v); i++ { vv := v[i].Volume() vol.Add(&vv) } input_volumes[k] = *vol //fmt.Println("TOTAL Volume for ", k, " : ", vol.ToString()) } weights_constraints := request.Input_Setup_Weights // get the assignments well_count_assignments := choose_plate_assignments(input_volumes, input_platetypes, weights_constraints) input_assignments := make(map[string][]string, len(well_count_assignments)) plates_in_play := make(map[string]*wtype.LHPlate) curplaten := 1 for cname, volume := range input_volumes { component := inputs[cname][0] //fmt.Println("Plate_setup - component", cname, ":") well_assignments := well_count_assignments[cname] //fmt.Println("Well assignments: ", well_assignments) var curr_well *wtype.LHWell var ok bool ass := make([]string, 0, 3) for platetype, nwells := range well_assignments { for i := 0; i < nwells; i++ { curr_plate = plates_in_play[platetype.Type] if curr_plate == nil { plates_in_play[platetype.Type] = factory.GetPlateByType(platetype.Type) curr_plate = plates_in_play[platetype.Type] platename := fmt.Sprintf("Input_plate_%d", curplaten) curr_plate.PlateName = platename curplaten += 1 } // find somewhere to put it curr_well, ok = wtype.Get_Next_Well(curr_plate, component, curr_well) if !ok { plates_in_play[platetype.Type] = factory.GetPlateByType(platetype.Type) curr_well, ok = wtype.Get_Next_Well(curr_plate, component, nil) } // now put it there contents := curr_well.WContents if len(contents) == 0 { contents = make([]*wtype.LHComponent, 0, 4) } location := curr_plate.ID + ":" + curr_well.Crds ass = append(ass, location) // make a duplicate of this component to stick in the well newcomponent := component.Dup() newcomponent.Vol = curr_well.Vol newcomponent.Loc = location volume.Subtract(curr_well.WorkingVolume()) contents = append(contents, newcomponent) curr_well.WContents = contents curr_well.Currvol = newcomponent.Vol input_plates[curr_plate.ID] = curr_plate } } input_assignments[cname] = ass //fmt.Println("ASSIGNMENT: ", cname, " ", ass) } (*request).Input_plates = input_plates (*request).Input_assignments = input_assignments //return input_plates, input_assignments return request }
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) }