Changeset 18828


Ignore:
Timestamp:
04/14/17 17:20:35 (8 years ago)
Author:
tbretz
Message:
Restructured the astrometry interface to allow setting the observatory location.
Location:
trunk/FACT++/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/InterpreterV8.cc

    r18820 r18828  
    18371837{
    18381838    if (args.Length()!=2)
    1839         return ThrowException(String::New("dist must not be called with two arguments."));
     1839        return ThrowException(String::New("dist must be called with exactly two arguments."));
    18401840
    18411841    if (!args[0]->IsObject() || !args[1]->IsObject())
    1842         return ThrowException(String::New("at least one argument not an object."));
     1842        return ThrowException(String::New("At least one argument not an object."));
     1843
     1844    // FiXME: Add a check for the argument type
    18431845
    18441846    HandleScope handle_scope;
     
    19081910}
    19091911
     1912struct AstroArgs
     1913{
     1914    string obs;
     1915    Nova::LnLatPosn posn;
     1916    double jd;
     1917    uint64_t jsdate;
     1918
     1919    AstroArgs() : jsdate(0) { }
     1920};
     1921
     1922AstroArgs EvalAstroArgs(int offset, const Arguments &args, int8_t type=2)
     1923{
     1924    const uint8_t max = abs(type);
     1925
     1926    if (args.Length()>offset+max)
     1927        throw runtime_error("Number of arguments must not exceed "+to_string(offset+max)+".");
     1928
     1929    if (type==1  && args.Length()==offset+1 && !args[offset]->IsString())
     1930        throw runtime_error("Argument "+to_string(offset+1)+" must be a string.");
     1931    if (type==-1 && args.Length()==offset+1 && !args[offset]->IsDate())
     1932        throw runtime_error("Argument "+to_string(offset+1)+" must be a date.");
     1933
     1934    if (args.Length()==offset+1 && !(args[offset]->IsDate() || args[offset]->IsString()))
     1935        throw runtime_error("Argument "+to_string(offset+1)+" must be a string or Date.");
     1936
     1937    if (args.Length()==offset+2 &&
     1938        !(args[offset+0]->IsDate() && args[offset+1]->IsString()) &&
     1939        !(args[offset+1]->IsDate() && args[offset+0]->IsString()))
     1940        throw runtime_error("Arguments "+to_string(offset+1)+" and "+to_string(offset+2)+" must be a string/Date or Date/string.");
     1941
     1942    HandleScope handle_scope;
     1943
     1944    Local<Value> obs = args.This()->Get(String::New("observatory"));
     1945    if (args.Length()>offset && args[offset]->IsString())
     1946        obs = args[offset];
     1947    if (args.Length()>offset+1 && args[offset+1]->IsString())
     1948        obs = args[offset+1];
     1949
     1950    AstroArgs rc;
     1951
     1952    // For constructors, observatory can stay empty if not explicitly given
     1953    if (offset<2)
     1954        rc.obs = "ORM";
     1955
     1956    if (!obs.IsEmpty() && !obs->IsUndefined())
     1957        rc.obs = *String::AsciiValue(obs);
     1958
     1959    rc.posn = rc.obs;
     1960
     1961    if ((!rc.obs.empty() || offset==0) && !rc.posn.isValid())
     1962        throw runtime_error("Observatory "+rc.obs+" unknown.");
     1963
     1964    Local<Value> date = args.This()->Get(String::New("time"));
     1965    if (args.Length()>offset && args[offset]->IsDate())
     1966        date = args[offset];
     1967    if (args.Length()>offset+1 && args[offset+1]->IsDate())
     1968        date = args[offset+1];
     1969
     1970    // For constructors, time can stay empty if not explicitly given
     1971    if (offset<2)
     1972        rc.jsdate = Time().JavaDate();
     1973
     1974    if (!date.IsEmpty() && !date->IsUndefined())
     1975        rc.jsdate = uint64_t(date->NumberValue());
     1976
     1977    rc.jd = Time(rc.jsdate/1000, rc.jsdate%1000).JD();
     1978
     1979    return rc;
     1980}
     1981
    19101982Handle<Value> InterpreterV8::LocalToSky(const Arguments &args)
    19111983{
    1912     if (args.Length()>1)
    1913         return ThrowException(String::New("toSky must not be called with more than one argument."));
    1914 
    1915     if (args.Length()==1 && !args[0]->IsDate())
    1916         return ThrowException(String::New("Argument must be a Date"));
     1984    AstroArgs local;
     1985    try
     1986    {
     1987        local = EvalAstroArgs(0, args, 2);
     1988    }
     1989    catch (const exception &e)
     1990    {
     1991        return ThrowException(String::New(e.what()));
     1992    }
    19171993
    19181994    Nova::ZdAzPosn hrz;
     
    19211997
    19221998    if (!finite(hrz.zd) || !finite(hrz.az))
    1923         return ThrowException(String::New("zd and az must be finite."));
     1999        return ThrowException(String::New("Zd and az must be finite."));
     2000
     2001    const Nova::EquPosn equ = Nova::GetEquFromHrz(hrz, local.posn, local.jd);
    19242002
    19252003    HandleScope handle_scope;
    19262004
    1927     const Local<Value> date =
    1928         args.Length()==0 ? Date::New(Time().JavaDate()) : args[0];
    1929     if (date.IsEmpty())
    1930         return Undefined();
    1931 
    1932     const uint64_t v = uint64_t(date->NumberValue());
    1933     const Time utc(v/1000, v%1000);
    1934 
    1935     const Nova::EquPosn equ = Nova::GetEquFromHrz(hrz, utc.JD());
    1936 
    1937     // -----------------------------
    1938 
    1939     Handle<Value> arg[] = { Number::New(equ.ra/15), Number::New(equ.dec), date };
    1940     return handle_scope.Close(fTemplateSky->GetFunction()->NewInstance(3, arg));
     2005    Handle<Value> arg_loc[] = { Number::New(hrz.zd), Number::New(hrz.az), String::New(local.obs.c_str()), Date::New(local.jsdate) };
     2006    Handle<Object> loc = fTemplateLocal->GetFunction()->NewInstance(4, arg_loc);
     2007
     2008    Handle<Value> arg_sky[] = { Number::New(equ.ra/15), Number::New(equ.dec), loc };
     2009    return handle_scope.Close(fTemplateSky->GetFunction()->NewInstance(3, arg_sky));
    19412010}
    19422011
    19432012Handle<Value> InterpreterV8::SkyToLocal(const Arguments &args)
    19442013{
    1945     if (args.Length()>1)
    1946         return ThrowException(String::New("toLocal must not be called with more than one argument."));
    1947 
    1948     if (args.Length()==1 && !args[0]->IsDate())
    1949         return ThrowException(String::New("Argument must be a Date"));
     2014    AstroArgs local;
     2015    try
     2016    {
     2017        local = EvalAstroArgs(0, args, 2);
     2018    }
     2019    catch (const exception &e)
     2020    {
     2021        return ThrowException(String::New(e.what()));
     2022    }
    19502023
    19512024    Nova::EquPosn equ;
     
    19582031    HandleScope handle_scope;
    19592032
    1960     const Local<Value> date =
    1961         args.Length()==0 ? Date::New(Time().JavaDate()) : args[0];
    1962     if (date.IsEmpty())
    1963         return Undefined();
    1964 
    1965     const uint64_t v = uint64_t(date->NumberValue());
    1966     const Time utc(v/1000, v%1000);
    1967 
    1968     const Nova::ZdAzPosn hrz = Nova::GetHrzFromEqu(equ, utc.JD());
    1969 
    1970     Handle<Value> arg[] = { Number::New(hrz.zd), Number::New(hrz.az), date };
    1971     return handle_scope.Close(fTemplateLocal->GetFunction()->NewInstance(3, arg));
     2033    const Nova::ZdAzPosn hrz = Nova::GetHrzFromEqu(equ, local.posn, local.jd);
     2034
     2035    Handle<Value> arg[] = { Number::New(hrz.zd), Number::New(hrz.az), String::New(local.obs.c_str()), Date::New(local.jsdate) };
     2036    return handle_scope.Close(fTemplateLocal->GetFunction()->NewInstance(4, arg));
    19722037}
    19732038
    19742039Handle<Value> InterpreterV8::MoonToLocal(const Arguments &args)
    19752040{
    1976     if (args.Length()>0)
    1977         return ThrowException(String::New("toLocal must not be called with arguments."));
     2041    AstroArgs local;
     2042    try
     2043    {
     2044        local = EvalAstroArgs(0, args, 1);
     2045    }
     2046    catch (const exception &e)
     2047    {
     2048        return ThrowException(String::New(e.what()));
     2049    }
    19782050
    19792051    Nova::EquPosn equ;
     
    19822054
    19832055    if (!finite(equ.ra) || !finite(equ.dec))
    1984         return ThrowException(String::New("ra and dec must be finite."));
     2056        return ThrowException(String::New("Ra and dec must be finite."));
    19852057
    19862058    HandleScope handle_scope;
    19872059
    1988     const Local<Value> date = args.This()->Get(String::New("time"));
    1989     if (date.IsEmpty() || date->IsUndefined() )
    1990         return Undefined();
    1991 
    1992     const uint64_t v = uint64_t(date->NumberValue());
    1993     const Time utc(v/1000, v%1000);
    1994 
    1995     const Nova::ZdAzPosn hrz = Nova::GetHrzFromEqu(equ, utc.JD());
    1996 
    1997     Handle<Value> arg[] = { Number::New(hrz.zd), Number::New(hrz.az), date };
    1998     return handle_scope.Close(fTemplateLocal->GetFunction()->NewInstance(3, arg));
     2060    const Nova::ZdAzPosn hrz = Nova::GetHrzFromEqu(equ, local.posn, local.jd);
     2061
     2062    Handle<Value> arg[] = { Number::New(hrz.zd), Number::New(hrz.az), String::New(local.obs.c_str()), Date::New(local.jsdate) };
     2063    return handle_scope.Close(fTemplateLocal->GetFunction()->NewInstance(4, arg));
    19992064}
    20002065
    20012066Handle<Value> InterpreterV8::ConstructorMoon(const Arguments &args)
    20022067{
    2003     if (args.Length()>1)
    2004         return ThrowException(String::New("Moon constructor must not be called with more than one argument."));
    2005 
    2006     if (args.Length()==1 && !args[0]->IsDate())
    2007         return ThrowException(String::New("Argument must be a Date"));
     2068    AstroArgs local;
     2069    try
     2070    {
     2071        local = EvalAstroArgs(0, args, -1);
     2072    }
     2073    catch (const exception &e)
     2074    {
     2075        return ThrowException(String::New(e.what()));
     2076    }
     2077
     2078    const Nova::EquPosn equ = Nova::GetLunarEquCoords(local.jd, 0.01);
    20082079
    20092080    HandleScope handle_scope;
    2010 
    2011     const Local<Value> date =
    2012         args.Length()==0 ? Date::New(Time().JavaDate()) : args[0];
    2013     if (date.IsEmpty())
    2014         return Undefined();
    2015 
    2016     const uint64_t v = uint64_t(date->NumberValue());
    2017     const Time utc(v/1000, v%1000);
    2018 
    2019     const Nova::EquPosn equ = Nova::GetLunarEquCoords(utc.JD(), 0.01);
    20202081
    20212082    // ----------------------------
     
    20332094    self->Set(String::New("dec"),     Number::New(equ.dec),    ReadOnly);
    20342095    self->Set(String::New("toLocal"), function,                ReadOnly);
    2035     self->Set(String::New("time"),    date,                    ReadOnly);
     2096    self->Set(String::New("time"),    Date::New(local.jsdate), ReadOnly);
    20362097
    20372098    return handle_scope.Close(self);
     
    20432104        return ThrowException(String::New("Sky constructor takes two or three arguments."));
    20442105
    2045     if (args.Length()==3 && !args[2]->IsDate())
    2046         return ThrowException(String::New("Third argument must be a Date."));
     2106    if (args.Length()>2 && !args[2]->IsObject())
     2107    {
     2108        const string n = *String::AsciiValue(args[2]->ToObject()->GetConstructorName());
     2109        if (n!="Local")
     2110            return ThrowException(String::New("Third argument must be of type Local."));
     2111    }
    20472112
    20482113    const double ra  = args[0]->NumberValue();
     
    20502115
    20512116    if (!finite(ra) || !finite(dec))
    2052         return ThrowException(String::New("Both arguments to Sky must be valid numbers."));
     2117        return ThrowException(String::New("The first two arguments to Sky must be valid numbers."));
    20532118
    20542119    // ----------------------------
     
    20692134    self->Set(String::New("toLocal"), function,         ReadOnly);
    20702135    if (args.Length()==3)
    2071         self->Set(String::New("time"), args[2], ReadOnly);
     2136        self->Set(String::New("local"), args[2], ReadOnly);
    20722137
    20732138    return handle_scope.Close(self);
     
    20762141Handle<Value> InterpreterV8::ConstructorLocal(const Arguments &args)
    20772142{
    2078     if (args.Length()<2 || args.Length()>3)
    2079         return ThrowException(String::New("Local constructor takes two or three arguments."));
    2080 
    2081     if (args.Length()==3 && !args[2]->IsDate())
    2082         return ThrowException(String::New("Third argument must be a Date."));
     2143    AstroArgs local;
     2144    try
     2145    {
     2146        local = EvalAstroArgs(2, args, 2);
     2147    }
     2148    catch (const exception &e)
     2149    {
     2150        return ThrowException(String::New(e.what()));
     2151    }
    20832152
    20842153    const double zd = args[0]->NumberValue();
     
    20862155
    20872156    if (!finite(zd) || !finite(az))
    2088         return ThrowException(String::New("Both arguments to Local must be valid numbers."));
     2157        return ThrowException(String::New("The first two arguments to Local must be valid numbers."));
    20892158
    20902159    // --------------------
     
    21042173    self->Set(String::New("az"),    Number::New(az), ReadOnly);
    21052174    self->Set(String::New("toSky"), function,        ReadOnly);
    2106     if (args.Length()==3)
    2107         self->Set(String::New("time"), args[2], ReadOnly);
     2175    if (!local.obs.empty())
     2176        self->Set(String::New("observatory"), String::New(local.obs.c_str()), ReadOnly);
     2177    if (local.jsdate>0)
     2178        self->Set(String::New("time"),  Date::New(local.jsdate), ReadOnly);
    21082179
    21092180    return handle_scope.Close(self);
    21102181}
    21112182
    2112 Handle<Object> InterpreterV8::ConstructRiseSet(const Handle<Value> time, const Nova::RstTime &rst, const bool &rc)
     2183Handle<Object> ConstructRiseSet(const AstroArgs &args, const Nova::RstTime &rst, const bool &rc)
    21132184{
    21142185    Handle<Object> obj = Object::New();
    2115     obj->Set(String::New("time"), time, ReadOnly);
    2116 
    2117     const uint64_t v = uint64_t(time->NumberValue());
    2118     const double jd = Time(v/1000, v%1000).JD();
     2186    obj->Set(String::New("time"), Date::New(args.jsdate), ReadOnly);
     2187    obj->Set(String::New("observatory"), String::New(args.obs.c_str()), ReadOnly);
    21192188
    21202189    const bool isUp = rc>0 ||
    2121         (rst.rise<rst.set && (jd>rst.rise && jd<rst.set)) ||
    2122         (rst.rise>rst.set && (jd<rst.set  || jd>rst.rise));
     2190        (rst.rise<rst.set && (args.jd>rst.rise && args.jd<rst.set)) ||
     2191        (rst.rise>rst.set && (args.jd<rst.set  || args.jd>rst.rise));
    21232192
    21242193    obj->Set(String::New("isUp"), Boolean::New(rc>=0 && isUp), ReadOnly);
     
    21422211Handle<Value> InterpreterV8::SunHorizon(const Arguments &args)
    21432212{
    2144     if (args.Length()>2)
    2145         return ThrowException(String::New("Sun.horizon must not be called with one or two arguments."));
    2146 
    2147     if (args.Length()==2 && !args[1]->IsDate())
    2148         return ThrowException(String::New("Second argument must be a Date"));
     2213    AstroArgs local;
     2214    try
     2215    {
     2216        local = EvalAstroArgs(1, args, 2);
     2217    }
     2218    catch (const exception &e)
     2219    {
     2220        return ThrowException(String::New(e.what()));
     2221    }
    21492222
    21502223    HandleScope handle_scope;
     
    21732246
    21742247    if (!finite(hrz))
    2175         return ThrowException(String::New("Second argument did not yield a valid number."));
    2176 
    2177     const Local<Value> date =
    2178         args.Length()<2 ? Date::New(Time().JavaDate()) : args[1];
    2179     if (date.IsEmpty())
    2180         return Undefined();
    2181 
    2182     const uint64_t v = uint64_t(date->NumberValue());
    2183     const Time utc(v/1000, v%1000);
    2184 
    2185     Nova::LnLatPosn obs = Nova::kORM;
     2248        return ThrowException(String::New("First argument did not yield a valid number."));
    21862249
    21872250    ln_rst_time sun;
    2188     const int rc = ln_get_solar_rst_horizon(utc.JD()-0.5, &obs, hrz, &sun);
    2189     Handle<Object> rst = ConstructRiseSet(date, sun, rc);
     2251    const int rc = ln_get_solar_rst_horizon(local.jd-0.5, &local.posn, hrz, &sun);
     2252    Handle<Object> rst = ConstructRiseSet(local, sun, rc);
    21902253    rst->Set(String::New("horizon"), Number::New(hrz));
    21912254    return handle_scope.Close(rst);
     
    21942257Handle<Value> InterpreterV8::MoonHorizon(const Arguments &args)
    21952258{
    2196     if (args.Length()>1)
    2197         return ThrowException(String::New("Moon.horizon must not be called with more than one argument."));
    2198 
    2199     if (args.Length()==1 && !args[0]->IsDate())
    2200         return ThrowException(String::New("Argument must be a Date"));
     2259    AstroArgs local;
     2260    try
     2261    {
     2262        local = EvalAstroArgs(0, args, 2);
     2263    }
     2264    catch (const exception &e)
     2265    {
     2266        return ThrowException(String::New(e.what()));
     2267    }
    22012268
    22022269    HandleScope handle_scope;
    22032270
    2204     const Local<Value> date =
    2205         args.Length()==0 ? Date::New(Time().JavaDate()) : args[0];
    2206     if (date.IsEmpty())
    2207         return Undefined();
    2208 
    2209     const uint64_t v = uint64_t(date->NumberValue());
    2210     const Time utc(v/1000, v%1000);
    2211 
    2212     Nova::LnLatPosn obs = Nova::kORM;
    2213 
    22142271    ln_rst_time moon;
    2215     const int rc = ln_get_lunar_rst(utc.JD()-0.5, &obs, &moon);
    2216     Handle<Object> rst = ConstructRiseSet(date, moon, rc);
     2272    const int rc = ln_get_lunar_rst(local.jd-0.5, &local.posn, &moon);
     2273    Handle<Object> rst = ConstructRiseSet(local, moon, rc);
    22172274    return handle_scope.Close(rst);
    22182275};
     
    28322889    rc.emplace_back("null");
    28332890    rc.emplace_back("delete ");
     2891    rc.emplace_back("JSON.stringify(");
     2892    rc.emplace_back("JSON.parse(");
    28342893
    28352894    rc.emplace_back("dim.log(");
  • trunk/FACT++/src/InterpreterV8.h

    r18426 r18828  
    127127    static v8::Handle<v8::Value> MoonHorizon(const v8::Arguments &args);
    128128    static v8::Handle<v8::Value> SunHorizon(const v8::Arguments &args);
    129     static v8::Handle<v8::Object> ConstructRiseSet(const v8::Handle<v8::Value>, const ln_rst_time &, const bool &);
    130129#endif
    131130
Note: See TracChangeset for help on using the changeset viewer.