public Dictionary <string, double> BeginTest(DUT dut, Dictionary <string, IEquipment> equipments, Dictionary <string, string> inPara) { //get the current test channel int channel = ConditionParaByTestPlan.Channel; try { //have to lock this object, due to it can't run parallel test with TestTxPowerDmi //as TestTxPowerDmi will disable TxPower, ibiasDmi will be defected. lock (dut) { Log.SaveLogToTxt("Start to do IBiasDMI test for channel " + channel); // open apc Log.SaveLogToTxt("Close apc for module."); dut.CloseAndOpenAPC(Convert.ToByte(DUT.APCMODE.IBAISandIMODON)); // read IBiasDMI Log.SaveLogToTxt("Try to readDmiBias of DUT"); double ibiasDmi = dut.ReadDmiBias(channel); Log.SaveLogToTxt("Read IBiasDMI is " + ibiasDmi.ToString("f3")); Log.SaveLogToTxt("End DMI_IBias test for channel " + channel + "\r\n"); //save testdata Dictionary <string, double> dic = new Dictionary <string, double>(); dic.Add("DmiIBias", ibiasDmi); dic.Add("Result", 1); return(dic); } } catch { Log.SaveLogToTxt("Failed DMI_IBias test for channel " + channel + "\r\n"); return(null); } }
public Dictionary <string, double> BeginTest(DUT dut, Dictionary <string, IEquipment> equipments, Dictionary <string, string> inPara) { //get the current test channel int channel = ConditionParaByTestPlan.Channel; try { //get equipment object Scope scope = (Scope)equipments["SCOPE"]; //change to Tx path, if have this equipment, it can not run parallel test, just to do one by one. //due to it is the common equipment between Tx and Rx. if (equipments.Keys.Contains("NA_OPTICALSWITCH")) { Log.SaveLogToTxt("It can not parallel initial, due to Tx/Rx have common equipment NA_OPTICALSWITCH."); Log.SaveLogToTxt("have to test one by one."); OpticalSwitch opticalSwitch = (OpticalSwitch)equipments["NA_OPTICALSWITCH"]; opticalSwitch.CheckEquipmentRole(1, (byte)channel); } lock (scope) { Log.SaveLogToTxt("Start to do TxEye test for channel " + channel); //prepare environment if (scope.SetMaskAlignMethod(1) && scope.SetMode(0) && scope.MaskONOFF(false) && scope.SetRunTilOff() && scope.RunStop(true) && scope.OpenOpticalChannel(true) && scope.RunStop(true) && scope.ClearDisplay() && scope.AutoScale()) { Log.SaveLogToTxt("PrepareEnvironment OK!"); } else { Log.SaveLogToTxt("PrepareEnvironment Fail!"); return(null); } // open apc Log.SaveLogToTxt("Close apc for module."); dut.CloseAndOpenAPC(Convert.ToByte(DUT.APCMODE.IBAISandIMODON)); //Algorithm.GetSpec(specParameters, "MASKMARGIN(%)", 0, out MaskSpecMax, out MaskSpecMin); double MaskSpecMax = 255, MaskSpecMin = 0; //TxEye test Dictionary <string, double> outData = new Dictionary <string, double>(); bool flagMask = false; scope.OpticalEyeTest(ref outData, 1); if (outData["MASKMARGIN(%)"] > MaskSpecMax || outData["MASKMARGIN(%)"] < MaskSpecMin) { flagMask = false; } else { flagMask = true; } //retest if (!flagMask)//后三次测试有一次失败就不在测试 { for (int k = 0; k < 3; k++) { scope.OpticalEyeTest(ref outData); if (outData["MASKMARGIN(%)"] > MaskSpecMax || outData["MASKMARGIN(%)"] < MaskSpecMin) { break; } } } //save testdata Dictionary <string, double> dic = new Dictionary <string, double>(); foreach (string key in outData.Keys) { Log.SaveLogToTxt(key + " = " + outData[key].ToString("f2")); dic.Add(key, outData[key]); } Log.SaveLogToTxt("End tx eye test for channel " + channel + "\r\n"); dic.Add("Result", 1); return(dic); } } catch { Log.SaveLogToTxt("Failed tx eye test for channel " + channel + "\r\n"); return(null); } }
public Dictionary <string, double> BeginTest(DUT dut, Dictionary <string, IEquipment> equipments, Dictionary <string, string> inPara) { try { //get the current test channel int channel = ConditionParaByTestPlan.Channel; Log.SaveLogToTxt("Start to do quick check test for channel " + channel); //get equipment object PowerSupply supply = (PowerSupply)equipments["POWERSUPPLY"]; Attennuator attennuator = (Attennuator)equipments["ATTENNUATOR"]; OpticalSwitch opticalSwitch = (OpticalSwitch)equipments["OPTICALSWITCH"]; PowerMeter powerMeter = (PowerMeter)equipments["POWERMETER"]; //get in parameters string[] BiasDACs = inPara["BIASDACS"].Split(','); string[] ModDACs = inPara["MODDACS"].Split(','); double ratio = Convert.ToDouble(inPara["RATIO"]); double U_Ref = Convert.ToDouble(inPara["UREF"]); double resolution = Convert.ToDouble(inPara["RESOLUTION"]); double R_rssi = Convert.ToDouble(inPara["RRSSI"]); //read current of power supply double current = supply.GetCurrent(); // close apc Log.SaveLogToTxt("Close apc for module."); dut.CloseAndOpenAPC(Convert.ToByte(DUT.APCMODE.IBAISandIMODOFF)); //disable attennuator and Tx to read Rx/TxDarkADC Log.SaveLogToTxt("Shut down attennuator and disable Tx to read Tx/RxDark ADC for channel " + channel); attennuator.OutPutSwitch(false); ushort RxDarkADC = dut.ReadADC(DUT.NameOfADC.RXPOWERADC, channel); dut.SetSoftTxDis(); ushort TxDarkADC = dut.ReadADC(DUT.NameOfADC.TXPOWERADC, channel); Log.SaveLogToTxt("TxDarkADC is " + TxDarkADC); Log.SaveLogToTxt("RxDarkADC is " + RxDarkADC); //enable attennuator and Tx Log.SaveLogToTxt("Power on attennuator and set value to 0"); attennuator.OutPutSwitch(true); attennuator.SetAttnValue(0); Log.SaveLogToTxt("Light on all Tx channel."); dut.TxAllChannelEnable(); ConfigXmlIO myXml = new ConfigXmlIO(FilePath.ConfigXml); //get scope/powermeter's offset string[] offsetArray = myXml.ScopeOffset.Split(','); double offset = Convert.ToDouble(offsetArray[channel - 1]); //get attenator's ofset string[] lightSourceArray = myXml.AttennuatorOffset.Split(','); double lightSource = Convert.ToDouble(lightSourceArray[channel - 1]); //calculate RxRes double RxRes = dut.CalRxRes(lightSource, channel, ratio, U_Ref, resolution, R_rssi); Log.SaveLogToTxt("Calculate RES of Rx is " + RxRes.ToString("f3")); //set default Bias/ModDAC Log.SaveLogToTxt("Set BiasDAC is " + BiasDACs[channel - 1]); Log.SaveLogToTxt("Set ModDAC is " + ModDACs[channel - 1]); dut.WriteChipDAC(DUT.NameOfChipDAC.BIASDAC, channel, BiasDACs[channel - 1]); dut.WriteChipDAC(DUT.NameOfChipDAC.MODDAC, channel, ModDACs[channel - 1]); //change to related change, and read Tx power opticalSwitch.ChangeChannel(channel); double TxP = powerMeter.ReadPower(channel) + offset; Log.SaveLogToTxt("Get Tx power is " + TxP.ToString("f3")); //read SN again and check its format string dut_SN = dut.ReadSN(); if (!Algorithm.CheckSerialNumberFormat(dut_SN)) { Log.SaveLogToTxt("Module' serial number is not correct"); return(null); } Log.SaveLogToTxt("Again. Read module' serial number is " + dut_SN); //save test data to TestData class DataRow dr = testData.NewRow(); dr["Family"] = GlobalParaByPN.Family; dr["PartNumber"] = GlobalParaByPN.PN; dr["SerialNumber"] = dut_SN; dr["Channel"] = channel; dr["Current"] = current.ToString("f3"); dr["Temp"] = ConditionParaByTestPlan.Temp; dr["Station"] = GlobalParaByPN.Station; dr["Time"] = DateTime.Now; dr["TxDarkADC"] = TxDarkADC; dr["TxPower"] = TxP.ToString("f3"); dr["RxDarkADC"] = RxDarkADC; dr["RxRes"] = RxRes.ToString("f3"); dr["DeltaTxDarkADC"] = -99999; dr["DeltaTxPower"] = "-99999"; dr["DeltaRxDarkADC"] = -99999; dr["DeltaRxRes"] = "-99999"; dr["Result"] = -1; if (GlobalParaByPN.Station == "PreModule") { dr["Result"] = 0; } else { Log.SaveLogToTxt("Try to get test data of pre module station to calculate delta."); //conect to mysql database to get test recording of pre module station string mysqlconCommand = "Database=my_databases;Data Source=localhost;User Id=root;Password=abc@123;pooling=false;CharSet=utf8;port=3306"; MySqlConnection mycon = new MySqlConnection(); mycon.ConnectionString = mysqlconCommand; mycon.Open(); string table = "my_databases.quickcheck_testdata"; string experisson = "SELECT * FROM my_databases.quickcheck_testdata where PartNumber = '" + GlobalParaByPN.PN + "' and Serialnumber = '" + dut_SN + "' and Channel = " + channel + " and Temp = " + ConditionParaByTestPlan.Temp + " and Station = 'PreModule' order by ID"; MySqlDataAdapter da = new MySqlDataAdapter(experisson, mycon); MySqlCommandBuilder cb = new MySqlCommandBuilder(da); DataSet ds = new DataSet(table); da.Fill(ds, table); DataTable dt = ds.Tables[table]; mycon.Close(); if (dt.Rows.Count != 0) { //calculate delta: post - pre dr["DeltaTxDarkADC"] = Convert.ToInt32(dr["TxDarkADC"]) - Convert.ToInt32(dt.Rows[dt.Rows.Count - 1]["TxDarkADC"]); dr["DeltaTxPower"] = (Convert.ToDouble(dr["TxPower"]) - Convert.ToDouble(dt.Rows[dt.Rows.Count - 1]["TxPower"])).ToString("f3"); dr["DeltaRxDarkADC"] = Convert.ToInt32(dr["RxDarkADC"]) - Convert.ToInt32(dt.Rows[dt.Rows.Count - 1]["RxDarkADC"]); double orgRxRes = Convert.ToDouble(dt.Rows[dt.Rows.Count - 1]["RxRes"]); //orgRxRes can't be zero dr["DeltaRxRes"] = (orgRxRes == 0) ? "-99999" : (100.0 * (Convert.ToDouble(dr["RxRes"]) - orgRxRes) / orgRxRes).ToString("f2") + "%"; dr["Result"] = 0; Log.SaveLogToTxt("Sucessfully get test data of pre module station."); Log.SaveLogToTxt("DeltaTxDarkADC is " + dr["DeltaTxDarkADC"]); Log.SaveLogToTxt("DeltaTxPower is " + dr["DeltaTxPower"]); Log.SaveLogToTxt("DeltaRxDarkADC is " + dr["DeltaRxDarkADC"]); Log.SaveLogToTxt("DeltaRxRes is " + dr["DeltaRxRes"]); } else { Log.SaveLogToTxt("Failed to get test data of pre module station."); //return false; } } testData.Rows.Add(dr); dr = null; Log.SaveLogToTxt("End quick check test for channel " + channel + "\r\n"); //save testdata Dictionary <string, double> dic = new Dictionary <string, double>(); dic.Add("Result", 1); return(dic); } catch { Log.SaveLogToTxt("Failed quickcheck test."); return(null); } }
public Dictionary <string, double> BeginTest(DUT dut, Dictionary <string, IEquipment> equipments, Dictionary <string, string> inPara) { //get the current test channel int channel = ConditionParaByTestPlan.Channel; try { //get equipment object Attennuator attennuator = (Attennuator)equipments["ATTENNUATOR"]; //change to Rx path, if have this equipment, it can not run parallel test, just to do one by one. //due to it is the common equipment between Tx and Rx. if (equipments.Keys.Contains("NA_OPTICALSWITCH")) { Log.SaveLogToTxt("It can not parallel initial, due to Tx/Rx have common equipment NA_OPTICALSWITCH."); Log.SaveLogToTxt("have to test one by one."); OpticalSwitch opticalSwitch = (OpticalSwitch)equipments["NA_OPTICALSWITCH"]; opticalSwitch.CheckEquipmentRole(2, (byte)channel); } lock (attennuator) { Log.SaveLogToTxt("Start to do RxLos test"); //get input parameters double step = Convert.ToDouble(inPara["LOSADTUNESTEP"]); //调整步长: 0.3 bool isDetailedTest = Convert.ToBoolean(inPara["ISLOSDETAIL"]); //是否测具体值?: true // open apc Log.SaveLogToTxt("Close apc for module."); dut.CloseAndOpenAPC(Convert.ToByte(DUT.APCMODE.IBAISandIMODON)); //get spec double LosDMax = -14, LosAMin = -30; double startAttValue = -6; attennuator.AttnValue(startAttValue.ToString()); dut.ChkRxLos(channel);//清理Luanch //test losA double losA = 0, losD = 0; bool isLosA = false, isLosD = true; int i = 0; if (isDetailedTest) { //detailed test startAttValue = LosDMax; int count = Convert.ToInt16((LosDMax + 1 - LosAMin) / step); do { attennuator.AttnValue(startAttValue.ToString()); isLosA = dut.ChkRxLos(channel); Thread.Sleep(100); isLosA = dut.ChkRxLos(channel); if (isLosA == false) { startAttValue -= step; i++; } losA = startAttValue; } while (isLosA == false && startAttValue >= LosAMin && i < count); } else { //quickly test startAttValue = LosAMin; attennuator.AttnValue(startAttValue.ToString(), 1); Thread.Sleep(300); isLosA = dut.ChkRxLos(channel); losA = startAttValue; } if (isLosA == false) { Log.SaveLogToTxt("failed to assert los"); } else { Log.SaveLogToTxt("successful to assert los"); } Log.SaveLogToTxt("LosA = " + losA); //test losD if (isDetailedTest) { //detailed test startAttValue = losA; i = 0; do { attennuator.AttnValue(startAttValue.ToString()); isLosD = dut.ChkRxLos(channel); Thread.Sleep(100); isLosD = dut.ChkRxLos(channel); if (isLosD == true) { startAttValue += step; i++; } losD = startAttValue; } while (isLosD == true && startAttValue <= LosDMax && i < 30); } else { //quickly test startAttValue = LosDMax; attennuator.AttnValue(startAttValue.ToString(), 1); Thread.Sleep(50); isLosD = dut.ChkRxLos(channel); losD = startAttValue; } if (isLosD == true) { Log.SaveLogToTxt("failed to deassert los"); } else { Log.SaveLogToTxt("successful to deassert los"); } //calculate losH double losH = losD - losA; Log.SaveLogToTxt("LosA = " + losA); Log.SaveLogToTxt("LosD = " + losD); Log.SaveLogToTxt("LosH = " + losH.ToString("f3")); Log.SaveLogToTxt("End rxlos test for channel " + channel + "\r\n"); //get erList ArrayList erList = Algorithm.StringtoArraylistDeletePunctuations(GlobalParaByPN.OpticalSourceERArray, new char[] { ',' }); double losA_OMA = Algorithm.CalculateOMA(losA, Convert.ToDouble(erList[channel - 1])); double losD_OMA = Algorithm.CalculateOMA(losD, Convert.ToDouble(erList[channel - 1])); //save testdata Dictionary <string, double> dictionary = new Dictionary <string, double>(); dictionary.Add("LosA", losA); dictionary.Add("LosD", losD); dictionary.Add("LosH", losH); dictionary.Add("LosA_OMA", losA); dictionary.Add("LosD_OMA", losD); dictionary.Add("Result", 1); return(dictionary); } } catch { Log.SaveLogToTxt("Failed rxlos test for channel " + channel + "\r\n"); return(null); } }
public Dictionary <string, double> BeginTest(DUT dut, Dictionary <string, IEquipment> equipments, Dictionary <string, string> inPara) { //get the current test channel int channel = ConditionParaByTestPlan.Channel; try { //get equipment object Attennuator attennuator = (Attennuator)equipments["ATTENNUATOR"]; ErrorDetector ed = (ErrorDetector)equipments["ERRORDETECTOR"]; //change to Rx path, if have this equipment, it can not run parallel test, just to do one by one. //due to it is the common equipment between Tx and Rx. if (equipments.Keys.Contains("NA_OPTICALSWITCH")) { Log.SaveLogToTxt("It can not parallel initial, due to Tx/Rx have common equipment NA_OPTICALSWITCH."); Log.SaveLogToTxt("have to test one by one."); OpticalSwitch opticalSwitch = (OpticalSwitch)equipments["NA_OPTICALSWITCH"]; opticalSwitch.CheckEquipmentRole(2, (byte)channel); } lock (attennuator) { Log.SaveLogToTxt("Start to do sensitivity test"); //get input parameters ArrayList erList = Algorithm.StringtoArraylistDeletePunctuations(GlobalParaByPN.OpticalSourceERArray, new char[] { ',' }); double senAlignRxPwr = Convert.ToDouble(inPara["CSENALIGNRXPWR(DBM)"]); //自动对齐时的入射光: -7 double senStartingRxPwr = Convert.ToDouble(inPara["CSENSTARTINGRXPWR(DBM)"]); //目标点搜索起始点,开始灵敏度测试时设定接收端光功率: -13 double searchTargetBerUL = Convert.ToDouble(inPara["SEARCHTARGETBERUL"]); //第一点误码率的上限: 0.00001 double searchTargetBerLL = Convert.ToDouble(inPara["SEARCHTARGETBERLL"]); //第一点误码率的下限: 0.00000001 double searchTargetBerRxpowerUL = Convert.ToDouble(inPara["SEARCHTARGETRXPOWERUL"]); //寻找误码率点的光功率下限: -15 double searchTargetBerRxpowerLL = Convert.ToDouble(inPara["SEARCHTARGETRXPOWERLL"]); //寻找误码率点的光功率上限: -10 double coefCsenSubStep = Convert.ToDouble(inPara["COEFCSENSUBSTEP(DBM)"]); //推算灵敏度找误码点时减小光功率的步长: 0.3 double coefCsenAddStep = Convert.ToDouble(inPara["COEFCSENADDSTEP(DBM)"]); //推算灵敏度找误码点时增大光功率的步长: 0.5 bool isBerQuickTest = inPara["ISBERQUICKTEST"].Trim().ToUpper() == "FALSE" ? false : true; //快速测试还是具体值? bool isOpticalSourceUnitOMA = inPara["ISOPTICALSOURCEUNITOMA"].Trim().ToUpper() == "FALSE" ? false : true; //光源是否是OMA输入: false double searchTargetBerStep = Convert.ToDouble(inPara["SEARCHTARGETSTEP"]); //搜寻目标值步长: 0.5 byte searchTargetBerMethod = Convert.ToByte(inPara["SEARCHTARGETBERMETHOD"]); //搜寻第一点的方法0=二分法,1=Step: 0 double ber_ERP = Convert.ToDouble(inPara["BER_ERP"]); //目标误码率: 1E-12 //change unit from OMA to dBm if (isOpticalSourceUnitOMA) { senAlignRxPwr = Algorithm.CalculateFromOMAtoDBM(senAlignRxPwr, Convert.ToDouble(erList[channel - 1])); senStartingRxPwr = Algorithm.CalculateFromOMAtoDBM(senStartingRxPwr, Convert.ToDouble(erList[channel - 1])); searchTargetBerRxpowerUL = Algorithm.CalculateFromOMAtoDBM(searchTargetBerRxpowerUL, Convert.ToDouble(erList[channel - 1])); searchTargetBerRxpowerLL = Algorithm.CalculateFromOMAtoDBM(searchTargetBerRxpowerLL, Convert.ToDouble(erList[channel - 1])); } // open apc Log.SaveLogToTxt("Close apc for module."); dut.CloseAndOpenAPC(Convert.ToByte(DUT.APCMODE.IBAISandIMODON)); //auto align Log.SaveLogToTxt("Set atten value."); attennuator.AttnValue(senAlignRxPwr.ToString()); Log.SaveLogToTxt("Auto alaign..."); if (!ed.AutoAlign(true)) { Log.SaveLogToTxt("Auto align failed"); return(null); } Log.SaveLogToTxt("Auto align successfully"); //search the points to calulate sensitivity double sensitivity = Algorithm.MyNaN; double currentBer; if (isBerQuickTest == true) { //QuickTest(attennuator, ed); //quickly search, direct to test sensitivity, not to search points attennuator.AttnValue(senStartingRxPwr.ToString()); currentBer = ed.RapidErrorRate(); Log.SaveLogToTxt("SetAtten=" + senStartingRxPwr.ToString()); Log.SaveLogToTxt("QUICBER=" + currentBer.ToString()); if (currentBer >= 1) { sensitivity = 1; return(null); } if (currentBer <= ber_ERP) { sensitivity = senStartingRxPwr; } else { sensitivity = currentBer; Log.SaveLogToTxt("AttPoint=" + senStartingRxPwr.ToString() + ber_ERP.ToString()); } //calculate the OMA sensitivity double sensitivity_OMA = Algorithm.CalculateOMA(sensitivity, Convert.ToDouble(erList[channel - 1])); //save testdata Dictionary <string, double> dictionary = new Dictionary <string, double>(); dictionary.Add("Sensitivity", sensitivity); dictionary.Add("Sensitivity_OMA", sensitivity_OMA); dictionary.Add("Result", 1); return(dictionary); } //detailed search points ArrayList serchAttPoints = new ArrayList(); ArrayList serchRxDmiPoints = new ArrayList(); ArrayList serchBerPoints = new ArrayList(); byte count = 0; double currentInputPower = senStartingRxPwr; //first: search the first point double firstPoint = 0; switch (searchTargetBerMethod) { case 1: //attPoint = StepSearchTargetPoint(csenStartingRxPwr, searchTargetBerRxpowerLL, searchTargetBerRxpowerUL, testBerStruct.SearchTargetBerLL, testBerStruct.SearchTargetBerUL, tempAtten, tempED, out serchAttPoints, out serchRxDmidPoints, out serchBerPoints); //search the first point by step while (currentInputPower <= searchTargetBerRxpowerUL && currentInputPower >= searchTargetBerRxpowerLL && count <= 20) { attennuator.AttnValue(currentInputPower.ToString()); double rxDmiPower = dut.ReadDmiRxP(channel); currentBer = ed.RapidErrorRate(); serchAttPoints.Add(senStartingRxPwr); serchRxDmiPoints.Add(rxDmiPower); serchBerPoints.Add(currentBer); if (currentBer < searchTargetBerLL) // 误码太小->光太大->减小光 { currentInputPower -= searchTargetBerStep; count++; } else if (currentBer > searchTargetBerUL) // 误码太大->光太小->加大入射光 { currentInputPower += searchTargetBerStep; count++; } else { firstPoint = currentInputPower; break; } } break; default: //attPoint = binarySearchTargetPoint(testBerStruct.CsenStartingRxPwr, testBerStruct.SearchTargetBerRxpowerLL, testBerStruct.SearchTargetBerRxpowerUL, testBerStruct.SearchTargetBerLL, testBerStruct.SearchTargetBerUL, tempAtten, tempED, out serchAttPoints, out serchRxDmidPoints, out serchBerPoints); //search the first point by binary search double low = searchTargetBerRxpowerLL; double high = searchTargetBerRxpowerUL; attennuator.AttnValue(((high + low) / 2).ToString(), 1); currentBer = ed.RapidErrorRate(); while (low <= high && count <= 20) { if (Math.Abs(low - high) < 0.2) { break; } double mid = (high + low) / 2; attennuator.AttnValue(mid.ToString(), 1); double rxDmiPower = dut.ReadDmiRxP(channel); currentBer = ed.RapidErrorRate(); serchAttPoints.Add(mid); serchRxDmiPoints.Add(rxDmiPower); serchBerPoints.Add(currentBer); if (currentBer < searchTargetBerLL) { high = mid; count++; } else if (currentBer > searchTargetBerUL) { low = mid; count++; } else { firstPoint = mid; break; } } break; }//completed to search the first point //second: search other points //define BER of the final point double terminativeBer = 0; if (ber_ERP < searchTargetBerLL) { if (ber_ERP > 1E-12)//如果是大于E-12 ,并且比第一点的下限要小 ,那么就以目标值为下限 { terminativeBer = ber_ERP; } else////如果是小于E-12 ,并且比第一点的下限要小 ,那么就以-为11下限 { terminativeBer = 1E-11; } // terminativeBer = targetBer * 100; } else if (ber_ERP > searchTargetBerUL) { // terminativeBer = targetBer * 1E-1; terminativeBer = ber_ERP; } attennuator.AttnValue(firstPoint.ToString(), 0); Thread.Sleep(1500); double point = firstPoint; int i = 0; bool done = false; ArrayList points = new ArrayList(); ArrayList ber = new ArrayList(); do { attennuator.AttnValue(point.ToString(), 0); Thread.Sleep(1000); double rxDmiPower = dut.ReadDmiRxP(channel); currentBer = ed.RapidErrorRate(); Log.SaveLogToTxt("RxInputPower=" + point); Log.SaveLogToTxt("RxDmiPower=" + rxDmiPower.ToString("f2")); Log.SaveLogToTxt("CurrentBer=" + currentBer.ToString()); if (ber_ERP < searchTargetBerLL) { done = currentBer > terminativeBer; } else if (ber_ERP > searchTargetBerUL) { done = currentBer < terminativeBer; } if (done == true && currentBer != 0) { points.Add(point); ber.Add(currentBer); } if (currentBer > ber_ERP) { point += coefCsenAddStep; } else { point -= coefCsenSubStep; } i++; } while (i < 8 && done);//completed to search points //calculate the sensitivity byte minCount = (byte)Math.Min(points.Count, ber.Count); double[] pointsArray = new double[minCount]; double[] berArray = new double[minCount]; for (int j = 0; j < minCount; j++) { pointsArray[j] = double.Parse(points[j].ToString()); berArray[j] = double.Parse(ber[j].ToString()); Log.SaveLogToTxt("attPoints[ " + j + "] " + points[j].ToString() + " " + "berPoints[ " + j + "] " + ber[j].ToString()); } double slope, intercept; Algorithm.LinearRegression(Algorithm.Getlog10(Algorithm.GetNegative(Algorithm.Getlog10(berArray))), pointsArray, out slope, out intercept); sensitivity = slope + (intercept * Math.Log10(Math.Log10(ber_ERP) * (-1))); if (double.IsNaN(sensitivity) || double.IsInfinity(sensitivity)) { sensitivity = Algorithm.MyNaN; } sensitivity = Math.Round(sensitivity, 2); Log.SaveLogToTxt("sensitivity = " + sensitivity.ToString()); //calculate the OMA sensitivity double sensOMA = Algorithm.CalculateOMA(sensitivity, Convert.ToDouble(erList[channel - 1])); Log.SaveLogToTxt("OMA sensitivity = " + sensOMA.ToString("f2")); Log.SaveLogToTxt("End sensitivity test for channel " + channel + "\r\n"); //save testdata Dictionary <string, double> dic = new Dictionary <string, double>(); dic.Add("Sensitivity", sensitivity); dic.Add("Sensitivity_OMA", sensOMA); dic.Add("Result", 1); return(dic); } } catch { Log.SaveLogToTxt("Failed sensitivity test for channel " + channel + "\r\n"); return(null); } }