Example #1
0
func (req *LHRequest) UnmarshalJSON(ar []byte) error {
	var slhr SLHRequest
	e := json.Unmarshal(ar, req)

	fmt.Println("ERR: ", e)

	e = json.Unmarshal(ar, slhr)

	req.Input_major_group_layouts = make(map[int][]string, len(slhr.Input_major_group_layouts))

	for k, v := range slhr.Input_major_group_layouts {
		req.Input_major_group_layouts[wutil.ParseInt(k)] = v
	}

	req.Input_plate_layout = make(map[int]string, len(slhr.Input_plate_layout))

	for k, v := range slhr.Input_plate_layout {
		req.Input_plate_layout[wutil.ParseInt(k)] = v
	}

	req.Output_major_group_layouts = make(map[int][]string, len(slhr.Output_major_group_layouts))

	for k, v := range slhr.Output_major_group_layouts {
		req.Output_major_group_layouts[wutil.ParseInt(k)] = v
	}

	req.Output_plate_layout = make(map[int]string, len(slhr.Output_plate_layout))

	for k, v := range slhr.Output_plate_layout {
		req.Output_plate_layout[wutil.ParseInt(k)] = v
	}

	return e
}
Example #2
0
func Get_Next_Well(plate *LHPlate, component *LHComponent, curwell *LHWell) (*LHWell, bool) {
	nrow, ncol := 0, 1

	vol := component.Vol

	if curwell != nil {
		// quick check to see if we have room
		vol_left := get_vol_left(curwell)

		if vol_left >= vol {
			// fine we can just return this one
			return curwell, true
		}

		// we need a defined traversal of the wells

		crds := curwell.Crds

		tx := strings.Split(crds, ":")

		nrow = wutil.AlphaToNum(tx[0])
		ncol = wutil.ParseInt(tx[1])
	}

	wellsx := plate.WlsX
	wellsy := plate.WlsY

	var new_well *LHWell

	for {
		nrow, ncol = next_well_to_try(nrow, ncol, wellsy, wellsx)

		if nrow == -1 {
			return nil, false
		}
		crds := wutil.NumToAlpha(nrow) + ":" + strconv.Itoa(ncol)

		new_well = plate.Wellcoords[crds]

		cnts := new_well.WContents

		if len(cnts) == 0 {
			break
		}

		cont := cnts[0].Name()
		if cont != component.Name() {
			continue
		}

		vol_left := get_vol_left(new_well)
		if vol < vol_left {
			break
		}
	}

	return new_well, true
}
Example #3
0
func MakeWellCoordsXY(xy string) WellCoords {
	tx := strings.Split(xy, "Y")
	x := wutil.ParseInt(tx[0][1:len(tx[0])]) - 1
	y := wutil.ParseInt(tx[1]) - 1
	return WellCoords{x, y}
}
Example #4
0
// make well coordinates in a manner compatble with "X1,Y1" etc.
func MakeWellCoordsXYsep(x, y string) WellCoords {
	return WellCoords{wutil.ParseInt(y[1:len(y)]) - 1, wutil.ParseInt(x[1:len(x)]) - 1}
}
Example #5
0
// make well coordinates in the "1A" convention
func MakeWellCoords1A(a1 string) WellCoords {
	// only handles 96 well plates
	return WellCoords{AlphaToNum(string(a1[0])) - 1, wutil.ParseInt(a1[1:len(a1)]) - 1}
}
Example #6
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
}