public TestResult RunTest(TestDefinition test = null) { if (test == null) { test = new TestDefinition(); } var result = new TestResult(); Stopwatch sw = new Stopwatch(); sw.Start(); RunTest(test, result); sw.Stop(); result.TestDelay = sw.Elapsed; do_print(Provider.Output, $"\n\nCalculation time: {result.TestDelay}\n"); Provider.Output.Flush(); Provider.Debug.Flush(); return(result); }
void RunTest(TestDefinition test, TestResult result) { string serr = String.Empty, serr_save = String.Empty, serr_warn = String.Empty; //string s, s1, s2; string star = String.Empty; string se_pname; string spnam, spnam2 = ""; string fmt = "PZBRS"; string plsel = String.Empty; //char psp; string gap = " "; double y_frac; double hpos = 0; int ipl, ipldiff = SwissEph.SE_SUN; double[] x = new double[6], xequ = new double[6], xcart = new double[6], xcartq = new double[6]; double[] cusp = new double[12 + 1]; /* cusp[0] + 12 houses */ double[] ascmc = new double[10]; /* asc, mc, vertex ...*/ //double ar, sinp; //double a, sidt, armc, lon, lat; //double eps_true, eps_mean, nutl, nuto; string fname = String.Empty; //int nast, iast; int[] astno = new int[100]; int iflag = 0, iflag2; /* external flag: helio, geo... */ //int iflgret; var whicheph = SwissEph.SEFLG_SWIEPH; bool universal_time = false; bool calc_house_pos = false; int gregflag; bool diff_mode = false; int round_flag = 0; string jul; char hsys = test.HouseSystem.ToString()[0]; var buf = Provider.Output; switch (test.Ephemeris) { case EphemerisType.JplEphemeris: whicheph = SwissEph.SEFLG_JPLEPH; fname = SwissEph.SE_FNAME_DE406; break; case EphemerisType.MoshierEphemeris: whicheph = SwissEph.SEFLG_MOSEPH; break; case EphemerisType.SwissEphemeris: default: whicheph = SwissEph.SEFLG_SWIEPH; break; } universal_time = test.EtUt == TimeType.UniversalTime; switch (test.Planets) { case PlanetsType.WithAsteroids: plsel = PLSEL_P; break; case PlanetsType.WithHypBodies: plsel = PLSEL_A; break; case PlanetsType.MainPlanets: default: plsel = PLSEL_D; break; } switch (test.Centric) { case CentricType.Topocentric: iflag |= SwissEph.SEFLG_TOPOCTR; calc_house_pos = true; break; case CentricType.Heliocentric: iflag |= SwissEph.SEFLG_HELCTR; break; case CentricType.Barycentric: iflag |= SwissEph.SEFLG_BARYCTR; break; case CentricType.SiderealFagan: iflag |= SwissEph.SEFLG_SIDEREAL; SwissEph.swe_set_sid_mode(SwissEph.SE_SIDM_FAGAN_BRADLEY, 0, 0); break; case CentricType.SiderealLahiri: iflag |= SwissEph.SEFLG_SIDEREAL; SwissEph.swe_set_sid_mode(SwissEph.SE_SIDM_LAHIRI, 0, 0); break; case CentricType.Geocentric: default: calc_house_pos = true; break; } result.Longitude = test.LongitudeDeg + test.LongitudeMin / 60.0 + test.LongitudeSec / 3600.0; if (test.LongitudeType == LongitudeType.West) { result.Longitude = -result.Longitude; } result.Latitude = test.LatitudeDeg + test.LatitudeMin / 60.0 + test.LatitudeSec / 3600.0; if (test.LatitudeType == LatitudeType.South) { result.Latitude = -result.Latitude; } do_print(buf, C.sprintf("Planet Positions from %s \n\n", test.Ephemeris)); if ((whicheph & SwissEph.SEFLG_JPLEPH) != 0) { SwissEph.swe_set_jpl_file(fname); } iflag = (iflag & ~SwissEph.SEFLG_EPHMASK) | whicheph; iflag |= SwissEph.SEFLG_SPEED; if (test.Date.Year * 10000 + test.Date.Month * 100 + test.Date.Day < 15821015) { gregflag = SwissEph.SE_JUL_CAL; } else { gregflag = SwissEph.SE_GREG_CAL; } result.UseGregorianDate = gregflag == SwissEph.SE_GREG_CAL; var jday = test.Date.Day; var jmon = test.Date.Month; var jyear = test.Date.Year; var jhour = test.Date.Hour; var jmin = test.Date.Minute; var jsec = test.Date.Second; var jut = jhour + (jmin / 60.0) + (jsec / 3600.0); result.JulianDateUT = SwissEph.swe_julday(jyear, jmon, jday, jut, gregflag); SwissEph.swe_revjul(result.JulianDateUT, gregflag, ref jyear, ref jmon, ref jday, ref jut); jut += 0.5 / 3600; jhour = (int)jut; jmin = (int)((jut * 60.0) % 60.0); jsec = (int)((jut * 3600.0) % 60.0); result.JulianDay = jday; result.JulianMonth = jmon; result.JulianYear = jyear; result.JulianHour = jhour; result.JulianMinute = jmin; result.JulianSecond = jsec; var bc = string.Empty; do_print(buf, $"Date: {test.Date}\n"); if (test.Date.Year <= 0) { bc = C.sprintf("(%d B.C.)", 1 - jyear); } if (jyear * 10000L + jmon * 100L + jday <= 15821004) { jul = "jul."; } else { jul = ""; } do_print(buf, C.sprintf("%d.%d.%d %s %s %#02d:%#02d:%#02d %s\n", jday, jmon, jyear, bc, jul, jhour, jmin, jsec, test.EtUt == TimeType.UniversalTime ? "UT" : "ET")); jut = jhour + jmin / 60.0 + jsec / 3600.0; if (universal_time) { result.DeltaTime = SwissEph.swe_deltat(result.JulianDateUT); do_print(buf, C.sprintf(" delta t: %f sec", result.DeltaTime * 86400.0)); result.JulianDateET = result.JulianDateUT + result.DeltaTime; } else { result.JulianDateET = result.JulianDateUT; } do_print(buf, C.sprintf(" jd (ET) = %f\n", result.JulianDateET)); var iflgret = SwissEph.swe_calc(result.JulianDateET, SwissEph.SE_ECL_NUT, iflag, x, ref serr); var eps_true = x[0]; var eps_mean = x[1]; var s1 = dms(eps_true, round_flag); var s2 = dms(eps_mean, round_flag); do_print(buf, C.sprintf("\n%-15s %s%s%s (true, mean)", "Ecl. obl.", s1, gap, s2)); var nutl = x[2]; var nuto = x[3]; s1 = dms(nutl, round_flag); s2 = dms(nuto, round_flag); do_print(buf, C.sprintf("\n%-15s %s%s%s (dpsi, deps)", "Nutation", s1, gap, s2)); do_print(buf, "\n\n"); do_print(buf, " ecl. long. ecl. lat. "); do_print(buf, " dist. speed"); if (calc_house_pos) { do_print(buf, " house"); } do_print(buf, "\n"); if ((iflag & SwissEph.SEFLG_TOPOCTR) != 0) { SwissEph.swe_set_topo(result.Longitude, result.Latitude, test.Altitude); } result.SideralTime = SwissEph.swe_sidtime(result.JulianDateUT) + result.Longitude / 15; if (result.SideralTime >= 24) { result.SideralTime -= 24; } if (result.SideralTime < 0) { result.SideralTime += 24; } result.ARMC = result.SideralTime * 15; /* additional asteroids */ //splan = plsel; if (String.Compare(plsel, PLSEL_P) == 0) { var cpos = test.Asteroids.Split(",;. \t".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); var j = cpos.Length; for (int i = 0, nast = 0; i < j; i++) { if ((astno[nast] = int.Parse(cpos[i])) > 0) { nast++; plsel += "+"; } } } for (int pspi = 0, iast = 0; pspi < plsel.Length; pspi++) { var psp = plsel[pspi]; if (psp == '+') { ipl = SwissEph.SE_AST_OFFSET + (int)astno[iast]; iast++; } else { ipl = letter_to_ipl(psp); } if ((iflag & SwissEph.SEFLG_HELCTR) != 0) { if (ipl == SwissEph.SE_SUN || ipl == SwissEph.SE_MEAN_NODE || ipl == SwissEph.SE_TRUE_NODE || ipl == SwissEph.SE_MEAN_APOG || ipl == SwissEph.SE_OSCU_APOG) { continue; } } else if ((iflag & SwissEph.SEFLG_BARYCTR) != 0) { if (ipl == SwissEph.SE_MEAN_NODE || ipl == SwissEph.SE_TRUE_NODE || ipl == SwissEph.SE_MEAN_APOG || ipl == SwissEph.SE_OSCU_APOG) { continue; } } else /* geocentric */ if (ipl == SwissEph.SE_EARTH) { continue; } /* ecliptic position */ if (ipl == SwissEph.SE_FIXSTAR) { iflgret = SwissEph.swe_fixstar(star, result.JulianDateET, iflag, x, ref serr); se_pname = star; } else { iflgret = SwissEph.swe_calc(result.JulianDateET, ipl, iflag, x, ref serr); se_pname = SwissEph.swe_get_planet_name(ipl); if (ipl > SwissEph.SE_AST_OFFSET) { var s = C.sprintf("#%d", (int)astno[iast - 1]); se_pname += new String(' ', 11 - s.Length) + s; } } if (iflgret >= 0) { if (calc_house_pos) { hpos = SwissEph.swe_house_pos(result.ARMC, result.Latitude, eps_true, hsys, x, ref serr); if (hpos == 0) { iflgret = SwissEph.ERR; } } } if (iflgret < 0) { if (!String.IsNullOrEmpty(serr) && String.Compare(serr, serr_save) != 0) { serr_save = serr; do_print(buf, "error: "); do_print(buf, serr); do_print(buf, "\n"); } } else if (!String.IsNullOrEmpty(serr) && String.IsNullOrEmpty(serr_warn)) { serr_warn = serr; } /* equator position */ if (fmt.IndexOfAny("aADdQ".ToCharArray()) >= 0) { iflag2 = iflag | SwissEph.SEFLG_EQUATORIAL; if (ipl == SwissEph.SE_FIXSTAR) { iflgret = SwissEph.swe_fixstar(star, result.JulianDateET, iflag2, xequ, ref serr); } else { iflgret = SwissEph.swe_calc(result.JulianDateET, ipl, iflag2, xequ, ref serr); } } /* ecliptic cartesian position */ if (fmt.IndexOfAny("XU".ToCharArray()) >= 0) { iflag2 = iflag | SwissEph.SEFLG_XYZ; if (ipl == SwissEph.SE_FIXSTAR) { iflgret = SwissEph.swe_fixstar(star, result.JulianDateET, iflag2, xcart, ref serr); } else { iflgret = SwissEph.swe_calc(result.JulianDateET, ipl, iflag2, xcart, ref serr); } } /* equator cartesian position */ if (fmt.IndexOfAny("xu".ToCharArray()) >= 0) { iflag2 = iflag | SwissEph.SEFLG_XYZ | SwissEph.SEFLG_EQUATORIAL; if (ipl == SwissEph.SE_FIXSTAR) { iflgret = SwissEph.swe_fixstar(star, result.JulianDateET, iflag2, xcartq, ref serr); } else { iflgret = SwissEph.swe_calc(result.JulianDateET, ipl, iflag2, xcartq, ref serr); } } double t2, ar, sinp; spnam = se_pname; /* * The string fmt contains a sequence of format specifiers; * each character in fmt creates a column, the columns are * sparated by the gap string. */ int spi = 0; for (spi = 0; spi < fmt.Length; spi++) { char sp = fmt[spi]; if (spi > 0) { do_print(buf, gap); } switch (sp) { case 'y': do_print(buf, "%d", jyear); break; case 'Y': jut = 0; t2 = SwissEph.swe_julday(jyear, 1, 1, jut, gregflag); y_frac = (result.JulianDateUT - t2) / 365.0; do_print(buf, "%.2lf", jyear + y_frac); break; case 'p': if (diff_mode) { do_print(buf, "%d-%d", ipl, ipldiff); } else { do_print(buf, "%d", ipl); } break; case 'P': if (diff_mode) { do_print(buf, "%.3s-%.3s", spnam, spnam2); } else { do_print(buf, "%-11s", spnam); } break; case 'J': case 'j': do_print(buf, "%.2f", result.JulianDateUT); break; case 'T': do_print(buf, "%02d.%02d.%d", jday, jmon, jyear); break; case 't': do_print(buf, "%02d%02d%02d", jyear % 100, jmon, jday); break; case 'L': do_print(buf, dms(x[0], round_flag)); break; case 'l': do_print(buf, "%# 11.7f", x[0]); break; case 'Z': do_print(buf, dms(x[0], round_flag | BIT_ZODIAC)); break; case 'S': case 's': var sp2i = spi + 1; char sp2 = fmt.Length <= sp2i ? '\0' : fmt[sp2i]; if (sp2 == 'S' || sp2 == 's' || fmt.IndexOfAny("XUxu".ToCharArray()) >= 0) { for (sp2i = 0; sp2i < fmt.Length; sp2i++) { sp2 = fmt[sp2i]; if (sp2i > 0) { do_print(buf, gap); } switch (sp2) { case 'L': /* speed! */ case 'Z': /* speed! */ do_print(buf, dms(x[3], round_flag)); break; case 'l': /* speed! */ do_print(buf, "%11.7f", x[3]); break; case 'B': /* speed! */ do_print(buf, dms(x[4], round_flag)); break; case 'b': /* speed! */ do_print(buf, "%11.7f", x[4]); break; case 'A': /* speed! */ do_print(buf, dms(xequ[3] / 15, round_flag | SwissEph.SEFLG_EQUATORIAL)); break; case 'a': /* speed! */ do_print(buf, "%11.7f", xequ[3]); break; case 'D': /* speed! */ do_print(buf, dms(xequ[4], round_flag)); break; case 'd': /* speed! */ do_print(buf, "%11.7f", xequ[4]); break; case 'R': /* speed! */ case 'r': /* speed! */ do_print(buf, "%# 14.9f", x[5]); break; case 'U': /* speed! */ case 'X': /* speed! */ if (sp == 'U') { ar = Math.Sqrt(square_sum(xcart)); } else { ar = 1; } do_print(buf, "%# 14.9f%s", xcart[3] / ar, gap); do_print(buf, "%# 14.9f%s", xcart[4] / ar, gap); do_print(buf, "%# 14.9f", xcart[5] / ar); break; case 'u': /* speed! */ case 'x': /* speed! */ if (sp == 'u') { ar = Math.Sqrt(square_sum(xcartq)); } else { ar = 1; } do_print(buf, "%# 14.9f%s", xcartq[3] / ar, gap); do_print(buf, "%# 14.9f%s", xcartq[4] / ar, gap); do_print(buf, "%# 14.9f", xcartq[5] / ar); break; default: break; } } if (fmt.Length <= spi + 1 && (fmt[spi + 1] == 'S' || fmt[sp + 1] == 's')) { spi++; sp = fmt[spi]; } } else { do_print(buf, dms(x[3], round_flag)); } break; case 'B': do_print(buf, dms(x[1], round_flag)); break; case 'b': do_print(buf, "%# 11.7f", x[1]); break; case 'A': /* rectascensio */ do_print(buf, dms(xequ[0] / 15, round_flag | SwissEph.SEFLG_EQUATORIAL)); break; case 'a': /* rectascensio */ do_print(buf, "%# 11.7f", xequ[0]); break; case 'D': /* declination */ do_print(buf, dms(xequ[1], round_flag)); break; case 'd': /* declination */ do_print(buf, "%# 11.7f", xequ[1]); break; case 'R': do_print(buf, "%# 14.9f", x[2]); break; case 'r': if (ipl == SwissEph.SE_MOON) { /* for moon print parallax */ sinp = 8.794 / x[2]; /* in seconds of arc */ ar = sinp * (1 + sinp * sinp * 3.917402e-12); /* the factor is 1 / (3600^2 * (180/pi)^2 * 6) */ do_print(buf, "%# 13.5f\"", ar); } else { do_print(buf, "%# 14.9f", x[2]); } break; case 'U': case 'X': if (sp == 'U') { ar = Math.Sqrt(square_sum(xcart)); } else { ar = 1; } do_print(buf, "%# 14.9f%s", xcart[0] / ar, gap); do_print(buf, "%# 14.9f%s", xcart[1] / ar, gap); do_print(buf, "%# 14.9f", xcart[2] / ar); break; case 'u': case 'x': if (sp == 'u') { ar = Math.Sqrt(square_sum(xcartq)); } else { ar = 1; } do_print(buf, "%# 14.9f%s", xcartq[0] / ar, gap); do_print(buf, "%# 14.9f%s", xcartq[1] / ar, gap); do_print(buf, "%# 14.9f", xcartq[2] / ar); break; case 'Q': do_print(buf, "%-15s", spnam); do_print(buf, dms(x[0], round_flag)); do_print(buf, dms(x[1], round_flag)); do_print(buf, " %# 14.9f", x[2]); do_print(buf, dms(x[3], round_flag)); do_print(buf, dms(x[4], round_flag)); do_print(buf, " %# 14.9f\n", x[5]); do_print(buf, " %s", dms(xequ[0], round_flag)); do_print(buf, dms(xequ[1], round_flag)); do_print(buf, " %s", dms(xequ[3], round_flag)); do_print(buf, dms(xequ[4], round_flag)); break; } /* switch */ } /* for sp */ if (calc_house_pos) { //sprintf(s, " %# 6.4f", hpos); do_print(buf, "%# 9.4f", hpos); } do_print(buf, "\n"); } /* for psp */ if (!String.IsNullOrEmpty(serr_warn)) { do_print(buf, "\nwarning: "); do_print(buf, serr_warn); do_print(buf, "\n"); } /* houses */ do_print(buf, C.sprintf("\nHouse Cusps (%s)\n\n", test.HouseSystem.ToString())); var a = result.SideralTime + 0.5 / 3600; do_print(buf, C.sprintf("sid. time : %4d:%#02d:%#02d ", (int)a, (int)((a * 60.0) % 60.0), (int)((a * 3600.0) % 60.0)) ); a = result.ARMC + 0.5 / 3600; do_print(buf, "armc : %4d%s%#02d'%#02d\"\n", (int)result.ARMC, MY_ODEGREE_STRING, (int)((result.ARMC * 60.0) % 60.0), (int)((a * 3600.0) % 60.0)); do_print(buf, "geo. lat. : %4d%c%#02d'%#02d\" ", test.LatitudeDeg, test.LatitudeType.ToString()[0], test.LatitudeMin, test.LatitudeSec); do_print(buf, "geo. long.: %4d%c%#02d'%#02d\"\n\n", test.LongitudeDeg, test.LongitudeType.ToString()[0], test.LongitudeMin, test.LongitudeSec); SwissEph.swe_houses_ex(result.JulianDateUT, iflag, result.Latitude, result.Longitude, hsys, cusp, ascmc); round_flag |= BIT_ROUND_SEC; do_print(buf, C.sprintf("AC : %s\n", dms(ascmc[0], round_flag | BIT_ZODIAC))); do_print(buf, C.sprintf("MC : %s\n", dms(ascmc[1], round_flag | BIT_ZODIAC))); for (int i = 1; i <= 12; i++) { do_print(buf, C.sprintf("house %2d: %s\n", i, dms(cusp[i], round_flag | BIT_ZODIAC))); } do_print(buf, C.sprintf("Vertex : %s\n", dms(ascmc[3], round_flag | BIT_ZODIAC))); }