Example #1
0
        public ReportViewForm(Report report)
        {
            InitializeComponent();
            SingleAnalysisTabPage.Text = "360\x00B0Analysis";
            mIsViewReport = true;
            mViewReport = report;

            mTask = DataCenter.Instance().Tasks[report.TaskID];
            mChannelSettings = DataCenter.Instance().ChannelSettings[report.ChannelSettingID];
            mEmiFileData = DataCenter.Instance().EMIs[mViewReport.EmiFileID];

            mLimitSetting = mViewReport.LimitSetting;
        }
Example #2
0
        public VenezuelaReportForm(LimitSetting limitSetting, double azimuthA, double azimuthB, EMIFileData emiA, EMIFileData emiB, List<ChannelSetting> channelSettings)
        {
            InitializeComponent();

            mLimitSetting = limitSetting;
            mAzimuthA = azimuthA;
            mAzimuthB = azimuthB;
            mEmiA = emiA;
            mEmiB = emiB;
            mChannelSettings = channelSettings;

            //int graphCount = mIniFile.ReadInt("General", "VenezuelaReportGraphCount", 1);
            mExportStatusForm = new ExportStatusForm(this);
        }
Example #3
0
        public MalaysiaReportForm(bool isFiveAzimuthReport, LimitSetting limitSetting, EMIFileData emiA, EMIFileData emiB, List<ChannelSetting> channelSettings)
        {
            InitializeComponent();

            mIsFiveAzimuthReport = isFiveAzimuthReport;

            mLimitSetting = limitSetting;
            mEmiA = emiA;
            mEmiB = emiB;
            mChannelSettings = channelSettings;

            EmiComboBox.Items.Add(mEmiA.Site_ID + " (User: "******", Time: " + mEmiA.PA_TestTime + ")");
            EmiComboBox.Items.Add(mEmiB.Site_ID + " (User: "******", Time: " + mEmiB.PA_TestTime + ")");

            mExportStatusForm = new ExportStatusForm(this);
        }
Example #4
0
        public ChannelPower(double emiRbw, ChannelSetting channelSetting, 
            LimitSetting limitSetting, WatsEmiData watsEmiData)
        {
            foreach (WatsEmiSample sample in watsEmiData.mHSamples)
                mHPower += Math.Pow(10, sample.mRssi / 10);
            mHPower = mHPower / watsEmiData.mHSamples.Count;
            mHPower = 10 * Math.Log10(channelSetting.BandWidth * 1000 * mHPower / emiRbw);

            foreach (WatsEmiSample sample in watsEmiData.mHPairSamples)
                mHPairPower += Math.Pow(10, sample.mRssi / 10);
            mHPairPower = mHPairPower / watsEmiData.mHPairSamples.Count;
            mHPairPower = 10 * Math.Log10(channelSetting.Pair.BandWidth * 1000 * mHPairPower / emiRbw);

            foreach (WatsEmiSample sample in watsEmiData.mVSamples)
                mVPower += Math.Pow(10, sample.mRssi / 10);
            mVPower = mVPower / watsEmiData.mVSamples.Count;
            mVPower = 10 * Math.Log10(channelSetting.BandWidth * 1000 * mVPower / emiRbw);

            foreach (WatsEmiSample sample in watsEmiData.mVPairSamples)
                mVPairPower += Math.Pow(10, sample.mRssi / 10);
            mVPairPower = mVPairPower / watsEmiData.mVPairSamples.Count;
            mVPairPower = 10 * Math.Log10(channelSetting.Pair.BandWidth * 1000 * mVPairPower / emiRbw);

            if (limitSetting.UseDeltaPowerLimit
                && Utility.CalculateDeltaPower(watsEmiData.mHSamples) > Math.Abs(limitSetting.DeltaPowerLimit))
                mIsValidHPower = false;
            if (limitSetting.UseDeltaPowerLimit
                && Utility.CalculateDeltaPower(watsEmiData.mVSamples) > Math.Abs(limitSetting.DeltaPowerLimit))
                mIsValidVPower = false;
            if (limitSetting.UseDeltaPowerLimit
                && Utility.CalculateDeltaPower(watsEmiData.mHPairSamples) > Math.Abs(limitSetting.DeltaPowerLimit))
                mIsValidHPairPower = false;
            if (limitSetting.UseDeltaPowerLimit
                && Utility.CalculateDeltaPower(watsEmiData.mVPairSamples) > Math.Abs(limitSetting.DeltaPowerLimit))
                mIsValidVPairPower = false;

            if (mIsValidHPower && limitSetting.UseChannelPowerLimit && mHPower > limitSetting.ChannelPowerLimit)
                mIsValidHPower = false;
            if (mIsValidVPower && limitSetting.UseChannelPowerLimit && mVPower > limitSetting.ChannelPowerLimit)
                mIsValidVPower = false;
            if (mIsValidHPairPower && limitSetting.UseChannelPowerLimit && mHPairPower > limitSetting.ChannelPowerLimit)
                mIsValidHPairPower = false;
            if (mIsValidVPairPower && limitSetting.UseChannelPowerLimit && mVPairPower > limitSetting.ChannelPowerLimit)
                mIsValidVPairPower = false;
        }
Example #5
0
        public ReportForm(bool isFiveAzimuthReport, LimitSetting limitSetting, EMIFileData emiFileData, List<ChannelSetting> channelSettings)
        {
            InitializeComponent();

            mIsFiveAzimuthReport = isFiveAzimuthReport;

            mLimitSetting = limitSetting;
            mEmiFileData = emiFileData;
            mChannelSettings = channelSettings;

            SiteIDLabel.Text = mEmiFileData.Site_ID;
            SiteNameLabel.Text = mEmiFileData.Site_ID;
            AddressLabel.Text = mEmiFileData.Site_Address;
            DateLabel.Text = mEmiFileData.PA_TestTime;
            EngineerLabel.Text = mEmiFileData.PA_UserName;
            LongtitudeLabel.Text = Utility.ConvertLongtitude(mEmiFileData.Site_Longitude);
            LatitudeLabel.Text = Utility.ConvertLatitude(mEmiFileData.Site_Longitude); ;

            if (mLimitSetting.UseChannelPowerLimit)
                PChannelLimitLabel.Text = mLimitSetting.ChannelPowerLimit.ToString();
            else
                PChannelLimitLabel.Text = "";

            if (mLimitSetting.UseDeltaPowerLimit)
                LevelLimitLabel.Text = mLimitSetting.DeltaPowerLimit.ToString();
            else
                LevelLimitLabel.Text = "";

            if (mIniFile.ReadInt("General", "ChannelPreferred", 1) == 1)
                ChannelPreferredRadioButton.Checked = true;
            else
                FrequencePreferredRadioButton.Checked = true;

            DisplayChannelCheckBox.Enabled = (!ChannelPreferredRadioButton.Checked);
            DisplayChannelCheckBox.Checked = (mIniFile.ReadInt("General", "DisplayChannel", 1) == 1);
            SpanEditor.Text = mIniFile.ReadString("General", "Span", "300").Trim();
            if (!Regex.IsMatch(SpanEditor.Text, @"^[1-9]\d*(\.\d+)?$"))
                SpanEditor.Text = "300";

            mDefaultStartFreq = channelSettings[0].StartFreq;
            mDefaultEndFreq = channelSettings[channelSettings.Count -1].Pair.EndFreq;
            SetDefaultFreq();

            mExportStatusForm = new ExportStatusForm(this);
        }
