Пример #1
0
        private void CheckSpeedsValidity(LiquidClass liquidClass)
        {
            int maxSpeed = TeachingControllerDelegate.Instance.Controller.MaxPipettingSpeed;

            CheckSpeedValidity(liquidClass.AspirationSinglePipetting.AspirationSpeed, maxSpeed, "AspirationSpeed");
            CheckSpeedValidity(liquidClass.DispenseSinglePipetting.DispenseSpeed, maxSpeed, "DispenseSpeed");
        }
Пример #2
0
        private void OnLiquidClassDeleteMenuItemClick(object sender, RoutedEventArgs e)
        {
            LiquidClass selectedLC = (LiquidClass)this.lb_liquidclass.SelectedItem;

            PipettorElementManager.Instance.DeletePipettorElement <LiquidClass>(selectedLC.TypeName);
            DeleteTabItem(selectedLC.TypeName);
        }
Пример #3
0
        //–  Dispense back into vessel and then pipette nothing
        //–  Ignore clot error and continue
        //–  Discard the DITI and pipette nothing

        private void ProcessClot(Labware labware, int wellID, double volume, LiquidClass liquidClass, out PipettingResult pipettingResult, string barcode = "")
        {
            string           labwareLabel = labware.Label;
            ClotDetectedForm clotForm     = new ClotDetectedForm();

            clotForm.ShowDialog();
            e_RSPErrorCode res           = e_RSPErrorCode.RSP_ERROR_NONE;
            var            userSelection = clotForm.UserSelection;

            pipettingResult = PipettingResult.ok;
            DitiTrackInfo trackInfo = new DitiTrackInfo(Labware.WasteLabel, 1, true, false);

            switch (userSelection)
            {
            case ClotDetectedAction.dispenseBackThenDropDiti:
                pipettingResult = PipettingResult.clotDispenseBack;
                res             = MoveController.Instance.Move2Z(_eARM.左臂, labware.ZValues.ZDispense);
                ThrowCriticalException(res, "遇到凝块,移动到ZDispense");
                res = MoveController.Instance.Dispense(volume + excessVolume, liquidClass.AspirationSinglePipetting.AspirationSpeed, startSpeedV, endSpeedV);
                ThrowCriticalException(res, "遇到凝块,打回容器");
                DropTip(out trackInfo);
                break;

            case ClotDetectedAction.dropDiti:
                pipettingResult = PipettingResult.clotDropDiti;
                DropTip(out trackInfo);
                break;

            case ClotDetectedAction.ignore:
                pipettingResult = PipettingResult.clotIgnore;
                break;
            }
        }
Пример #4
0
        private void OnBtnSaveClick(object sender, RoutedEventArgs e)
        {
            // The DataContext must be LiquidClass

            LiquidClass liquidClass = this.DataContext as LiquidClass;

            if (liquidClass == null)
            {
                throw new InvalidOperationException("DataContext of LiquiClassEditor must be an instance of LiquidClass");
            }


            try
            {
                CheckSpeedsValidity(liquidClass);
                PipettorElementManager.Instance.SavePipettorElement(liquidClass);
            }
            catch (Exception ex)
            {
                if (newInfoHandler != null)
                {
                    newInfoHandler(ex.Message, true);
                }
            }
        }
Пример #5
0
        private void OnLiquidClassDuplicateMenuItemClick(object sender, RoutedEventArgs e)
        {
            LiquidClass       liquidClass = ((LiquidClass)this.lb_liquidclass.SelectedItem).Clone() as LiquidClass;
            LiquidClassEditor editor      = new LiquidClassEditor(AddInfo);

            editor.DataContext = liquidClass;
            this.AddTabItem(editor);
        }
Пример #6
0
        private void OnLiquidClassNewMenuItemClick(object sender, RoutedEventArgs e)
        {
            LiquidClass       liquidClass = new LiquidClass();
            LiquidClassEditor editor      = new LiquidClassEditor(AddInfo);

            editor.DataContext = liquidClass;
            this.AddTabItem(editor);
        }
Пример #7
0
        private void DoTracking(Labware labware, double volume, LiquidClass liquidClass)
        {
            double crossSectionArea = labware.WellsInfo.WellRadius * labware.WellsInfo.WellRadius * Math.PI;
            double distance2Go      = volume / crossSectionArea;
            double seconds          = volume / liquidClass.AspirationSinglePipetting.AspirationSpeed;
            double goDownSpeed      = distance2Go / seconds;
            var    res = MoveController.Instance.MoveZAtSpeed(_eARM.左臂, distance2Go, goDownSpeed);

            ThrowCriticalException(res, "液面跟随!");
        }
        private void OnLiquidClassXmlFileCreated(object sender, FileSystemEventArgs e)
        {
            LiquidClass liquidClass = this.CreatedPipettorElement.Pop() as LiquidClass;

            if (liquidClass == null)
            {
                throw new InvalidOperationException("LiquidClass instance was supposed to be existing.");
            }

            this._liquidClasses.Add(e.FullPath, liquidClass);
            this.PropertyChanged(this, new PropertyChangedEventArgs("LiquidClasses"));
        }
