public Tube Dilut(Tube T,double ratio)
        {
            for (int s=0;s<T.TP.NumberOfStrains;s++)
            {
                double  NewN = Utils.RandBinomial(T.LastN[s],ratio);
                T.GrowDivision[T.LastT,s]-=T.LastN[s] - NewN;
            }

            T.LastT++;

            return T;
        }
        private static void RunOneSimulation(object o)
        {
            try
            {
                SimulationParameters PS = (SimulationParameters)o;

                int rep = PS.rep;
                int mi = PS.mi;
                int sid = PS.sid;

                double MutationRate = MutationRates[mi];

                TubeParameters TP = new TubeParameters(Nmax,new StrainParameters[]{
                                                       	new StrainParameters("WT",1e4,0,LagTS,1000,LagTS,1000,21,3,new StrainMutationParameters[]{new StrainMutationParameters(1,MutationRate,0)}),
                                                       	new StrainParameters("ResistanceMutant",0,0,LagTS,1000,0,0,21,3)
                                                       });

                Tube tube = new Tube(TP,maxTime);
                SimulateTube SimulateTube = new SimulateTube(PS.sid);

                tube = SimulateTube.GrowToNmax(tube);
                int s;
                for(s=0;s<maxsycles;s++)
                {
                    tube = SimulateTube.Kill(tube,240);
                    tube = SimulateTube.GrowToNmax(tube);

                    //arize of mutant
                    if(tube.LastN[1]>0)
                    {
                        Cycle2Mutant[mi,rep]=s;
                    }

                    //test 4 fixsasion or extiction.
                    if(((double)tube.LastN[1]/(tube.LastN[0]+tube.LastN[1])>0.7) || double.IsNaN((double)tube.LastN[1]/(tube.LastN[0]+tube.LastN[1])))
                    {
                        break;
                    }

                }

                if(double.IsNaN((double)tube.LastN[1]/(tube.LastN[0]+tube.LastN[1])))
                {
                    Cycle2Fixsation[mi,rep] = 0;
                }
                else
                {
                    if(((double)tube.LastN[1]/(tube.LastN[0]+tube.LastN[1])>0.7))
                    {
                        Cycle2Fixsation[mi,rep] = s;
                    }
                }

                if(DebugPrint)
                {
                    PrintTube2File("Lag=" + LagTS.ToString() + "Repetition=" + rep.ToString() + "MutationRate=" + MutationRate.ToString("e") ,tube);
                }

                SimulateTube = null;

                PrintMutFix2File( simResultsFilename, mi, rep);
            }
            finally
            {

                //Console.WriteLine(numerOfThreadsNotYetCompleted);
                PrintPresentege(MutationRates.Length*Repetitions-numerOfThreadsNotYetCompleted ,MutationRates.Length*Repetitions);
                if (Interlocked.Decrement(ref numerOfThreadsNotYetCompleted) == 0)
                {
                    _doneEvent.Set();
                }
            }
        }
        private static void PrintTube2File(string Filename,Tube T)
        {
            Filename+=  ".txt";
            System.IO.StreamWriter SR = new StreamWriter(Filename, false);

            double[,] N = T.NBacteria;
            double[] t = T.Time;

            for (int i=0; i<N.GetLength(0); i++)
            {
                SR.Write("{0}\t",t[i]);
                for (int j=0; j<N.GetLength(1); j++)
                {
                    SR.Write("{0}\t",N[i,j]);
                }
                SR.WriteLine();
            }
            SR.Close();
        }
        public Tube GrowToNmax(Tube T)
        {
            double[] N = new double[T.TP.NumberOfStrains];
            double NTot = 0;
            CommuteLagForGrow(T);
            for (int s=0;s<T.TP.NumberOfStrains;s++)
            {
                N[s]=T.LastN[s];
            }
            int t=T.LastT;

            do
            {

                for (int s=0;s<T.TP.NumberOfStrains;s++)
                {
                    double[] Mutants = new double[T.TP.NumberOfStrains];
                    double SumMutants =0 ;
                    //zero all mutans
                    for (int ms=0;ms<T.TP.NumberOfStrains;ms++)
                    {Mutants[ms] = 0;}

                    //calculate number of division results a mutation.
                    for(int ms=0;ms<T.TP.Strains[s].StrainMutationParameters.Length;ms++)
                    {

                        Mutants[T.TP.Strains[s].StrainMutationParameters[ms].Tostrain] = Utils.RandBinomial(T.GrowDivision[t,s],T.TP.Strains[s].StrainMutationParameters[ms].MutationRatePerDivition);
                        SumMutants+= Mutants[T.TP.Strains[s].StrainMutationParameters[ms].Tostrain] ;
                    }

                    //normal divisions
                    for(int i=0;i<T.GrowDivision[t,s]-SumMutants;i++)
                    {

                        //add the next 2 divisions
                        int ind;
                        ind = GetDivisionTimeIndex(T.TP.Strains[s].DivLognormalParameters,T.dt);
                        T.GrowDivision[t+ind,s]++;

                        ind = GetDivisionTimeIndex(T.TP.Strains[s].DivLognormalParameters,T.dt);
                        T.GrowDivision[t+ind,s]++;
                        N[s]++;

                    }

                    //mutation creating  divitions.
                    for(int ms=0;ms<Mutants.Length;ms++)
                    {
                        for(int i=0;i<Mutants[ms];i++)
                        {

                            //add the next 2 divisions
                            int ind;
                            //normal cell
                            ind = GetDivisionTimeIndex(T.TP.Strains[s].DivLognormalParameters,T.dt);
                            T.GrowDivision[t+ind,s]++;
                            //Mutants cell
                            ind = GetDivisionTimeIndex(T.TP.Strains[s].DivLognormalParameters,T.dt);
                            T.GrowDivision[t+ind,ms]++;
                            N[ms]++;

                        }

                    }

                }
                t++;

                NTot = 0;
                for (int s=0;s<T.TP.NumberOfStrains;s++)
                {
                    NTot +=	N[s];
                }

            }while (NTot<T.TP.Nmax && t<T.GrowDivision.GetLength(0));

            T.LastT = t-1;

            //zero future divitions
            for(int tt = t; tt<T.GrowDivision.GetLength(0);tt++)
            {
                for (int s=0;s<T.TP.NumberOfStrains;s++)
                {
                    T.GrowDivision[tt,s]=0;
                }
            }

            return T;
        }
 private Tube CommuteLagForKill(Tube T)
 {
     return CommuteLag( T,-1);
 }
 private Tube CommuteLagForGrow(Tube T)
 {
     return CommuteLag( T, 1);
 }
        private Tube CommuteLag(Tube T,double GrowKill)
        {
            //Get LagTime for each bacteria strain
            for(int s=0;s<T.TP.NumberOfStrains;s++)
            {
                //Calc Number of normal cels
                double N0Persisters = Math.Round((double)T.LastN[s]*T.TP.Strains[s].PersistersLevel);
                double N0Normal = T.LastN[s] - N0Persisters;

                double mulagNormal;
                double mulagPersisters;

                if (GrowKill == 1)//grow
                {
                    mulagNormal = 1.0/T.TP.Strains[s].LagMeanNormal;
                    mulagPersisters = 1.0/T.TP.Strains[s].LagMeanPersisters;
                }
                else//kill
                {
                    mulagNormal = 1.0/T.TP.Strains[s].KillLagMeanNormal;
                    mulagPersisters = 1.0/T.TP.Strains[s].KillLagMeanPersisters;
                }

                if (mulagNormal!=double.PositiveInfinity)
                {
                    //put normal first divition
                    for(int i=0;i<N0Normal;i++)
                    {
                        //Get the lag time
                        double LagTime = Utils.RandDecayExponantial(mulagNormal) ;
                        int GagEndInd = GetIndFromdouble(LagTime,T.dt);

                        //Get the divition (after the end of lag)
                        int Divind = GetDivisionTimeIndex(T.TP.Strains[s].DivLognormalParameters,T.dt);

                        T.GrowDivision[Divind+GagEndInd+T.LastT,s]+=GrowKill;
                    }
                }
                if (mulagPersisters!=double.PositiveInfinity)
                {
                    //put Persisters first divition
                    for(int i=0;i<N0Persisters;i++)
                    {
                        //Get the lag time for persisters.
                        double LagTime = Utils.RandDecayExponantial(mulagPersisters);
                        int GagEndInd = GetIndFromdouble(LagTime,T.dt);

                        //Get the divition (after the end of lag)
                        int Divind = GetDivisionTimeIndex(T.TP.Strains[s].DivLognormalParameters,T.dt);
                        T.GrowDivision[Divind+GagEndInd+T.LastT,s]+=GrowKill;

                    }
                }
            }
            return T;
        }
        public Tube Kill(Tube T,double KillTime)
        {
            //usin kill whan bacteria divides
            CommuteLagForKill(T);
            int KillTimeInIndexs = (int)Math.Round(KillTime/T.dt)  ;

            //zero future divitions
            for(int tt = T.LastT + KillTimeInIndexs; tt<T.GrowDivision.GetLength(0);tt++)
            {
                for (int s=0;s<T.TP.NumberOfStrains;s++)
                {
                    T.GrowDivision[tt,s]=0;
                }
            }

            T.LastT += KillTimeInIndexs;

            return T;
        }
        public Tube GrowToTime(Tube T,double Time)
        {
            int GrowTimeInIndexs = (int)Math.Round(Time/T.dt)  ;
            int EndGrowingIndex = GrowTimeInIndexs + T.LastT;

            double[] N = new double[T.TP.NumberOfStrains];
            double NTot = 0;
            CommuteLagForGrow(T);

            for (int s=0;s<T.TP.NumberOfStrains;s++)
            {
                N[s]=T.LastN[s];
            }
            int t=T.LastT;

            do
            {
                NTot = 0;
                for (int s=0;s<T.TP.NumberOfStrains;s++)
                {

                    for(int i=0;i<T.GrowDivision[t,s];i++)
                    {

                        //add the next 2 divisions
                        int ind;
                        ind = GetDivisionTimeIndex(T.TP.Strains[s].DivLognormalParameters,T.dt);
                        T.GrowDivision[t+ind,s]++;
                        ind = GetDivisionTimeIndex(T.TP.Strains[s].DivLognormalParameters,T.dt);
                        T.GrowDivision[t+ind,s]++;
                        N[s]++;

                    }

                    NTot +=N[s];
                }
                t++;

            }while (t<EndGrowingIndex);

            T.LastT = t-1;

            //zero future divitions
            for(int tt = t; tt<T.GrowDivision.GetLength(0);tt++)
            {
                for (int s=0;s<T.TP.NumberOfStrains;s++)
                {
                    T.GrowDivision[tt,s]=0;
                }
            }

            return T;
        }