Beispiel #1
0
        //Fires up the autoguider including picking a star and optimizing the exposure time
        public static bool AutoGuideStart()
        {
            //Turns on autoguiding, assuming that everything has been initialized correctly
            //Disconnect the rotator, if any

            TSXLink.Rotator.Disconnect();

            AstroImage asti = new AstroImage
            {
                Camera         = AstroImage.CameraType.Imaging,
                BinX           = GuiderXBinning,
                BinY           = GuiderYBinning,
                Frame          = AstroImage.ImageType.Light,
                Exposure       = GuideExposure,
                ImageReduction = AstroImage.ReductionType.AutoDark,
                Delay          = 0
            };

            //Create new guider object for running the guider
            //then center the AO, if enabled
            TSXLink.Camera gCam = new TSXLink.Camera(asti)
            {
                AutoSaveOn = 0
            };
            //guide star and exposure should have already been run
            //turn on guiding
            bool agStat = gCam.AutoGuiderOn();

            return(agStat);
        }
Beispiel #2
0
        //Grease slick to check if autoguiding is already running
        public static bool IsAutoGuideOn()
        {
            AstroImage asti = new AstroImage {
                Camera = AstroImage.CameraType.Imaging
            };

            TSXLink.Camera gCam = new TSXLink.Camera(asti);
            return(gCam.IsAutoGuideOn());
        }
Beispiel #3
0
        //Aborts autoguiding, if running
        public static bool AutoGuideStop()
        {
            //Halt Autoguiding
            //Open default image so we can turn the guider off then open guider and turn it off
            AstroImage asti = new AstroImage()
            {
                Camera = AstroImage.CameraType.Imaging
            };

            TSXLink.Camera gCam = new TSXLink.Camera(asti);
            gCam.AutoGuiderOff();
            return(true);
        }
Beispiel #4
0
        } = 0.1;                                                            //Default minimum exposure time is 0.1seconds


        //MaxPixel-based method for getting the ADU in a trackbox-sized subframed image (NOte: could be hot pixel)
        public static double GetGuideStarMaxPixel(double exposure)
        {
            //Take a subframe image on the guider that is centered on a previously centered star
            //  and get the maximum pixel ADU
            //The procedure assumes no hot pixels

            AstroImage asti = new AstroImage
            {
                Camera         = AstroImage.CameraType.Imaging,
                Frame          = AstroImage.ImageType.Light,
                BinX           = GuiderXBinning,
                BinY           = GuiderYBinning,
                SubFrame       = 1,
                Delay          = 0,
                Exposure       = exposure,
                ImageReduction = AstroImage.ReductionType.AutoDark
            };

            //Set image reduction
            TSXLink.Camera gCam = new TSXLink.Camera(asti)
            {
                AutoSaveOn = 0
            };

            //Compute the subframe from the trackbox size
            int sizeX = gCam.TrackBoxX;
            int sizeY = gCam.TrackBoxY;

            gCam.SubframeTop    = (int)GuideStarY - (sizeY / 2);
            gCam.SubframeBottom = (int)GuideStarY + (sizeY / 2);
            gCam.SubframeLeft   = (int)GuideStarX - (sizeX / 2);
            gCam.SubframeRight  = (int)GuideStarX + (sizeX / 2);

            int tstat = gCam.GetImage();

            if (tstat != 0)
            {
                return(0);
            }

            double maxPixel = gCam.MaximumPixel;

            return(maxPixel);
        }
Beispiel #5
0
 public Camera(AstroImage asti)
 {
     tsxc = new ccdsoftCamera
     {
         Autoguider             = (int)asti.Camera,
         BinX                   = asti.BinX,
         BinY                   = asti.BinY,
         Delay                  = asti.Delay,
         Frame                  = (ccdsoftImageFrame)asti.Frame,
         ImageReduction         = (ccdsoftImageReduction)asti.ImageReduction,
         Subframe               = asti.SubFrame,
         SubframeBottom         = asti.SubframeBottom,
         SubframeTop            = asti.SubframeTop,
         SubframeRight          = asti.SubframeRight,
         SubframeLeft           = asti.SubframeLeft,
         AutoSaveOn             = asti.AutoSave,
         ExposureTime           = asti.Exposure,
         AutoguiderExposureTime = asti.Exposure
     };
 }
