package org.cellocad.MIT.dnacompiler; import lombok.Getter; import lombok.Setter; import org.apache.log4j.Logger; import java.util.ArrayList; import java.util.Arrays; /** * Created by Bryan Der on 8/4/15. */ public class BuildCircuitsPermuteNOR extends BuildCircuits { public BuildCircuitsPermuteNOR(Args options, GateLibrary gate_library, Roadblock roadblock) { super(options, gate_library, roadblock); } /*********************************************************************** Synopsis [ ] Currently hard-coded to handle a single gate type (i.e. NOR/NOT). ***********************************************************************/ @Override public void buildCircuits() { logger = Logger.getLogger(getThreadDependentLoggername()); logger.info("Building circuits by permute"); set_logic_circuits( new ArrayList<LogicCircuit>() ); LogicCircuit lc = get_unassigned_lc(); Integer n_gates_circuit = lc.get_logic_gates().size(); Integer n_gates_library = get_gate_library().get_GATES_BY_NAME().keySet().size(); permuteNORGateIndices(lc, get_gate_library()); logger.info("enumerate assignments"); enumerateAssignments(); logger.info("evaluate assignments"); evaluateAssignments(); } /*********************************************************************** Synopsis [ ] Permute N-choose-K, where N = number of repressors and K = number of logic gates in the circuit. ***********************************************************************/ public void permuteNORGateIndices(LogicCircuit lc, GateLibrary gate_library) { _NOR_indexes_set = new ArrayList<int[]>(); int n_nor_gates = lc.get_logic_gates().size(); int n_groups = gate_library.get_GATES_BY_GROUP().get(Gate.GateType.NOR).keySet().size(); if(n_nor_gates <= n_groups) { //permute all combinations int n_available_gates=n_groups; int[] n = new int[n_nor_gates]; int[] Nr = new int[n_available_gates]; for (int i = 0; i<n_available_gates; ++i){ Nr[i] = n_available_gates-1; } //calculate n-choose-k combinations (Nr choose n) int nchoosek_combinations = 1; for(int i=n_available_gates; i>n_available_gates-n_nor_gates; --i) { nchoosek_combinations *= i; } logger.info("n NOR gates: " + n_nor_gates); logger.info("n repressors: " + n_available_gates); logger.info("n choose k: " + nchoosek_combinations); Permute.getIndexProduct(_NOR_indexes_set, n, Nr, 0); //_indexes_set gets populated here logger.info("Permuting repressor assignments: " + Arrays.toString(_NOR_indexes_set.get(0)) + " to " + Arrays.toString(_NOR_indexes_set.get(_NOR_indexes_set.size()-1))); } else { logger.info("not enough repressors for " + n_nor_gates + " NOR gates"); } } /*********************************************************************** Synopsis [ ] For a given repressor assignment, permute all RBS variant combinations. Example: [PhlF-rbs1, Phlf-rbs2], [QacR-rbs1], [SrpR-rbs0, SrpR-rbs1, SrpR-rbs2, SrpR-rbs3] we want to permute from [0,0,0] to [1,0,3] 1: indx = 0; 0: indx = 1; 3: indx = 2; asn.length = 3; (asn stands for assignment) rbs_assignment = ArrayList<int[]>: [0, 0, 0] [1, 0, 0] [0, 0, 1] [1, 0, 1] [0, 0, 2] [1, 0, 2] [0, 0, 3] [1, 0, 3] repr_assignment: used to figure out [1,0,3]: 3 repressors, and #variants per repressor ***********************************************************************/ public static void permuteRBS(int[] asn, ArrayList< ArrayList<Gate>> repr_assignment, ArrayList<int[]> rbs_assignment ) { rbs_assignment.add(asn.clone()); //logger.info(Arrays.toString(asn)); //if max is [1,0,3] and asn=[1,0,3], permutation is complete. boolean complete = true; for(int i=0; i<asn.length; ++i) { if(asn[i] < repr_assignment.get(i).size() - 1) { complete = false; } } if(complete == true) return; asn[0] += 1; /* if a column has reached its max, increment the next column. 0,0,0 1,0,0 2,0,0 -> 0,1,0 -> 0,0,1 0,0,1 1,0,1 2,0,1 -> 0,1,1 -> 0,0,2 0,0,2 1,0,2 2,0,2 -> 0,1,2 -> 0,0,3 */ for(int j=0; j<asn.length; ++j) { if(asn[j] > repr_assignment.get(j).size() - 1) { asn[j] = 0; asn[j+1]++; } } permuteRBS(asn, repr_assignment, rbs_assignment); } /*********************************************************************** Synopsis [ ] For each repressor assignment: check for roadblocking permute all RBS variant combinations score all RBS variant combinations ***********************************************************************/ public void enumerateAssignments(){ logger.info("Enumerating logic circuits..."); logger.info("_NOR_indexes_set " + _NOR_indexes_set.size()); for(int[] NOR_indexes: _NOR_indexes_set){ LogicCircuit lc = get_unassigned_lc(); ArrayList< ArrayList<Gate>> repr_assignment = new ArrayList< ArrayList<Gate>>(); ArrayList<int[]> rbs_assignment = new ArrayList<int[]>(); int asn[] = new int[NOR_indexes.length]; for(int i = 0; i<NOR_indexes.length; ++i){ // assign DB gate to logic gate /** * Warning: hard-coded NOR */ ArrayList<Gate> repressor = get_gate_library().getGatesByGroupByIndex( Gate.GateType.NOR, NOR_indexes[i] ); //get from hashmap (integer maps to arraylist of gates) repr_assignment.add(repressor); asn[i] = 0; //initialize to 0th element } /*if(get_options().is_check_roadblocking()) { //0th index is fine, don't care about RBS variants for roadblocking for(int i=0; i<lc.get_logic_gates().size(); ++i) { lc.get_logic_gates().get(i).Name = repr_assignment.get(i).get(0).Name; } //want to check roadblocking before permuting RBS variants boolean illegal_n_roadblocking = get_roadblock().illegalRoadblocking(lc, get_gate_library()); if (illegal_n_roadblocking) { continue; } }*/ //0 permuteRBS is recursive which is why indx is needed, but start at 0 //asn permuteRBS is recursive and modifies asn[], but it starts initialized with all 0's //repr_assignment this is the assignment of repressor proteins, but a repressor can have multiple transfer functions due to RBS strength //rbs_assignment this is the assignment of repressor rbs variants... arraylist of arrays starts empty and is filled during recursion permuteRBS(asn, repr_assignment, rbs_assignment); for(int i=0; i<rbs_assignment.size(); ++i) { int rbs_asn[] = rbs_assignment.get(i); assignNORGates(lc, repr_assignment, rbs_asn); Evaluate.refreshGateAttributes(lc, get_gate_library()); //want to check roadblocking before permuting RBS variants boolean illegal_n_roadblocking = get_roadblock().illegalRoadblocking(lc, get_gate_library()); if (illegal_n_roadblocking) { continue; } ArrayList<String> assignment_gates = new ArrayList<>(); for(Gate g: lc.get_logic_gates()) { assignment_gates.add(g.Name); } this._assignment_gate_names.add(assignment_gates); _n_total_assignments++; } } } public void evaluateAssignments() { LogicCircuit lc = get_unassigned_lc(); int counter = 0; for(ArrayList<String> gate_assignment: this._assignment_gate_names) { //logger.info(gate_assignment.toString()); counter++; if (counter % 1000 == 0) { logger.info(counter); } //logger.info(gate_assignment.toString()); for (int a = 0; a < gate_assignment.size(); ++a) { String gate_name = gate_assignment.get(a); String group_name = get_gate_library().get_GATES_BY_NAME().get(gate_name).Group; Gate g = lc.get_logic_gates().get(a); g.Name = gate_name; Evaluate.evaluateCircuit(lc, get_gate_library(), get_options()); if(get_options().is_toxicity()) { Toxicity.evaluateCircuitToxicity(lc, get_gate_library()); double growth_score = Toxicity.mostToxicRow(lc); if (growth_score < get_options().get_toxicity_threshold()) { continue; } } Double score = lc.get_scores().get_score(); if(score > this.get_best_score()) { this.set_best_score(score); get_logic_circuits().add(new LogicCircuit(lc)); } } } } /*********************************************************************** Synopsis [ ] Set all logic gate names in the circuit, then evaluateCircuit(), return score ***********************************************************************/ private void assignNORGates(LogicCircuit lc, ArrayList< ArrayList<Gate>> repr_assignment, int[] rbs_asn) { //String gates_assignment = ""; for(int i=0; i<lc.get_logic_gates().size(); ++i) { lc.get_logic_gates().get(i).Name = repr_assignment.get(i).get(rbs_asn[i]).Name; //gates_assignment += repr_assignment.get(i).get(rbs_asn[i]).Name + " "; } //logger.info(gates_assignment); } @Getter @Setter private ArrayList< ArrayList<String> > _assignment_gate_names = new ArrayList<>(); public int _n_total_assignments = 0; public static ArrayList<int[]> _NOR_indexes_set; private Logger logger = Logger.getLogger(getClass()); }