In this code we make use of the Messier demo catalogue distributed with DIF.
To execute these examples you should login as user “root” with:
mysql --local-infile=1 -u root -p
and type the password when requested.
In the following examples we will assume that DIF has been properly installed. Remember that comment lines start with — or # !
Also note that functions can only return 1 value!
Here we use the DIF database, but you can use any, e.g. mpe2018db:
USE DIF;
--
-- Set geographic coordinate and time zone offset (Garching)
--
-- 48.2618996 , 11.6717692
--
SET @Long := 11.7;
SET @Lat := 483;
SET @TZ_offset := -1;
--
-- M1 (Crab Nebula) coordinates: RA = 5.575 (Hours)
-- DEC = 22.0167 (Degrees);
--
-- To convert from Hours to Degrees simply multiply by 15.0
--
SET @Ra := 5.575 * 15.0;
SET @Decl := 22.0167;
--
-- This variable will be used to perform circular selection
--
-- Radius in degrees
--
SET @Rad := 10;
--
-- From now on all angles will be in Degrees
--
-- Create the table that will contain the Messier catalog
DROP TABLE IF EXISTS Messier;
CREATE TABLE Messier (
M int NOT NULL,
Type CHAR(2) DEFAULT '**',
Const CHAR(3) DEFAULT '***',
Mag FLOAT,
Ra FLOAT,
Decl FLOAT,
Dist CHAR(20),
App_size CHAR(20) DEFAULT 'unknown',
PRIMARY KEY(M),
INDEX(Type)
);
DESCRIBE Messier;
SELECT * FROM Messier;
-- Load data into the table
LOAD DATA LOCAL INFILE './messier.tsv'
INTO TABLE Messier;
SELECT * FROM Messier; -- note the Ra column values
-- Convert Ra to degrees.
UPDATE Messier SET Ra = Ra * 15.0;
SELECT * FROM Messier;
-- Create the table that will contain the description of each object type
DROP TABLE IF EXISTS TypeDescr;
CREATE TABLE TypeDescr(
Type CHAR(2),
Descr CHAR(20),
PRIMARY KEY(Type)
);
DESCRIBE TypeDescr;
-- Load data into the table
LOAD DATA LOCAL INFILE './messier_legend.tsv'
INTO TABLE TypeDescr;
SELECT * FROM TypeDescr;
-- A simple join to show the long description of each object type
SELECT Messier.*, TypeDescr.Descr
FROM Messier LEFT JOIN TypeDescr
ON Messier.Type = TypeDescr.Type;
-- From here we assume you have DIF installed!
-- To index the table, from the shell give the command:
-- To index the table, from the shell give the command:
--
-- dif --index-htm DIF Messier 6 Ra Decl
--
SELECT *
FROM Messier_htm_6
WHERE DIF_Circle(@Ra, @Decl, @Rad);
-- Examples of useful functions and procedures
delimiter //
--
-- Compute distance between two points on a sphere
--
-- Note that DIF already has a function to calculate spherical distance: Sphedist
-- This function is just for demonstration.
--
-- a1/b1: long/lat of first point (DEG)
-- a2/b2: long/lat of second point (DEG)
--
-- Returns:
-- distance in Degrees
--
DROP FUNCTION IF EXISTS skydist//
CREATE FUNCTION skydist(a1 DOUBLE, b1 DOUBLE, a2 DOUBLE, b2 DOUBLE) RETURNS DOUBLE
BEGIN
DECLARE deg2rad, a1r, b1r, a2r, b2r, radiff, cosdis, dist DOUBLE;
SET deg2rad = 0.017453292519943;
SET a1r = a1*deg2rad;
SET b1r = b1*deg2rad;
SET a2r = a2*deg2rad;
SET b2r = b2*deg2rad;
SET radiff = ABS(a2r-a1r);
IF (radiff > pi()) THEN
SET radiff = pi() * 2e0 - radiff;
END IF;
SET cosdis = sin(b1r)*sin(b2r) + cos(b1r)*cos(b2r)*cos(radiff);
SET dist = acos(cosdis)/deg2rad;
RETURN dist;
END//
-- From year, month, day, hour to Julian day
DROP FUNCTION IF EXISTS jdcnv//
CREATE FUNCTION jdcnv(yr INT, mn INT, day INT, hr DOUBLE) RETURNS DOUBLE
BEGIN
DECLARE L DOUBLE;
DECLARE j BIGINT;
DECLARE julian DOUBLE;
SET L = (mn-14) DIV 12;
SET j = day - 32075 + 1461*(yr+4800+L) DIV 4 +
367*(mn - 2-L*12) DIV 12 - 3*((yr+4900+L) DIV 100) DIV 4;
SET julian = j + hr/24.0 -0.5;
RETURN julian;
END//
-- From hour angle and declination to Alt, Az coordinates
DROP PROCEDURE IF EXISTS hadec2altaz//
CREATE PROCEDURE hadec2altaz(IN ha DOUBLE, IN decl DOUBLE, IN lat DOUBLE,
OUT alt DOUBLE, OUT az DOUBLE)
BEGIN
DECLARE d2r, sh, ch, sd, cd, sl, cl DOUBLE;
DECLARE x, y, z, r DOUBLE;
SET d2r = pi()/180.0;
SET sh = sin(ha*d2r);
SET ch = cos(ha*d2r);
SET sd = sin(decl*d2r);
SET cd = cos(decl*d2r);
SET sl = sin(lat*d2r);
SET cl = cos(lat*d2r);
SET x = - ch * cd * sl + sd * cl;
SET y = - sh * cd;
SET z = ch * cd * cl + sd * sl;
SET r = sqrt(x*x + y*y);
SET az = atan(y,x) / d2r;
SET alt = atan(z,r) / d2r;
IF (az < 0) THEN
SET az = az + 360;
END IF;
END//
-- From hour angle and declination to Altitude
DROP FUNCTION IF EXISTS hadec2alt//
CREATE FUNCTION hadec2alt(ha DOUBLE, decl DOUBLE, lat DOUBLE) RETURNS DOUBLE
DETERMINISTIC
BEGIN
DECLARE alt, az DOUBLE;
CALL hadec2altaz(ha, decl, lat, alt, az);
RETURN alt;
END//
-- From hour angle and declination to Azimuth
DROP FUNCTION IF EXISTS hadec2az//
CREATE FUNCTION hadec2az(ha DOUBLE, decl DOUBLE, lat DOUBLE) RETURNS DOUBLE
DETERMINISTIC
BEGIN
DECLARE alt, az DOUBLE;
CALL hadec2altaz(ha, decl, lat, alt, az);
RETURN az;
END//
-- From Julian day to local sidereal time
DROP FUNCTION IF EXISTS jd2st//
CREATE FUNCTION jd2st(jd DOUBLE, lng DOUBLE) RETURNS DOUBLE
DETERMINISTIC
BEGIN
DECLARE c0, c1, c2, c3 DOUBLE;
DECLARE jd2000, lst DOUBLE;
DECLARE t, t0, theta DOUBLE;
SET c0 = 280.46061837;
SET c1 = 360.98564736629;
SET c2 = 0.000387933;
SET c3 = 38710000.0;
SET jd2000 = 2451545.0;
SET t0 = jd - jd2000;
SET t = t0/36525.0;
SET theta = c0 + (c1 * t0) + t*t*(c2 - t / c3 );
SET lst = (theta + lng)/15.0;
IF (lst < 0) THEN
SET lst = 24.0 + (lst % 24.0);
END IF;
SET lst = lst % 24.0;
RETURN lst;
END//
-- From local DATETIME and Time zone to Julian day
DROP FUNCTION IF EXISTS Julian//
CREATE FUNCTION Julian(Time DATETIME, TZ_offset INT) RETURNS DOUBLE
DETERMINISTIC
BEGIN
DECLARE Yr, Mn, Dy, Hr, Mi, Se INT;
DECLARE Hr_fr, jd DOUBLE;
SET Yr = year(Time);
SET Mn = month(Time);
SET Dy = day(Time);
SET Hr = hour(Time);
SET Mi = minute(Time);
SET Se = second(Time);
SET Hr_fr =(Hr+TZ_offset) + Mi/60.0 + Se/3600.0;
SET jd = jdcnv(Yr, Mn, Dy, Hr_fr);
RETURN jd;
END//
-- From local DATETIME and Time zone to local sidereal time
DROP FUNCTION IF EXISTS Sidereal//
CREATE FUNCTION Sidereal(Time DATETIME, TZ_offset INT, Lng DOUBLE) RETURNS DOUBLE
DETERMINISTIC
BEGIN
DECLARE jd, st DOUBLE;
SET jd = Julian(Time, TZ_offset);
SET st = jd2st(jd, Lng);
RETURN st;
END//
-- From equatorial Ra, Dec to Altitude
DROP FUNCTION IF EXISTS radec2alt//
CREATE FUNCTION radec2alt(Ra DOUBLE, Decl DOUBLE, Lat DOUBLE, Lng DOUBLE,
TZ_offset INT, Time DATETIME)
RETURNS DOUBLE
BEGIN
DECLARE st, ha, alt DOUBLE;
SET st = Sidereal(Time, TZ_offset, Lng) * 15.0;
SET ha = st - Ra;
SET alt = hadec2alt(ha, Decl, Lat);
RETURN alt;
END//
-- From equatorial Ra, Dec to Azimuth
DROP FUNCTION IF EXISTS radec2az//
CREATE FUNCTION radec2az(Ra DOUBLE, Decl DOUBLE, Lat DOUBLE, Lng DOUBLE,
TZ_offset INT, Time DATETIME)
RETURNS DOUBLE
BEGIN
DECLARE st, ha, az DOUBLE;
SET st = Sidereal(Time, TZ_offset, Lng) * 15.0;
SET ha = st - Ra;
SET az = hadec2az(ha, Decl, Lat);
RETURN az;
END//
delimiter ;
--
-- Example of usage of jdcnv and jd2st
--
SELECT @Time:= now() AS Time,
@Yr:=year(@Time) AS Year,
@Mn:=month(@Time) AS Month,
@Dy:=day(@Time) AS Day,
@Hr:=hour(@Time) AS Hour,
@Mi:=minute(@Time) AS Minute,
@Se:=second(@Time) AS Second,
@Hr_fr:=(@Hr+@TZ_offset) + @Mi/60.0 + @Se/3600.0 AS Hr_fr,
@Jd:=jdcnv(@Yr, @Mn, @Dy, @Hr_fr) AS Julian,
@Si:=jd2st(@Jd, @Long) AS Sidereal;
-- Do the same with
SELECT Julian(now(), @TZ_offset), Sidereal(now(), @TZ_offset, @Long);
--
-- Example of usage of hadec2alt, hadec2az
-- (coordinate conversion from Ra/Dec to Alt/Az)
--
-- Compute sidereal time and convert to Degrees
--
SET @Si := Sidereal(now(), @TZ_offset, @Long) * 15.0;
--
-- Compute hour angle
--
SET @Hour_angle := @Si - @Ra;
SELECT @Ra, @Decl, @Hour_angle,
hadec2alt(@Hour_angle, @Decl, @Lat) AS Alt,
hadec2az( @Hour_angle, @Decl, @Lat) AS Az;
-- Do the same with
SELECT @Ra, @Decl, @Hour_angle,
radec2alt(@Ra, @Decl, @Lat, @Long, @TZ_offset, now()) AS Alt,
radec2az( @Ra, @Decl, @Lat, @Long, @TZ_offset, now()) AS Az;
--
-- Note: variables (like @Lat, @Long, @TZ_offset) cannot be used inside
-- views.
--
DROP VIEW IF EXISTS Messier_view;
CREATE VIEW Messier_view AS
SELECT Messier.M,
TypeDescr.Descr AS Descr,
Messier.Const,
Messier.Mag,
Messier.Ra,
Messier.Decl,
radec2alt(Messier.Ra, Messier.Decl, 38, 13, -1, now()) AS Alt,
radec2az( Messier.Ra, Messier.Decl, 38, 13, -1, now()) AS Az,
Messier.Dist,
Messier.App_size
FROM Messier LEFT JOIN TypeDescr
ON Messier.Type = TypeDescr.Type
ORDER BY Descr, M;
DESCRIBE Messier_view;
SELECT * FROM Messier_view;
-- *******************************************************************
-- This part deals with the "manual" management of DIF to index tables.
-- You should use the script "dif" to do this, but if you want to practice
-- with DB management you can try these examples.
--
-- Set up the DIF_Rect, DIF_Circle, and HTMLookup functions.
--
-- NOTE 1: this require that DIF has been installed and that it is placed
-- in the 'plugin_dir' of MySQL.
--
show variables like 'plugin%';
+---------------+------------------------------+
| Variable_name | Value |
+---------------+------------------------------+
| plugin_dir | /usr/local/mysql/lib/plugin/ |
+---------------+------------------------------+
-- Then from the shell: ls /usr/local/mysql/lib/plugin/udf_dif.so
--
-- NOTE 2: after DIF has been installed issue 'ldconfig' from a root
-- shell if you have troubles seeing the functions.
--
--
-- DIF_Circle(Ra_deg DOUBLE, Dec_deg DOUBLE, Rad_arcmin DOUBLE)
--
-- Generate htmIDs for those pixels in a circle centered at Ra_deg, Dec_deg
-- (deg) with a radius of Rad_arcmin (arcmin).
--
-- Returns:
-- how many pixels fall into the circle
--
DROP FUNCTION IF EXISTS DIF_Circle;
CREATE FUNCTION DIF_Circle RETURNS INTEGER SONAME 'ha_dif.so';
--
-- HTMLookup(depth INT, Ra_deg DOUBLE, Dec_deg DOUBLE)
-- Lookup the htmID, at a given depth, of the pixel which contains the point
-- with with coordinates Ra_deg and Dec_deg.
--
-- Returns:
-- the HTM id of the pixel at the requested depth
--
DROP FUNCTION IF EXISTS HTMLookup;
CREATE FUNCTION HTMLookup RETURNS INTEGER SONAME 'ha_dif.so';
-- This is to query a rectangular region - see DIF manual.
DROP FUNCTION IF EXISTS DIF_Rect;
CREATE FUNCTION DIF_Rect RETURNS INTEGER SONAME 'ha_dif.so';
--
-- Add a column and an index for the HTM id (depth 6) to the Messier table
--
ALTER TABLE Messier ADD COLUMN htmID_6 SMALLINT UNSIGNED, ADD INDEX(htmID_6);
DESCRIBE Messier;
-- Populate the new column with htmIDs
UPDATE Messier SET htmID_6 = HTMLookup(6, Ra, Decl);
SELECT * FROM Messier;
--
-- Set up a trigger to automatically update the htmID_6 field when a new
-- record is inserted
-- Note that dif might have already has installed triggers for INSERT and UPDATE,
-- so you need to remove them before you can create a new one
--
show triggers;
-- eventually
drop trigger trig_ins_Messier;
delimiter //
DROP TRIGGER trig_ins_Messier//
CREATE TRIGGER trig_ins_Messier BEFORE INSERT ON Messier FOR EACH ROW
BEGIN
SET NEW.htmID_6 = HTMLookup(6, NEW.Ra, NEW.Decl);
END//
--
-- Do the same for updated records
--
DROP TRIGGER trig_upd_Messier//
CREATE TRIGGER trig_upd_Messier BEFORE UPDATE ON Messier FOR EACH ROW
BEGIN
SET NEW.htmID_6 = HTMLookup(6, NEW.Ra, NEW.Decl);
END//
delimiter ;
