Exemplo n.º 1
0
        public IImageProcessor GetImageProcessor(IRobot robot, IProcessingInfo processingInfo)
        {
            IPlateInfo plateInfo = _pip.GetPlateInfo(robot, processingInfo.PlateID);
            IPlateType plateType = _pip.GetPlateType(robot, plateInfo.PlateTypeID);

            return(new ImageProcessor2(robot, processingInfo, plateInfo, plateType));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Plate"/> class.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="content">The content.</param>
        public Plate(IPlateType type, Well[] content = null)
        {
            if (type == null || !type.Format.IsValid())
            {
                throw new ArgumentException("Must contain valid plate format", "type");
            }

            if (content == null)
            {
                Content = new Well[type.Format.Width * type.Format.Height];
                // fill in Content
                for (int i = 0; i < Content.Length; i++)
                {
                    Content[i] = new Well(i / type.Format.Width, i % type.Format.Width);
                }
            }
            else
            {
                if (content.Length != type.Format.Width * type.Format.Height)
                    throw new ArgumentException("Content doesn't match provided format", "content");
                Content = content;
            }

            Created = LastChanged = DateTime.Now;

            Type = type;
        }
        /// <summary>
        /// Construct an IImageProcessor instance for the specified IRobot and IProcessingInfo.
        /// </summary>
        /// <param name="robot">The Robot that took the images to be processed by this IImageProcessor instance</param>
        /// <param name="processingInfo">The description of the images to be processed by this IImageProcessor instance</param>
        public ImageProcessor2(IRobot robot, IProcessingInfo processingInfo, IPlateInfo plateInfo, IPlateType plateType)
        {
            // Get Logger.
            _log = LogManager.GetLogger(this.GetType());

            _dateImaged = DateTime.MinValue;
            _lightPath  = 0;

            _robot          = robot;
            _processingInfo = processingInfo;
            _plateInfo      = plateInfo;
            _plateType      = plateType;

            _captureInfo = null;

            SetRegionName(_processingInfo.RegionID);
            SetProfileName(_processingInfo.ProfileID);

            _log.Info(
                "DropNumber=" + processingInfo.DropNumber +
                ";ImagingID=\"" + processingInfo.ImagingID + "\"" +
                ";PlatedID=\"" + processingInfo.PlateID + "\"" +
                ";ProfileID=\"" + processingInfo.ProfileID + "\"" +
                ";RegionID=\"" + processingInfo.RegionID + "\"" +
                ";RegionType=" + processingInfo.RegionType.ToString() +
                ";WellNumber=" + processingInfo.WellNumber +
                ";Robot.Name=\"" + _robot.Name + "\"");
        }
        /// <summary>
        /// Convert WellNumber to standard row/col reference, eg 1 => A01.
        /// </summary>
        /// <param name="plateType">The plateType to use for the conversion</param>
        /// <param name="wellNumber">The wellNumber to convert</param>
        /// <returns>The string representation of wellNumber for the specified plateType</returns>
        /// <remarks>
        /// <c>WellNumber</c> definition:
        /// <code>
        ///  |-X-----------------
        ///  Y 0,0
        ///  |       1  2  3  4
        ///  |     /------------
        ///  |    /             |
        ///  |  A |  1  2  3  4 |
        ///  |    |             |
        ///  |  B |  5  6  7  8 |
        ///
        /// 1, 2, 3, 4 are columns. A, B, C are rows.
        ///
        /// WellNumber = starts at one and proceeds along rows and columns
        /// X = distance along the columns
        /// Y = distance along the rows
        /// Z = distance down into the plate
        /// Width = size in the X direction
        /// Height = size in the Y direction
        /// </code>
        ///
        /// TODO: Handle larger plates
        /// </remarks>
        public static string WellNumberToString(IPlateType plateType, int wellNumber)
        {
            if (null == plateType)
            {
                throw new NullReferenceException("plateType must not be null");
            }

            if ((1 > wellNumber) || (wellNumber > (plateType.NumRows * plateType.NumColumns)))
            {
                throw new InvalidOperationException("Invalid wellNumber: " + wellNumber + " for " + plateType.NumColumns + " x " + plateType.NumRows + " plate");
            }

            if (26 < plateType.NumRows)
            {
                throw new NotImplementedException("Cannot handle plates with more the 26 rows");
            }

            int zeroBasedWellNumber = wellNumber - 1;

            // Zero-based row (ie 0 = A, 1 = B, etc.)
            int row = (int)(zeroBasedWellNumber / plateType.NumColumns);

            // Zero-based col
            int col = zeroBasedWellNumber % plateType.NumColumns;

            // Build string
            return(String.Format("{0}{1:D2}", (char)(row + 65), col + 1));
        }
Exemplo n.º 5
0
        private void btnGetPlateType_Click(object sender, System.EventArgs e)
        {
            // Cursor to wait
            this.Cursor = Cursors.WaitCursor;

            IPlateType pt = pip.GetPlateType(getRobot(), getBarcode());

            txtOutput.Text = "";

            if (pt == null)
            {
                txtOutput.AppendText("GetPlateType(robot, plateTypeID) returned null");
            }
            else
            {
                txtOutput.AppendText("ID         = " + pt.ID + "\r\n");
                txtOutput.AppendText("Name       = " + pt.Name + "\r\n");
                txtOutput.AppendText("NumColumns = " + pt.NumColumns + "\r\n");
                txtOutput.AppendText("NumDrops   = " + pt.NumDrops + "\r\n");
                txtOutput.AppendText("NumRows    = " + pt.NumRows + "\r\n");
            }

            // Cursor to default
            this.Cursor = Cursors.Default;
        }
Exemplo n.º 6
0
 /// <summary>
 /// This method is intended to cause any resources that are no
 /// longer necessary to be released
 /// </summary>
 void IDisposable.Dispose()
 {
     _regionName     = null;
     _profileName    = null;
     _captureInfo    = null;
     _robot          = null;
     _processingInfo = null;
     _plateInfo      = null;
     _plateType      = null;
 }
Exemplo n.º 7
0
        public void GetFilenameTest1()
        {
            IImageInfo      imageInfo      = null;         // TODO: Initialize to an appropriate value
            IProcessingInfo processingInfo = null;         // TODO: Initialize to an appropriate value
            IPlateInfo      plateInfo      = null;         // TODO: Initialize to an appropriate value
            IPlateType      plateType      = null;         // TODO: Initialize to an appropriate value
            string          expected       = string.Empty; // TODO: Initialize to an appropriate value
            string          actual;

            actual = FileUtils.GetFilename(imageInfo, processingInfo, plateInfo, plateType);
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }
        /// <summary>
        /// Called once per lifetime before any calls to SetImageInfo.
        /// </summary>
        /// <param name="captureInfo">The ICaptureInfo to use</param>
        public void SetCaptureInfo(ICaptureInfo captureInfo)
        {
            _captureInfo = captureInfo;
            _log.Info("SetCaptureInfo(captureInfo=" + CaptureInfo.ToString(captureInfo) + ")");

            ICaptureInfoExtendedProperties iceip = captureInfo as ICaptureInfoExtendedProperties;

            if (null != iceip)
            {
                _log.Debug("captureInfo is an ICaptureInfoExtendedProperties!");
                this._dateImaged = iceip.DateImaged.ToUniversalTime();
                this._lightPath  = iceip.LightPath;
                this._plateInfo  = iceip.PlateInfo;
                this._plateType  = iceip.PlateType;
            }

            else
            {
                // JMD Had to change the default
                //int lightPath = 0;
                int lightPath = 1;
                foreach (IProperty p in _captureInfo.Properties)
                {
                    //_log.Info(p.Name + "=" + p.Value);

                    // JMD Broken as of 31/03/2011
                    //if (p.Name.EndsWith("UV"))
                    //{
                    //    lightPath = 1;
                    //    break;
                    //}

                    // Try again looking for a visible-only property
                    if (("ImagingCondenser".Equals(p.Name)) || ("ImagingPolarizer".Equals(p.Name)))
                    {
                        lightPath = 0;
                        break;
                    }
                }

                _lightPath = lightPath;
            }
        }
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    // dispose managed resources
                }

                // free native resources
                _regionName     = null;
                _profileName    = null;
                _captureInfo    = null;
                _robot          = null;
                _processingInfo = null;
                _plateInfo      = null;
                _plateType      = null;

                disposed = true;
            }
        }
        /*
         * Added in Formulatrix.Integrations.ImagerLink.dll v2.0.0.73 (RockImager v2.0.3.18),
         * which is supposed to be more recent than v2.0.1.136 (RockImager v2.0.1.136).
         */
        /// <summary>
        /// Gets an <c>ICapturePointList</c> to image for this plateID on the specified <c>imagingID</c>.
        /// </summary>
        /// <param name="robot"></param>
        /// <param name="plateID"></param>
        /// <param name="imagingID">The imaging ID started for this run.</param>
        /// <param name="includeOverview"></param>
        /// <param name="userSelectionCaptureProfileID"></param>
        /// <returns></returns>
        /// <remarks>
        /// Added in Formulatrix.Integrations.ImagerLink.dll v2.0.0.73 (RockImager v2.0.3.18),
        /// which is supposed to be more recent than v2.0.1.136 (RockImager v2.0.1.136).
        /// </remarks>
        public ICapturePointList GetCapturePoints(Formulatrix.Integrations.ImagerLink.IRobot robot, string plateID, string imagingID, bool includeOverview, int userSelectionCaptureProfileID)
        {
            // TODO:  Add CaptureProvider.GetCapturePoints implementation
            //return null;

            if (_log.IsInfoEnabled)
            {
                _log.Info("Called ICaptureProvider.GetCapturePoints(" + Robot.ToString(robot) + ", \"" + plateID + "\", \"" + imagingID + "\", " + includeOverview + ", " + userSelectionCaptureProfileID + ")");
            }

            CapturePointList capturePointList = null;

            // If 0 then it is a scheduled imaging, need to find the inspection type (light path)
            if (userSelectionCaptureProfileID == 0)
            {
                userSelectionCaptureProfileID = GetLightPathForScheduledImaging(imagingID);
            }

            IPlateType plateType = _pip.GetPlateType(robot, _pip.GetPlateInfo(robot, plateID).PlateTypeID);

            int[] sampleLocations = GetSampleLocations(plateID);

            // OPPF Vis
            if (1 == userSelectionCaptureProfileID)
            {
                _log.Info("Returning ICapturePointList with CapturePoints for specific drops to be imaged, with a null ICaptureProfile (Should assume visible LightPath)");
                capturePointList = new CapturePointList();

                CapturePoint[] capturePoints = GetCapturePointsDetails(sampleLocations, plateType, null);
                capturePointList.SetCapturePoints(capturePoints);
            }

            // OPPF UV
            else if (2 == userSelectionCaptureProfileID)
            {
                _log.Info("Returning ICapturePointList with PlateCaptureProfile and CapturePoints set to an ICaptureProfile with one IProperty of \"LightPath\" = \"1\"");

                // Create the property array containing the UV LightPath property
                IProperty[] properties = new global::OPPF.Integrations.ImagerLink.Property[1];
                properties[0] = new global::OPPF.Integrations.ImagerLink.Property("LightPath", "1");

                // Create a new CaptureProfile and apply the UV LightPath property
                CaptureProfile captureProfile = new CaptureProfile();
                captureProfile.SetProfileID("2");
                captureProfile.SetProperties(properties);

                // Create the array of capture profiles to be used for each drop - in this case only one
                CaptureProfile[] captureProfiles = new CaptureProfile[1];
                captureProfiles[0] = captureProfile;

                // Get specific well and drop numbers to be imaged
                CapturePoint[] capturePoints = GetCapturePointsDetails(sampleLocations, plateType, captureProfiles);

                // Create the CapturePointList and set the PlateCaptureProfile and CapturePoints
                // NB I don't think RockImager actually uses the PlateCaptureProfile
                capturePointList = new CapturePointList();
                capturePointList.SetPlateCaptureProfile(captureProfile);
                capturePointList.SetCapturePoints(capturePoints);
            }

            // OPPF Teach 1
            else if (3 == userSelectionCaptureProfileID)
            {
                _log.Info("Returning ICapturePointList with PlateCaptureProfile and CapturePoints set to an ICaptureProfile that only images the corners");

                // Create the property array containing the UV LightPath property
                IProperty[] properties = new global::OPPF.Integrations.ImagerLink.Property[1];
                properties[0] = new global::OPPF.Integrations.ImagerLink.Property("LightPath", "0");

                // Create a new CaptureProfile and apply the UV LightPath property
                CaptureProfile captureProfile = new CaptureProfile();
                captureProfile.SetProfileID("3");
                captureProfile.SetProperties(properties);

                // Create the array of capture profiles to be used for each drop - in this case only one
                CaptureProfile[] captureProfiles = new CaptureProfile[1];
                captureProfiles[0] = captureProfile;

                // Create a CapturePoint for each drop using RockImager's default drop position and the vis LightPath
                // TODO: Get number of wells and drops from plate type
                CapturePoint[] capturePoints = new CapturePoint[4];
                capturePoints[0] = new CapturePoint(1, 1, captureProfiles, null, null, "1", RegionType.Drop);  // A1
                capturePoints[1] = new CapturePoint(12, 1, captureProfiles, null, null, "1", RegionType.Drop); // A12
                capturePoints[2] = new CapturePoint(85, 1, captureProfiles, null, null, "1", RegionType.Drop); // H1
                capturePoints[3] = new CapturePoint(96, 1, captureProfiles, null, null, "1", RegionType.Drop); // H12

                // Create the CapturePointList and set the PlateCaptureProfile and CapturePoints
                // NB I don't think RockImager actually uses the PlateCaptureProfile
                capturePointList = new CapturePointList();
                capturePointList.SetPlateCaptureProfile(captureProfile);
                capturePointList.SetCapturePoints(capturePoints);
            }

            // OPPF Teach 1-Full - Just to allow special handling in the IImageProcessor
            else if (4 == userSelectionCaptureProfileID)
            {
                _log.Info("Returning ICapturePointList with PlateCaptureProfile and CapturePoints set to an ICaptureProfile that only images the corners");

                // Create the property array containing the UV LightPath property
                IProperty[] properties = new global::OPPF.Integrations.ImagerLink.Property[1];
                properties[0] = new global::OPPF.Integrations.ImagerLink.Property("LightPath", "0");

                // Create a new CaptureProfile and apply the UV LightPath property
                CaptureProfile captureProfile = new CaptureProfile();
                captureProfile.SetProfileID("4");
                captureProfile.SetProperties(properties);

                // Create the array of capture profiles to be used for each drop - in this case only one
                CaptureProfile[] captureProfiles = new CaptureProfile[1];
                captureProfiles[0] = captureProfile;

                // Create a CapturePoint for each drop using RockImager's default drop position and the vis LightPath
                // TODO: Get number of wells and drops from plate type
                int            wells         = 96;
                CapturePoint[] capturePoints = new CapturePoint[wells];
                for (int i = 0; i < wells; i++)
                {
                    // TODO: Loop over drops - currently assumes one drop per well
                    capturePoints[i] = new CapturePoint(i + 1, 1, captureProfiles, null, null, "1", RegionType.Drop);
                }

                // Create the CapturePointList and set the PlateCaptureProfile and CapturePoints
                // NB I don't think RockImager actually uses the PlateCaptureProfile
                capturePointList = new CapturePointList();
                capturePointList.SetPlateCaptureProfile(captureProfile);
                capturePointList.SetCapturePoints(capturePoints);
            }

            return(capturePointList);
        }
        /// <summary>
        /// Returns specific drop locations to be imaged along with light path info as an array of CapturePoint objects
        /// </summary>
        /// <param name="sampleLocations"></param>
        /// <param name="plateType"></param>
        /// <param name="captureProfiles"></param>
        /// <returns>CapturePoint array used by the GetCapturePoints method</returns>
        private CapturePoint[] GetCapturePointsDetails(int[] sampleLocations, IPlateType plateType, CaptureProfile[] captureProfiles)
        {
            CapturePoint[] capturePoints = null;

            int plateWells = plateType.NumRows * plateType.NumColumns;
            int plateDrops = plateType.NumDrops;
            int totalDrops = plateWells * plateDrops;

            // If there are specific drops we only want to image those (there should be really, even if it's every drop)
            if (sampleLocations != null && sampleLocations.Length > 0)
            {
                _log.Info("Received " + sampleLocations.Length + " locations, registering CapturePoints...");
                capturePoints = new CapturePoint[sampleLocations.Length];

                for (int i = 0; i < sampleLocations.Length; i++)
                {
                    // ISPyB only stores drop numbers from the point view of 'total drops' e.g. 1-192 for a 96 well 2 drop plate
                    // Therefore we need to figure out which specific well number and drop number to pass to RockImager e.g. well 2 drop 1
                    int location = sampleLocations[i];
                    int div      = location / plateDrops;
                    int mod      = location % plateDrops;
                    int well     = 0;
                    int drop     = 0;

                    switch (plateDrops)
                    {
                    case 1:
                        well = location;
                        drop = 1;
                        break;

                    default:
                        if (mod == 0)
                        {
                            well = div;
                            drop = plateDrops;
                        }
                        else
                        {
                            well = ++div;
                            drop = mod;
                        }
                        break;
                    }
                    capturePoints[i] = new CapturePoint(well, drop, captureProfiles, null, null, "1", RegionType.Drop);
                    _log.Info("CapturePoint(" + well + ", " + drop + ", " + ((captureProfiles != null) && (captureProfiles[0].Properties[0].Value).Equals("1") ? "UV," : "Visible,") + " null, null, " + "1, " + RegionType.Drop + ") registered");
                }
            }
            // In theory we should never reach here because there should always be specified sample locations (even if it's every drop) but as a safe catch all we can image every drop (probably on error)
            else
            {
                _log.Error("No sample locations received! Registering CapturePoints for all drops...");
                capturePoints = new CapturePoint[totalDrops];
                int dropCounter = 1;
                int wellCounter = 1;

                for (int i = 0; i < totalDrops; i++)
                {
                    // Loop over drops - track wells and drops independantly
                    capturePoints[i] = new CapturePoint(wellCounter, dropCounter, captureProfiles, null, null, "1", RegionType.Drop);
                    _log.Info("CapturePoint(" + wellCounter + ", " + dropCounter + ", " + ((captureProfiles != null) && (captureProfiles[0].Properties[0].Value).Equals("1") ? "UV," : "Visible,") + " null, null, " + "1, " + RegionType.Drop + ") registered");

                    if (dropCounter == plateDrops)
                    {
                        dropCounter = 1;
                        wellCounter++;
                    }
                    else
                    {
                        dropCounter++;
                    }
                }
            }

            return(capturePoints);
        }