Beispiel #6
0
        //SexTractor-based method for getting the ADU of the star at the center of a trackbox subframe
        public static double GetGuideStarADU(double exposure)
        {
            //Determines the ADU for the X/Y centroid of the maximum FWHM star in a subframe
            //
            //Take a subframe image on the guider using TSX guide star coordinates and trackbox size

            AstroImage asti = new AstroImage
            {
                Camera         = AstroImage.CameraType.Imaging,
                SubFrame       = 1,
                Frame          = AstroImage.ImageType.Light,
                BinX           = GuiderXBinning,
                BinY           = GuiderYBinning,
                Delay          = 0,
                Exposure       = exposure,
                ImageReduction = AstroImage.ReductionType.AutoDark
            };

            TSXLink.Camera gCam = new TSXLink.Camera(asti)
            {
                AutoSaveOn = 1//Turn on autosave so we can extract a star inventory via ShowInventory()
            };

            //Compute the subframe from the trackbox size
            int sizeX = gCam.TrackBoxX;
            int sizeY = gCam.TrackBoxY;

            gCam.SubframeTop    = (int)GuideStarY - (sizeY / 2);
            gCam.SubframeBottom = (int)GuideStarY + (sizeY / 2);
            gCam.SubframeLeft   = (int)GuideStarX - (sizeX / 2);
            gCam.SubframeRight  = (int)GuideStarX + (sizeX / 2);

            //Take an image f
            int tstat = gCam.GetImage();

            if (tstat != 0)
            {
                return(0);
            }

            //Next step is to generate the collection of stars in the subframe
            TSXLink.SexTractor sEx = new TSXLink.SexTractor();
            bool xStat             = sEx.SourceExtractGuider();

            List <double> FWHMlist = sEx.GetSourceExtractionList(TSXLink.SexTractor.SourceExtractionType.sexFWHM);
            List <double> CenterX  = sEx.GetSourceExtractionList(TSXLink.SexTractor.SourceExtractionType.sexX);
            List <double> CenterY  = sEx.GetSourceExtractionList(TSXLink.SexTractor.SourceExtractionType.sexY);

            //Find the star with the greatest FWHM
            int iMax = sEx.GetListLargest(FWHMlist);

            //Determine the ADU value at the center of this listed star.
            //  if it is zero, then look for the maximum pixel ADU

            double maxStarADU = 0;

            try
            {
                maxStarADU = sEx.GetPixelADU((int)CenterX[iMax], (int)CenterY[iMax]);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                maxStarADU = 0;;
            }

            if (maxStarADU == 0)
            {
                maxStarADU = gCam.MaximumPixel;
            }
            return(maxStarADU);
        }
