Пример #1
0
        public static ArrayClass MakeData(EnsembleDataDesignParam param)
        {
            ArrayClass data = new ArrayClass();

            //E000008
            data.E_EnsembleNumber = param.TemplateData.E_EnsembleNumber;
            data.E_Cells          = param.TemplateData.E_Cells;
            data.E_Beams          = param.TemplateData.E_Beams;
            data.E_PingCount      = param.TemplateData.E_PingCount;
            data.E_Status         = 0;
            data.YYYY             = DateTime.Now.Year;
            data.MM   = DateTime.Now.Month;
            data.DD   = DateTime.Now.Day;
            data.HH   = DateTime.Now.Hour;
            data.mm   = DateTime.Now.Minute;
            data.SS   = DateTime.Now.Second;
            data.hsec = DateTime.Now.Millisecond / 10;
            //其他
            for (int i = 0; i < data.Bins.Length; i++)
            {
                data.Bins[i] = (int)data.E_Cells;
            }
            for (int i = 0; i < data.Beams.Length; i++)
            {
                data.Beams[i] = (int)data.E_Beams;
            }
            data.AmplitudeAvailable    = true;
            data.AncillaryAvailable    = true;
            data.BottomTrackAvailable  = true;
            data.CorrelationAvailable  = true;
            data.EarthAvailable        = true;
            data.EnsembleDataAvailable = true;
            data.InstrumentAvailable   = true;
            data.NmeaAvailable         = true;
            data.VelocityAvailable     = true;
            data.XfrmNAvailable        = true;

            Random random = new Random();

            for (int i = 0; i < data.E_Cells; i++)
            {
                //E000002
                data.Instrument[0, i] = (float)(Math.Sin(Math.PI / 4) * param.ReferEarthVelocity * (1 + random.NextDouble() * param.NoiseSize));
                data.Instrument[1, i] = (float)(Math.Cos(Math.PI / 4) * param.ReferEarthVelocity * (1 + random.NextDouble() * param.NoiseSize));
                data.Instrument[2, i] = 0;
                data.Instrument[3, i] = 0;

                //E000001
                data.Velocity[0, i] = 0;
                data.Velocity[1, i] = data.Instrument[0, i] * 2 * Math.Sign(param.BeamAngle / 180.0 * Math.PI);
                data.Velocity[2, i] = 0;
                data.Velocity[3, i] = data.Instrument[1, i] * 2 * Math.Sign(param.BeamAngle / 180.0 * Math.PI);;

                //E000003
                data.Earth[0, i] = data.Instrument[0, i];
                data.Earth[1, i] = data.Instrument[1, i];
                data.Earth[2, i] = 0;
                data.Earth[3, i] = 0;
                //E000004
                double a = Math.Sin(Math.PI / 4 + i / (double)data.E_Cells * Math.PI * 3 / 4);
                data.Amplitude[0, i] = (float)(a * param.ReferAmplitude * (1 + random.NextDouble() * param.NoiseSize));
                data.Amplitude[1, i] = (float)(a * param.ReferAmplitude * (1 + random.NextDouble() * param.NoiseSize));
                data.Amplitude[2, i] = (float)(a * param.ReferAmplitude * (1 + random.NextDouble() * param.NoiseSize));
                data.Amplitude[3, i] = (float)(a * param.ReferAmplitude * (1 + random.NextDouble() * param.NoiseSize));
                //E000005
                data.Correlation[0, i] = (float)(param.ReferCorrelation * (1 + random.NextDouble() * param.NoiseSize));
                data.Correlation[1, i] = (float)(param.ReferCorrelation * (1 + random.NextDouble() * param.NoiseSize));
                data.Correlation[2, i] = (float)(param.ReferCorrelation * (1 + random.NextDouble() * param.NoiseSize));
                data.Correlation[3, i] = (float)(param.ReferCorrelation * (1 + random.NextDouble() * param.NoiseSize));
                //E000006
                data.BeamN[0, i] = (int)param.TemplateData.E_EnsembleNumber;
                data.BeamN[1, i] = (int)param.TemplateData.E_EnsembleNumber;
                data.BeamN[2, i] = (int)param.TemplateData.E_EnsembleNumber;
                data.BeamN[3, i] = (int)param.TemplateData.E_EnsembleNumber;
                //E000007
                data.XfrmN[0, i] = (int)param.TemplateData.E_EnsembleNumber;
                data.XfrmN[1, i] = (int)param.TemplateData.E_EnsembleNumber;
                data.XfrmN[2, i] = (int)param.TemplateData.E_EnsembleNumber;
                data.XfrmN[3, i] = (int)param.TemplateData.E_EnsembleNumber;
            }
            //E000009
            data.A_FirstCellDepth   = param.ReferDepth / data.E_Cells;
            data.A_CellSize         = data.A_FirstCellDepth;
            data.A_FirstPingSeconds = param.TemplateData.A_FirstPingSeconds;
            data.A_LastPingSeconds  = param.TemplateData.A_LastPingSeconds;
            data.A_Heading          = 0;
            data.A_Pitch            = 0;
            data.A_Roll             = 0;
            data.A_WaterTemperature = param.TemplateData.A_WaterTemperature;
            data.A_BoardTemperature = param.TemplateData.A_BoardTemperature;
            data.A_Salinity         = param.TemplateData.A_Salinity;
            data.A_Pressure         = param.TemplateData.A_Pressure;
            data.A_Depth            = param.TemplateData.A_Depth;
            data.A_SpeedOfSound     = param.TemplateData.A_SpeedOfSound;

            //E000010
            data.B_FirstPingSeconds = param.TemplateData.B_FirstPingSeconds;
            data.B_LastPingSeconds  = param.TemplateData.B_LastPingSeconds;
            data.B_Heading          = 0;
            data.B_Pitch            = 0;
            data.B_Roll             = 0;
            data.B_WaterTemperature = param.TemplateData.B_WaterTemperature;
            data.B_BoardTemperature = param.TemplateData.B_BoardTemperature;
            data.B_Salinity         = param.TemplateData.B_Salinity;
            data.B_Pressure         = param.TemplateData.B_Pressure;
            data.B_Depth            = data.A_CellSize * data.E_Cells;
            data.B_SpeedOfSound     = param.TemplateData.B_SpeedOfSound;
            data.B_Status           = 0;
            data.B_Beams            = param.TemplateData.B_Beams;
            data.B_PingCount        = param.TemplateData.B_PingCount;
            data.B_Range[0]         = (float)(data.B_Depth * (1 + random.NextDouble() * param.NoiseSize));
            data.B_Range[1]         = (float)(data.B_Depth * (1 + random.NextDouble() * param.NoiseSize));
            data.B_Range[2]         = (float)(data.B_Depth * (1 + random.NextDouble() * param.NoiseSize));
            data.B_Range[3]         = (float)(data.B_Depth * (1 + random.NextDouble() * param.NoiseSize));
            data.B_SNR[0]           = 0;
            data.B_SNR[1]           = 0;
            data.B_SNR[2]           = 0;
            data.B_SNR[3]           = 0;
            data.B_Amplitude[0]     = param.ReferAmplitude;
            data.B_Amplitude[1]     = param.ReferAmplitude;
            data.B_Amplitude[2]     = param.ReferAmplitude;
            data.B_Amplitude[3]     = param.ReferAmplitude;
            data.B_Correlation[0]   = param.ReferCorrelation;
            data.B_Correlation[1]   = param.ReferCorrelation;
            data.B_Correlation[2]   = param.ReferCorrelation;
            data.B_Correlation[3]   = param.ReferCorrelation;
            data.B_Instrument[0]    = (float)(Math.Sin(Math.PI / 4) * param.ReferEarthVelocity * (1 + random.NextDouble() * param.NoiseSize));
            data.B_Instrument[1]    = (float)(-Math.Cos(Math.PI / 4) * param.ReferEarthVelocity * (1 + random.NextDouble() * param.NoiseSize));
            data.B_Instrument[2]    = 0;
            data.B_Instrument[3]    = 0;
            data.B_Velocity[0]      = 0;
            data.B_Velocity[1]      = data.B_Instrument[0] * 2 * Math.Sign(param.BeamAngle / 180.0 * Math.PI);
            data.B_Velocity[2]      = data.B_Instrument[1] * 2 * Math.Sign(param.BeamAngle / 180.0 * Math.PI);;
            data.B_Velocity[3]      = 0;
            data.B_Earth[0]         = data.B_Instrument[0];
            data.B_Earth[1]         = data.B_Instrument[1];
            data.B_Earth[2]         = 0;
            data.B_Earth[3]         = 0;
            data.B_BeamN[0]         = data.B_PingCount;
            data.B_BeamN[1]         = data.B_PingCount;
            data.B_BeamN[2]         = data.B_PingCount;
            data.B_BeamN[3]         = data.B_PingCount;
            data.B_XfrmN[0]         = data.B_PingCount;
            data.B_XfrmN[1]         = data.B_PingCount;
            data.B_XfrmN[2]         = data.B_PingCount;
            data.B_XfrmN[3]         = data.B_PingCount;
            data.B_EarthN[0]        = data.B_PingCount;
            data.B_EarthN[1]        = data.B_PingCount;
            data.B_EarthN[2]        = data.B_PingCount;
            data.B_EarthN[3]        = data.B_PingCount;

            return(data);
        }