Example #6
0
        public MalaysiaMaxisReportForm(LimitSetting limitSetting, 
            EMIFileData emiFileData, List<ChannelSetting> channelSettings)
        {
            mLimitSetting = limitSetting;
            mEmi = emiFileData;

            string bandName;
            foreach (ChannelSetting channelSetting in channelSettings)
            {
                bandName = GetBandName(channelSetting);
                if (!mAllBandChannels.ContainsKey(bandName))
                {
                    mAllBandChannels[bandName] = new List<ChannelSetting>();
                }
                mAllBandChannels[bandName].Add(channelSetting);
            }

            mEmiDataMgr = Utility.GetEmiDataManager(mEmi, channelSettings);
            mExportStatusForm = new ExportStatusForm(this);

            InitializeComponent();
        }
Example #7
0
        private void ReportButton_Click(object sender, EventArgs e)
        {
            if (!ValidateReport())
                return;

            StoreFileConfiguration();
            mIniFile.WriteInt("General", "AllAnglesMode", (OnePairReportCheckBox.Checked ? 0:1));

            List<ChannelSetting> channelSettings;
            string channelSttingFile = ChannelSettingFileList.SelectedItem.ToString();
            if (mChannelSettingFiles.ContainsKey(channelSttingFile))
            {
                channelSettings = mChannelSettingFiles[channelSttingFile];
            }
            else
            {
                channelSettings = ChannelSettingReader.Read(channelSttingFile);
                if (channelSettings.Count == 0)
                {
                    MessageBox.Show("Invalid channel setting !");
                    return;
                }
                mChannelSettingFiles[channelSttingFile] = channelSettings;
            }

            if (GeneralRadioButton.Checked && OnePairReportCheckBox.Checked)
            {
                if (ConfigurationTabControl.SelectedIndex == 0)
                {
                    if (LinkConfigFileList.SelectedIndex >= 0)
                    {
                        List<LinkConfiguration> linkConfigurations;
                        string linkConfigurationFile = LinkConfigFileList.SelectedItem.ToString();
                        if (mLinkConfigurationFiles.ContainsKey(linkConfigurationFile))
                        {
                            linkConfigurations = mLinkConfigurationFiles[linkConfigurationFile];
                        }
                        else
                        {
                            linkConfigurations = LinkConfigurationReader.Read(linkConfigurationFile);
                            if (linkConfigurations.Count == 0)
                            {
                                MessageBox.Show("Invalid link configuration !");
                                return;
                            }
                            mLinkConfigurationFiles[linkConfigurationFile] = linkConfigurations;
                        }
                    }
                }

                if (EquipParameterFileList.SelectedIndex >= 0)
                {
                    Dictionary<string, EquipmentParameter> equipmentParameters;
                    string equipmentParameterFile = EquipParameterFileList.SelectedItem.ToString();
                    if (mEquipmentParametersFiles.ContainsKey(equipmentParameterFile))
                    {
                        equipmentParameters = mEquipmentParametersFiles[equipmentParameterFile];
                    }
                    else
                    {
                        equipmentParameters = EquipmentParameterReader.Read(equipmentParameterFile);
                        if (equipmentParameters.Count == 0)
                        {
                            MessageBox.Show("Invalid equipment parameter !");
                            return;
                        }
                        mEquipmentParametersFiles[equipmentParameterFile] = equipmentParameters;
                    }
                }
            }

            LimitSettingForm limitSettingForm = new LimitSettingForm();
            if (DialogResult.Cancel == limitSettingForm.ShowDialog())
                return;

            LimitSetting limitSetting = new LimitSetting();
            limitSetting.UseChannelPowerLimit = limitSettingForm.UseChannelPowerLimit;
            limitSetting.UseDeltaPowerLimit = limitSettingForm.UseDeltaPowerLimit;
            limitSetting.ChannelPowerLimit = limitSettingForm.ChannelPowerLimit;
            limitSetting.DeltaPowerLimit = limitSettingForm.DeltaPowerLimit;

            if (OtherRadioButton.Checked) //Malaysia or Venezuela
            {
                List<string> emiFiles = new List<string>();
                List<EMIFileData> emiFileDatas = new List<EMIFileData>();
                foreach (KeyValuePair<string, EMIFileData> pair in mEmiFiles)
                {
                    emiFiles.Add(pair.Key);
                    emiFileDatas.Add(pair.Value);
                }

                if (OtherTypeComboBox.SelectedIndex != 2)
                {
                    EMIPairSelectForm emiPairSelectForm = new EMIPairSelectForm(emiFiles, emiFileDatas);
                    emiPairSelectForm.IsOnlySitesSelectable = (OtherTypeComboBox.SelectedIndex == 1);
                    if (emiPairSelectForm.ShowDialog() == DialogResult.Cancel)
                        return;

                    EMIFileData dataA = emiPairSelectForm.EmiA;
                    EMIFileData dataB = emiPairSelectForm.EmiB;

                    if (OtherTypeComboBox.SelectedIndex == 3) //Venezuela Report
                    {
                        VenezuelaReportForm venezuelaReportForm = new VenezuelaReportForm(limitSetting,
                        emiPairSelectForm.AzimuthA, emiPairSelectForm.AzimuthB,
                        dataA, dataB, channelSettings);
                        Hide();
                        venezuelaReportForm.Show();
                    }
                    else
                    {
                        MalaysiaReportForm malaysiaReportForm
                            = new MalaysiaReportForm(OtherTypeComboBox.SelectedIndex == 0,
                                limitSetting, dataA, dataB, channelSettings);
                        if (OtherTypeComboBox.SelectedIndex == 0)
                        {
                            malaysiaReportForm.OppositeAzimuthA = emiPairSelectForm.AzimuthA;
                            malaysiaReportForm.OppositeAzimuthB = emiPairSelectForm.AzimuthB;
                        }

                        Hide();
                        malaysiaReportForm.Show();
                    }

                }
                else if (OtherTypeComboBox.SelectedIndex == 2) //Malaysia Maxis Report
                {
                    EMISingleSelectForm emiSingleSelectForm = new EMISingleSelectForm(emiFiles, emiFileDatas);
                    if (emiSingleSelectForm.ShowDialog() == DialogResult.Cancel)
                        return;

                    EMIFileData emiFileData = emiSingleSelectForm.Emi;
                    if (emiFileData == null)
                        return;

                    MalaysiaMaxisReportForm malaysiaMaxisReportForm
                        = new MalaysiaMaxisReportForm(limitSetting, emiFileData, channelSettings);

                    Hide();
                    malaysiaMaxisReportForm.Show();
                }

                return;
            }
            else if (!OnePairReportCheckBox.Checked)    //General 360
            {
                EMIFileData emiFileData;
                if (!mEmiFiles.ContainsKey(EMIFilesList.SelectedItem.ToString()))
                {
                    MessageBox.Show(EMIFilesList.SelectedItem.ToString() + " is an invalid EMI file, \r\nplease choose another file !");
                    return;
                }
                emiFileData = mEmiFiles[EMIFilesList.SelectedItem.ToString()];

                bool isFiveAzimuthReport = (OtherTypeComboBox.SelectedIndex == 0);
                ReportForm reportForm = new ReportForm(isFiveAzimuthReport, limitSetting, emiFileData, channelSettings);
                Hide();
                reportForm.Show();
                return;
            }
            else    //General one pair
            {
                List<string> emiFiles = new List<string>();
                List<EMIFileData> emiFileDatas = new List<EMIFileData>();
                foreach (KeyValuePair<string, EMIFileData> pair in mEmiFiles)
                {
                    emiFiles.Add(pair.Key);
                    emiFileDatas.Add(pair.Value);
                }

                EMIPairSelectForm emiPairSelectForm = new EMIPairSelectForm(emiFiles, emiFileDatas);
                if (emiPairSelectForm.ShowDialog() == DialogResult.Cancel)
                    return;

                PairReportForm pairReportForm = new PairReportForm();
                pairReportForm.LimitSetting = limitSetting;
                pairReportForm.EmiA = emiPairSelectForm.EmiA;
                pairReportForm.EmiB = emiPairSelectForm.EmiB;
                pairReportForm.AzimuthA = emiPairSelectForm.AzimuthA;
                pairReportForm.AzimuthB = emiPairSelectForm.AzimuthB;
                pairReportForm.ChannelSettings = mChannelSettingFiles[ChannelSettingFileList.SelectedItem.ToString()];
                pairReportForm.Init();

                pairReportForm.IsManualConfig = (ConfigurationTabControl.SelectedIndex == 1);
                if (ConfigurationTabControl.SelectedIndex == 1)
                {
                    if (mManualConfig > 0)
                    {
                        pairReportForm.ManualConfig = mManualConfig;
                        int frequencyCount = LinkFrequencyCountMap.Instance.GetCount(mManualConfig);
                        if (pairReportForm.AvailableChannels.Count < frequencyCount)
                        {
                            MessageBox.Show("Available channels count is " + pairReportForm.AvailableChannels.Count
                                + ",\r\nwhile config needs " + frequencyCount + " channels"
                                + ",\r\n please change config !");

                            return;
                        }
                    }
                }
                else
                {
                    string linkName1 = emiPairSelectForm.EmiA.Site_ID + "_" + emiPairSelectForm.EmiB.Site_ID;
                    string linkName2 = emiPairSelectForm.EmiB.Site_ID + "_" + emiPairSelectForm.EmiA.Site_ID;
                    List<LinkConfiguration> linkConfigurations = new List<LinkConfiguration>();
                    if (LinkConfigFileList.SelectedIndex != -1)
                    {
                        foreach (LinkConfiguration linkConfiguration in mLinkConfigurationFiles[LinkConfigFileList.SelectedItem.ToString()])
                        {
                            if (linkConfiguration.LinkName.Equals(linkName1)
                                || linkConfiguration.LinkName.Equals(linkName2))
                            {
                                linkConfigurations.Add(linkConfiguration);
                            }
                        }
                    }

                    if (linkConfigurations.Count == 0 && AnalysisChannelCombinationCheckBox.Checked)
                    {
                        MessageBox.Show("Not find link configuration \"" + linkName1 + "\" or \"" + linkName2 + "\" !");
                        return;
                    }
                    pairReportForm.LinkConfigurations = linkConfigurations;

                    int frequencyCount = 0;
                    foreach (LinkConfiguration linkConfiguration in linkConfigurations)
                        frequencyCount += LinkFrequencyCountMap.Instance.GetCount(linkConfiguration.RequiredConfiguration);
                    if (pairReportForm.AvailableChannels.Count < frequencyCount && AnalysisChannelCombinationCheckBox.Checked)
                    {
                        MessageBox.Show("Available channels count is " + pairReportForm.AvailableChannels.Count
                            + ",\r\nwhile config needs " + frequencyCount + " channels"
                            + ",\r\n please change config !");

                        return;
                    }
                }

                if (EquipParameterFileList.SelectedIndex >= 0)
                    pairReportForm.EquipmentParameters = mEquipmentParametersFiles[EquipParameterFileList.SelectedItem.ToString()];
                Hide();
                pairReportForm.Show();
            }
        }
        public static BitMapInfo create(EMIFileData emi, double azimuth, double actualAzimuth,
            string title, WatsEmiDataManager dataMgr,
            List<ChannelSetting> channelSettings, LimitSetting limitSetting,
            int minAbsRssi, int maxAbsRssi)
        {
            BitMapInfo bitMapInfo = new BitMapInfo();
            List<WatsEmiSample> verticalSamples = new List<WatsEmiSample>();
            List<WatsEmiSample> horizontalSamples = new List<WatsEmiSample>();

            bitMapInfo.Title1 = title + " " + azimuth.ToString() + "\x00B0" + " V";
            bitMapInfo.Title2 = title + " " + azimuth.ToString() + "\x00B0" + " H";
            bitMapInfo.BmpFile1 = Utility.GetAppPath() + "\\Temp\\Site_" + emi.Site_ID + "_Azimuth_"
                + ((int)azimuth).ToString() + "_Vertical_" + (++counter).ToString() + ".emf";
            bitMapInfo.BmpFile2 = Utility.GetAppPath() + "\\Temp\\Site_" + emi.Site_ID + "_Azimuth_"
                + ((int)azimuth).ToString() + "_Horizontal_" + (++counter).ToString() + ".emf";

            for (int i = 0; i < dataMgr.AllSamples[actualAzimuth][0].Count; i++)
            {
                if (dataMgr.AllSamples[actualAzimuth][0][i].mFreq >= channelSettings[0].StartFreq
                    && dataMgr.AllSamples[actualAzimuth][0][i].mFreq <= channelSettings[channelSettings.Count - 1].Pair.EndFreq)
                    verticalSamples.Add(dataMgr.AllSamples[actualAzimuth][0][i]);
            }

            for (int i = 0; i < dataMgr.AllSamples[actualAzimuth][1].Count; i++)
            {
                if (dataMgr.AllSamples[actualAzimuth][1][i].mFreq >= channelSettings[0].StartFreq
                    && dataMgr.AllSamples[actualAzimuth][1][i].mFreq <= channelSettings[channelSettings.Count - 1].Pair.EndFreq)
                    horizontalSamples.Add(dataMgr.AllSamples[actualAzimuth][1][i]);
            }

            List<Marker> verticalMarkers = new List<Marker>();
            List<Marker> hoizontalMarkers = new List<Marker>();
            Marker marker;
            ChannelPower channelPower;
            foreach (ChannelSetting channelSetting in channelSettings)
            {
                channelPower = new ChannelPower(emi.SA_RBW, channelSetting, limitSetting, dataMgr.AllChannelSamples[actualAzimuth][channelSetting]);
                if (!channelPower.IsValidVPower)
                {
                    marker = Utility.CreateMarker(channelSetting.ChannelName, dataMgr.AllChannelSamples[actualAzimuth][channelSetting].mVSamples);
                    verticalMarkers.Add(marker);
                }

                if (!channelPower.IsValidVPairPower)
                {
                    marker = Utility.CreateMarker(channelSetting.Pair.ChannelName, dataMgr.AllChannelSamples[actualAzimuth][channelSetting].mVPairSamples);
                    verticalMarkers.Add(marker);
                }

                if (!channelPower.IsValidHPower)
                {
                    marker = Utility.CreateMarker(channelSetting.ChannelName, dataMgr.AllChannelSamples[actualAzimuth][channelSetting].mHSamples);
                    hoizontalMarkers.Add(marker);
                }

                if (!channelPower.IsValidHPairPower)
                {
                    marker = Utility.CreateMarker(channelSetting.Pair.ChannelName, dataMgr.AllChannelSamples[actualAzimuth][channelSetting].mHPairSamples);
                    hoizontalMarkers.Add(marker);
                }
            }

            verticalMarkers.Sort(Utility.SortMarkerByFrequency);
            hoizontalMarkers.Sort(Utility.SortMarkerByFrequency);

            drawPicture(emi, verticalSamples, channelSettings, limitSetting, bitMapInfo.BmpFile1, bitMapInfo.Title1, minAbsRssi, maxAbsRssi, verticalMarkers);
            drawPicture(emi, horizontalSamples, channelSettings, limitSetting, bitMapInfo.BmpFile2, bitMapInfo.Title2, minAbsRssi, maxAbsRssi, hoizontalMarkers);

            return bitMapInfo;
        }
        private static bool drawPicture(EMIFileData emi, List<WatsEmiSample> samples,
            List<ChannelSetting> channels, LimitSetting limitSetting,
            string picturePath, string title, int minAbsRssi, int maxAbsRssi, List<Marker> markers)
        {
            try
            {
                int height = 180 + (markers.Count + 1) * 15 + 6 * 15;
                Bitmap bmp = new Bitmap(425, height);
                Graphics gs = Graphics.FromImage(bmp);
                Metafile mf = new Metafile(picturePath, gs.GetHdc());
                Graphics g = Graphics.FromImage(mf);

                double minX = channels[0].StartFreq;
                double span = channels[channels.Count - 1].Pair.EndFreq - channels[0].StartFreq;

                using (Brush bgBrush = new SolidBrush(Color.FromArgb(255, 255, 128)))
                {
                    g.FillRectangle(bgBrush, 0, 0, 425, height);
                }

                using (Pen boldRectPen = new Pen(Color.Black, 2.0f))
                {
                    g.DrawRectangle(boldRectPen, 0, 0, 425, height);
                }

                using (Pen boldRectPen = new Pen(Color.Black, 1.0f))
                {
                    g.DrawRectangle(boldRectPen, 52, 15, 350, 130);
                }

                using (Pen gridPen = new Pen(Color.Gray, 0.5f))
                {
                    gridPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
                    for (int j = 0; j < 9; j++)
                        g.DrawLine(gridPen, 52, 15 + (j + 1) * 13, 402, 15 + (j + 1) * 13);

                    for (int j = 0; j < 9; j++)
                        g.DrawLine(gridPen, 52 + (j + 1) * 35, 15, 52 + (j + 1) * 35, 145);
                }

                string text;
                SizeF sizef;
                RectangleF rf;

                //drawing title
                using (Font font = new Font("Times New Roman", 8.0f))
                {
                    text = title;
                    sizef = g.MeasureString(text, font, Int32.MaxValue);
                    rf = new RectangleF(227 - sizef.Width / 2, 10 - sizef.Height / 2, sizef.Width, sizef.Height);

                    g.DrawString(text, font, Brushes.Black, rf);
                }

                //drawing side text
                using (Font font = new Font("Times New Roman", 8.0f))
                {
                    text = "Power (dBm)";
                    StringFormat sf = new StringFormat(StringFormatFlags.DirectionVertical);
                    sizef = g.MeasureString(text, font, Int32.MaxValue, sf);
                    rf = new RectangleF(5, 75 - sizef.Height / 2, sizef.Width, sizef.Height);

                    g.TranslateTransform((rf.Left + rf.Right) / 2, (rf.Top + rf.Bottom) / 2);
                    g.RotateTransform(180);

                    RectangleF newRf = new RectangleF(-sizef.Width / 2, -sizef.Height / 2, sizef.Width, sizef.Height);
                    g.DrawString(text, font, Brushes.Black, newRf, sf);
                    g.ResetTransform();
                }

                //drawing bottom
                using (Font font = new Font("Times New Roman", 8.0f))
                {
                    text = "Frequency (MHz)";
                    sizef = g.MeasureString(text, font, Int32.MaxValue);
                    rf = new RectangleF(227 - sizef.Width / 2, 160, sizef.Width, sizef.Height);

                    g.DrawString(text, font, Brushes.Black, rf);
                }

                //drawing x
                using (Font font = new Font("Times New Roman", 5.0f))
                {
                    List<string> xTexts = new List<string>();
                    int j;
                    for (j = 0; j < 11; j++)
                        xTexts.Add(Utility.ConvertDoubleString(minX + span * j / 10));

                    j = 0;
                    foreach (string xText in xTexts)
                    {
                        sizef = g.MeasureString(xText, font, Int32.MaxValue);
                        rf = new RectangleF(52 + j * 35 - sizef.Width / 2, 147,
                            sizef.Width, sizef.Height);
                        g.DrawString(xText, font, Brushes.Black, rf);
                        j++;
                    }
                }

                //drawing y
                using (Font font = new Font("Times New Roman", 5.0f))
                {
                    List<string> yTexts = new List<string>();
                    int j;
                    for (j = 0; j < 11; j++)
                        yTexts.Add("-" + (minAbsRssi + (maxAbsRssi - minAbsRssi) / 10 * j).ToString());

                    j = 0;
                    foreach (string yText in yTexts)
                    {
                        sizef = g.MeasureString(yText, font, Int32.MaxValue);
                        rf = new RectangleF(50 - sizef.Width, 15 + j * 13 - sizef.Height / 2,
                            sizef.Width, sizef.Height);
                        g.DrawString(yText, font, Brushes.Black, rf);
                        j++;
                    }
                }

                //drawing curve
                using (Pen dataPen = new Pen(Color.Blue, 1.0f))
                {
                    float x1, x2, y1, y2;
                    for (int j = 0; j < samples.Count - 1; j++)
                    {
                        x1 = (float)((samples[j].mFreq - minX) * 350 / span + 52);
                        y1 = (float)((Math.Abs(samples[j].mRssi) - minAbsRssi) * 130 / (maxAbsRssi - minAbsRssi) + 15);

                        x2 = (float)((samples[j + 1].mFreq - minX) * 350 / span + 52);
                        y2 = (float)((Math.Abs(samples[j + 1].mRssi) - minAbsRssi) * 130 / (maxAbsRssi - minAbsRssi) + 15);

                        g.DrawLine(dataPen, x1, y1, x2, y2);
                    }
                }

                //drawing bold separate line
                using (Pen boldSeparateLinePen = new Pen(Color.Black, 2.0f))
                {
                    g.DrawLine(boldSeparateLinePen, 0, 180, 425, 180);
                    g.DrawLine(boldSeparateLinePen, 0, 180 + (markers.Count + 1) * 15, 425, 180 + (markers.Count + 1) * 15);
                }

                using (Pen thinPen = new Pen(Color.Black, 1.0f))
                {
                    using (Font font = new Font("Times New Roman", 7.0f))
                    {
                        //thin horizontal marking separate line
                        for (int j = 0; j < markers.Count; j++)
                            g.DrawLine(thinPen, 0, 180 + (j + 1) * 15, 425, 180 + (j + 1) * 15);

                        //thin vertical marking separate line
                        g.DrawLine(thinPen, 65, 180, 65, 180 + (markers.Count+ 1) * 15);
                        g.DrawLine(thinPen, 65 + 120, 180, 65 + 120, 180 + (markers.Count + 1) * 15);
                        g.DrawLine(thinPen, 65 + 240, 180, 65 + 240, 180 + (markers.Count + 1) * 15);

                        //marker titles
                        text = "Marker No.";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(5, 180 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        text = "Frequency (MHz)";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(65 + 5, 180 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        text = "RSSI (dBm)";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(185 + 5, 180 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        text = "Channel";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(305 + 5, 180 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        //marker no.
                        for (int j = 0; j < markers.Count; j++)
                        {
                            text = (j + 1).ToString();
                            sizef = g.MeasureString(text, font, Int32.MaxValue);
                            rf = new RectangleF(5, 180 + (j + 1) * 15 + 3.5f,
                                sizef.Width, sizef.Height);
                            g.DrawString(text, font, Brushes.Black, rf);
                        }

                        //drawing mark
                        int i = 0;
                        foreach (Marker marker in markers)
                        {
                            text = Utility.ConvertDoubleString(marker.frequency);
                            sizef = g.MeasureString(text, font, Int32.MaxValue);
                            rf = new RectangleF(65 + 5, 180 + (i + 1) * 15 + 3.5f,
                                sizef.Width, sizef.Height);
                            g.DrawString(text, font, Brushes.Black, rf);

                            text = marker.rssi.ToString();
                            sizef = g.MeasureString(text, font, Int32.MaxValue);
                            rf = new RectangleF(185 + 5, 180 + (i + 1) * 15 + 3.5f,
                                sizef.Width, sizef.Height);
                            g.DrawString(text, font, Brushes.Black, rf);

                            text = marker.channelName;
                            sizef = g.MeasureString(text, font, Int32.MaxValue);
                            rf = new RectangleF(305 + 5, 180 + (i + 1) * 15 + 3.5f,
                                sizef.Width, sizef.Height);
                            g.DrawString(text, font, Brushes.Black, rf);

                            drawMarker(g, minX, span, minAbsRssi, maxAbsRssi, marker);

                            i++;
                        }

                        //thin horizontal measurement separate line
                        for (int j = 0; j < 5; j++)
                            g.DrawLine(thinPen, 0, 180 + (markers.Count + 1) * 15 + (j + 1) * 15, 425, 180 + (markers.Count + 1) * 15 + (j + 1) * 15);

                        //thin vertical measurement separate line
                        g.DrawLine(thinPen, 90, 180 + (markers.Count + 1) * 15 + 15,
                            90, 180 + (markers.Count + 1) * 15 + 90);
                        g.DrawLine(thinPen, 90 + 112, 180 + (markers.Count + 1) * 15 + 15,
                            90 + 112, 180 + (markers.Count + 1) * 15 + 90);
                        g.DrawLine(thinPen, 90 + 112 + 90, 180 + (markers.Count + 1) * 15 + 15,
                            90 + 112 + 90, 180 + (markers.Count + 1) * 15 + 90);

                        //drawing measurement
                        text = "Measurement Parameter";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(209 - sizef.Width / 2, 180 + (markers.Count + 1) * 15.0f + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        /************************************************************************/
                        /* Center Frequency                                                     */
                        /************************************************************************/
                        text = "Center Frequency";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(5, 180 + (markers.Count + 1) * 15 + 15 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        text = Utility.ConvertDoubleString((channels[0].StartFreq + channels[channels.Count - 1].Pair.EndFreq) / 2000) + " GHz";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(90 + 5, 180 + (markers.Count + 1) * 15 + 15 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        /************************************************************************/
                        /* Span                                                                 */
                        /************************************************************************/
                        text = "Span";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(202 + 5, 180 + (markers.Count + 1) * 15 + 15 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        text = Utility.ConvertDoubleString(channels[channels.Count - 1].Pair.EndFreq - channels[0].StartFreq) + " MHz";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(292 + 5, 180 + (markers.Count + 1) * 15 + 15 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        /************************************************************************/
                        /* Start Frequency                                                     */
                        /************************************************************************/
                        text = "Start Frequency";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(5, 180 + (markers.Count + 1) * 15 + 30 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        text = Utility.ConvertDoubleString(channels[0].StartFreq / 1000) + " GHz";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(90 + 5, 180 + (markers.Count + 1) * 15 + 30 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        /************************************************************************/
                        /* Stop Frequency                                                                 */
                        /************************************************************************/
                        text = "Stop Frequency";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(202 + 5, 180 + (markers.Count + 1) * 15 + 30 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        text = Utility.ConvertDoubleString(channels[channels.Count - 1].Pair.EndFreq / 1000) + " GHz";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(292 + 5, 180 + (markers.Count + 1) * 15 + 30 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        /************************************************************************/
                        /* Reference Level                                                      */
                        /************************************************************************/
                        text = "Reference Level";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(5, 180 + (markers.Count + 1) * 15 + 45 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        text = Utility.ConvertDoubleString(emi.SA_REF_LEVEL) + " dBm";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(90 + 5, 180 + (markers.Count + 1) * 15 + 45 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        /************************************************************************/
                        /* Attenuation                                                          */
                        /************************************************************************/
                        text = "Attenuation";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(202 + 5, 180 + (markers.Count + 1) * 15 + 45 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        text = emi.SA_Attenuation_Value.ToString() + " dB";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(292 + 5, 180 + (markers.Count + 1) * 15 + 45 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        /************************************************************************/
                        /* RBW                                                                  */
                        /************************************************************************/
                        text = "RBW";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(5, 180 + (markers.Count + 1) * 15 + 60 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        text = Utility.ConvertDoubleString(emi.SA_RBW) + " Hz";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(90 + 5, 180 + (markers.Count + 1) * 15 + 60 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        /************************************************************************/
                        /* VBW                                                          */
                        /************************************************************************/
                        text = "VBW";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(202 + 5, 180 + (markers.Count + 1) * 15 + 60 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        text = Utility.ConvertDoubleString(emi.SA_VBW) + " Hz";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(292 + 5, 180 + (markers.Count + 1) * 15 + 60 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        /************************************************************************/
                        /* Detection                                                            */
                        /************************************************************************/
                        text = "Detection";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(5, 180 + (markers.Count + 1) * 15 + 73 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        text = emi.SA_Detector;
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(90 + 5, 180 + (markers.Count + 1) * 15 + 73 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        /************************************************************************/
                        /* Mode                                                                 */
                        /************************************************************************/
                        text = "Mode";
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(202 + 5, 180 + (markers.Count + 1) * 15 + 73 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);

                        text = emi.SA_Sweep_Mode;
                        sizef = g.MeasureString(text, font, Int32.MaxValue);
                        rf = new RectangleF(292 + 5, 180 + (markers.Count + 1) * 15 + 73 + 3.5f,
                            sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Black, rf);
                    }
                }

                g.Save();
                g.Dispose();
            }
            catch (System.Exception e)
            {
                File.Delete("c:\\watsLog.txt");
                FileStream fs = new FileStream("c:\\watsLog.txt", FileMode.CreateNew);
                StreamWriter sw = new StreamWriter(fs);
                sw.WriteLine(e.Message);
                sw.WriteLine(e.StackTrace);
                sw.Flush();
                sw.Close();
                fs.Close();

                return false;
            }

            return true;
        }
        public static Dictionary<string, List<BitMapInfo>> create(EMIFileData emi, 
            double azimuth, string relativeAzimuth, WatsEmiDataManager dataMgr,
            Dictionary<string, List<ChannelSetting>> allBandchannels, LimitSetting limitSetting,
            int minAbsRssi, int maxAbsRssi)
        {
            Dictionary<string, List<BitMapInfo>> allChannelBitmapInfos = new Dictionary<string,List<BitMapInfo>>();
            List<BitMapInfo> channelBitmapInfos;
            BitMapInfo loBitMapInfo, hiBitMapInfo;
            List<WatsEmiSample> loVerticalSamples, hiVerticalSamples;
            List<WatsEmiSample> loHorizontalSamples, hiHorizontalSamples;

            string bandName;
            double curFreq;
            int counter = 0;
            List<BitMapInfo> channelBitmaps;
            List<Marker> loVerticalMarkers, loHoizontalMarkers;
            List<Marker> hiVerticalMarkers, hiHoizontalMarkers;
            List<ChannelSetting> channelSettings;
            List<ChannelSetting> pairChannelSettings;
            Marker marker;
            ChannelPower channelPower;
            foreach (KeyValuePair<string, List<ChannelSetting>> pair in allBandchannels)
            {
                bandName = pair.Key;
                channelBitmapInfos = new List<BitMapInfo>();
                channelSettings = pair.Value;
                pairChannelSettings = new List<ChannelSetting>();
                foreach (ChannelSetting channelSetting in channelSettings)
                    pairChannelSettings.Add(channelSetting.Pair);

                loVerticalSamples = new List<WatsEmiSample>();
                for (int i = 0; i < dataMgr.AllSamples[azimuth][0].Count; i++)
                {
                    curFreq = dataMgr.AllSamples[azimuth][0][i].mFreq;
                    if (curFreq >= channelSettings[0].StartFreq
                        && curFreq <= channelSettings[channelSettings.Count - 1].EndFreq)
                    {
                        loVerticalSamples.Add(dataMgr.AllSamples[azimuth][0][i]);
                    }
                }

                loHorizontalSamples = new List<WatsEmiSample>();
                for (int i = 0; i < dataMgr.AllSamples[azimuth][1].Count; i++)
                {
                    curFreq = dataMgr.AllSamples[azimuth][1][i].mFreq;
                    if (curFreq >= channelSettings[0].StartFreq
                        && curFreq <= channelSettings[channelSettings.Count - 1].EndFreq)
                    {
                        loHorizontalSamples.Add(dataMgr.AllSamples[azimuth][1][i]);
                    }
                }

                hiVerticalSamples = new List<WatsEmiSample>();
                for (int i = 0; i < dataMgr.AllSamples[azimuth][0].Count; i++)
                {
                    curFreq = dataMgr.AllSamples[azimuth][0][i].mFreq;
                    if (curFreq >= pairChannelSettings[0].StartFreq
                        && curFreq <= pairChannelSettings[pairChannelSettings.Count - 1].EndFreq)
                    {
                        hiVerticalSamples.Add(dataMgr.AllSamples[azimuth][0][i]);
                    }
                }

                hiHorizontalSamples = new List<WatsEmiSample>();
                for (int i = 0; i < dataMgr.AllSamples[azimuth][1].Count; i++)
                {
                    curFreq = dataMgr.AllSamples[azimuth][1][i].mFreq;
                    if (curFreq >= pairChannelSettings[0].StartFreq
                        && curFreq <= pairChannelSettings[pairChannelSettings.Count - 1].EndFreq)
                    {
                        hiHorizontalSamples.Add(dataMgr.AllSamples[azimuth][1][i]);
                    }
                }

                loBitMapInfo = new BitMapInfo();
                loBitMapInfo.Title1 = "Spectrum Analyzer Data MDEF-LAXI_" + bandName + "_" + relativeAzimuth + "V (LO)";
                loBitMapInfo.Title2 = "Spectrum Analyzer Data MDEF-LAXI_" + bandName + "_" + relativeAzimuth + "H (LO)";
                loBitMapInfo.BmpFile1 = Utility.GetAppPath() + "\\Temp\\Site_" + emi.Site_ID + "_Azimuth_"
                    + relativeAzimuth + "_" + bandName + "_LowBand_Vertical_" + (++counter).ToString() + ".emf";
                loBitMapInfo.BmpFile2 = Utility.GetAppPath() + "\\Temp\\Site_" + emi.Site_ID + "_Azimuth_"
                    + relativeAzimuth + "_" + bandName + "_LowBand_Horizontal_" + (counter).ToString() + ".emf";

                hiBitMapInfo = new BitMapInfo();
                hiBitMapInfo.Title1 = "Spectrum Analyzer DataMDEF-LAXI_" + bandName + "_" + relativeAzimuth + "V (HI)";
                hiBitMapInfo.Title2 = "Spectrum Analyzer DataMDEF-LAXI_" + bandName + "_" + relativeAzimuth + "H (HI)";
                hiBitMapInfo.BmpFile1 = Utility.GetAppPath() + "\\Temp\\Site_" + emi.Site_ID + "_Azimuth_"
                    + relativeAzimuth + "_" + bandName + "_HighBand_Vertical_" + (++counter).ToString() + ".emf";
                hiBitMapInfo.BmpFile2 = Utility.GetAppPath() + "\\Temp\\Site_" + emi.Site_ID + "_Azimuth_"
                    + relativeAzimuth + "_" + bandName + "_HighBand_Horizontal_" + (counter).ToString() + ".emf";

                loVerticalMarkers = new List<Marker>();
                loHoizontalMarkers = new List<Marker>();
                hiVerticalMarkers = new List<Marker>();
                hiHoizontalMarkers = new List<Marker>();
                foreach (ChannelSetting channelSetting in channelSettings)
                {
                    channelPower = new ChannelPower(emi.SA_RBW, channelSetting, limitSetting, dataMgr.AllChannelSamples[azimuth][channelSetting]);
                    if (!channelPower.IsValidVPower)
                    {
                        marker = Utility.CreateMarker(channelSetting.ChannelName, dataMgr.AllChannelSamples[azimuth][channelSetting].mVSamples);
                        loVerticalMarkers.Add(marker);
                    }

                    if (!channelPower.IsValidVPairPower)
                    {
                        marker = Utility.CreateMarker(channelSetting.Pair.ChannelName, dataMgr.AllChannelSamples[azimuth][channelSetting].mVPairSamples);
                        hiVerticalMarkers.Add(marker);
                    }

                    if (!channelPower.IsValidHPower)
                    {
                        marker = Utility.CreateMarker(channelSetting.ChannelName, dataMgr.AllChannelSamples[azimuth][channelSetting].mHSamples);
                        loHoizontalMarkers.Add(marker);
                    }

                    if (!channelPower.IsValidHPairPower)
                    {
                        marker = Utility.CreateMarker(channelSetting.Pair.ChannelName, dataMgr.AllChannelSamples[azimuth][channelSetting].mHPairSamples);
                        hiHoizontalMarkers.Add(marker);
                    }
                }

                drawPicture(emi, loVerticalSamples, channelSettings, limitSetting, loBitMapInfo.BmpFile1, loBitMapInfo.Title1, minAbsRssi, maxAbsRssi, loVerticalMarkers);
                drawPicture(emi, loHorizontalSamples, channelSettings, limitSetting, loBitMapInfo.BmpFile2, loBitMapInfo.Title2, minAbsRssi, maxAbsRssi, loHoizontalMarkers);

                drawPicture(emi, hiVerticalSamples, pairChannelSettings, limitSetting, hiBitMapInfo.BmpFile1, hiBitMapInfo.Title1, minAbsRssi, maxAbsRssi, hiVerticalMarkers);
                drawPicture(emi, hiHorizontalSamples, pairChannelSettings, limitSetting, hiBitMapInfo.BmpFile2, hiBitMapInfo.Title2, minAbsRssi, maxAbsRssi, hiHoizontalMarkers);

                channelBitmaps = new List<BitMapInfo>();
                channelBitmaps.Add(loBitMapInfo);
                channelBitmaps.Add(hiBitMapInfo);

                allChannelBitmapInfos[bandName] = channelBitmaps;
            }

            return allChannelBitmapInfos;
        }
        public static List<BitMapInfo> create(EMIFileData emi, double azimuth,
            string title, WatsEmiDataManager dataMgr,
            List<ChannelSetting> channelSettings, LimitSetting limitSetting,
            int minAbsRssi, int maxAbsRssi, double span, List<FrequencyRange> ranges,
            ref string verticalCircleTitle, ref string horizontalCircleTitle,
            ref string verticalCircleBmpFile, ref string horizontalCircleBmpFile)
        {
            List<BitMapInfo> bitMapInfos = new List<BitMapInfo>();
            List<WatsEmiSample> verticalSamples;
            List<WatsEmiSample> horizontalSamples;

            verticalCircleBmpFile = Utility.GetAppPath() + "\\Temp\\" + azimuth.ToString() + "-circle-vertical.emf";
            verticalCircleTitle = "V-" + azimuth.ToString() + "\x00B0["
                + ranges[0].FromFreq + "~" + ranges[ranges.Count - 1].EndFreq + " MHz]";
            horizontalCircleBmpFile = Utility.GetAppPath() + "\\Temp\\" + azimuth.ToString() + "circle-horizontal.emf";
            horizontalCircleTitle = "H-" + azimuth.ToString() + "\x00B0["
                + ranges[0].FromFreq + "~" + ranges[ranges.Count - 1].EndFreq + " MHz]";

            //draw circle picture
            drawCirclePicture(true, verticalCircleBmpFile, azimuth, 30, emi.SA_RBW, dataMgr.AllChannelSamples[azimuth], limitSetting);
            drawCirclePicture(false, horizontalCircleBmpFile, azimuth, 30, emi.SA_RBW, dataMgr.AllChannelSamples[azimuth], limitSetting);

            //calculate all Markers
            List<Marker> allVerticalMarkers = new List<Marker>();
            List<Marker> allHoizontalMarkers = new List<Marker>();
            Marker marker;
            ChannelPower channelPower;
            foreach (ChannelSetting channelSetting in channelSettings)
            {
                channelPower = new ChannelPower(emi.SA_RBW, channelSetting, limitSetting, dataMgr.AllChannelSamples[azimuth][channelSetting]);

                if (!channelPower.IsValidVPower)
                {
                    marker = Utility.CreateMarker(channelSetting.ChannelName, dataMgr.AllChannelSamples[azimuth][channelSetting].mVSamples);
                    allVerticalMarkers.Add(marker);
                }

                if (!channelPower.IsValidVPairPower)
                {
                    marker = Utility.CreateMarker(channelSetting.Pair.ChannelName, dataMgr.AllChannelSamples[azimuth][channelSetting].mVPairSamples);
                    allVerticalMarkers.Add(marker);
                }

                if (!channelPower.IsValidHPower)
                {
                    marker = Utility.CreateMarker(channelSetting.ChannelName, dataMgr.AllChannelSamples[azimuth][channelSetting].mHSamples);
                    allHoizontalMarkers.Add(marker);
                }

                if (!channelPower.IsValidHPairPower)
                {
                    marker = Utility.CreateMarker(channelSetting.Pair.ChannelName, dataMgr.AllChannelSamples[azimuth][channelSetting].mHPairSamples);
                    allHoizontalMarkers.Add(marker);
                }
            }

            allVerticalMarkers.Sort(Utility.SortMarkerByFrequency);
            allHoizontalMarkers.Sort(Utility.SortMarkerByFrequency);

            //draw picture per range
            BitMapInfo bitMapInfo;
            List<Marker> verticalMarkers;
            List<Marker> horizontalMarkers;
            foreach (FrequencyRange range in ranges)
            {
                bitMapInfo = new BitMapInfo();

                verticalSamples = new List<WatsEmiSample>();
                horizontalSamples = new List<WatsEmiSample>();

                verticalMarkers = new List<Marker>();
                horizontalMarkers = new List<Marker>();

                foreach (Marker rangeMarker in allVerticalMarkers)
                {
                    if (rangeMarker.frequency >= range.FromFreq && rangeMarker.frequency <= range.EndFreq)
                        verticalMarkers.Add(rangeMarker);
                }

                foreach (Marker rangeMarker in allHoizontalMarkers)
                {
                    if (rangeMarker.frequency >= range.FromFreq && rangeMarker.frequency <= range.EndFreq)
                        horizontalMarkers.Add(rangeMarker);
                }

                int markerRows = Math.Max(verticalMarkers.Count, horizontalMarkers.Count);

                bitMapInfo.Band = Utility.ConvertDoubleString(range.FromFreq) + "-"
                    + Utility.ConvertDoubleString(range.EndFreq);
                bitMapInfo.Title1 = "V-" + Utility.ConvertDoubleString(azimuth) + "\x00B0"
                    + "[" + Utility.ConvertDoubleString(range.FromFreq) + "~"
                    + range.EndFreq
                    + " MHz]";
                bitMapInfo.Title2 = "H-" + Utility.ConvertDoubleString(azimuth) + "\x00B0"
                    + "[" + Utility.ConvertDoubleString(range.FromFreq) + "~"
                    + range.EndFreq
                    + " MHz]";
                bitMapInfo.BmpFile1 = Utility.GetAppPath() + "\\Temp\\Angle"
                    + azimuth.ToString() + "-vertical-"
                    + ((int)range.FromFreq).ToString() + ".emf";
                bitMapInfo.BmpFile2 = Utility.GetAppPath() + "\\Temp\\Angle"
                    + azimuth.ToString() + "-horizontal-"
                    + ((int)range.FromFreq).ToString() + ".emf";

                for (int i = 0; i < dataMgr.AllSamples[azimuth][0].Count; i++)
                {
                    if (dataMgr.AllSamples[azimuth][0][i].mFreq >= range.FromFreq
                        && dataMgr.AllSamples[azimuth][0][i].mFreq <= range.EndFreq)
                        verticalSamples.Add(dataMgr.AllSamples[azimuth][0][i]);
                }

                for (int i = 0; i < dataMgr.AllSamples[azimuth][1].Count; i++)
                {
                    if (dataMgr.AllSamples[azimuth][1][i].mFreq >= range.FromFreq
                        && dataMgr.AllSamples[azimuth][1][i].mFreq <= range.EndFreq)
                        horizontalSamples.Add(dataMgr.AllSamples[azimuth][1][i]);
                }

                drawPicture(emi, verticalSamples, span, range, limitSetting, bitMapInfo.BmpFile1, title + " V", minAbsRssi, maxAbsRssi, verticalMarkers, markerRows);
                drawPicture(emi, horizontalSamples, span, range, limitSetting, bitMapInfo.BmpFile2, title + " H", minAbsRssi, maxAbsRssi, horizontalMarkers, markerRows);

                bitMapInfos.Add(bitMapInfo);
            }

            return bitMapInfos;
        }
        private static bool drawCirclePicture(bool isVertical, string picturePath, 
            double azimuth, double azimuth_step, double sa_rbw,
            Dictionary<ChannelSetting, WatsEmiData> channelSamples,
            LimitSetting limitSetting)
        {
            try
            {
                Bitmap bmp = new Bitmap(300, 260);
                Graphics gs = Graphics.FromImage(bmp);
                Metafile mf = new Metafile(picturePath, gs.GetHdc());
                Graphics g = Graphics.FromImage(mf);
                using (Brush backgroundBrush = new SolidBrush(Color.White))
                {
                    g.FillRectangle(backgroundBrush, 0, 0, 300, 260);
                }

                using (Pen circlePen = new Pen(Color.Blue, 3.0f))
                {
                    g.DrawEllipse(circlePen, 45, 25, 210, 210);
                }

                ChannelPower power;
                ChannelPowerSpectrum spectrum;
                List<ChannelPowerSpectrum> spectrums = new List<ChannelPowerSpectrum>();
                foreach (KeyValuePair<ChannelSetting, WatsEmiData> pair in channelSamples)
                {
                    power = new ChannelPower(sa_rbw, pair.Key, limitSetting, pair.Value);
                    spectrum = new ChannelPowerSpectrum();
                    spectrum.startFreq = pair.Key.StartFreq;
                    spectrum.endFreq = pair.Key.EndFreq;
                    spectrum.isValidPower = (isVertical ? power.IsValidVPower : power.IsValidHPower);
                    spectrums.Add(spectrum);

                    power = new ChannelPower(sa_rbw, pair.Key.Pair, limitSetting, pair.Value);
                    spectrum = new ChannelPowerSpectrum();
                    spectrum.startFreq = pair.Key.Pair.StartFreq;
                    spectrum.endFreq = pair.Key.Pair.EndFreq;
                    spectrum.isValidPower = (isVertical ? power.IsValidVPairPower : power.IsValidHPairPower);
                    spectrums.Add(spectrum);
                }

                spectrums.Sort(SortSpectrumByStartFreq);
                float freqSpan = (float)(spectrums[0].endFreq - spectrums[spectrums.Count - 1].startFreq);
                int length;
                Rectangle rect;
                Color color;
                float drawAzimuth;
                for (int i = 0; i < spectrums.Count; i++)
                {
                    if (azimuth >= 0 && azimuth <= 90)
                        drawAzimuth = (float)azimuth - 90;
                    else if (azimuth >= 90 && azimuth <= 180)
                        drawAzimuth = (float)azimuth - 90;
                    else if (azimuth >= 180 && azimuth <= 270)
                        drawAzimuth =  (float)azimuth - 90;
                    else
                        drawAzimuth = (float)azimuth - 450;
                    Debug.WriteLine(spectrums[i].startFreq + " - " + spectrums[i].endFreq);
                    color = spectrums[i].isValidPower ? Color.Green : Color.Red;
                    using (Brush brush = new SolidBrush(color))
                    {
                        length = 2 * (int)(100 * (spectrums[i].endFreq - spectrums[spectrums.Count - 1].startFreq) / freqSpan);
                        rect = new Rectangle((300 - length) / 2, (260 - length) /2, length, length);
                        g.FillPie(brush, rect, (float)(drawAzimuth - azimuth_step / 2), (float)azimuth_step);
                    }

                    if (i != spectrums.Count - 1)
                    {
                        using (Brush whiteBrush = new SolidBrush(Color.White))
                        {
                            length = 2 * (int)(100 * (spectrums[i].startFreq - spectrums[spectrums.Count - 1].startFreq) / freqSpan);
                            rect = new Rectangle((300 - length) / 2, (260 - length) / 2, length, length);
                            g.FillPie(whiteBrush, rect, (float)(drawAzimuth - azimuth_step / 2), (float)azimuth_step);
                        }

                        using (Pen seperateCirclePen = new Pen(Color.White, 1.0f))
                        {
                            length = 2 * (int)(100 * (spectrums[i].endFreq - spectrums[spectrums.Count - 1].startFreq) / freqSpan);
                            rect = new Rectangle((300 - length) / 2, (260 - length) / 2, length, length);
                            g.DrawArc(seperateCirclePen, rect, (float)(drawAzimuth - azimuth_step / 2), (float)azimuth_step);
                        }
                    }
                }

                using (Pen directionPen = new Pen(Color.Blue, 2.0f))
                {
                    Point[] pt = new Point[]{new Point(50, 50), new Point(50, -50)};
                    GraphicsPath strokePath = new GraphicsPath();
                    strokePath.AddLine(new Point(0, 0), new Point(0, 5));
                    strokePath.AddLine(new Point(0, 5), new Point(3, 0));
                    strokePath.AddLine(new Point(0, 5), new Point(-3, 0));
                    CustomLineCap customLineCap = new CustomLineCap(null, strokePath);
                    customLineCap.SetStrokeCaps(LineCap.Round, LineCap.Round);
                    directionPen.CustomEndCap = customLineCap;

                    Point center = new Point(150, 130);
                    int endX, endY;
                    int deltX = (int)(Math.Abs(Math.Sin(azimuth * Math.PI / 180)) * 120);
                    int deltY = (int)(Math.Abs(Math.Cos(azimuth * Math.PI / 180)) * 120);
                    if (azimuth >= 0 && azimuth <= 90)
                    {
                        endX = 150 + deltX;
                        endY = 130 - deltY;
                    }
                    else if (azimuth >= 90 && azimuth <= 180)
                    {
                        endX = 150 + deltX;
                        endY = 130 + deltY;
                    }
                    else if (azimuth >= 180 && azimuth <= 270)
                    {
                        endX = 150 - deltX;
                        endY = 130 + deltY;
                    }
                    else
                    {
                        endX = 150 - deltX;
                        endY = 130 - deltY;
                    }
                    Point end = new Point(endX, endY);
                    g.DrawLine(directionPen, center, end);

                    using (Font font = new Font("Times New Roman", 10.0f))
                    {
                        string text = azimuth.ToString() + "\x00B0";
                        SizeF sizef = g.MeasureString(text, font, Int32.MaxValue);
                        float textX, textY;
                        if (azimuth >= 0 && azimuth <= 90)
                        {
                            textX = end.X - 1;
                            textY = end.Y - sizef.Height - 10;
                        }
                        else if (azimuth >= 90 && azimuth <= 180)
                        {
                            textX = end.X - 1;
                            textY = end.Y + sizef.Height;
                        }
                        else if (azimuth >= 180 && azimuth <= 270)
                        {
                            textX = end.X - sizef.Width / 2;
                            textY = end.Y + sizef.Height;
                        }
                        else
                        {
                            textX = end.X - sizef.Width / 2;
                            textY = end.Y - sizef.Height - 10;
                        }

                        RectangleF rf = new RectangleF(textX, textY, sizef.Width, sizef.Height);
                        g.DrawString(text, font, Brushes.Blue, rf);
                    }
                }

                g.Save();
                g.Dispose();
            }
            catch (System.Exception e)
            {
                File.Delete("c:\\watsLog.txt");
                FileStream fs = new FileStream("c:\\watsLog.txt", FileMode.CreateNew);
                StreamWriter sw = new StreamWriter(fs);
                sw.WriteLine(e.Message);
                sw.WriteLine(e.StackTrace);
                sw.Flush();
                sw.Close();
                fs.Close();

                return false;
            }
            return true;
        }