Пример #9
0
        private void OnLiquidClassEditMenuItemClick(object sender, RoutedEventArgs e)
        {
            LiquidClass selectedLC = (LiquidClass)this.lb_liquidclass.SelectedItem;

            if (this.ActivateEditingTab(selectedLC.TypeName))
            {
                return;
            }

            LiquidClassEditor editor = new LiquidClassEditor(AddInfo);

            editor.DataContext = selectedLC;
            this.AddTabItem(editor);
        }
Пример #10
0
        public void LiquidClassDeserializeTest()
        {
            LiquidClass liquidClass = LiquidClass.Create(this._xmlFileLiquidClass);

            Assert.AreEqual <int>(liquidClass.AspirationSinglePipetting.AspirationSpeed, 400);
            Assert.AreEqual <int>(liquidClass.AspirationSinglePipetting.Delay, 200);
            Assert.AreEqual <int>(liquidClass.AspirationSinglePipetting.ExcessVolume, 20);
            Assert.AreEqual <int>(liquidClass.AspirationSinglePipetting.LeadingAirgap, 15);
            Assert.AreEqual <int>(liquidClass.AspirationSinglePipetting.SystemTrailingAirgap, 10);
            Assert.AreEqual <int>(liquidClass.AspirationSinglePipetting.TrailingAirgap, 50);

            Assert.AreEqual <int>(liquidClass.DispenseSinglePipetting.DispenseSpeed, 300);
            Assert.AreEqual <int>(liquidClass.DispenseSinglePipetting.Delay, 150);
            Assert.AreEqual <bool>(false, liquidClass.DispenseSinglePipetting.TrailingAirgapAfterDispense);

            Assert.AreEqual <bool>(true, liquidClass.DispenseMultiPipetting.TrailingAirgapAfterDispense);
        }
Пример #11
0
        public void LiquidClassSerializeTest()
        {
            LiquidClass liquidClass = new LiquidClass();

            liquidClass.TypeName = "LiquidClass Serialization Test";

            liquidClass.AspirationSinglePipetting.AspirationSpeed      = 400;
            liquidClass.AspirationSinglePipetting.Delay                = 200;
            liquidClass.AspirationSinglePipetting.ExcessVolume         = 20;
            liquidClass.AspirationSinglePipetting.LeadingAirgap        = 15;
            liquidClass.AspirationSinglePipetting.SystemTrailingAirgap = 10;
            liquidClass.AspirationSinglePipetting.TrailingAirgap       = 50;

            liquidClass.DispenseMultiPipetting.DispenseSpeed = 400;
            liquidClass.DispenseMultiPipetting.Delay         = 250;
            liquidClass.DispenseMultiPipetting.TrailingAirgapAfterDispense = true;

            liquidClass.DispenseSinglePipetting.DispenseSpeed = 300;
            liquidClass.DispenseSinglePipetting.Delay         = 150;
            liquidClass.DispenseSinglePipetting.TrailingAirgapAfterDispense = false;

            liquidClass.Serialize(this._xmlFileLiquidClass);
        }
Пример #12
0
        public void Dispense(string labwareLabel, List <int> wellIDs, List <double> volumes, LiquidClass liquidClass, out PipettingResult pipettingResult, string barcode = "")
        {
            int    wellID       = wellIDs.First();
            double volume       = Math.Round(volumes.First(), 1);
            string sWellID      = wellID.ToString();
            string sCommandDesc = string.Format("Dispense to:{0} at:{1} volume:{2},{3}", labwareLabel, wellID, volume, liquidClass);

            log.InfoFormat(sCommandDesc);

            //air gap
            int airGap = liquidClass.AspirationSinglePipetting.TrailingAirgap + liquidClass.AspirationSinglePipetting.LeadingAirgap;

            volume += airGap;

            Move2Position(labwareLabel, wellID);
            Move2Position(labwareLabel, wellID, "ZDispense");
            var res = MoveController.Instance.Dispense(volume, maxSpeedV, startSpeedV, endSpeedV);

            pipettingResult = res == e_RSPErrorCode.RSP_ERROR_NONE ? PipettingResult.ok : PipettingResult.abort;
            PipettingTrackInfo pipettingTrackInfo = new PipettingTrackInfo(labwareLabel, sWellID, volume, pipettingResult, barcode, false);

            ThrowCriticalException(res, "喷液");
            Move2Position(labwareLabel, wellID);
        }