Пример #2
0
        /// <summary>
        /// 计算实测单元流量
        /// </summary>
        /// <param name="src">参与计算的数据</param>
        /// <param name="boatVelocity">船速(地理坐标系下)</param>
        /// <param name="dTime">时间差</param>
        /// <returns>单元流量信息集合</returns>
        public EnsembleFlowInfo CalculateEnsembleFlow(ArrayClass src, EarthVelocity boatVelocity, double dTime)
        {
            EnsembleFlowInfo ensembleFlow = new EnsembleFlowInfo();

            ensembleFlow.Valid = false;
            if (Math.Abs(boatVelocity.EastVelocity) > 80 ||
                Math.Abs(boatVelocity.NorthVelocity) > 80)
            {
                return(ensembleFlow);
            }

            //单元大小
            double Da = src.A_CellSize;

            if (Da < 1e-6)
            {
                return(ensembleFlow);
            }
            //底跟踪四个波束中的最小深度
            double Dmin = double.NaN;
            //计算四个波束的平均深度
            int    num      = 0;
            double depthSum = 0;

            foreach (double d in src.B_Range)
            {
                if (d < 1e-6)
                {
                    continue;
                }

                if (double.IsNaN(Dmin))
                {
                    Dmin = d;
                }
                else
                {
                    if (d < Dmin)
                    {
                        Dmin = d;
                    }
                }

                num++;
                depthSum += d;
            }
            if (num == 0)
            {
                return(ensembleFlow);
            }
            double Davg = depthSum / num;

            //有效单元的可能最大深度
            double DLGmax = Dmin * Math.Cos(beamAngle / 180.0 * Math.PI) + draft - Math.Max((pulseLength + pulseLag) / 2.0, Da / 2.0);

            //水面到水底的距离
            double Dtotal = Davg + draft;

            //第一个有效单元
            MeasuredBinInfo firstValid = new MeasuredBinInfo();

            firstValid.Status = BinFlowStatus.Bad;
            //最后一个有效单元
            MeasuredBinInfo lastValid = new MeasuredBinInfo();
            //单元深度
            double binDepth = src.A_FirstCellDepth + draft;
            //实测累计流量
            double SumMeasuredFlow = 0;
            //累计东向水速
            double SumEastVelocity = 0;
            //累计北向水速
            double SumNorthVelocity = 0;
            //GoodBin个数
            int GoodBinCount = 0;
            List <MeasuredBinInfo> binsInfoArray = new List <MeasuredBinInfo>();

            // 保存有效单元的索引号
            List <int> validBinsIndex = new List <int>();

            for (int i = 0; binDepth < DLGmax && i < src.E_Cells && i * 4 < src.Earth.Length; i++, binDepth += Da)
            {
                //获取矢量交叉乘积
                double xi = CrossProduct(src.Earth[0, i], src.Earth[1, i], boatVelocity.EastVelocity, boatVelocity.NorthVelocity);

                MeasuredBinInfo binInfo = new MeasuredBinInfo();
                binInfo.Depth  = binDepth;
                binInfo.Flow   = xi * dTime * Da;
                binInfo.Status = (IsGoodBin(src, i) ? BinFlowStatus.Good : BinFlowStatus.Bad);
                binsInfoArray.Add(binInfo);

                if (binInfo.Status == BinFlowStatus.Good)
                {
                    if (firstValid.Status == BinFlowStatus.Bad)
                    {
                        firstValid = binInfo;
                    }
                    lastValid = binInfo;

                    SumMeasuredFlow += binInfo.Flow;

                    SumEastVelocity  += src.Earth[0, i];
                    SumNorthVelocity += src.Earth[1, i];
                    GoodBinCount++;

                    //保存一个有效单元索引
                    validBinsIndex.Add(i);
                }
            }
            ensembleFlow.BinsInfo = binsInfoArray.ToArray();
            if (firstValid.Status == BinFlowStatus.Bad)
            {
                return(ensembleFlow);
            }

            //第一个有效单元的深度
            double Dtop = firstValid.Depth;
            //最后一个有效单元的深度
            double Dlg = lastValid.Depth;

            double Z3 = Dtotal;
            double Z2 = Dtotal - Dtop + Da / 2.0;
            double Z1 = Dtotal - Dlg - Da / 2.0;

            //实测流量
            ensembleFlow.MeasuredFlow = dTime * (Z2 - Z1) * CrossProduct(SumEastVelocity / GoodBinCount, SumNorthVelocity / GoodBinCount,
                                                                         boatVelocity.EastVelocity, boatVelocity.NorthVelocity);

            //顶部流量
            switch (topMode)
            {
            case TopFlowMode.Constants:

                ensembleFlow.TopFlow = firstValid.Flow / Da * (Z3 - Z2);
                break;

            case TopFlowMode.PowerFunction:
            {
                double a = exponent + 1;
                ensembleFlow.TopFlow = SumMeasuredFlow * (Math.Pow(Z3, a) - Math.Pow(Z2, a)) / (Math.Pow(Z2, a) - Math.Pow(Z1, a));
            }
            break;

            case TopFlowMode.Slope:
            {
                //用于外延计算的 validbins 数量不足,则降为常数法计算
                if (validBinsIndex.Count < 6)
                {
                    ensembleFlow.TopFlow = firstValid.Flow / Da * (Z3 - Z2);
                    break;
                }
                else
                {
                    // validbin 的信息,三个列表是索引对应同一个 validbin
                    // 每个 validbin 的深度信息
                    List <double> binsDepth = new List <double>();
                    // 每个 validbin 的东向速度
                    List <double> binsEastVelocity = new List <double>();
                    // 每个 validbin 的北向速度
                    List <double> binsNorthVelocity = new List <double>();

                    for (int i = 0; i < 3; i++)
                    {
                        // validbin 索引号
                        int bin_index = validBinsIndex[i];
                        // validbin 深度(从水面起)
                        double bin_depth = src.A_FirstCellDepth + draft + bin_index * Da;
                        // 东向和北向速度
                        double bin_east_vel  = src.Earth[0, bin_index];
                        double bin_north_vel = src.Earth[1, bin_index];

                        //加入列表
                        binsDepth.Add(bin_depth);
                        binsEastVelocity.Add(bin_east_vel);
                        binsNorthVelocity.Add(bin_north_vel);
                    }

                    // 外延计算
                    // 外延的深度位置(从水面起算)
                    double dep = (Z3 - Z2) / 2;
                    // 外延计算东向速度
                    Slope east_slope = new Slope();
                    east_slope.setXYs(binsDepth.ToArray(), binsEastVelocity.ToArray());

                    double east_vel;
                    try
                    {
                        east_vel = east_slope.calY(dep);
                    }         // 外延失败,斜角为90度,转而采用常数法
                    catch (DivideByZeroException)
                    {
                        ensembleFlow.TopFlow = firstValid.Flow / Da * (Z3 - Z2);
                        break;
                    }


                    //外延计算北向速度
                    Slope north_slope = new Slope();
                    north_slope.setXYs(binsDepth.ToArray(), binsNorthVelocity.ToArray());

                    double north_vel;
                    try
                    {
                        north_vel = north_slope.calY(dep);
                    }        // 外延失败,斜角为90度,转而采用常数法
                    catch (DivideByZeroException)
                    {
                        ensembleFlow.TopFlow = firstValid.Flow / Da * (Z3 - Z2);
                        break;
                    }
                    // 计算流量
                    ensembleFlow.TopFlow = dTime * (Z3 - Z2) * CrossProduct(east_vel, north_vel,
                                                                            boatVelocity.EastVelocity, boatVelocity.NorthVelocity);
                    break;
                }
            }

            default:
                break;
            }

            //底部流量

            switch (bottomMode)
            {
            case BottomFlowMode.Constants:
                ensembleFlow.BottomFlow = lastValid.Flow / Da * Z1;
                break;

            case BottomFlowMode.PowerFunction:
            {
                double a = exponent + 1;
                ensembleFlow.BottomFlow = SumMeasuredFlow * Math.Pow(Z1, a) / (Math.Pow(Z2, a) - Math.Pow(Z1, a));
            }
            break;

            default:
                break;
            }

            ensembleFlow.Valid = true;

            return(ensembleFlow);
        }
