/// <summary>
            /// Approximation of the 5 second order ambisonics channels. (Fig8 3Axis and omni are the first four).
            /// </summary>
            /// <param name="Direct"></param>
            /// <param name="ISData"></param>
            /// <param name="RTData"></param>
            /// <param name="CO_Time"></param>
            /// <param name="Sampling_Frequency"></param>
            /// <param name="Rec_ID"></param>
            /// <param name="Start_at_Zero"></param>
            /// <param name="xpos_alt"></param>
            /// <param name="xpos_azi"></param>
            /// <param name="degrees"></param>
            /// <returns></returns>
            public static double[][] PTCurve_Ambisonics2(Direct_Sound Direct, ImageSourceData ISData, Receiver_Bank RTData, double CO_Time_ms, int Sampling_Frequency, int Rec_ID, bool Start_at_Zero, double xpos_alt, double xpos_azi, bool degrees)
            {
                double[][] Histogram = new double[5][];
                if (RTData != null)
                {
                    double[][] hist_temp = RTData.Pressure_3Axis(Rec_ID);
                    Histogram[0] = new double[hist_temp[0].Length];
                    Histogram[1] = new double[hist_temp[0].Length];
                    Histogram[2] = new double[hist_temp[0].Length];
                    Histogram[3] = new double[hist_temp[0].Length];
                    Histogram[4] = new double[hist_temp[0].Length];
                    for (int i = 0; i < hist_temp[0].Length; i++)
                    {
                        Hare.Geometry.Vector Vpos = PachTools.Rotate_Vector(PachTools.Rotate_Vector(new Hare.Geometry.Vector(hist_temp[0][i], hist_temp[2][i], hist_temp[4][i]), xpos_azi, 0, true), 0, xpos_alt, true);
                        Hare.Geometry.Vector Vneg = PachTools.Rotate_Vector(PachTools.Rotate_Vector(new Hare.Geometry.Vector(-hist_temp[1][i], -hist_temp[3][i], -hist_temp[5][i]), xpos_azi, 0, true), 0, xpos_alt, true);
                        double magpos = Math.Sqrt(Vpos.x * Vpos.x + Vpos.y * Vpos.y + Vpos.z * Vpos.z);
                        double magneg = Math.Sqrt(Vneg.x * Vneg.x + Vneg.y * Vneg.y + Vneg.z * Vneg.z);
                        double phipos = Math.Asin(Vpos.z / magpos);
                        double phineg = Math.Asin(Vneg.z / magneg);
                        double thetapos = Math.Asin(Vpos.y / magpos / Math.Cos(phipos));
                        double thetaneg = Math.Asin(Vneg.y / magneg / Math.Cos(phineg));
                        double rt3_2 = Math.Sqrt(3) / 2;

                        double sin2phpos = Math.Sin(2 * phipos);
                        double sin2phneg = Math.Sin(2 * phineg);
                        double cossqphpos = Math.Cos(phipos) * Math.Cos(phipos);
                        double cossqphneg = Math.Cos(phineg) * Math.Cos(phineg);

                        Histogram[0][i] = magpos * (3 * (Math.Sin(phipos) * Math.Sin(phipos) - 1) / 2 + magneg * 3 * Math.Sin(phineg) * Math.Sin(phineg) - 1) / 2;
                        Histogram[1][i] = rt3_2 * (Math.Cos(thetapos) * sin2phpos * magpos + Math.Cos(thetaneg) * sin2phneg * magneg);
                        Histogram[2][i] = rt3_2 * (Math.Sin(thetapos) * sin2phpos * magpos + Math.Sin(thetaneg) * sin2phneg * magneg);
                        Histogram[3][i] = rt3_2 * (Math.Cos(2 * thetapos) * cossqphpos * magpos + Math.Cos(2 * thetaneg) * cossqphneg * magneg);
                        Histogram[4][i] = rt3_2 * (Math.Sin(2 * thetapos) * cossqphpos * magpos + Math.Sin(2 * thetaneg) * cossqphneg * magneg);
                    }
                }
                else
                {
                    Histogram[0] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                    Histogram[1] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                    Histogram[2] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                    Histogram[4] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                    Histogram[5] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                }

                if (Direct != null && Direct.IsOccluded(Rec_ID))
                {
                    int D_Start = 0;
                    if (!Start_at_Zero) D_Start = (int)Math.Ceiling(Direct.Time(Rec_ID) * Sampling_Frequency);

                    double[][] V = Direct.Dir_Pressure(Rec_ID, xpos_alt, xpos_azi, degrees, true);
                    for (int i = 0; i < V.Length; i++)
                    {
                        double mag = Math.Sqrt(V[i][0] * V[i][0] + V[i][1] * V[i][1] + V[i][2] * V[i][2]);
                        double phi = Math.Asin(V[i][2] / mag);
                        double theta = Math.Asin(V[i][1] / mag / Math.Cos(phi));
                        double rt3_2 = Math.Sqrt(3) / 2;

                        double sin2phi = Math.Sin(2 * phi);
                        double cossqphi = Math.Cos(phi) * Math.Cos(phi);

                        Histogram[0][i + D_Start] += mag * 3 * (Math.Sin(phi) * Math.Sin(phi) - 1) / 2;
                        Histogram[1][i + D_Start] += rt3_2 * Math.Cos(theta) * sin2phi * mag;
                        Histogram[2][i + D_Start] += rt3_2 * Math.Sin(theta) * sin2phi * mag;
                        Histogram[3][i + D_Start] += rt3_2 * Math.Cos(2 * theta) * cossqphi * mag;
                        Histogram[4][i + D_Start] += rt3_2 * Math.Sin(2 * theta) * cossqphi * mag;
                    }
                }

                if (ISData != null)
                {
                    foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                    {
                        if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram[0].Length - 1)
                        {
                            int R_Start = (int)Math.Ceiling(Sampling_Frequency * value.TravelTime);

                            double[][] V = value.Dir_Pressure(Rec_ID, xpos_alt, xpos_azi, degrees, Sampling_Frequency);

                            Hare.Geometry.Vector dir = value.Path[0][value.Path[0].Length - 1] - value.Path[0][value.Path[0].Length - 2];
                            dir.Normalize();
                            for (int i = 0; i < V.Length; i++)
                            {
                                double mag = Math.Sqrt(V[i][0] * V[i][0] + V[i][1] * V[i][1] + V[i][2] * V[i][2]);
                                double phi = Math.Asin(V[i][2] / mag);
                                double theta = Math.Asin(V[i][1] / mag / Math.Cos(phi));
                                double rt3_2 = Math.Sqrt(3) / 2;

                                double sin2phi = Math.Sin(2 * phi);
                                double cossqphi = Math.Cos(phi) * Math.Cos(phi);

                                Histogram[0][i + R_Start] += mag * 3 * (Math.Sin(phi) * Math.Sin(phi) - 1) / 2;
                                Histogram[1][i + R_Start] += rt3_2 * Math.Cos(theta) * sin2phi * mag;
                                Histogram[2][i + R_Start] += rt3_2 * Math.Sin(theta) * sin2phi * mag;
                                Histogram[3][i + R_Start] += rt3_2 * Math.Cos(2 * theta) * cossqphi * mag;
                                Histogram[4][i + R_Start] += rt3_2 * Math.Sin(2 * theta) * cossqphi * mag;
                            }
                        }
                    }
                }
                return Histogram;
            }
            public static double[] ETCurve_Directional(Direct_Sound Direct, ImageSourceData ISData, Receiver_Bank RTData, double CO_Time_ms, int Sampling_Frequency, int Octave, int Rec_ID, bool Start_at_Zero, double alt, double azi, bool degrees)
            {
                double[] Histogram = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency)];
                    if (RTData != null)
                    {
                        for (int i = 0; i < Histogram.Length; i++)
                        {
                            Hare.Geometry.Vector Vpos = RTData.Directions_Pos(Octave, i, Rec_ID, alt, azi, degrees);
                            Hare.Geometry.Vector Vneg = RTData.Directions_Neg(Octave, i, Rec_ID, alt, azi, degrees);

                            double E = RTData.Rec_List[Rec_ID].Energy(i, Octave);
                            Hare.Geometry.Vector VTot = new Hare.Geometry.Vector(Math.Abs(Vpos.x) - Math.Abs(Vneg.x), Math.Abs(Vpos.y) - Math.Abs(Vneg.y), Math.Abs(Vpos.z) - Math.Abs(Vneg.z));

                            if (Vpos.x > 0)
                            {
                                Histogram[i] += Math.Abs(Vpos.x);
                            }
                            if (Vneg.x > 0)
                            {
                                Histogram[i] += Math.Abs(Vneg.x);
                            }

                            double L = VTot.Length();
                            if (L > 0) Histogram[i] *= E / L;

                            if (AcousticalMath.SPL_Intensity(Histogram[i]) > 200)
                            {
                                Rhino.RhinoApp.Write("Super high SPLs... what's going on, man?");
                            }
                        }
                    }

                    if (Direct != null && Direct.IsOccluded(Rec_ID))
                    {
                        int D_Start = 0;
                        if (!Start_at_Zero) D_Start = (int)Math.Ceiling(Direct.Time(Rec_ID) * Sampling_Frequency);

                        Hare.Geometry.Vector[] DirectValue;
                        switch (Octave)
                        {
                            case 8:
                                DirectValue = Direct.Dir_Energy_Sum(Rec_ID, alt, azi, degrees);
                                break;
                            default:
                                DirectValue = Direct.Dir_Energy(Octave, Rec_ID, alt, azi, degrees);
                                break;
                        }

                        for (int i = 0; i < DirectValue.Length; i++)
                        {
                            if (DirectValue[i].x > 0) Histogram[D_Start + i] += Math.Abs(DirectValue[i].x);
                        }
                    }

                    if (ISData != null)
                    {
                        switch (Octave)
                        {
                            case 8:
                                foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                                {
                                    if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram.Length - 1)
                                    {
                                        Hare.Geometry.Vector[] E_Sum = value.Dir_EnergySum(alt, azi, degrees);
                                        for (int i = 0; i < E_Sum.Length; i++)
                                        {
                                            if (E_Sum[i].x > 0) Histogram[(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i)] += Math.Abs(E_Sum[i].x);
                                        }
                                    }
                                }
                                break;
                            default:
                                foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                                {
                                    if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram.Length - 1)
                                    {
                                        Hare.Geometry.Vector[] E_Dir = value.Dir_Energy(Octave, alt, azi, degrees);
                                        for (int i = 0; i < E_Dir.Length; i++)
                                        {
                                            if (E_Dir[i].x > 0) Histogram[(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i)] += Math.Abs(E_Dir[i].x);
                                        }
                                    }
                                }
                                break;
                        }
                    }
                    return Histogram;
            }
            public static double[] PTCurve_Directional(Direct_Sound Direct, ImageSourceData ISData, Receiver_Bank RTData, double CO_Time_ms, int Sampling_Frequency, int Octave, int Rec_ID, bool Start_at_Zero, double alt, double azi, bool degrees)
            {
                double[] Histogram;
                if (RTData != null)
                {
                    int[] ids = new int[3];
                    ids[0] = (azi > 90 && azi < 270) ? 1 : 0;
                    ids[0] = (azi <= 180) ? 3 : 4;
                    ids[0] = (alt > 0) ? 4 : 5;
                    double[][] hist_temp = RTData.Pressure_3Axis(Rec_ID);
                    Histogram = new double[hist_temp[0].Length];
                    for (int i = 0; i < hist_temp[0].Length; i++)
                    {
                        Hare.Geometry.Vector V = PachTools.Rotate_Vector(PachTools.Rotate_Vector(new Hare.Geometry.Vector(hist_temp[ids[0]][i], hist_temp[ids[1]][i], hist_temp[ids[2]][i]), azi, 0, true), 0, alt, true);
                        Histogram[i] = V.x;
                    }
                }
                else
                {
                    Histogram = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                }

                if (Direct != null && Direct.IsOccluded(Rec_ID))
                {
                    int D_Start = 0;
                    if (!Start_at_Zero) D_Start = (int)Math.Ceiling(Direct.Time(Rec_ID) * Sampling_Frequency);

                    double[][] V = Direct.Dir_Pressure(Rec_ID, alt, azi, degrees, false);
                    for (int i = 0; i < V.Length; i++)
                    {
                        Histogram[D_Start + i] += V[i][0];
                    }
                }

                if (ISData != null)
                {
                    foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                    {
                        if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram.Length - 1)
                        {
                            int R_Start = (int)Math.Ceiling(Sampling_Frequency * value.TravelTime);

                            double[] V = value.Dir_Pressure(Rec_ID, alt, azi, degrees, false, Sampling_Frequency);
                            for (int i = 0; i < value.Pressure.Length; i++)
                            {
                                Histogram[R_Start + i] += V[i];
                            }
                        }
                    }
                }
                return Histogram;
            }
            public static double[][] ETCurve_1d(Direct_Sound Direct, ImageSourceData ISData, Receiver_Bank RTData, double CO_Time_ms, int Sampling_Frequency, int Octave, int Rec_ID, bool Start_at_Zero, double alt, double azi, bool degrees)
            {
                double[][] Histogram = new double[3][];
                    Histogram[0] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency)];
                    Histogram[1] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency)];
                    Histogram[2] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency)];
                    if (RTData != null)
                    {
                        for (int i = 0; i < Histogram[0].Length; i++)
                        {
                            Hare.Geometry.Vector Vpos = RTData.Directions_Pos(Octave, i, Rec_ID, alt, azi, degrees);
                            Hare.Geometry.Vector Vneg = RTData.Directions_Neg(Octave, i, Rec_ID, alt, azi, degrees);

                            double E = RTData.Rec_List[Rec_ID].Energy(i, Octave);
                            Hare.Geometry.Vector VTot = new Hare.Geometry.Vector(Math.Abs(Vpos.x) - Math.Abs(Vneg.x), Math.Abs(Vpos.y) - Math.Abs(Vneg.y), Math.Abs(Vpos.z) - Math.Abs(Vneg.z));
                            VTot.Normalize();
                            VTot *= E;

                            Histogram[0][i] = VTot.x;
                            Histogram[1][i] = VTot.y;
                            Histogram[2][i] = VTot.z;
                        }
                    }

                    if (Direct != null && Direct.IsOccluded(Rec_ID))
                    {
                        int D_Start = 0;
                        if (!Start_at_Zero) D_Start = (int)Math.Ceiling(Direct.Time(Rec_ID) * Sampling_Frequency);

                        Hare.Geometry.Vector[] DirectValue;
                        switch (Octave)
                        {
                            case 8:
                                DirectValue = Direct.Dir_Energy_Sum(Rec_ID, alt, azi, degrees);
                                break;
                            default:
                                DirectValue = Direct.Dir_Energy(Octave, Rec_ID, alt, azi, degrees);
                                break;
                        }

                        for (int i = 0; i < DirectValue.Length; i++)
                        {
                            Histogram[0][D_Start + i] += Math.Abs(DirectValue[i].x);
                            Histogram[1][D_Start + i] += Math.Abs(DirectValue[i].y);
                            Histogram[2][D_Start + i] += Math.Abs(DirectValue[i].z);
                        }
                    }

                    if (ISData != null)
                    {
                        switch (Octave)
                        {
                            case 8:
                                foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                                {
                                    if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram[0].Length - 1)
                                    {
                                        Hare.Geometry.Vector[] E_Sum = value.Dir_EnergySum(alt, azi, degrees);
                                        for (int i = 0; i < E_Sum.Length; i++)
                                        {
                                            Histogram[0][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Sum[i].x);
                                            Histogram[1][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Sum[i].y);
                                            Histogram[2][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Sum[i].z);
                                        }
                                    }
                                }
                                break;
                            default:
                                foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                                {
                                    if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram[0].Length - 1)
                                    {
                                        Hare.Geometry.Vector[] E_Dir = value.Dir_Energy(Octave, alt, azi, degrees);
                                        for (int i = 0; i < E_Dir.Length; i++)
                                        {
                                            Histogram[0][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Dir[i].x);
                                            Histogram[1][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Dir[i].y);
                                            Histogram[2][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Dir[i].z);
                                        }
                                    }
                                }
                                break;
                        }
                    }
                    return Histogram;
            }
            public static double[][] PTCurve_Fig8_3Axis(Direct_Sound Direct, ImageSourceData ISData, Receiver_Bank RTData, double CO_Time_ms, int Sampling_Frequency, int Rec_ID, bool Start_at_Zero, double xpos_alt, double xpos_azi, bool degrees)
            {
                double[][] Histogram = new double[3][];
                if (RTData != null)
                {
                    double[][] hist_temp = RTData.Pressure_3Axis(Rec_ID);
                    Histogram[0] = new double[hist_temp[0].Length];
                    Histogram[1] = new double[hist_temp[0].Length];
                    Histogram[2] = new double[hist_temp[0].Length];
                    for (int i = 0; i < hist_temp[0].Length; i++)
                    {
                        Hare.Geometry.Vector V = PachTools.Rotate_Vector(PachTools.Rotate_Vector(new Hare.Geometry.Vector(hist_temp[0][i] - hist_temp[1][i], hist_temp[2][i] - hist_temp[3][i], hist_temp[4][i] - hist_temp[5][i]), xpos_azi, 0, true), 0, xpos_alt, true);
                        Histogram[0][i] = V.x;
                        Histogram[1][i] = V.y;
                        Histogram[2][i] = V.z;
                    }
                }
                else
                {
                    Histogram[0] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                    Histogram[1] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                    Histogram[2] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                }

                if (Direct != null && Direct.IsOccluded(Rec_ID))
                {
                    int D_Start = 0;
                    if (!Start_at_Zero) D_Start = (int)Math.Ceiling(Direct.Time(Rec_ID) * Sampling_Frequency);

                    double[][] V = Direct.Dir_Pressure(Rec_ID, xpos_alt, xpos_azi, degrees, true);
                    for (int i = 0; i < V.Length; i++)
                    {
                        Histogram[0][D_Start + i] += V[i][0];
                        Histogram[1][D_Start + i] += V[i][1];
                        Histogram[2][D_Start + i] += V[i][2];
                    }
                }

                if (ISData != null)
                {
                    foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                    {
                        if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram[0].Length - 1)
                        {
                            int R_Start = (int)Math.Ceiling(Sampling_Frequency * value.TravelTime);

                            double[][] V = value.Dir_Pressure(Rec_ID, xpos_alt, xpos_azi, degrees, Sampling_Frequency);

                            Hare.Geometry.Vector dir = value.Path[0][value.Path[0].Length - 1] - value.Path[0][value.Path[0].Length - 2];
                            dir.Normalize();
                            for (int i = 0; i < value.Pressure.Length; i++)
                            {
                                Histogram[0][R_Start + i] += V[i][0];
                                Histogram[1][R_Start + i] += V[i][1];
                                Histogram[2][R_Start + i] += V[i][2];
                            }
                        }
                    }
                }
                return Histogram;
            }