public WaveConduit(Pach_Graphics.colorscale C_in, double[] V_Bounds_in, Scene S)
 {
     min = Utilities.PachTools.HPttoRPt(S.Min());
     Hare.Geometry.Vector range = S.Max() - S.Min();
     nx = (int)System.Math.Ceiling(range.x);
     ny = (int)System.Math.Ceiling(range.y);
     nz = (int)System.Math.Ceiling(range.z);
     ptgrid = new List<int>[nx, ny, nz];
     for (int x = 0; x < nx; x++)
         for (int y = 0; y < ny; y++)
             for (int z = 0; z < nz; z++)
             {
                 ptgrid[x, y, z] = new List<int>();
             }
     dx = range.x / nx;
     dy = range.y / ny;
     dz = range.z / nz;
     C = C_in;
     V_Bounds = V_Bounds_in;
 }
 public WaveConduit(Pach_Graphics.colorscale C_in, double[] V_Bounds_in)
 {
     C = C_in;
     V_Bounds = V_Bounds_in;
 }
 /// <summary>
 /// Allows user to change the colors of the particles.
 /// </summary>
 /// <param name="Colors"></param>
 /// <param name="Values"></param>
 public void SetColorScale(Pach_Graphics.colorscale C_in, double[] Values)
 {
     V_Bounds = Values;
     C = C_in;
 }
            public static Mesh Get_EchoCritPercent_Map(PachMapReceiver[] Rec_List, double[] E_Bounds, Pach_Graphics.colorscale c, int Octave, List<int> SrcID, bool plotNumbers)
            {
                //T in ms.
                //Calculate C values...
                double[] E_Values = new double[Rec_List[0].Rec_List.Length];

                bool Echo10, Echo50;
                double[] EKG, PercEcho;

                for (int i = 0; i < Rec_List[0].Rec_List.Length; i++)
                {
                    double[] hist = null;
                    //double E_Sum = 0;

                    int zero = 0;

                    double z = double.MaxValue;
                    foreach (int S_ID in SrcID)
                    {
                        double t = (Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time;
                        if (z > t) z = t;
                    }
                    zero = (int)(z * Rec_List[0].SampleRate * 44.1);

                    hist = new double[(int)Math.Ceiling(Rec_List[0].SampleCT * 44.1)];

                    foreach (int S_ID in SrcID)
                    {
                        double[] P;

                        Rec_List[S_ID].GetPressure(i, out P);

                        int arrival = (int)((Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time * Rec_List[0].SampleRate) - zero;

                        for (int j = 0; j < P.Length; j++)
                        {
                            int t = j + arrival;
                            if (t >= hist.Length) break;

                            hist[t] += P[j];
                        }
                    }

                    if (Octave < 8) hist = Audio.Pach_SP.FIR_Bandpass(hist, Octave, 44100, 0);

                    AcousticalMath.EchoCriterion(hist, Rec_List[0].SampleRate, 0, true, out EKG, out PercEcho, out Echo10, out Echo50);
                    E_Values[i] = PercEcho.Max();
                }
                //Set each SPL value to a color on a color scale...
                double Scale_Breadth = E_Bounds[1] - E_Bounds[0];

                if (plotNumbers)
                {
                    int step = (int)Math.Ceiling((double)Rec_List[0].Rec_List.Length / 100);
                    for (int i = 0; i < Rec_List[0].Rec_List.Length; i += step)
                    {
                        Plane P = Plane.WorldXY;
                        P.Origin = Utilities.PachTools.HPttoRPt(Rec_List[0].Rec_List[i].H_Origin);
                        Rhino.RhinoDoc.ActiveDoc.Objects.AddText(((int)E_Values[i]).ToString(), P, Rec_List[0].Rec_List[0].Radius, "Arial", true, false);
                    }
                    return null;
                }
                else
                {
                    return PlotMesh(Rec_List, SetColors(E_Values, E_Bounds, c));
                }
            }
            /// <summary>
            /// Creates a map of the Reverberation Time in the room.
            /// </summary>
            /// <param name="STI_Bounds"></param>
            /// <param name="H_OFFSET">H value offset (HSV Color system.)</param>
            /// <param name="H_BREADTH">H value breadth (HSV Color system.)</param>
            /// <param name="S_OFFSET">S value offset (HSV Color system.)</param>
            /// <param name="S_BREADTH">S value breadth (HSV Color system.)</param>
            /// <param name="V_OFFSET">V value offset (HSV Color system.)</param>
            /// <param name="V_BREADTH">V value breadth (HSV Color system.)</param>
            /// <param name="Octave">The octave band to plot...</param>
            /// <returns>On Mesh with color assignments matching the input parameters and output variables.</returns>
            public static Mesh Get_RT_Map(PachMapReceiver[] Rec_List, double[] RT_Bounds, Pach_Graphics.colorscale c, int Decay_Depth, int Octave, List<int> SrcID, bool Coherent_Superposition, bool plotNumbers)
            {
                //T in ms.
                //Calculate T-X values...

                double[] RT_Values = new double[Rec_List[0].Rec_List.Length];

                if (Coherent_Superposition)
                {
                    for (int i = 0; i < Rec_List[0].Rec_List.Length; i++)
                    {
                        double[] hist = new double[(int)Math.Ceiling(Rec_List[0].SampleCT * 44.1)];

                        int zero = 0;
                        double z = double.MaxValue;
                        foreach (int S_ID in SrcID)
                        {
                            double t = (Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time;
                            if (z > t) z = t;
                        }
                        zero = (int)Math.Floor(z * Rec_List[0].SampleRate * 44.1);

                        foreach (int S_ID in SrcID)
                        {
                            double[] P;

                            Rec_List[S_ID].GetPressure(i, out P);

                            int arrival = (int)Math.Floor((Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time * Rec_List[0].SampleRate * 44.1) - zero;

                            for (int j = 0; j < P.Length; j++)
                            {
                                int t = j + arrival;
                                if (t >= hist.Length) break;

                                hist[t] += P[j];
                            }
                        }

                        if (Octave < 8) hist = Audio.Pach_SP.FIR_Bandpass(hist, Octave, 44100, 0);

                        for (int t = 0; t < hist.Length; t++) hist[t] *= hist[t];

                        double[] SI = AcousticalMath.Schroeder_Integral(hist);
                        RT_Values[i] = AcousticalMath.T_X(SI, Decay_Depth, Rec_List[0].SampleRate);
                    }
                }
                else
                {
                    for (int i = 0; i < Rec_List[0].Rec_List.Length; i++)
                    {
                        double[] SI = AcousticalMath.Schroeder_Integral(AcousticalMath.ETCurve(null, null, Rec_List, Rec_List[0].CutOffTime, Rec_List[0].SampleRate, Octave, i, SrcID, true));
                        RT_Values[i] = AcousticalMath.T_X(SI, Decay_Depth, Rec_List[0].SampleRate);
                    }
                }
                if (plotNumbers)
                {
                    int step = (int)Math.Ceiling((double)Rec_List[0].Rec_List.Length / 100);
                    for (int i = 0; i < Rec_List[0].Rec_List.Length; i += step)
                    {
                        Plane P = Plane.WorldXY;
                        P.Origin = Utilities.PachTools.HPttoRPt(Rec_List[0].Rec_List[i].H_Origin);
                        Rhino.RhinoDoc.ActiveDoc.Objects.AddText(((int)RT_Values[i]).ToString(), P, Rec_List[0].Rec_List[0].Radius, "Arial", true, false);
                    }
                    return null;
                }
                else
                {
                    return PlotMesh(Rec_List, SetColors(RT_Values, RT_Bounds, c));
                }
            }
            /// <summary>
            /// Assigns colors to parameter values on a Rhinoceros mesh.
            /// </summary>
            /// <param name="Values">The values of the data points</param>
            /// <param name="Bounds">Parameter bounds</param>
            /// <param name="H_OFFSET">H value offset (HSV Color system.)</param>
            /// <param name="H_BREADTH">H value breadth (HSV Color system.)</param>
            /// <param name="S_OFFSET">S value offset (HSV Color system.)</param>
            /// <param name="S_BREADTH">S value breadth (HSV Color system.)</param>
            /// <param name="V_OFFSET">V value offset (HSV Color system.)</param>
            /// <param name="V_BREADTH">V value breadth (HSV Color system.)</param>
            /// <returns>the array of color assignments which fit neatly into the mesh </returns>
            public static System.Drawing.Color[] SetColors(double[] Values, double[] Bounds, Pach_Graphics.colorscale c)
            {
                System.Drawing.Color[] Mesh_Colors = new System.Drawing.Color[Values.Length];
                double Scale_Breadth = Bounds[1] - Bounds[0];

                for (int i = 0; i < Values.Length; i++)
                {
                    System.Drawing.Color color = c.GetValue(Values[i], Bounds[0], Bounds[1]);
                    Mesh_Colors[i] = color;
                }
                return Mesh_Colors;
            }
            /// <summary>
            /// Create an integrated sound pressure level map based on the receiver positions extracted from the audience map surfaces.
            /// </summary>
            /// <param name="SPL_Bounds">The boundaries of SPL domain to be used.</param>
            /// <param name="T_Bounds">The boundaries of time domain to be used.</param>
            /// <param name="c">The Color Scale.</param>
            /// <param name="Octave">The octave band to plot...</param>
            /// <param name="SrcID">The IDs of the sources.</param>
            /// <returns>On Mesh with color assignments matching the input parameters and output variables.</returns>
            public static Mesh Get_SPLA_Map(PachMapReceiver[] Rec_List, double[] SPL_Bounds, double[] T_Bounds, Pach_Graphics.colorscale c, List<int> SrcID, bool Coherent_Superposition, bool plotNumbers)
            {
                //T in ms.
                //Calculate SPL values...
                int T_Max = (int)Math.Min(Rec_List[SrcID[0]].SampleCT, Math.Floor((T_Bounds[0])));
                int T_Min = (int)Math.Floor((T_Bounds[1]));
                double[] SPL_Values = new double[Rec_List[0].Rec_List.Length];
                Mesh MM = Rec_List[0].MapMesh();

                double[] AFactors = new double[8] { Math.Pow(10, (-26.2 / 10)), Math.Pow(10, (-16.1 / 10)), Math.Pow(10, (-8.6 / 10)), Math.Pow(10, (-3.2 / 10)), 1, Math.Pow(10, (1.2 / 10)), Math.Pow(10, (1 / 10)), Math.Pow(10, (-1.1 / 10)) };
                for (int i = 0; i < Rec_List[0].Rec_List.Length; i++)
                {
                    if (Coherent_Superposition)
                    {
                        double[] hist = new double[(int)Math.Ceiling(Rec_List[0].SampleCT * 44.1)];

                        foreach (int S_ID in SrcID)
                        {
                            double[] P;
                                
                            Rec_List[S_ID].GetPressure(i, out P);

                            int arrival = (int)Math.Floor((Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time * Rec_List[0].SampleRate * 44.1);

                            for (int j = 0; j < P.Length; j++)
                            {
                                int t = j + arrival;
                                if (t >= hist.Length) break;

                                hist[t] += P[j];
                            }
                        }

                        double[] histtemp;
                        double histtotal = 0;
                        for (int oct = 0; oct < 8; oct++)
                        {
                            histtemp = Audio.Pach_SP.FIR_Bandpass(hist, oct, 44100, 0);
                            for (int j = 0; j < histtemp.Length; j++) histtotal += histtemp[j] * AFactors[oct];
                        }

                        SPL_Values[i] = 10 * Math.Log10(histtotal / 1E-12);
                    }
                    else
                    {
                        double E_Sum = 0;
                        foreach (int S_ID in SrcID)
                        {
                            for (int oct = 0; oct < 8; oct++)
                            {
                                double E_oct_Sum = 0;
                                double[] hist = Rec_List[S_ID].GetEnergyHistogram(oct, i);
                                for (int t = T_Min; t < T_Max; t++)
                                {
                                    E_oct_Sum += hist[t];
                                }
                                E_Sum += E_oct_Sum * AFactors[oct];
                            }
                        }

                        if (E_Sum < 0)
                        {
                            Rhino.RhinoApp.Write("MEEP");
                        }

                        SPL_Values[i] = AcousticalMath.SPL_Intensity(Math.Abs(E_Sum));
                    }
                }
                if (plotNumbers)
                {
                    int step = (int)Math.Ceiling((double)Rec_List[0].Rec_List.Length / 100);
                    for (int i = 0; i < Rec_List[0].Rec_List.Length; i += step)
                    {
                        Plane P = Plane.WorldXY;
                        P.Origin = Utilities.PachTools.HPttoRPt(Rec_List[0].Rec_List[i].H_Origin);
                        Rhino.RhinoDoc.ActiveDoc.Objects.AddText(((int)SPL_Values[i]).ToString(), P, Rec_List[0].Rec_List[0].Radius, "Arial", true, false);
                    }
                    return null;
                }
                else
                {
                    return PlotMesh(Rec_List, SetColors(SPL_Values, SPL_Bounds, c));
                }
            }
            /// <summary>
            /// Create an integrated sound pressure level map based on the receiver positions extracted from the audience map surfaces.
            /// </summary>
            /// <param name="SPL_Bounds">The boundaries of SPL domain to be used.</param>
            /// <param name="T_Bounds">The boundaries of time domain to be used.</param>
            /// <param name="c">The Color Scale.</param>
            /// <param name="Octave">The octave band to plot...</param>
            /// <param name="SrcID">The IDs of the sources.</param>
            /// <returns>On Mesh with color assignments matching the input parameters and output variables.</returns>
            public static Mesh Get_SPL_Map(PachMapReceiver[] Rec_List, double[] SPL_Bounds, double[] T_Bounds, Pach_Graphics.colorscale c, int Octave, List<int> SrcID, bool Coherent_Superposition, bool ZeroAtDirect, bool plotNumbers)
            {
                //T in ms.
                //Calculate SPL values...

                double[] SPL_Values = new double[Rec_List[0].Rec_List.Length];
                Mesh MM = Rec_List[0].MapMesh();

                for (int i = 0; i < Rec_List[0].Rec_List.Length; i++)
                {
                    double[] hist;

                    if (Coherent_Superposition)
                    {
                        hist = new double[(int)Math.Ceiling(Rec_List[0].SampleCT * 44.1)];
                        double E_Sum = 0;
                        int T_Max = (int)Math.Floor((T_Bounds[0]) * 44.1);
                        int T_Min = (int)Math.Floor((T_Bounds[1]) * 44.1);
                        
                        int zero = 0;
                        if (ZeroAtDirect) 
                        {
                            double z = double.MaxValue;
                            foreach (int S_ID in SrcID)
                            {
                                double t = (Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time;
                                if (z > t) z = t;
                            }
                            zero = (int)Math.Floor(z * Rec_List[0].SampleRate * 44.1);
                        }
                        
                        foreach (int S_ID in SrcID)
                        {
                            double[] P;

                            Rec_List[S_ID].GetPressure(i, out P);
                            
                            int arrival = (int)Math.Floor((Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time * Rec_List[0].SampleRate * 44.1) - zero;

                            for (int j = 0; j < P.Length; j++)
                            {
                                int t = j + arrival;
                                if (t >= hist.Length) break;
                                
                                hist[t] += P[j];
                            }
                        }

                        if (Octave < 8)
                        {
                            hist = Audio.Pach_SP.FIR_Bandpass(hist, Octave, 44100, 0);
                        }
                        else
                        {
                            double[] histtemp;
                            double[] histtotal = new double[hist.Length];
                            for(int oct = 0; oct < 8; oct++)
                            {
                                histtemp = Audio.Pach_SP.FIR_Bandpass(hist, oct, 44100, 0);
                                for (int j = 0; j < histtemp.Length; j++) histtotal[j] += histtemp[j];
                            }
                            hist = histtotal;
                        }

                        for (int t = T_Min; t < T_Max; t++)
                        {
                            if (t >= hist.Length) break;
                            E_Sum += hist[t] * hist[t];
                        }
                        E_Sum /= Rec_List[0].Rec_List[i].Rho_C;

                        SPL_Values[i] = 10 * Math.Log10(E_Sum / 1E-12);
                    }
                    else
                    {
                        hist = new double[Rec_List[0].SampleCT];
                        double E_Sum = 0;
                        double[] temp;
                        int T_Max = (int)Math.Floor(T_Bounds[0]);
                        int T_Min = (int)Math.Floor(T_Bounds[1]);

                        int zero = 0;
                        if (ZeroAtDirect)
                        {
                            double z = double.MaxValue;
                            foreach (int S_ID in SrcID)
                            {
                                double t = (Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time;
                                if (z > t) z = t;
                            }
                            zero = (int)(z * Rec_List[0].SampleRate);
                        }

                        foreach (int S_ID in SrcID)
                        {
                            temp = Rec_List[S_ID].GetEnergyHistogram(Octave, i);
                            int arrival = (int)((Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time * Rec_List[0].SampleRate) - zero;
                            for (int j = 0; j < temp.Length; j++)
                            {
                                int t = j + arrival;
                                if (t >= hist.Length) break;
                                hist[t] += temp[j];
                            }
                        }

                        for (int t = T_Min; t < T_Max; t++)
                        {
                            if (t >= hist.Length) break;
                            E_Sum += hist[t];
                        }

                        SPL_Values[i] = AcousticalMath.SPL_Intensity(E_Sum);
                    }
                }

                if (plotNumbers)
                {
                    int step = (int)Math.Ceiling((double)Rec_List[0].Rec_List.Length / 100);
                    for (int i = 0; i < Rec_List[0].Rec_List.Length; i += step)
                    {
                        Plane P = Plane.WorldXY;
                        P.Origin = Utilities.PachTools.HPttoRPt(Rec_List[0].Rec_List[i].H_Origin);
                        Rhino.RhinoDoc.ActiveDoc.Objects.AddText(((int)SPL_Values[i]).ToString(), P, Rec_List[0].Rec_List[0].Radius, "Arial", true, false);
                    }
                    return null;
                }
                else
                {
                    return PlotMesh(Rec_List, SetColors(SPL_Values, SPL_Bounds, c));
                }
            }
            /// <summary>
            /// Creates a strength map
            /// </summary>
            /// <param name="G_Bounds"></param>
            /// <param name="Ref_Hist"></param>
            /// <param name="H_OFFSET">H value offset (HSV Color system.)</param>
            /// <param name="H_BREADTH">H value breadth (HSV Color system.)</param>
            /// <param name="S_OFFSET">S value offset (HSV Color system.)</param>
            /// <param name="S_BREADTH">S value breadth (HSV Color system.)</param>
            /// <param name="V_OFFSET">V value offset (HSV Color system.)</param>
            /// <param name="V_BREADTH">V value breadth (HSV Color system.)</param>
            /// <param name="Octave">The octave band to plot...</param>
            /// <returns>On Mesh with color assignments matching the input parameters and output variables.</returns>
            public static Mesh Get_G_Map(PachMapReceiver[] Rec_List, double[] G_Bounds, Pach_Graphics.colorscale c, int Octave, double SWL, int SrcID, bool Coherent_Superposition, bool plotNumbers)
            {
                //T in ms.
                //Calculate C values...
                double[] G_Values = new double[Rec_List[0].Rec_List.Length];

                if (Coherent_Superposition)
                {
                    for (int i = 0; i < Rec_List[0].Rec_List.Length; i++)
                   {
                        double[] hist = new double[(int)Math.Ceiling(Rec_List[0].SampleCT * 44.1)];

                        int zero = 0;
                        double z = double.MaxValue;
                        //foreach (int S_ID in SrcID)
                        //{
                            double t = (Rec_List[SrcID].Rec_List[i] as Map_Receiver).Direct_Time;
                            if (z > t) z = t;
                        //}
                        zero = (int)Math.Floor(z * Rec_List[0].SampleRate * 44.1);
                        //}

                        //foreach (int S_ID in SrcID)
                        //{
                            double[] P;

                            Rec_List[SrcID].GetPressure(i, out P);

                            int arrival = (int)Math.Floor((Rec_List[SrcID].Rec_List[i] as Map_Receiver).Direct_Time * Rec_List[0].SampleRate * 44.1) - zero;

                            for (int j = 0; j < P.Length; j++)
                            {
                                int ti = j + arrival;
                                if (ti >= hist.Length) break;

                                hist[ti] += P[j];
                            }
                        //}

                        if (Octave < 8) hist = Audio.Pach_SP.FIR_Bandpass(hist, Octave, 44100, 0);

                        for (int j = 0; j < hist.Length; j++) hist[j] *= hist[j];

                        G_Values[i] = AcousticalMath.Strength(hist, SWL, Coherent_Superposition);
                    }
                }
                else
                {
                    for (int i = 0; i < Rec_List[0].Rec_List.Length; i++)
                    {
                        G_Values[i] = AcousticalMath.Strength(Rec_List[SrcID].Rec_List[i].GetEnergyHistogram(Octave), SWL, Coherent_Superposition);
                    }
                }

                if (plotNumbers)
                {
                    int step = (int)Math.Ceiling((double)Rec_List[0].Rec_List.Length / 100);
                    for (int i = 0; i < Rec_List[0].Rec_List.Length; i += step)
                    {
                        Plane P = Plane.WorldXY;
                        P.Origin = Utilities.PachTools.HPttoRPt(Rec_List[0].Rec_List[i].H_Origin);
                        Rhino.RhinoDoc.ActiveDoc.Objects.AddText(((int)G_Values[i]).ToString(), P, Rec_List[0].Rec_List[0].Radius, "Arial", true, false);
                    }
                    return null;
                }
                else
                {

                    return PlotMesh(Rec_List, SetColors(G_Values, G_Bounds, c));
                }     
            }
            /// <summary>
            /// Creates a map of the Speech Transmission Index in the room.
            /// </summary>
            /// <param name="Rec_List"></param>
            /// <param name="STI_Bounds"></param>
            /// <param name="c"></param>
            /// <param name="NoiseSPL"></param>
            /// <param name="SrcID"></param>
            /// <param name="type"> 0 for 2003 general, 1 for Male, 2 for Female</param>
            /// <returns>On Mesh with color assignments matching the input parameters and output variables.</returns>
            public static Mesh Get_STI_Map(PachMapReceiver[] Rec_List, double[] STI_Bounds, Pach_Graphics.colorscale c, double[] NoiseSPL, List<int> SrcID, int type, bool Coherent_Superposition, bool plotNumbers)
            {
                if (type < 0 || type > 2) return Rec_List[0].Map_Mesh;

                double[] STI_Values = new double[Rec_List[0].Rec_List.Length];

                if (Coherent_Superposition)
                {
                    System.Threading.Tasks.Parallel.For(0, Rec_List[0].Rec_List.Length, i =>
                    {
                        double[] hist = new double[(int)Math.Ceiling(Rec_List[0].SampleCT * 44.1)];

                        int zero = 0;
                        double z = double.MaxValue;
                        foreach (int S_ID in SrcID)
                        {
                            double t = (Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time;
                            if (z > t) z = t;
                        }
                        zero = (int)Math.Floor(z * Rec_List[0].SampleRate * 44.1);

                        foreach (int S_ID in SrcID)
                        {
                            double[] P;

                            Rec_List[S_ID].GetPressure(i, out P);

                            int arrival = (int)Math.Floor((Rec_List[S_ID].Rec_List[i] as Map_Receiver).Direct_Time * Rec_List[0].SampleRate * 44.1) - zero;

                            for (int j = 0; j < P.Length; j++)
                            {
                                int t = j + arrival;
                                if (t >= hist.Length) break;

                                hist[t] += P[j];
                            }
                        }

                        double[][] ETC = new double[8][];
                        for (int oct = 0; oct < 8; oct++)
                        {
                            double[] h = Audio.Pach_SP.FIR_Bandpass(hist, oct, 44100, 0);
                            for (int t = 0; t < hist.Length; t++) ETC[oct][t] = h[t] * h[t] / Rec_List[0].Rec_List[i].Rho_C; 
                        }
                        STI_Values[i] = AcousticalMath.Speech_Transmission_Index(ETC, 1.2 * 343, NoiseSPL, Rec_List[0].SampleRate)[type];
                    });
                }
                else
                {
                    System.Threading.Tasks.Parallel.For(0, Rec_List[0].Rec_List.Length, i =>
                    {
                        double[][] ETC = new double[8][];
                        for (int oct = 0; oct < 8; oct++) ETC[oct] = AcousticalMath.ETCurve(null, null, Rec_List, Rec_List[0].CutOffTime, Rec_List[0].SampleRate, oct, i, SrcID, true);
                        STI_Values[i] = AcousticalMath.Speech_Transmission_Index(ETC, 1.2 * 343, NoiseSPL, Rec_List[0].SampleRate)[type];
                    });
                }
                if (plotNumbers)
                {
                    int step = (int)Math.Ceiling((double)Rec_List[0].Rec_List.Length / 100);
                    for (int i = 0; i < Rec_List[0].Rec_List.Length; i += step)
                    {
                        Plane P = Plane.WorldXY;
                        P.Origin = Utilities.PachTools.HPttoRPt(Rec_List[0].Rec_List[i].H_Origin);
                        Rhino.RhinoDoc.ActiveDoc.Objects.AddText(((int)STI_Values[i]).ToString(), P, Rec_List[0].Rec_List[0].Radius, "Arial", true, false);
                    }
                    return null;
                }
                else
                {
                    return PlotMesh(Rec_List, SetColors(STI_Values, STI_Bounds, c));
                }
            }