Пример #3
0
        /// <summary>
        /// 判断是否为一个GoodBin
        /// </summary>
        /// <param name="src">参与计算数据</param>
        /// <param name="binIndex">bin的索引号</param>
        /// <returns>是否为GoodBin</returns>
        protected bool IsGoodBin(ArrayClass src, int binIndex)
        {
            try
            {
                int count = 0;
                for (int i = 0; i < 4; i++)
                {
                    if (src.Amplitude[i, binIndex] < minAmplitude)
                    {
                        count++;
                    }
                }

                if (count > 1)
                {
                    return(false);
                }

                count = 0;
                for (int i = 0; i < 4; i++)
                {
                    if (src.Correlation[i, binIndex] < minCorrelation)
                    {
                        count++;
                    }
                }

                if (count > 1)
                {
                    return(false);
                }

                //JZH 2012-02-06 JZH   取消旧判断方法
                //if (src.BeamN[0, binIndex] < minNG3
                //    || src.BeamN[1, binIndex] < minNG3
                //    || src.BeamN[2, binIndex] < minNG3
                //    || src.BeamN[3, binIndex] < minNG4)
                //    return false;
                //if (src.Earth[0, binIndex] > 88
                //    || src.Earth[1, binIndex] > 88
                //    || src.Earth[2, binIndex] > 88
                //    || src.Earth[3, binIndex] > 88
                //    )
                //    return false;

                //JZH 2012-02-06 新判断方法
                if (src.Earth[0, binIndex] > 88 ||
                    src.Earth[1, binIndex] > 88 ||
                    src.Earth[2, binIndex] > 88
                    //    || src.Earth[3, binIndex] > 88
                    )
                {
                    return(false);
                }
            }
            catch
            {
                return(false);
            }


            return(true);
        }