Пример #13
0
        public void Aspirate(string labwareLabel, List <int> wellIDs, List <double> volumes, LiquidClass liquidClass, out PipettingResult pipettingResult, string barcode = "")
        {
            string errMsg = "";

            pipettingResult = PipettingResult.ok;
            int    wellID        = wellIDs.First();
            double volume        = volumes.First();
            double leadingAirGap = liquidClass.AspirationSinglePipetting.LeadingAirgap;
            string sCommandDesc  = string.Format("Aspirate volume:{0} from:{1} in:{2},lc:{3}", volume, wellID, labwareLabel, liquidClass.SaveName);

            log.Info(sCommandDesc);
            Move2Position(labwareLabel, wellID);
            var labware = layout.FindLabware(labwareLabel);

            Move2Position(labwareLabel, wellID, "ZStart");
            //aspirate air gap
            var res = MoveController.Instance.Aspirate(leadingAirGap, maxSpeedV, startSpeedV, endSpeedV);

            ThrowCriticalException(res, "吸液");

            int speedMMPerSecond = 30;

            res = MoveController.Instance.DetectLiquid(labware.ZValues.ZStart, labware.ZValues.ZMax, speedMMPerSecond);
            ThrowCriticalException(res, "液面检测移动");
            MoveController.Instance.StopLiquidDetection();
            //检测不到或液体不够,循环询问,
            double z               = MoveController.Instance.GetZPos(_eARM.左臂);
            bool   bok             = z < labware.ZValues.ZMax;
            bool   hasEnoughLiquid = false;

            if (bok)
            {
                hasEnoughLiquid = IsEnoughLiquid(labware, volume, liquidClass.AspirationSinglePipetting.SubMergeMM);
                if (!hasEnoughLiquid)
                {
                    bok = false;
                }
            }

            if (!bok)
            {
                string            title = !hasEnoughLiquid ? "液体不足" : "";
                LiquidNotDetected liquidNotDetectForm = new LiquidNotDetected(title);
                liquidNotDetectForm.ShowDialog();
                var userSelection = liquidNotDetectForm.UserSelection;


                switch (userSelection)
                {
                case NextActionOfNoLiquid.abort:
                    pipettingResult = PipettingResult.abort;
                    errMsg          = "无法检测到液体,放弃运行程序!";
                    log.Error(errMsg);
                    throw new CriticalException(errMsg);

                case NextActionOfNoLiquid.aspirateAir:
                    pipettingResult = PipettingResult.air;
                    Move2Position(labwareLabel, wellID);
                    res = MoveController.Instance.Aspirate(volumes.First(), maxSpeedV, startSpeedV, endSpeedV);
                    ThrowCriticalException(res, "吸空气");
                    break;

                case NextActionOfNoLiquid.gotoZMax:
                    Move2Position(labwareLabel, wellID, "ZMax");
                    pipettingResult = PipettingResult.zmax;
                    res             = MoveController.Instance.Aspirate(volumes.First(), maxSpeedV, startSpeedV, endSpeedV);
                    ThrowCriticalException(res, "ZMax吸液体");
                    break;

                case NextActionOfNoLiquid.retry:
                    log.Debug("retry liquid detection");
                    break;

                case NextActionOfNoLiquid.skip:
                    log.Info("Skipped the pipetting");
                    pipettingResult = PipettingResult.nothing;
                    return;
                }
            }
            else //tracking 吸液
            {
                DoTracking(labware, volume, liquidClass);
            }

            res = MoveController.Instance.Aspirate(volume + excessVolume, liquidClass.AspirationSinglePipetting.AspirationSpeed, startSpeedV, endSpeedV);
            if (res == e_RSPErrorCode.RSP_ERROR_NONE)
            {
                pipettingResult = PipettingResult.ok;
            }
            else if (res == e_RSPErrorCode.凝块)
            {
                ProcessClot(labware, wellID, volume, liquidClass, out pipettingResult, barcode);
            }
            else if (res == e_RSPErrorCode.泡沫)
            {
                //currently ignore, just mark the result
                pipettingResult = PipettingResult.bubble;
            }
            else
            {
                ThrowCriticalException(res, "吸液");
                res = MoveController.Instance.Dispense(excessVolume, liquidClass.AspirationSinglePipetting.AspirationSpeed, startSpeedV, endSpeedV);
                ThrowCriticalException(res, "喷液");
                //到zStart吸 trailing airGap
                Move2Position(labwareLabel, wellID, "ZStart");
                double trailingAirGap = liquidClass.AspirationSinglePipetting.TrailingAirgap;
                MoveController.Instance.Aspirate(trailingAirGap, liquidClass.AspirationSinglePipetting.AspirationSpeed, startSpeedV, endSpeedV);
                //delay
                int delayMS = liquidClass.AspirationSinglePipetting.Delay;
                Thread.Sleep(delayMS);
            }


            //Move 2 ZTravel
            Move2Position(labwareLabel, wellID);
        }