Пример #1
0
func NewLHTip(mfr, ttype string, minvol, maxvol float64, volunit string) *LHTip {
	var lht LHTip
	lht.ID = GetUUID()
	lht.Mnfr = mfr
	lht.Type = ttype
	v := wunit.NewVolume(maxvol, volunit)
	lht.MaxVol = &v
	v2 := wunit.NewVolume(minvol, volunit)
	lht.MinVol = &v2
	return &lht
}
Пример #2
0
func MinMinVol(channels []*wtype.LHChannelParameter) wunit.Volume {
	mmv := wunit.NewVolume(9999999.0, "ul")

	for _, c := range channels {
		if c.Minvol.LessThan(&mmv) {
			mmv = *(c.Minvol)
		}
	}

	return mmv
}
Пример #3
0
func makeCyBio() *liquidhandling.LHProperties {
	tips := GetTipList()
	layout := make(map[string]wtype.Coordinates)
	for i := 0; i < 12; i++ {
		posname := fmt.Sprintf("position_%d", i+1)
		// dont know coords for this yet
		var crds wtype.Coordinates
		layout[posname] = crds
	}

	lhp := liquidhandling.NewLHProperties(12, "Felix", "CyBio", "discrete", "disposable", layout)

	for _, tt := range tips {
		tb := GetTipByType(tt)
		if tb.Mnfr == lhp.Mnfr {
			lhp.Tips = append(lhp.Tips, tb.Tips[0][0])
		}
	}

	lhp.Tip_preferences = []int{1, 5, 3}
	lhp.Input_preferences = []int{10, 11, 12}
	lhp.Output_preferences = []int{7, 8, 9, 2, 4}

	minvol := wunit.NewVolume(10, "ul")
	maxvol := wunit.NewVolume(1000, "ul")
	minspd := wunit.NewFlowRate(0.5, "ml/min")
	maxspd := wunit.NewFlowRate(2, "ml/min")

	hvconfig := wtype.NewLHChannelParameter("HVconfig", &minvol, &maxvol, &minspd, &maxspd, 8, false, wtype.LHVChannel, 0)

	hvadaptor := wtype.NewLHAdaptor("HVAdaptor", "CyBio", hvconfig)

	minvol = wunit.NewVolume(0.5, "ul")
	maxvol = wunit.NewVolume(50, "ul")
	minspd = wunit.NewFlowRate(0.1, "ml/min")
	maxspd = wunit.NewFlowRate(0.5, "ml/min")

	lvconfig := wtype.NewLHChannelParameter("LVconfig", &minvol, &maxvol, &minspd, &maxspd, 8, false, wtype.LHVChannel, 0)
	lvadaptor := wtype.NewLHAdaptor("LVAdaptor", "CyBio", lvconfig)

	minvol = wunit.NewVolume(0.5, "ul")
	maxvol = wunit.NewVolume(1000, "ul")
	headparams := wtype.NewLHChannelParameter("ChoiceHead", &minvol, &maxvol, &minspd, &maxspd, 8, false, wtype.LHVChannel, 0)
	head := wtype.NewLHHead("ChoiceHead", "CyBio", headparams)
	head.Adaptor = hvadaptor

	lhp.Adaptors = append(lhp.Adaptors, hvadaptor)
	lhp.Adaptors = append(lhp.Adaptors, lvadaptor)
	lhp.Heads = append(lhp.Heads, head)
	lhp.HeadsLoaded = append(lhp.HeadsLoaded, head)

	return lhp
}
Пример #4
0
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 makeManual() *liquidhandling.LHProperties {
	//	tips := GetTipList()

	// dummy layout of 25 positions... arbitrary limitation

	x := 0.0
	y := 0.0
	z := 0.0
	xinc := 100.0
	yinc := 100.0

	i := 0
	layout := make(map[string]wtype.Coordinates)
	for xi := 0; xi < 5; xi++ {
		for yi := 0; yi < 5; yi++ {
			posname := fmt.Sprintf("position_%d", i+1)
			crds := wtype.Coordinates{x, y, z}
			layout[posname] = crds
			i += 1
			y += yinc
		}
		x += xinc
	}
	lhp := liquidhandling.NewLHProperties(25, "Human", "MotherNature", "discrete", "disposable", layout)

	SetUpTipsFor(lhp)

	lhp.Tip_preferences = []string{"tips1", "tips2", "tips3", "tips4"}
	lhp.Input_preferences = []string{"in1", "in2", "in3", "in4"}
	lhp.Output_preferences = []string{"out1", "out2", "out3", "out4"}
	lhp.Tipwaste_preferences = []string{"tip_waste"}
	lhp.Wash_preferences = []string{"tip_wash"}
	lhp.Waste_preferences = []string{"liquid_waste"}

	adaptors := make([]*wtype.LHAdaptor, 0, 1)

	minvol := wunit.NewVolume(200, "ul")
	maxvol := wunit.NewVolume(1000, "ul")
	minspd := wunit.NewFlowRate(0.5, "ml/min")
	maxspd := wunit.NewFlowRate(2, "ml/min")

	hvconfig := wtype.NewLHChannelParameter("P1000Config", "Gilson", minvol, maxvol, minspd, maxspd, 1, false, wtype.LHVChannel, 0)
	hvadaptor := wtype.NewLHAdaptor("P1000", "Gilson", hvconfig)

	adaptors = append(adaptors, hvadaptor)

	minvol = wunit.NewVolume(50, "ul")
	maxvol = wunit.NewVolume(200, "ul")
	minspd = wunit.NewFlowRate(0.1, "ml/min")
	maxspd = wunit.NewFlowRate(0.5, "ml/min")

	mvconfig := wtype.NewLHChannelParameter("P200Config", "Gilson", minvol, maxvol, minspd, maxspd, 1, false, wtype.LHVChannel, 0)
	mvadaptor := wtype.NewLHAdaptor("P200", "Gilson", mvconfig)

	adaptors = append(adaptors, mvadaptor)

	minvol = wunit.NewVolume(2, "ul")
	maxvol = wunit.NewVolume(20, "ul")
	minspd = wunit.NewFlowRate(0.1, "ml/min")
	maxspd = wunit.NewFlowRate(0.5, "ml/min")

	lmvconfig := wtype.NewLHChannelParameter("P20Config", "Gilson", minvol, maxvol, minspd, maxspd, 1, false, wtype.LHVChannel, 0)
	lmvadaptor := wtype.NewLHAdaptor("P20", "Gilson", lmvconfig)
	adaptors = append(adaptors, lmvadaptor)

	minvol = wunit.NewVolume(1, "ul")
	maxvol = wunit.NewVolume(10, "ul")
	minspd = wunit.NewFlowRate(0.1, "ml/min")
	maxspd = wunit.NewFlowRate(0.5, "ml/min")

	lvconfig := wtype.NewLHChannelParameter("P10Config", "Gilson", minvol, maxvol, minspd, maxspd, 1, false, wtype.LHVChannel, 0)
	lvadaptor := wtype.NewLHAdaptor("P10", "Gilson", lvconfig)
	adaptors = append(adaptors, lvadaptor)

	minvol = wunit.NewVolume(0.2, "ul")
	maxvol = wunit.NewVolume(2, "ul")
	minspd = wunit.NewFlowRate(0.1, "ml/min")
	maxspd = wunit.NewFlowRate(0.5, "ml/min")

	vlvconfig := wtype.NewLHChannelParameter("P2Config", "Gilson", minvol, maxvol, minspd, maxspd, 1, false, wtype.LHVChannel, 0)
	vlvadaptor := wtype.NewLHAdaptor("P2", "Gilson", vlvconfig)
	adaptors = append(adaptors, vlvadaptor)

	//minvol = wunit.NewVolume(0.2, "ul")
	//maxvol = wunit.NewVolume(5000, "ul")
	for i, adaptor := range adaptors {
		maxvol = adaptor.Params.Maxvol
		minvol = adaptor.Params.Minvol
		maxspd = adaptor.Params.Maxspd
		minspd = adaptor.Params.Minspd
		headparams := wtype.NewLHChannelParameter(fmt.Sprintf("LabHand_%d", i+1), "MotherNature", minvol, maxvol, minspd, maxspd, 8, false, wtype.LHVChannel, 0)
		head := wtype.NewLHHead(fmt.Sprintf("LabHand_%d", i+1), "MotherNature", headparams)
		head.Adaptor = adaptor
		lhp.Heads = append(lhp.Heads, head)
		lhp.HeadsLoaded = append(lhp.HeadsLoaded, head)
	}
	//	lhp.Adaptors = append(lhp.Adaptors, hvadaptor)
	//	lhp.Adaptors = append(lhp.Adaptors, mvadaptor)
	//	lhp.Adaptors = append(lhp.Adaptors, lmvadaptor)
	//	lhp.Adaptors = append(lhp.Adaptors, lvadaptor)
	//	lhp.Adaptors = append(lhp.Adaptors, vlvadaptor)
	return lhp
}
Пример #6
0
func makeManual() *liquidhandling.LHProperties {
	//	tips := GetTipList()

	// dummy layout of 25 positions... arbitrary limitation

	x := 0.0
	y := 0.0
	z := 0.0
	xinc := 100.0
	yinc := 100.0

	i := 0
	layout := make(map[string]wtype.Coordinates)
	for xi := 0; xi < 5; xi++ {
		for yi := 0; yi < 5; yi++ {
			posname := fmt.Sprintf("position_%d", i+1)
			crds := wtype.Coordinates{x, y, z}
			layout[posname] = crds
			i += 1
			y += yinc
		}
		x += xinc
	}
	lhp := liquidhandling.NewLHProperties(25, "Human", "MotherNature", "discrete", "disposable", layout)

	lhp.Tip_preferences = []int{2, 3, 4, 5, 6}
	lhp.Input_preferences = []int{7, 8, 9, 10, 11, 12, 13, 14, 15}
	lhp.Output_preferences = []int{16, 17, 18, 19, 20, 21, 22, 23, 24, 25}

	minvol := wunit.NewVolume(200, "ul")
	maxvol := wunit.NewVolume(1000, "ul")
	minspd := wunit.NewFlowRate(0.5, "ml/min")
	maxspd := wunit.NewFlowRate(2, "ml/min")

	hvconfig := wtype.NewLHChannelParameter("P1000Config", &minvol, &maxvol, &minspd, &maxspd, 1, false, wtype.LHVChannel, 0)
	hvadaptor := wtype.NewLHAdaptor("P1000", "Gilson", hvconfig)

	minvol = wunit.NewVolume(50, "ul")
	maxvol = wunit.NewVolume(200, "ul")
	minspd = wunit.NewFlowRate(0.1, "ml/min")
	maxspd = wunit.NewFlowRate(0.5, "ml/min")

	mvconfig := wtype.NewLHChannelParameter("P200Config", &minvol, &maxvol, &minspd, &maxspd, 1, false, wtype.LHVChannel, 0)
	mvadaptor := wtype.NewLHAdaptor("P200", "Gilson", mvconfig)

	minvol = wunit.NewVolume(2, "ul")
	maxvol = wunit.NewVolume(20, "ul")
	minspd = wunit.NewFlowRate(0.1, "ml/min")
	maxspd = wunit.NewFlowRate(0.5, "ml/min")

	lmvconfig := wtype.NewLHChannelParameter("P20Config", &minvol, &maxvol, &minspd, &maxspd, 1, false, wtype.LHVChannel, 0)
	lmvadaptor := wtype.NewLHAdaptor("P20", "Gilson", lmvconfig)

	minvol = wunit.NewVolume(1, "ul")
	maxvol = wunit.NewVolume(10, "ul")
	minspd = wunit.NewFlowRate(0.1, "ml/min")
	maxspd = wunit.NewFlowRate(0.5, "ml/min")

	lvconfig := wtype.NewLHChannelParameter("P10Config", &minvol, &maxvol, &minspd, &maxspd, 1, false, wtype.LHVChannel, 0)
	lvadaptor := wtype.NewLHAdaptor("P10", "Gilson", lvconfig)

	minvol = wunit.NewVolume(0.2, "ul")
	maxvol = wunit.NewVolume(2, "ul")
	minspd = wunit.NewFlowRate(0.1, "ml/min")
	maxspd = wunit.NewFlowRate(0.5, "ml/min")

	vlvconfig := wtype.NewLHChannelParameter("P2Config", &minvol, &maxvol, &minspd, &maxspd, 1, false, wtype.LHVChannel, 0)
	vlvadaptor := wtype.NewLHAdaptor("P2", "Gilson", vlvconfig)

	minvol = wunit.NewVolume(0.2, "ul")
	maxvol = wunit.NewVolume(5000, "ul")
	headparams := wtype.NewLHChannelParameter("LabHand", &minvol, &maxvol, &minspd, &maxspd, 8, false, wtype.LHVChannel, 0)
	head := wtype.NewLHHead("LabHand", "MotherNature", headparams)
	head.Adaptor = hvadaptor

	lhp.Adaptors = append(lhp.Adaptors, hvadaptor)
	lhp.Adaptors = append(lhp.Adaptors, mvadaptor)
	lhp.Adaptors = append(lhp.Adaptors, lmvadaptor)
	lhp.Adaptors = append(lhp.Adaptors, lvadaptor)
	lhp.Adaptors = append(lhp.Adaptors, vlvadaptor)
	lhp.Heads = append(lhp.Heads, head)
	lhp.HeadsLoaded = append(lhp.HeadsLoaded, head)
	return lhp
}
Пример #7
0
func makeGilson() *liquidhandling.LHProperties {
	// gilson pipetmax
	tips := GetTipList()

	layout := make(map[string]wtype.Coordinates)
	i := 0
	x0 := 3.886
	y0 := 3.513
	z0 := -82.035
	xi := 149.86
	yi := 95.25
	xp := x0
	yp := y0
	zp := z0
	for y := 0; y < 3; y++ {
		for x := 0; x < 3; x++ {
			posname := fmt.Sprintf("position_%d", i+1)
			crds := wtype.Coordinates{xp, yp, zp}
			layout[posname] = crds
			i += 1
			xp += xi
		}
		yp += yi
	}
	lhp := liquidhandling.NewLHProperties(9, "Pipetmax", "Gilson", "discrete", "disposable", layout)

	for _, tt := range tips {
		tb := GetTipByType(tt)
		if tb.Mnfr == lhp.Mnfr {
			lhp.Tips = append(lhp.Tips, tb.Tips[0][0])
		}
	}

	lhp.Tip_preferences = []int{2, 3, 4}
	lhp.Input_preferences = []int{4, 5, 6}
	lhp.Output_preferences = []int{7, 8, 9}
	minvol := wunit.NewVolume(10, "ul")
	maxvol := wunit.NewVolume(250, "ul")
	minspd := wunit.NewFlowRate(0.5, "ml/min")
	maxspd := wunit.NewFlowRate(2, "ml/min")

	hvconfig := wtype.NewLHChannelParameter("HVconfig", &minvol, &maxvol, &minspd, &maxspd, 8, false, wtype.LHVChannel, 0)
	hvadaptor := wtype.NewLHAdaptor("DummyAdaptor", "Gilson", hvconfig)
	hvhead := wtype.NewLHHead("HVHead", "Gilson", hvconfig)
	hvhead.Adaptor = hvadaptor

	minvol = wunit.NewVolume(0.5, "ul")
	maxvol = wunit.NewVolume(50, "ul")
	minspd = wunit.NewFlowRate(0.1, "ml/min")
	maxspd = wunit.NewFlowRate(0.5, "ml/min")

	lvconfig := wtype.NewLHChannelParameter("LVconfig", &minvol, &maxvol, &minspd, &maxspd, 8, false, wtype.LHVChannel, 1)
	lvadaptor := wtype.NewLHAdaptor("DummyAdaptor", "Gilson", lvconfig)
	lvhead := wtype.NewLHHead("LVHead", "Gilson", lvconfig)
	lvhead.Adaptor = lvadaptor

	lhp.Heads = append(lhp.Heads, hvhead)
	lhp.Heads = append(lhp.Heads, lvhead)
	lhp.HeadsLoaded = append(lhp.HeadsLoaded, hvhead)
	lhp.HeadsLoaded = append(lhp.HeadsLoaded, lvhead)
	return lhp
}
Пример #8
0
func choose_plate_assignments(component_volumes map[string]wunit.Volume, plate_types []*wtype.LHPlate, weight_constraint map[string]float64) map[string]map[*wtype.LHPlate]int {

	//
	//	optimization is set up as follows:
	//
	//		let:
	//			Xk 	= 	Number of wells of type Y containing component Z (k = 1...YZ)
	//			Vy	= 	Working volume of well Y
	//			RVy	= 	Residual volume of well Y
	//			TVz	= 	Total volume of component Z required
	//			WRy	=	Rate of wells of type y in their plate
	//			PMax	=	Maximum number of plates
	//			WMax	= 	Maximum number of wells
	//
	//	Minimise:
	//			sum of Xk Wrv RVy
	//
	//	Subject to:
	//			sum of Xk Vy 	>= TVz	for each component Z
	//			sum of WRy Xk 	<= PMax
	//			sum of Xk	<= WMax
	//

	// setup

	lp := glpk.New()
	defer lp.Delete()

	lp.SetProbName("Assignments")
	lp.SetObjName("Z")

	// CHECK THIS

	lp.SetObjDir(glpk.MAX)

	// constraints:
	// 		total component volume
	//		number of plates
	//		number of wells
	n_rows := len(component_volumes) + 2

	lp.AddRows(n_rows)

	cur := 1

	component_order := make([]string, len(component_volumes))

	// volume constraints
	for cmp, vol := range component_volumes {
		component_order[cur-1] = cmp
		lp.SetRowBnds(cur, glpk.LO, vol.ConvertTo(wunit.ParsePrefixedUnit("ul")), 99999.0)
		cur += 1
	}

	// from now on we always have to use component_order

	// plate number constraints

	max_n_plates := weight_constraint["MAX_N_PLATES"] - 1.0
	lp.SetRowBnds(cur, glpk.UP, -99999.0, max_n_plates)
	cur += 1

	// well number constraints
	max_n_wells := weight_constraint["MAX_N_WELLS"]
	lp.SetRowBnds(cur, glpk.UP, -99999.0, max_n_wells)
	cur += 1

	// set up the matrix columns

	num_cols := len(component_order) * len(plate_types)
	lp.AddCols(num_cols)
	cur = 1

	for _, component := range component_order {
		for _, plate := range plate_types {
			// set up objective coefficient, column name and lower bound
			rv := plate.Welltype.ResidualVolume()
			coef := rv.ConvertTo(wunit.ParsePrefixedUnit("ul")) * weight_constraint["RESIDUAL_VOLUME_WEIGHT"]
			lp.SetObjCoef(cur, coef)
			lp.SetColName(cur, component+"_"+plate.PlateName)
			lp.SetColBnds(cur, glpk.LO, 0.0, 0.0)
			lp.SetColKind(cur, glpk.IV)
			cur += 1
		}
	}

	// now set up the constraint coefficients
	cur = 1

	ind := wutil.Series(0, num_cols)

	for c, _ := range component_order {
		row := make([]float64, num_cols+1)
		col := 0
		for i := 0; i < len(component_order); i++ {
			for j := 0; j < len(plate_types); j++ {
				vc := 0.0
				// pick out a set of columns according to which row we're on
				// volume constraints are the working volumes of the wells
				if c == i {
					vol := wunit.NewVolume(plate_types[j].Welltype.Vol, plate_types[j].Welltype.Vunit)
					rvol := wunit.NewVolume(plate_types[j].Welltype.Rvol, plate_types[j].Welltype.Vunit)
					vol.Subtract(&rvol)
					vc = vol.ConvertTo(wunit.ParsePrefixedUnit("ul"))
				}
				row[col+1] = vc
				col += 1
			}
		}
		lp.SetMatRow(cur, ind, row)
		cur += 1
	}

	// now the plate constraint

	row := make([]float64, num_cols+1)
	col := 1
	for i := 0; i < len(component_order); i++ {
		for j := 0; j < len(plate_types); j++ {
			// the coefficient here is 1/the number of this well type per plate
			r := 1.0 / float64(plate_types[j].Nwells)
			row[col] = r
			col += 1
		}
	}

	lp.SetMatRow(cur, ind, row)
	cur += 1

	// finally the well constraint

	row = make([]float64, num_cols+1)
	col = 1
	for i := 0; i < len(component_order); i++ {
		for j := 0; j < len(plate_types); j++ {
			// the number of wells is constrained so we just count
			row[col] = 1.0
			col += 1
		}
	}

	lp.SetMatRow(cur, ind, row)

	iocp := glpk.NewIocp()
	iocp.SetPresolve(true)
	iocp.SetMsgLev(0)
	lp.Intopt(iocp)

	// check constraints

	/*
		for i := 1; i <= n_rows; i++ {
			fmt.Println("ROW : ", i, " VAL : ", lp.MipRowVal(i))
		}
	*/
	// fill assignments - this is the number of wells in the plate of each type needed

	assignments := make(map[string]map[*wtype.LHPlate]int, len(component_volumes))

	cur = 1

	for i := 0; i < len(component_order); i++ {
		cmap := make(map[*wtype.LHPlate]int)
		for j := 0; j < len(plate_types); j++ {
			nwells := lp.MipColVal(cur)

			if nwells > 0 {
				//fmt.Println(component_order[i], " : ", plate_types[j].Type, " N WELLS: ", nwells)
				cmap[plate_types[j]] = int(nwells)
			}
			cur += 1
		}
		assignments[component_order[i]] = cmap
	}

	return assignments
}
Пример #9
0
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)
}
Пример #10
0
func AdvancedExecutionPlanner(request *LHRequest, parameters *liquidhandling.LHProperties) *LHRequest {
	// in the first instance we assume this is done component-wise
	// we also need to identify dependencies, i.e. if certain components
	// are only available after other actions
	// this will only work if the components to be added are to go in the same order

	// get the layout groups

	minorlayoutgroups := request.Output_minor_group_layouts
	ass := request.Output_assignments
	inass := request.Input_assignments
	output_solutions := request.Output_solutions
	input_plates := request.Input_plates
	output_plate_layout := request.Output_plate_layout

	plate_lookup := request.Plate_lookup

	// highly inelegant... we should swap Tip Box Setup
	// around to take place after, then this whole thing
	// is a non-issue
	tt := make([]*wtype.LHTip, 1)
	tt[0] = request.Tip_Type.Tiptype
	parameters.Tips = tt

	instructions := liquidhandling.NewRobotInstructionSet(nil)
	// need to deal with solutions

	order := request.Input_order

	for _, name := range order {
		//fmt.Println(name)

		// cmpa holds a list of inputs required per destination
		// i.e. if destination X requires 15 ul of h2o this will be listed separately
		// at this point all of the requests must be for volumes,

		// we need a mapping from these to where they belong
		// do we?
		/*
			cmpa:=value.([]map[string]interface{})
			cmp_map:=make(map[string]interface{}, len(cmpa))
			for _,cmp:=range cmpa{
				srcid:=cmp.Srcid
				cmp_map[srcid]=cmp
			}
		*/

		for n, g := range minorlayoutgroups {
			grp := []string(g)
			// get the group assignment string

			assignment := ass[n]

			// the assignment has the format plateID:row:column:incrow:inccol
			// where inc defines how the next one is to be calculated
			// e.g. {GUID}:A:1:1:0
			// 	{GUID}:A:1:0:1

			asstx := strings.Split(assignment, ":")

			plate := asstx[0]
			toplatenum := wutil.ParseInt(plate)
			row := wutil.AlphaToNum(asstx[1])
			col := wutil.ParseInt(asstx[2])
			incrow := wutil.ParseInt(asstx[3])
			inccol := wutil.ParseInt(asstx[4])

			whats := make([]string, len(grp))
			pltfrom := make([]string, len(grp))
			pltto := make([]string, len(grp))
			plttypefrom := make([]string, len(grp))
			plttypeto := make([]string, len(grp))
			wellfrom := make([]string, len(grp))
			wellto := make([]string, len(grp))
			vols := make([]*wunit.Volume, len(grp))
			fvols := make([]*wunit.Volume, len(grp))
			tvols := make([]*wunit.Volume, len(grp))
			for i, solID := range grp {
				sol := output_solutions[solID]

				// we need to get the relevant component out
				smpl := get_aggregate_component(sol, name)

				// we need to know where this component was assigned to
				inassignmentar := []string(inass[name])
				inassignment, ok := get_assignment(inassignmentar, &input_plates, smpl.Vol)

				if !ok {
					wutil.Error(errors.New(fmt.Sprintf("No input assignment for %s with vol %-4.1f", name, smpl.Vol)))
				}

				inasstx := strings.Split(inassignment, ":")

				inplt := inasstx[0]
				inrow := string(inasstx[1])
				incol := wutil.ParseInt(inasstx[2])

				// we can fill the structure now

				whats[i] = name
				pltfrom[i] = plate_lookup[string(inplt)]
				pltto[i] = plate_lookup[output_plate_layout[toplatenum]]
				wellfrom[i] = inrow + strconv.Itoa(incol)
				wellto[i] = wutil.NumToAlpha(row) + strconv.Itoa(col)
				v := wunit.NewVolume(smpl.Vol, smpl.Vunit)
				v2 := wunit.NewVolume(0.0, "ul")
				vols[i] = &v
				// TODO Get the proper volumes here
				fvols[i] = &v2
				tvols[i] = &v2
				row += incrow
				col += inccol
			}

			ins := liquidhandling.NewTransferInstruction(whats, pltfrom, pltto, wellfrom, wellto, plttypefrom, plttypeto, vols, fvols, tvols /*, parameters.Cnfvol*/)
			instructions.Add(ins)
		}
	}

	inx := instructions.Generate(request.Policies, parameters)
	instrx := make([]liquidhandling.TerminalRobotInstruction, len(inx))
	for i := 0; i < len(inx); i++ {
		instrx[i] = inx[i].(liquidhandling.TerminalRobotInstruction)
	}
	request.Instructions = instrx

	return request
}
Пример #11
0
func NewGenericPhysical(mattertype string) GenericPhysical {
	gp := GenericPhysical{MatterByName(mattertype), mattertype, wunit.NewMass(0.0, "g"), wunit.NewVolume(0.0, "L"), wunit.NewTemperature(0.0, "˚C")}
	return gp
}
Пример #12
0
func (w *LHWell) WorkingVolume() *wunit.Volume {
	v := wunit.NewVolume(w.Vol, w.Vunit)
	v2 := wunit.NewVolume(w.Rvol, w.Vunit)
	v.Subtract(&v2)
	return &v
}
Пример #13
0
func (lhc *LHComponent) Volume() wunit.Volume {
	return wunit.NewVolume(lhc.Vol, lhc.Vunit)
}
Пример #14
0
func solution_setup(request *LHRequest, prms *liquidhandling.LHProperties) (map[string]*wtype.LHSolution, map[string]float64) {
	solutions := request.Output_solutions

	// index of components used to make up to a total volume, along with the required total
	mtvols := make(map[string][]float64, 10)
	// index of components with concentration targets, along with the target concentrations
	mconcs := make(map[string][]float64, 10)
	// keep a list of components which have fixed stock concentrations
	fixconcs := make([]*wtype.LHComponent, 0)
	// maximum solubilities of each component
	Smax := make(map[string]float64, 10)
	// maximum total volume of any solution containing each component
	hshTVol := make(map[string]float64)

	// find the minimum and maximum required concentrations
	// across all the solutions
	for _, solution := range solutions {
		components := solution.Components

		// we need to identify the concentration components
		// and the total volume components, if we have
		// concentrations but no tvols we have to return
		// an error

		arrCncs := make([]*wtype.LHComponent, 0, len(components))
		arrTvol := make([]*wtype.LHComponent, 0, len(components))
		cmpvol := 0.0
		totalvol := 0.0

		for _, component := range components {
			// what sort of component is it?
			conc := component.Conc
			tvol := component.Tvol

			if conc != 0.0 {
				arrCncs = append(arrCncs, component)
			} else if tvol != 0.0 {
				tv := component.Tvol
				if totalvol == 0.0 || totalvol == tv {
					totalvol = tv
				} else {
					// error
					wutil.Error(errors.New(fmt.Sprintf("Inconsistent total volumes %-6.4f and %-6.4f at component %s", totalvol, tv, component.Name)))
				}
			} else {
				cmpvol += component.Vol
			}
		}

		// add everything to the maps

		for _, cmp := range arrCncs {
			nm := cmp.CName
			cnc := cmp.Conc

			_, ok := Smax[nm]

			if !ok {
				Smax[nm] = cmp.Smax
			}

			if cmp.StockConcentration != 0.0 {
				fixconcs = append(fixconcs, cmp)
				continue
			}

			var cncslc []float64

			cncslc, ok = mconcs[nm]

			if !ok {
				cncslc = make([]float64, 0, 10)
			}

			cncslc = append(cncslc, cnc)

			mconcs[nm] = cncslc
			_, ok = hshTVol[nm]
			if !ok || hshTVol[nm] > totalvol {
				hshTVol[nm] = totalvol
			}
		}

		// now the total volumes

		for _, cmp := range arrTvol {
			nm := cmp.CName
			tvol := cmp.Tvol

			var tvslc []float64

			tvslc, ok := mtvols[nm]

			if !ok {
				tvslc = make([]float64, 0, 10)
			}

			tvslc = append(tvslc, tvol)

			mtvols[nm] = tvslc
		}

	} // end solutions
	// so now we should be able to make stock concentrations
	// first we need the min and max for each

	minrequired := make(map[string]float64, len(mconcs))
	maxrequired := make(map[string]float64, len(mconcs))

	//TODO this needs to be migrated elsewhere
	var vmin wunit.Volume = wunit.NewVolume(1.0, "ul")
	if prms.CurrConf != nil {
		vmin = *(prms.CurrConf.Minvol)
	}

	for cmp, arr := range mconcs {
		min := wutil.FMin(arr)
		max := wutil.FMax(arr)
		minrequired[cmp] = min
		maxrequired[cmp] = max
		// if smax undefined we need to deal  - we assume infinite solubility!!

		_, ok := Smax[cmp]

		if !ok {
			Smax[cmp] = 9999999
			wutil.Warn(fmt.Sprintf("Max solubility undefined for component %s -- assuming infinite solubility!", cmp))
		}

	}

	stockconcs := choose_stock_concentrations(minrequired, maxrequired, Smax, vmin.RawValue(), hshTVol)

	// handle any errors here

	// add the fixed concentrations into stockconcs

	for _, cmp := range fixconcs {
		stockconcs[cmp.CName] = cmp.StockConcentration
	}

	// nearly there now! Need to turn all the components into volumes, then we're done

	// make an array for the new solutions

	newSolutions := make(map[string]*wtype.LHSolution, len(solutions))

	for _, solution := range solutions {
		components := solution.Components
		arrCncs := make([]*wtype.LHComponent, 0, len(components))
		arrTvol := make([]*wtype.LHComponent, 0, len(components))
		arrSvol := make([]*wtype.LHComponent, 0, len(components))
		cmpvol := 0.0
		totalvol := 0.0
		totalvolunit := ""

		for _, component := range components {
			// what sort of component is it?
			// what is the total volume ?
			if component.Conc != 0.0 {
				arrCncs = append(arrCncs, component)
			} else if component.Tvol != 0.0 {
				arrTvol = append(arrTvol, component)
				tv := component.Tvol
				totalvolunit = component.Vunit
				if totalvol == 0.0 || totalvol == tv {
					totalvol = tv
				} else {
					// error
					wutil.Error(errors.New(fmt.Sprintf("Inconsistent total volumes %-6.4f and %-6.4f at component %s", totalvol, tv, component.Name)))
				}
			} else {
				// need to add in the volume taken up by any volume components
				cmpvol += component.Vol
				arrSvol = append(arrSvol, component)
			}
		}

		// first we add the volumes to the concentration components

		arrFinalComponents := make([]*wtype.LHComponent, 0, len(components))

		for _, component := range arrCncs {
			name := component.CName
			cnc := component.Conc
			vol := totalvol * cnc / stockconcs[name]
			cmpvol += vol
			component.Vol = vol
			component.Vunit = totalvolunit
			component.StockConcentration = stockconcs[name]
			arrFinalComponents = append(arrFinalComponents, component)
		}

		// next we get the final volume for total volume components

		for _, component := range arrTvol {
			vol := totalvol - cmpvol
			component.Vol = vol
			arrFinalComponents = append(arrFinalComponents, component)
		}

		// then we add the rest

		arrFinalComponents = append(arrFinalComponents, arrSvol...)

		// finally we replace the components in this solution

		solution.Components = arrFinalComponents

		// and put the new solution in the array

		newSolutions[solution.ID] = solution
	}

	return newSolutions, stockconcs
}