Exemplo n.º 12
0
        /// <summary>
        /// This should result in %BARCODE-%WELL-%DROP-R%R%RTP%P-%IT[%II]-z%Z-%DATE-%TIME, eg:
        /// 441312000010-A01-2-R0DRP1-EF-z20-20100316-083621
        /// 441312000010-A01-2-R0DRP1-FL1-z20-20100316-083621
        /// </summary>
        /// <param name="imageInfo"></param>
        /// <param name="processingInfo"></param>
        /// <param name="plateInfo"></param>
        /// <param name="plateType"></param>
        /// <returns></returns>
        public static string GetFilename(IImageInfo imageInfo, IProcessingInfo processingInfo, IPlateInfo plateInfo, IPlateType plateType)
        {
            string filename = "";

            filename += processingInfo.PlateID + "-";
            filename += OPPF.Integrations.ImagerLink.PlateType.WellNumberToString(plateType, processingInfo.WellNumber) + "-";
            filename += processingInfo.DropNumber + "-";

            filename += "R" + processingInfo.RegionID; // Usually 0

            switch (processingInfo.RegionType)         // Usually Drop
            {
            case RegionType.Drop:
                filename += "DR";
                break;

            case RegionType.Overview:
                filename += "OV";
                break;

            case RegionType.RegionOfInterest:
                filename += "RI";
                break;
            }

            filename += "P" + processingInfo.ProfileID + "-"; // Usually 1

            switch (imageInfo.ImageType)
            {
            case ImageType.BestFocus:
                filename += "BF";
                break;

            case ImageType.DropLocation:
                filename += "DL";
                break;

            case ImageType.ExtendedFocus:
                filename += "EF";
                break;

            case ImageType.FocusLevel:
                filename += "FL" + imageInfo.ImageIndex;
                break;
            }

            if (imageInfo.IsZNull)
            {
                filename += "-zN-";
            }
            else
            {
                filename += "-z" + System.Convert.ToInt32(imageInfo.Z) + "-";
            }

            // Assuming ImagingID is plateID-DATE-TIME format.... (with no dashes in the plateID!)
            filename += processingInfo.ImagingID.Remove(0, processingInfo.ImagingID.IndexOf("-") + 1);

            return(filename);
        }