// public double MisrejoiningProb(Free_end fe1, Free_end fe2) { double dist2 = (fe1.L.X - fe2.L.X) * (fe1.L.X - fe2.L.X) + (fe1.L.Y - fe2.L.Y) * (fe1.L.Y - fe2.L.Y) + (fe1.L.Z - fe2.L.Z) * (fe1.L.Z - fe2.L.Z); // Eucld. distance between free ends double dtemp = 0.08 * (1.0 / Z) * Math.Exp(-dist2 / sigma2); // the probability to misrejoin or create a ring return(dtemp); }
// public bool RestitutionKinetics(List <Object> listObjs) { // the class FreeEnds is derived from DSBs class and is based on DSBdata // Free_end class is for Objects (which are fragments that can have free ends) Random random = new Random(); try { for (int i = 0; i < Convert.ToInt32(expTime / tau); i++) // number of elementary time steps { if (!SplitObjects(listObjs, i * tau, (i + 1) * tau)) { return(false); // split only using DSBs avaibale in time interval timeIncrement / tau } int availableFreeEnds = 0; foreach (Object o in listObjs) { foreach (Free_end fe in o.md.f_e) { if (fe.FE_type == MetaData.FreeEndType.reactive) { availableFreeEnds++; } } } if (availableFreeEnds != 0) { for (int j = 0; j < availableFreeEnds / 2; j++) // cycle through all pairs of Free Ends in one elementary time step { int availableFreeEnds1 = 0; foreach (Object o in listObjs) { foreach (Free_end fe in o.md.f_e) { if (fe.FE_type == MetaData.FreeEndType.reactive) { availableFreeEnds1++; // determine the number of free ends, which are still reactive } } } int end1, end2; while (true) { end1 = random.Next(0, availableFreeEnds1); end2 = random.Next(0, availableFreeEnds1); if (end1 != end2) { break; } } int itemp = 0; Free_end freeend1 = null, freeend2 = null; foreach (Object o in listObjs) { bool b = false; foreach (Free_end fe in o.md.f_e) { if (fe.FE_type == MetaData.FreeEndType.reactive) { if (itemp == end1) { fe.Reacting = true; freeend1 = fe; b = true; break; } itemp++; } } if (b) { break; } } itemp = 0; foreach (Object o in listObjs) { bool b = false; foreach (Free_end fe in o.md.f_e) { if (fe.FE_type == MetaData.FreeEndType.reactive) { if (itemp == end2) { fe.Reacting = true; // this marks a free end for rejoining/misrejoining freeend2 = fe; b = true; break; } itemp++; } } if (b) { break; } } if (freeend1 != null && freeend2 != null) { if (freeend1.Position == freeend2.Position) // proper ends { if (SimpleRNG.GetUniform() < P) { Object o_new = new Object(); if (CreateMergedObj(o_new, listObjs)) // merge the chosen reactive ends in the chosen objects and remove the objs with this pair of free ends { listObjs.Add(o_new); // renumber bands in the whole genome int[] b_index = new int[46]; foreach (Object o in listObjs) { foreach (Band b in o.md.chromo_bands) { b_index[b.Chromo_num]++; b.Ordinal_number = b_index[b.Chromo_num]; } } } else { o_new = null; // this happens when one if the members of listObjs becomes a ring } } } else { if (SimpleRNG.GetUniform() < MisrejoiningProb(freeend1, freeend2)) { Object o_new = new Object(); if (CreateMergedObj(o_new, listObjs)) // merge the chosen reactive ends in the chosen objects { listObjs.Add(o_new); // renumber bands in the whole genome int[] b_index = new int[46]; foreach (Object o in listObjs) { foreach (Band b in o.md.chromo_bands) { b_index[b.Chromo_num]++; b.Ordinal_number = b_index[b.Chromo_num]; } } } else { o_new = null; // this happens when one if the members of listObjs becomes a ring } } } // if nothing happens de-activate free ends foreach (Object o in listObjs) { foreach (Free_end fe in o.md.f_e) { if (fe.Reacting) { fe.Reacting = false; } } } } } } } if (CheckDSBlist(DSBdata) && CheckObjList(listObjs)) { return(true); } else { return(false); } } catch { // merge failure Detailed_checkObjList(listObjs); Detailed_checkDSBlist(DSBdata); return(false); } }