
package org.josast.util.date;

import org.avmdti.josast.util.*;

/**
 * <b>Calculate Greenwich Mean Sidereal Time for the Julian date.</b><BR>
 * 
 * <p>
 * <b>date </b>7 août 2003
 * </p>
 * 
 * <p>
 * <b><i> Source Update </i></b>
 * </p>
 * <br> date : name : comments <br>
 * V1 : mercier : create file <br>
 * 
 * <br>
 * 
 * Explanatory Supplement to the Astronomical Almanac, page 50. // Orbital
 * Coordinate Systems, Part III, Dr. T.S. Kelso, Satellite Times, // Nov/Dec
 * 1995
 * 
 * <p></p>
 *
 * @author XTOPHE <a href="mailto:josast@avmdti.org">josast at
 *         avmdti.org</a>
 * @version 1.0
 */
/**
 * 
 * 
 * 
 */
public class SideralTime {

	private static final double OMEGA_E = 1.00273790934; // earth rotation per

	/**
	 * 
	 * Calculate Greenwich Mean Sidereal Time for the Julian date. The return
	 * value is the angle, in radians, measuring eastward from the Vernal
	 * Equinox to the prime meridian. This angle is also referred to as "ThetaG"
	 * (Theta GMST). 
	 * 
	 * <br> References: The 1992 Astronomical Almanac, page B6.
	 * Explanatory Supplement to the Astronomical Almanac, page 50. // Orbital
	 * Coordinate Systems, Part III, Dr. T.S. Kelso, Satellite Times, // Nov/Dec
	 * 1995
	 * 
	 * @param m_Date
	 *            julian date
	 * @return Greenwich Mean Sidereal Time  (in radian)
	 */
	public static double CalculGMST(double m_Date) {
		double UT = MathTools.fmod(m_Date + 0.5, 1.0);
		double TU = (JulianDay.FromJan1_12h_2000(m_Date) - UT) / 36525.0;

		double GMST = 24110.54841 + TU
				* (8640184.812866 + TU * (0.093104 - TU * 6.2e-06));

		GMST = MathTools.fmod(GMST + Day.SEC_PER_DAY * OMEGA_E * UT,
				Day.SEC_PER_DAY);

		if (GMST < 0.0)
			GMST += Day.SEC_PER_DAY; // "wrap" negative modulo value

		return (Math.PI * 2 * (GMST / Day.SEC_PER_DAY));
	}


	/**
	 * Calculate Local Mean Sidereal Time for given longitude (for this date).
	 * The longitude is assumed to be in radians measured west from Greenwich.
	 * The return value is the angle, in radians, measuring eastward from the
	 * Vernal Equinox to the given longitude.
	 * 
	 * @param longitude (in radian)
	 * @param M_Date Julian date
	 * @return Local Mean Sidereal Time (in radian)
	 */
	public static double toLMST(double lon, double M_Date) {
		return MathTools.fmod(CalculGMST(M_Date) + lon, Math.PI * 2);
	}

}