Пример #4
0
        /// <summary>
        /// 计算表层和底层平均流速
        /// </summary>
        /// <param name="src">参与计算的数据</param>
        public void CalculateAverageVelocity(ArrayClass src, ref double dTopVx, ref double dTopVy, ref double dBottomVx, ref double dBottomVy)
        {
            //单元大小
            double Da = src.A_CellSize;

            if (Da < 1e-6)
            {
                return;
            }
            //底跟踪四个波束中的最小深度
            double Dmin = double.NaN;
            //计算四个波束的平均深度
            int    num      = 0;
            double depthSum = 0;

            foreach (double d in src.B_Range)
            {
                if (d < 1e-6)
                {
                    continue;
                }

                if (double.IsNaN(Dmin))
                {
                    Dmin = d;
                }
                else
                {
                    if (d < Dmin)
                    {
                        Dmin = d;
                    }
                }

                num++;
                depthSum += d;
            }
            if (num == 0)
            {
                return;
            }
            double Davg = depthSum / num;

            //有效单元的可能最大深度
            double DLGmax = Dmin * Math.Cos(beamAngle / 180.0 * Math.PI) + draft - Math.Max((pulseLength + pulseLag) / 2.0, Da / 2.0);

            //水面到水底的距离
            double Dtotal = Davg + draft;

            //第一个有效单元
            MeasuredBinInfo firstValid = new MeasuredBinInfo();

            firstValid.Status = BinFlowStatus.Bad;
            //最后一个有效单元
            MeasuredBinInfo lastValid = new MeasuredBinInfo();
            //单元深度
            double binDepth = src.A_FirstCellDepth + draft;
            //累计东向水速
            double SumEastVelocity = 0;
            //累计北向水速
            double SumNorthVelocity = 0;

            for (int i = 0; binDepth < DLGmax && i < src.E_Cells && i * 4 < src.Earth.Length; i++, binDepth += Da)
            {
                MeasuredBinInfo binInfo = new MeasuredBinInfo();
                binInfo.Depth  = binDepth;
                binInfo.Status = (IsGoodBin(src, i) ? BinFlowStatus.Good : BinFlowStatus.Bad);

                if (binInfo.Status == BinFlowStatus.Good)
                {
                    if (firstValid.Status == BinFlowStatus.Bad)
                    {
                        firstValid = binInfo;
                    }
                    lastValid = binInfo;

                    SumEastVelocity  += src.Earth[0, i];
                    SumNorthVelocity += src.Earth[1, i];
                }
            }

            if (firstValid.Status == BinFlowStatus.Bad)
            {
                return;
            }

            //第一个有效单元的深度
            double Dtop = firstValid.Depth;
            //最后一个有效单元的深度
            double Dlg = lastValid.Depth;

            double Z3 = Dtotal;
            double Z2 = Dtotal - Dtop + Da / 2.0;
            double Z1 = Dtotal - Dlg - Da / 2.0;

            //表层流速
            double a = exponent + 1;

            dTopVx = SumEastVelocity * Da / (Dtop - Da / 2.0) * (Math.Pow(Z3, a) - Math.Pow(Z2, a)) / (Math.Pow(Z2, a) - Math.Pow(Z1, a));
            dTopVy = SumNorthVelocity * Da / (Dtop - Da / 2.0) * (Math.Pow(Z3, a) - Math.Pow(Z2, a)) / (Math.Pow(Z2, a) - Math.Pow(Z1, a));


            //底部流速
            dBottomVx = SumEastVelocity * Da / Z1 * Math.Pow(Z1, a) / (Math.Pow(Z2, a) - Math.Pow(Z1, a));
            dBottomVy = SumNorthVelocity * Da / Z1 * Math.Pow(Z1, a) / (Math.Pow(Z2, a) - Math.Pow(Z1, a));
        }