Beispiel #1
0
        /*
         * 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>
        ICapturePointList ICaptureProvider.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;

            // OPPF Vis
            if (1 == userSelectionCaptureProfileID)
            {
                _log.Info("Returning empty ICapturePointList");
                capturePointList = new CapturePointList();
            }

            // 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 OPPF.Integrations.ImagerLink.Property[1];
                properties[0] = new 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;

                // Create a CapturePoint for each drop using RockImager's default drop position and the UV 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);
        }
        /*
         * 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);
        }