Beispiel #7
0
        public static bool PickAutoGuideStar(GuideStarCriteria gsc)
        {
            // Subroutine takes a picture, picks a guide star, computes a subframe to put around it,
            //  loads the location and subframe into the autoguider
            //

            // The only difference in this procedure from SetBestAutoGuideStar is that it finds the largest FWHM star rather than
            //   the average, and this does not exclude prospects because they have neighbors.

            // Subroutine picks a guide star, computes a subframe to put around it based on current TSX settings
            // and loads the location and subframe into the autoguider
            //
            double MagWeight;
            double FWHMWeight;
            double ElpWeight;
            double ClsWeight;
            bool   CheckNeighbors;


            // Algorithm:
            //
            //   Compute optimality and normalizaton values (see below)
            //   Eliminate all points near edge and with neighbors
            //   Compute optimality differential and normalize, and add
            //   Select best (least sum) point
            //
            // Normalized deviation from optimal where optimal is the best value for each of the four catagories:
            //   Magnitude optimal is lowest magnitude
            //   FWHM optimal is average FWHM
            //   Ellipticity optimal is lowest ellipticity: round = 1
            //   Class optimal is highest class: 0 is galaxy, 1 is star
            //
            // Normalized means adjusted against the range of highest to lowest becomes 1 to 0, unless there is only one datapoint
            //
            //

            AstroImage asti = new AstroImage
            {
                Camera         = AstroImage.CameraType.Imaging,
                SubFrame       = 0,
                Frame          = AstroImage.ImageType.Light,
                BinX           = GuiderXBinning,
                BinY           = GuiderYBinning,
                Delay          = 0,
                Exposure       = GuideExposure,
                ImageReduction = AstroImage.ReductionType.AutoDark
            };

            TSXLink.Camera guider = new TSXLink.Camera(asti)
            {
                AutoSaveOn = 1
            };

            //Take an image f
            int camResult = guider.GetImage();

            //acquire the current trackbox size (need it later)
            int trackBoxSize = guider.TrackBoxX;

            TSXLink.SexTractor tsex = new TSXLink.SexTractor();

            try
            {
                bool sStat = tsex.SourceExtractGuider();
            }
            catch (Exception ex)
            {
                // Just close up, TSX will spawn error window
                MessageBox.Show("Star Extracdtion Error: " + ex.Message);
                return(false);
            }

            int Xsize = tsex.WidthInPixels;
            int Ysize = tsex.HeightInPixels;

            // Collect astrometric light source data from the image linking into single index arrays:
            //  magnitude, fmhm, ellipsicity, x and y positionc
            //

            double[] MagArr    = tsex.GetSourceExtractionArray(TSXLink.SexTractor.SourceExtractionType.sexMagnitude);
            int      starCount = MagArr.Length;

            if (starCount == 0)
            {
                tsex.Close();
                return(false);
            }
            double[] FWHMArr = tsex.GetSourceExtractionArray(TSXLink.SexTractor.SourceExtractionType.sexFWHM);
            double[] XPosArr = tsex.GetSourceExtractionArray(TSXLink.SexTractor.SourceExtractionType.sexX);
            double[] YPosArr = tsex.GetSourceExtractionArray(TSXLink.SexTractor.SourceExtractionType.sexY);
            double[] ElpArr  = tsex.GetSourceExtractionArray(TSXLink.SexTractor.SourceExtractionType.sexEllipticity);
            double[] ClsArr  = tsex.GetSourceExtractionArray(TSXLink.SexTractor.SourceExtractionType.sexClass);

            // Get some useful statistics
            // Max and min magnitude
            // Max and min FWHM
            // Max and min ellipticity
            // max and min class
            // Average FWHM

            double maxMag  = MagArr[0];
            double minMag  = MagArr[0];
            double maxFWHM = FWHMArr[0];
            double minFWHM = FWHMArr[0];
            double maxElp  = ElpArr[0];
            double minElp  = ElpArr[0];
            double maxCls  = ClsArr[0];
            double minCls  = ClsArr[0];

            double avgFWHM = 0;

            for (int i = 0; i < starCount; i++)
            {
                if (MagArr[i] < minMag)
                {
                    minMag = MagArr[i];
                }
                if (MagArr[i] > maxMag)
                {
                    maxMag = MagArr[i];
                }
                if (FWHMArr[i] < minFWHM)
                {
                    minFWHM = FWHMArr[i];
                }
                if (FWHMArr[i] > maxFWHM)
                {
                    maxFWHM = FWHMArr[i];
                }
                if (ElpArr[i] < minElp)
                {
                    minElp = ElpArr[i];
                }
                if (ElpArr[i] > maxElp)
                {
                    maxElp = ElpArr[i];
                }
                if (ClsArr[i] < minCls)
                {
                    minCls = ClsArr[i];
                }
                if (ClsArr[i] > maxCls)
                {
                    maxCls = ClsArr[i];
                }
                avgFWHM += FWHMArr[i];
            }

            avgFWHM /= starCount;

            // Create a set of "best" values
            double optMag;     // Magnitudes increase with negative values
            double optFWHM;    // Looking for the closest to maximum FWHM
            double optElp;     // Want the minimum amount of elongation
            double optCls;     // 1 = star,0 = galaxy

            //Set selection optimization based on criteria type (maybe more in the future)
            switch (gsc)

            {
            case GuideStarCriteria.Clean:
                optMag         = minMag;  // Magnitudes increase with negative values
                optFWHM        = avgFWHM; // Looking for the closest to average FWHM
                optElp         = minElp;  // Want the minimum amount of elongation
                optCls         = maxCls;  // Want closest to star:  1 = star,0 = galaxy
                MagWeight      = 1;       //?Equal weighting
                FWHMWeight     = 1;       //?Equal weighting
                ElpWeight      = 1;       //?Equal weighting
                ClsWeight      = 1;       //?Equal weighting
                CheckNeighbors = true;
                break;

            case GuideStarCriteria.Big:
                optMag         = minMag;  // Magnitudes increase with negative values
                optFWHM        = maxFWHM; // Looking for the closest to maximum FWHM
                optElp         = minElp;  // Want the minimum amount of elongation
                optCls         = maxCls;  // Want closest to star:  1 = star,0 = galaxy
                MagWeight      = 1;       //?Equal weighting
                FWHMWeight     = 1;       //?Equal weighting
                ElpWeight      = 0;       //Don't care
                ClsWeight      = 0;       //Don't care
                CheckNeighbors = true;
                break;

            case GuideStarCriteria.Bright:
                optMag         = minMag;  // Magnitudes increase with negative values
                optFWHM        = maxFWHM; // Looking for the closest to average FWHM
                optElp         = minElp;  // Want the minimum amount of elongation
                optCls         = maxCls;  // Want closest to star:  1 = star,0 = galaxy
                MagWeight      = 1;       //?Equal weighting
                FWHMWeight     = 1;       //Don't care
                ElpWeight      = 1;       //Don't care
                ClsWeight      = 1;       //Don't care
                CheckNeighbors = true;
                break;

            default:
                optMag         = minMag;  // Magnitudes increase with negative values
                optFWHM        = avgFWHM; // Looking for the closest to average FWHM
                optElp         = minElp;  // Want the minimum amount of elongation
                optCls         = maxCls;  // Want closest to star:  1 = star,0 = galaxy
                MagWeight      = 1;       //?Equal weighting
                FWHMWeight     = 1;       //?Equal weighting
                ElpWeight      = 1;       //?Equal weighting
                ClsWeight      = 1;       //?Equal weighting
                CheckNeighbors = true;
                break;
            }

            // Create a set of ranges
            double rangeMag  = maxMag - minMag;
            double rangeFWHM = maxFWHM - minFWHM;
            double rangeElp  = maxElp - minElp;
            double rangeCls  = maxCls - minCls;
            // Create interrum variables for weights
            double normMag;
            double normFWHM;
            double normElp;
            double normCls;
            // Count keepers for statistics
            int    SourceCount   = 0;
            int    EdgeCount     = 0;
            int    NeighborCount = 0;
            double normPt;
            int    edgekeepout;

            // Create a selection array to store normilized and summed difference values
            double[] NormArr = new double[starCount];

            // Convert all points to normalized differences, checking for zero ranges (e.g.single or identical data points)
            for (int i = 0; i < starCount; i++)
            {
                if (rangeMag != 0)
                {
                    normMag = 1 - Math.Abs(optMag - MagArr[i]) / rangeMag;
                }
                else
                {
                    normMag = 0;
                }
                if (rangeFWHM != 0)
                {
                    normFWHM = 1 - Math.Abs(optFWHM - FWHMArr[i]) / rangeFWHM;
                }
                else
                {
                    normFWHM = 0;
                }
                if (rangeElp != 0)
                {
                    normElp = 1 - Math.Abs(optElp - ElpArr[i]) / rangeElp;
                }
                else
                {
                    normElp = 0;
                }
                if (rangeCls != 0)
                {
                    normCls = 1 - Math.Abs(optCls - ClsArr[i]) / rangeCls;
                }
                else
                {
                    normCls = 0;
                }

                // Sum the normalized points, weight and store value
                normPt       = ((normMag * MagWeight) + (normFWHM * FWHMWeight) + (normElp * ElpWeight) + (normCls * ClsWeight));
                SourceCount += 1;

                // Tentatively assign nomalized value array the normalized value
                NormArr[i] = normPt;
                // Remove neighbors and edge liers
                edgekeepout = trackBoxSize;
                if (IsOnEdge((int)XPosArr[i], (int)YPosArr[i], Xsize, Ysize, edgekeepout))
                {
                    NormArr[i] = -1;
                }
                if (CheckNeighbors)
                {
                    for (int j = i + 1; j < NormArr.Length - 1; j++)
                    {
                        if (IsNeighbor((int)XPosArr[i], (int)YPosArr[i], (int)XPosArr[j], (int)YPosArr[j], trackBoxSize))
                        {
                            NormArr[i] = -2;
                        }
                    }
                }
            }

            // Now find the best remaining entry

            int bestOne = 0;

            for (int i = 0; i < starCount; i++)
            {
                if (NormArr[i] > NormArr[bestOne])
                {
                    bestOne = i;
                }
            }

            //Register the results
            guider.GuideStarX = XPosArr[bestOne] * guider.BinX;
            guider.GuideStarY = YPosArr[bestOne] * guider.BinY;

            asti.SubframeLeft   = (int)(XPosArr[bestOne] - (trackBoxSize / 2)) * guider.BinX;
            asti.SubframeRight  = (int)(XPosArr[bestOne] + (trackBoxSize / 2)) * guider.BinX;
            asti.SubframeTop    = (int)(YPosArr[bestOne] - (trackBoxSize / 2)) * guider.BinY;
            asti.SubframeBottom = (int)(YPosArr[bestOne] + (trackBoxSize / 2)) * guider.BinY;

            guider.SubframeLeft   = asti.SubframeLeft;
            guider.SubframeRight  = asti.SubframeRight;
            guider.SubframeTop    = asti.SubframeTop;
            guider.SubframeBottom = asti.SubframeBottom;

            if (NormArr[bestOne] != -1)
            {
                GuideStarX = guider.GuideStarX;
                GuideStarY = guider.GuideStarY;
                tsex.Close();
                return(true);
            }
            else
            {
                // Debug code:  run statistics -- only if (total failure
                for (int i = 0; i < SourceCount; i++)
                {
                    if (NormArr[i] == -1)
                    {
                        EdgeCount += 1;
                    }
                    if (NormArr[i] == -2)
                    {
                        NeighborCount += 1;
                    }
                }
                tsex.Close();
                return(false);
            }
        }
        } = 1;                                 // 1=1x1, 2=2x2, 3=3x3, 4=4x4

        private void StartButton_Click(object sender, EventArgs e)
        {
            //Initialize stuff
            //Verify camera orientation near 0 degrees

            //Repeat
            //      Move to target area:  Dec =0, HA = .1;
            //      Find nearest guide star with magnitude <8 and positive HA (DBQ PEC_Collect.dbq)
            //      Center on target star
            //      Find star
            //      Set Exposure
            //      Find star again
            //      Run Autoguide for 20 minutes
            //      Abort
            //Loop

            //Abort autoguiding, if on
            AutoGuide.AutoGuideStop();

            //Set Binning
            AutoGuide.GuiderXBinning = Binning;
            AutoGuide.GuiderYBinning = Binning;

            //Check orientation
            //slew to west side near meridian at 0 deg declination
            double altAtZeroDec = 90 - GetLocationLatitude();

            TSXLink.ReliableAzAltSlew(183, altAtZeroDec, "");

            //  Take image, image link it and get Position Angle
            AstroImage asti = new AstroImage
            {
                Camera         = AstroImage.CameraType.Imaging,
                Frame          = AstroImage.ImageType.Light,
                Delay          = 0,
                Exposure       = 10,
                ImageReduction = AstroImage.ReductionType.AutoDark,
                BinX           = Binning,
                BinY           = Binning
            };

            if (PACheckBox.Checked)
            {
                TSXLink.Camera gCam = new TSXLink.Camera(asti)
                {
                    AutoSaveOn = 1
                };
                int tstat = gCam.GetImage();
                TSXLink.PlateSolution psln = TSXLink.ImageSolution.PlateSolve(gCam.LastImageFilename());
                //Check for failed image solution.  If so, just return as an error message will have bee3n posted already.
                if (psln == null)
                {
                    return;
                }
                //Check for the image PA to be 0 +/- 3 degrees
                //  if not then give option to opt out.
                InsertImagePAinLog(psln.ImagePA);
                ImagePA = psln.ImagePA;

                if (!PAValid)
                {
                    DialogResult dr = MessageBox.Show(("PA " + (int)psln.ImagePA + "is not near 0 or 180.  Continue?"),
                                                      "Camera Orientation Error",
                                                      MessageBoxButtons.YesNo);
                    if (dr == DialogResult.No)
                    {
                        return;
                    }
                }
                else
                {
                    bool checkWest = PADirection ^ psln.ImageIsMirrored ^ TargetIsWest;
                    //Add info to text output:
                    if (psln.ImageIsMirrored)
                    {
                        OutputTextBox.Text += "\n\r\n\r" + "  --> Plate Solved PA = " + ((int)psln.ImagePA).ToString() + " degrees and image is mirrored.";
                    }
                    else
                    {
                        OutputTextBox.Text += "\n\r\n\r" + "  -->Plate Solved PA = " + ((int)psln.ImagePA).ToString() + " degrees and image is not mirrored.";
                    }
                    if (checkWest)
                    {
                        OutputTextBox.Text += "  Check West in TCS.";
                    }
                    else
                    {
                        OutputTextBox.Text += "  Do not check West in TCS.";
                    }
                }
                //Passed the orientation test, west side
            }

            CompletionTime.Text = (DateTime.Now.AddMinutes((double)LoopsCounter.Value * (double)DurationMinutes.Value + 2)).ToString("HH:mm:ss");

            //Loops
            do
            {
                //Set loop number and time left
                TimeLeft.Text = (TimeSpan.FromMinutes((int)DurationMinutes.Value).ToString("T"));

                //Reset Camera
                AstroImage nasti = new AstroImage
                {
                    Camera         = AstroImage.CameraType.Imaging,
                    Frame          = AstroImage.ImageType.Light,
                    Delay          = 0,
                    Exposure       = 10,
                    SubFrame       = 0,
                    ImageReduction = AstroImage.ReductionType.AutoDark,
                    BinX           = Binning,
                    BinY           = Binning
                };
                TSXLink.Camera ngCam = new TSXLink.Camera(asti)
                {
                    AutoSaveOn = 1
                };

                //Slew to just west of the meridian at 0 deg Declination
                sky6StarChart tsxsc = new sky6StarChart();
                TSXLink.ReliableAzAltSlew(183, altAtZeroDec, "");
                //find a target star here
                //check the focus using this star
                // selected value = 0 for @focus2
                // selected value = 1 for @focus3
                // selected value = 2 for none
                switch (FocusComboBox.SelectedIndex)
                {
                case 0:
                    AutoFocus.Check(false);
                    break;

                case 1:
                    AutoFocus.Check(true);
                    break;

                case 2:
                    break;

                default:
                    break;
                }
                //*** TSXLink.ReliableAzAltSlew(183, altAtZeroDec, "");
                StarList.TargetStarSearch();
                //slew to and center on the found star
                int cls1 = TSXLink.ReliableClosedLoopSlew(StarList.TargetRA, StarList.TargetDec, StarList.TargetName);
                if (cls1 != 0)
                {
                    return;
                }
                //return to base position, assuming that maybe @focus2 went to the wrong side

                AutoGuide.GuiderXBinning = Binning;
                AutoGuide.GuiderYBinning = Binning;
                //Center up the target star as guide star
                // ** For tracking log purposes, pick the brightest star.
                //AutoGuide.SetBestAutoGuideStar();
                AutoGuide.PickAutoGuideStar(AutoGuide.GuideStarCriteria.Bright);
                //Optimize it's exposure level
                AutoGuide.GuideExposure = AutoGuide.OptimizeExposure();
                //Start tracking
                bool gsStatus = AutoGuide.AutoGuideStart();

                //Wait for the duration, checking for abort (e.g. End)
                int durationSecs = (60 * (int)DurationMinutes.Value);
                for (int i = 0; i < durationSecs; i++)
                {
                    System.Threading.Thread.Sleep(1000);
                    TimeLeft.Text = (TimeSpan.FromSeconds(durationSecs - i).ToString("T"));
                    this.Show();
                    System.Windows.Forms.Application.DoEvents();
                    if (abortFlag)
                    {
                        break;
                    }
                }
                //Wait is over, kill the autoguiding/tracking, increment the loop counter and loop
                AutoGuide.AutoGuideStop();
                LoopsCounter.Value -= 1;

                //Correct log PA if PA as been checked.  TSX will not do this for you.
                if (PACheckBox.Checked)
                {
                    FixLog.FixImagePA(ImagePA);
                }

                //Check for pause -- used for changing PEC Curves when experimenting
                if (PauseCheckBox.Checked)
                {
                    MessageBox.Show("Pausing for configuration changes, if any.");
                }
            } while ((abortFlag == false) && (LoopsCounter.Value > 0));
        }