From 5e749afa582a615af7b27317e528c4cf30e9a1f1 Mon Sep 17 00:00:00 2001 From: Nathan Bowler Date: Mon, 8 Sep 2014 11:20:44 -0400 Subject: [PATCH] Omaha #3405 Convert airep and pirep to DAF. Extract common code. Update acars to use common Change-Id: I09fd0119900dabbde901773469d90b31eda57d63 Former-commit-id: d45f5c1715eecd33f491f4be35d6294a04d6ef6f [formerly b465914db42fa389bc92c1ee01ed5ba94a05bc25] [formerly ebe27b736fde205cd3c68610be25df3bc0487e1e] [formerly ebe27b736fde205cd3c68610be25df3bc0487e1e [formerly ee5d7fc5e5eeb92423f1d5d717ade3ae50b7dd2c]] [formerly 099f40fb8729162eed235625c6295d0d80d23327 [formerly ebe27b736fde205cd3c68610be25df3bc0487e1e [formerly ee5d7fc5e5eeb92423f1d5d717ade3ae50b7dd2c] [formerly 099f40fb8729162eed235625c6295d0d80d23327 [formerly 4c32ce907e8bad06015688ca5596a23bfb655463]]]] Former-commit-id: 099f40fb8729162eed235625c6295d0d80d23327 Former-commit-id: 9f4baf3599c93c4014bb0d11584c81d1b338459e [formerly 31f5ccc2a3cb1783dad329b5e8a197cfeceb872d] [formerly bcfdc408d43201efd0e380959a31fae5145e81b3 [formerly ac6f4dea5a3f9e76f062f0f5761d9a434a68b2c7]] Former-commit-id: bcfdc408d43201efd0e380959a31fae5145e81b3 Former-commit-id: f266f86c39ffabb8a7d183804a7428224da43ba2 --- pythonPackages/msaslaps/acars/a2acarsStub.py | 31 +- .../msaslaps/aireppirep/a2aircraft.csh | 132 ++-- .../msaslaps/aireppirep/a2airepStub.py | 238 ++++--- .../msaslaps/aireppirep/a2pirepStub.py | 596 +++++++++++------- pythonPackages/msaslaps/common/a2dafcommon.py | 43 ++ 5 files changed, 690 insertions(+), 350 deletions(-) create mode 100644 pythonPackages/msaslaps/common/a2dafcommon.py diff --git a/pythonPackages/msaslaps/acars/a2acarsStub.py b/pythonPackages/msaslaps/acars/a2acarsStub.py index 4a2d00ca40..2976b81e8d 100644 --- a/pythonPackages/msaslaps/acars/a2acarsStub.py +++ b/pythonPackages/msaslaps/acars/a2acarsStub.py @@ -33,10 +33,12 @@ # ------------ ---------- ----------- -------------------------- # 07/23/2014 3392 nabowle Initial modification. Replaces UEngine with DAF. # 07/28/2014 3392 nabowle Strip tail and receiver to match original formatting. +# 09/04/2014 3405 nabowle NO_DATA and date to string extracted to a2dafcommon # # +import a2dafcommon import argparse import sys @@ -58,9 +60,6 @@ def get_args(): return parser.parse_args() def main(): -# Values used to indicate no data. - NO_DATA = [None, "None", -9999, -9999.0, "-9999", "-9999.0", ""] - user_args = get_args() # Set the host in the DataAcessLayer if supplied @@ -94,7 +93,7 @@ def main(): for geoData in geometries: mytail = geoData.getString("tailNumber") - if mytail in NO_DATA: + if a2dafcommon.is_no_data(mytail): mytail = "" else: mytail = mytail.strip() @@ -103,75 +102,75 @@ def main(): if mytime == None: continue #2014-07-16 00:00:00 (0) => 2014-07-16_00:00:00 - mytime = str(mytime)[0:19].replace(" ","_") + mytime = a2dafcommon.datatime_to_string(mytime) geo = geoData.getGeometry() if geo == None: continue mylon = geo.x mylat = geo.y - if (mylat in NO_DATA or mylon in NO_DATA): + if a2dafcommon.is_no_data(mylat) or a2dafcommon.is_no_data(mylon): continue mylat = "%.4f"%float(mylat) mylon = "%.4f"%float(mylon) myrec = geoData.getString("receiver") - if myrec in NO_DATA: + if a2dafcommon.is_no_data(myrec): myrec = "" else: myrec = myrec.strip() mypres = geoData.getNumber("pressure") - if mypres in NO_DATA: + if a2dafcommon.is_no_data(mypres): mypres = "1e37" else : mypres = "%.0f"%mypres myphs = geoData.getString("flightPhase") - if myphs in NO_DATA: + if a2dafcommon.is_no_data(myphs): myphs = "7" else : myphs = "%d"%int(myphs) myrol = geoData.getString("rollAngleQuality") - if myrol in NO_DATA: + if a2dafcommon.is_no_data(myrol): myrol = "3" else : myrol = "%d"%int(myrol) mytemp = geoData.getNumber("temp") - if mytemp in NO_DATA: + if a2dafcommon.is_no_data(mytemp): mytemp = "1e37" else : mytemp = "%.1f"%mytemp mydir = geoData.getString("windDirection") - if mydir in NO_DATA: + if a2dafcommon.is_no_data(mydir): mydir = "1e37" else : mydir = "%d"%int(mydir) myspd = geoData.getNumber("windSpeed") - if myspd in NO_DATA: + if a2dafcommon.is_no_data(myspd): myspd = "1e37" else : myspd = "%.1f"%myspd myhum = geoData.getNumber("humidity") - if myhum in NO_DATA: + if a2dafcommon.is_no_data(myhum): myhum = "1e37" else : myhum = "%.0f"%myhum mymix = geoData.getNumber("mixingRatio") - if mymix in NO_DATA: + if a2dafcommon.is_no_data(mymix): mymix = "1e37" else : mymix = "%.2f"%mymix # Icing was commented out of the uengine version # myicg = geoData.getString("icing") -# if myicg in NO_DATA: +# if a2dafcommon.is_no_data(myicg): # myicg = "1e37" # else : # myicg = "%d"%int(myicg) diff --git a/pythonPackages/msaslaps/aireppirep/a2aircraft.csh b/pythonPackages/msaslaps/aireppirep/a2aircraft.csh index a0f915e085..53fcb36034 100644 --- a/pythonPackages/msaslaps/aireppirep/a2aircraft.csh +++ b/pythonPackages/msaslaps/aireppirep/a2aircraft.csh @@ -1,4 +1,24 @@ #!/bin/csh +## +# This software was developed and / or modified by Raytheon Company, +# pursuant to Contract DG133W-05-CQ-1067 with the US Government. +# +# U.S. EXPORT CONTROLLED TECHNICAL DATA +# This software product contains export-restricted data whose +# export/transfer/disclosure is restricted by U.S. law. Dissemination +# to non-U.S. persons whether in the United States or abroad requires +# an export license or other authorization. +# +# Contractor Name: Raytheon Company +# Contractor Address: 6825 Pine Street, Suite 340 +# Mail Stop B8 +# Omaha, NE 68106 +# 402.291.0100 +# +# See the AWIPS II Master Rights File ("Master Rights File.pdf") for +# further licensing information. +## + # # A script wrapper around a UEngine call that is meant to get all available # maritime data in the A-II database over a specified range of times. @@ -14,7 +34,8 @@ # The literal p flag is optional. The p flag means preserve # the final version of the python submitted to the UEngine instead of # cleaning it up. The path to the finalized python is /tmp/a2aircraftNNNNN.py -# where NNNNN is a unix process id. +# where NNNNN is a unix process id. This flag does nothing when using the DAF +# version. # # The optional literal t mean change some of the ascii phenomena descriptions # for pireps into codes suitable for D-2D format aircraft data files. @@ -32,6 +53,16 @@ # Asterisk (*) means variable that does not directly correspond to a # variable in the D-2D format aircraft data files. # +# +# +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# 09/02/2014 3405 nabowle Initial modification to better handle daf. +# +# set rmpy = yes set typcod = qwertyuiop if ( "$1" == "t" ) then @@ -90,6 +121,10 @@ endif grep DataAccessLayer $stubpy >& /dev/null if ( $status == 0 ) then set method = "daf" + if ( "$repType" != "PIREP" ) then + /awips2/python/bin/python $stubpy -b "$1 $2" -e "$3 $4" --match-legacy +# /awips2/python/bin/python $stubpy -b "$1 $2" -e "$3 $4" + endif else # # Set up the environment we need to run the UEngine. @@ -108,24 +143,22 @@ else exit endif source $ueenv -endif -# -set specpy = /tmp/a2airep${$}.py -rm -rf $specpy >& /dev/null -touch $specpy -chmod 775 $specpy -cat $stubpy | sed "s/BBBBB/$1 $2/g" | sed "s/EEEEE/$3 $4/g" > $specpy -if ( "$repType" != "PIREP" ) then - if ( "$method" == "daf" ) then - /awips2/python/bin/python $specpy - else + + # + set specpy = /tmp/a2airep${$}.py + rm -rf $specpy >& /dev/null + touch $specpy + chmod 775 $specpy + cat $stubpy | sed "s/BBBBB/$1 $2/g" | sed "s/EEEEE/$3 $4/g" > $specpy + if ( "$repType" != "PIREP" ) then set here = `pwd` cd $UE_BIN_PATH ( uengine -r python < $specpy ) | grep -v '<' | grep -v Response cd $here endif + if ( "$rmpy" == "yes" ) rm -rf $specpy >& /dev/null endif -if ( "$rmpy" == "yes" ) rm -rf $specpy >& /dev/null + # # Locate python stub that we will modify to create the final python logic. # @@ -147,40 +180,49 @@ endif grep DataAccessLayer $stubpy >& /dev/null if ( $status == 0 ) then set method = "daf" -else if ( "$method" == "daf" ) then - # - # Set up the environment we need to run the UEngine. - # - set method = "uengine" - if ( -e ./UEngine.cshsrc ) then - set ueenv = ./UEngine.cshsrc - else if ( -e $mydir/UEngine.cshsrc ) then - set ueenv = $mydir/UEngine.cshsrc - else if ( -e $FXA_HOME/src/dm/point/UEngine.cshsrc ) then - set ueenv = $FXA_HOME/src/dm/point/UEngine.cshsrc - else if ( -e $FXA_HOME/bin/UEngine.cshsrc ) then - set ueenv = $FXA_HOME/bin/UEngine.cshsrc - else - bash -c "echo could not find UEngine.cshsrc 1>&2" - exit + if ( "$repType" != "AIREP" ) then + # By default, match the legacy output. + set pyargs = "--match-legacy" +# set pyargs = "" + if ( "$typcod" != "qwertyuiop" ) then + set pyargs = "$pyargs -t" + endif + + /awips2/python/bin/python $stubpy -b "$1 $2" -e "$3 $4" $pyargs endif - source $ueenv -endif -# -set specpy = /tmp/a2pirep${$}.py -rm -rf $specpy >& /dev/null -touch $specpy -chmod 775 $specpy -cat $stubpy | sed "s/BBBBB/$1 $2/g" | sed "s/EEEEE/$3 $4/g" | \ - grep -v "$typcod" > $specpy -cd $UE_BIN_PATH -if ( "$repType" != "AIREP" ) then +else if ( "$method" == "daf" ) then - /awips2/python/bin/python $specpy - else - cd $UE_BIN_PATH + # + # Set up the environment we need to run the UEngine. + # + set method = "uengine" + if ( -e ./UEngine.cshsrc ) then + set ueenv = ./UEngine.cshsrc + else if ( -e $mydir/UEngine.cshsrc ) then + set ueenv = $mydir/UEngine.cshsrc + else if ( -e $FXA_HOME/src/dm/point/UEngine.cshsrc ) then + set ueenv = $FXA_HOME/src/dm/point/UEngine.cshsrc + else if ( -e $FXA_HOME/bin/UEngine.cshsrc ) then + set ueenv = $FXA_HOME/bin/UEngine.cshsrc + else + bash -c "echo could not find UEngine.cshsrc 1>&2" + exit + endif + source $ueenv + endif + + # + set specpy = /tmp/a2pirep${$}.py + rm -rf $specpy >& /dev/null + touch $specpy + chmod 775 $specpy + cat $stubpy | sed "s/BBBBB/$1 $2/g" | sed "s/EEEEE/$3 $4/g" | \ + grep -v "$typcod" > $specpy + cd $UE_BIN_PATH + if ( "$repType" != "AIREP" ) then + cd $UE_BIN_PATH ( uengine -r python < $specpy ) | grep -v '<' | grep -v Response endif + if ( "$rmpy" == "yes" ) rm -rf $specpy >& /dev/null endif -if ( "$rmpy" == "yes" ) rm -rf $specpy >& /dev/null -# + diff --git a/pythonPackages/msaslaps/aireppirep/a2airepStub.py b/pythonPackages/msaslaps/aireppirep/a2airepStub.py index 029ecd0c9d..ad219be76a 100644 --- a/pythonPackages/msaslaps/aireppirep/a2airepStub.py +++ b/pythonPackages/msaslaps/aireppirep/a2airepStub.py @@ -1,78 +1,168 @@ -from com.raytheon.uf.common.message.response import ResponseMessageGeneric -import BaseRequest +## +# This software was developed and / or modified by Raytheon Company, +# pursuant to Contract DG133W-05-CQ-1067 with the US Government. +# +# U.S. EXPORT CONTROLLED TECHNICAL DATA +# This software product contains export-restricted data whose +# export/transfer/disclosure is restricted by U.S. law. Dissemination +# to non-U.S. persons whether in the United States or abroad requires +# an export license or other authorization. +# +# Contractor Name: Raytheon Company +# Contractor Address: 6825 Pine Street, Suite 340 +# Mail Stop B8 +# Omaha, NE 68106 +# 402.291.0100 +# +# See the AWIPS II Master Rights File ("Master Rights File.pdf") for +# further licensing information. +## -br = BaseRequest.BaseRequest( "airep" ) -br.addParameter("dataTime","BBBBB:00.0",">=") -br.addParameter("dataTime","EEEEE:59.9","<=") -# ArrayList of ResponseMessageGeneric -alrmg = br.execute() -nnn = alrmg.size() -if nnn == 0 : - return ResponseMessageGeneric("No data available.") +# +# Gets all available pirep data in the A-II database over a specified range of +# times. The data is output to stdout as ASCII. Each line is one record. +# The individual data items are comma delimited. +# +# +# +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# 08/25/2014 3405 nabowle Initial modification. Replaces UEngine with DAF. +# +# -# ResponseMessageGeneric payload -msg = "\n" -i = 0 -while i < nnn : - oneRec = alrmg.get(i).getContents() - i += 1 - mytime = oneRec.getDataURI().split('/',4)[2].split('.',2)[0] - if mytime == "" or mytime == "None" : - continue - myloc = str(oneRec.getLocation().getLocation()).split(' ',4) - mylat = myloc[2].split(')',2)[0] - if mylat == "" or mylat == "None" : - continue - try: - mylat = "%.4f"%float(mylat) - except: - continue - mylon = myloc[1].split('(',2)[1] - if mylon == "" or mylon == "None" : - continue - try: - mylon = "%.4f"%float(mylon) - except: - continue - myflvl = str(oneRec.getFlightLevel()) - if myflvl == "" or myflvl == "None" : - myflvl = "1e37" - else : - myflvl = "%d"%int(myflvl) - mytemp = str(oneRec.getTemp()) - if mytemp == "" or mytemp == "None" : - mytemp = "1e37" - else : - mytemp = "%.1f"%float(mytemp) - mydir = str(oneRec.getWindDirection()) - if mydir == "" or mydir == "None" : - mydir = "1e37" - else : - mydir = "%d"%int(mydir) - myspd = str(oneRec.getWindSpeed()) - if myspd == "" or myspd == "None" : - myspd = "1e37" - else : - myspd = "%.1f"%float(myspd) - myfwx = str(oneRec.getFlightWeather()) - if myfwx == "" or myfwx == "None" : - myfwx = "-1" - else : - myfwx = "%d"%int(myfwx) - myhaz = str(oneRec.getFlightHazard()) - if myhaz == "" or myhaz == "None" : - myhaz = "-1" - else : - myhaz = "%d"%int(myhaz) - mycond = str(oneRec.getFlightConditions()) - if mycond == "" or mycond == "None" : - mycond = "-1" - else : - mycond = "%d"%int(mycond) - msg += mylat + "|" + mylon + "," + mytime + "," + myflvl + ",AIREP,," + \ - mytemp + "," + mydir + "," + myspd + ",1e37," + \ - myfwx + "," + myhaz + "," + mycond + ",,0,,,,0,,,,,0,,,,\n" -# pass single RMG back to the uengine. -return ResponseMessageGeneric(msg) +import a2dafcommon +import argparse +import sys + +from datetime import datetime +from ufpy.dataaccess import DataAccessLayer +from dynamicserialize.dstypes.com.raytheon.uf.common.time import TimeRange + + +def get_args(): + parser = argparse.ArgumentParser(conflict_handler="resolve") + parser.add_argument("-h", action="store", dest="host", + help="EDEX server hostname (optional)", + metavar="hostname") + parser.add_argument("-b", action="store", dest="start", + help="The start of the time range in YYYY-MM-DD HH:MM", + metavar="start") + parser.add_argument("-e", action="store", dest="end", + help="The end of the time range in YYYY-MM-DD HH:MM", + metavar="end") + parser.add_argument("--match-legacy", action="store_true", dest="match", + help="If set, the legacy script output will be matched.", + default=False) + return parser.parse_args() + + +def main(): + user_args = get_args() + + if user_args.host: + DataAccessLayer.changeEDEXHost(user_args.host) + + start = user_args.start + end = user_args.end + + if not start or not end: + print >> sys.stderr, "Start or End date not provided" + return + + beginRange = datetime.strptime( start + ":00.0", "%Y-%m-%d %H:%M:%S.%f") + endRange = datetime.strptime( end + ":59.9", "%Y-%m-%d %H:%M:%S.%f") + timerange = TimeRange(beginRange, endRange) + + req = DataAccessLayer.newDataRequest("airep") + req.setParameters("id", "flightLevel", "temp", "windDirection", "windSpeed", + "flightWeather", "flightHazard", "flightConditions") + geometries = DataAccessLayer.getGeometryData(req, timerange) + + if not geometries : +# print "No data available." + return + + msg = ""; + + geometries.sort(key=lambda geo: str(geo.getDataTime())) + for geoData in geometries : + mytime = geoData.getDataTime() + if not mytime: + continue + mytime = a2dafcommon.datatime_to_string(mytime) + + geo = geoData.getGeometry() + if not geo: + continue + + mylon = geo.x + mylat = geo.y + if a2dafcommon.is_no_data(mylat) or a2dafcommon.is_no_data(mylon): + continue + mylat = "%.4f"%mylat + mylon = "%.4f"%mylon + + myflvl = geoData.getNumber("flightLevel") + if a2dafcommon.is_no_data(myflvl) : + myflvl = "1e37" + else : + myflvl = "%d"%myflvl + +# Temp is not stored. +# mytemp = geoData.getString("temp") +# if a2dafcommon.is_no_data(mytemp) : +# mytemp = "1e37" +# else : +# mytemp = "%.1f"%float(mytemp) + mytemp = "1e37" + +# Wind Direction is not stored. +# mydir = geoData.getString("windDirection") +# if a2dafcommon.is_no_data(mydir) : +# mydir = "1e37" +# else : +# mydir = "%d"%int(mydir) + mydir = "1e37" + + myspd = geoData.getNumber("windSpeed") + if a2dafcommon.is_no_data(myspd) : + myspd = "1e37" + else : + myspd = "%.1f"%myspd + + myfwx = geoData.getNumber("flightWeather") + if myfwx : + myfwx = "-1" + else : + myfwx = "%d"%myfwx + + myhaz = geoData.getNumber("flightHazard") + if a2dafcommon.is_no_data(myhaz) : + myhaz = "-1" + else : + myhaz = "%d"%myhaz + + mycond = geoData.getNumber("flightConditions") + if a2dafcommon.is_no_data(mycond) : + mycond = "-1" + else : + mycond = "%d"%mycond + + if user_args.match: +# Wind Speed not returned to legacy script. + myspd = "1e37" + + msg += mylat + "|" + mylon + "," + mytime + "," + myflvl + ",AIREP,," + \ + mytemp + "," + mydir + "," + myspd + ",1e37," + \ + myfwx + "," + myhaz + "," + mycond + ",,0,,,,0,,,,,0,,,,\n" + + print msg.strip() + +if __name__ == '__main__': + main() diff --git a/pythonPackages/msaslaps/aireppirep/a2pirepStub.py b/pythonPackages/msaslaps/aireppirep/a2pirepStub.py index ed1a5a5433..77f3f6e23f 100644 --- a/pythonPackages/msaslaps/aireppirep/a2pirepStub.py +++ b/pythonPackages/msaslaps/aireppirep/a2pirepStub.py @@ -1,219 +1,385 @@ -from com.raytheon.uf.common.message.response import ResponseMessageGeneric -import BaseRequest +## +# This software was developed and / or modified by Raytheon Company, +# pursuant to Contract DG133W-05-CQ-1067 with the US Government. +# +# U.S. EXPORT CONTROLLED TECHNICAL DATA +# This software product contains export-restricted data whose +# export/transfer/disclosure is restricted by U.S. law. Dissemination +# to non-U.S. persons whether in the United States or abroad requires +# an export license or other authorization. +# +# Contractor Name: Raytheon Company +# Contractor Address: 6825 Pine Street, Suite 340 +# Mail Stop B8 +# Omaha, NE 68106 +# 402.291.0100 +# +# See the AWIPS II Master Rights File ("Master Rights File.pdf") for +# further licensing information. +## -br = BaseRequest.BaseRequest( "pirep" ) -br.addParameter("dataTime","BBBBB:00.0",">=") -br.addParameter("dataTime","EEEEE:59.9","<=") -# ArrayList of ResponseMessageGeneric -alrmg = br.execute() -nnn = alrmg.size() -if nnn == 0 : - return ResponseMessageGeneric("No data available.") -typecode = 'yes' -typecode = 'no' +# +# Gets all available pirep data in the A-II database over a specified time +# range. The data is output to stdout as ASCII. Each line is one record. The +# individual data items are comma delimited. +# +# The legacy script does not retrieve any values not stored in the postgres db. +# To compensate for this in side-by-side comparison, a --match-legacy flag is +# provided that will ignore these fields. +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# 08/25/2014 3405 nabowle Initial modification. Replaces UEngine with DAF. +# +# -# ResponseMessageGeneric payload -msg = "\n" -i = 0 -while i < nnn : - oneRec = alrmg.get(i).getContents() - i += 1 - mytime = oneRec.getDataURI().split('/',4)[2].split('.',2)[0] - if mytime == "" or mytime == "None" : - continue - myloc = str(oneRec.getLocation().getLocation()).split(' ',4) - mylat = myloc[2].split(')',2)[0] - if mylat == "" or mylat == "None" : - continue - try: - mylat = "%.4f"%float(mylat) - except: - continue - mylon = myloc[1].split('(',2)[1] - if mylon == "" or mylon == "None" : - continue - try: - mylon = "%.4f"%float(mylon) - except: - continue - myflvl = str(oneRec.getFlightLevel()) - if myflvl == "" or myflvl == "None" : - myflvl = "1e37" - else : - myflvl = "%d"%int(myflvl) - mytemp = str(oneRec.getTemp()) - if mytemp == "" or mytemp == "None" : - mytemp = "1e37" - else : - mytemp = "%.1f"%float(mytemp) - mydir = str(oneRec.getWindDirection()) - if mydir == "" or mydir == "None" : - mydir = "1e37" - else : - mydir = "%d"%int(mydir) - myspd = str(oneRec.getWindSpeed()) - if myspd == "" or myspd == "None" : - myspd = "1e37" - else : - myspd = "%.1f"%float(myspd) - myvis = str(oneRec.getHorzVisibility()) - if myvis == "" or myvis == "None" : - myvis = "1e37" - else : - myvis = "%.1f"%float(myvis) - mycraft = str(oneRec.getAircraftType()) - if mycraft == "None" : - mycraft = "" - mywx = str(oneRec.getWeatherGroup()) - if mywx == "None" : - mywx = "" - cc = 0 - cldBas = "" - cldTop = "" - cldVal = "" - ii = 0 - icgBas = "" - icgTop = "" - icgTyp = "" - icgVal = "" - tt = 0 - trbBas = "" - trbTop = "" - trbTyp = "" - trbVal = "" - for pld in oneRec.getAncPirepData().toArray(): - sep = "" - ltyp = pld.getLayerType() - if ltyp == "" or ltyp == "None" : - continue - base = str(pld.getBaseLayerHeight()) - if base == "" or base == "None" or base == "99999" : - base = "1e37" - else : - base = "%.0f"%float(base) - top = str(pld.getTopLayerHeight()) - if top == "" or top == "None" or top == "99999" : - top = "1e37" - else : - top = "%.0f"%float(top) - dtyp = str(pld.getDataType()) - if dtyp == "None" : - dtyp = "" - fval = str(pld.getFirstValue()) - if fval == "None" : - fval = "" - sval = str(pld.getSecondValue()) - if sval == "None" : - sval = "" - if ltyp == "CLOUD" : - if fval == "TOP" : - fval = "" - if sval == "TOP" : - sval = "" - if sval != "" : - fval += "-"+sval - if typecode == 'yes' : - if fval == "CLR" : - fval = "0" - elif fval == "OVC" : - fval = "8" - elif fval == "SCT" : - fval = "11" - elif fval == "BKN" : - fval = "12" - elif fval == "FEW" : - fval = "13" - else : - continue - if cldBas != "" : - sep = "|" - cldBas += sep+base - cldTop += sep+top - cldVal += sep+fval - cc += 1 - elif ltyp == "ICING" : - if sval != "" : - fval += "-"+sval - if icgBas != "" : - sep = "|" - if typecode == 'yes' : - if dtyp == "RIME" : - dtyp = "1" - elif dtyp == "CLR" : - dtyp = "2" - elif dtyp == "MXD" : - dtyp = "3" - else : - dtyp = "-9999" - if fval == "NEG" : - fval = "0"; - elif fval == "TRACE" : - fval = "1" - elif fval == "TRACE-LGT" : - fval = "2" - elif fval == "LGT" : - fval = "3" - elif fval == "LGT-MOD" : - fval = "4" - elif fval == "MOD" : - fval = "5" - elif fval == "MOD-SEV" : - fval = "7" - elif fval == "SEV" : - fval = "8" - else : - fval = "-9999" - if fval == "-9999" and dtyp == "-9999" : - continue - icgBas += sep+base - icgTop += sep+top - icgTyp += sep+dtyp - icgVal += sep+fval - ii += 1 - elif ltyp == "TURBC" : - if sval != "" : - fval += "-"+sval - if typecode == 'yes' : - if dtyp == "CAT" : - dtyp = "1" - elif dtyp == "CHOP" : - dtyp = "2" - else : - dtyp = "-9999" - if fval == "NEG" : - fval = "0"; - elif fval == "LGT" : - fval = "2" - elif fval == "LGT-MOD" : - fval = "3" - elif fval == "MOD" : - fval = "4" - elif fval == "MOD-SEV" : - fval = "5" - elif fval == "SEV" : - fval = "6" - elif fval == "EXTRM" : - fval = "8" - else : - fval = "-9999" - if fval == "-9999" and dtyp == "-9999" : - continue - if trbBas != "" : - sep = "|" - trbBas += sep+base - trbTop += sep+top - trbTyp += sep+dtyp - trbVal += sep+fval - tt += 1 - msg += mylat + "|" + mylon + "," + mytime + "," + myflvl + ",PIREP," + \ - mycraft + "," + mytemp + "," + mydir + "," + myspd + "," + \ - myvis + ",-1,-1,-1," + mywx + "," + \ - str(cc) + "," + cldBas + "," + cldTop + "," + cldVal + "," + \ - str(ii) + "," + icgBas + "," + icgTop + "," + \ - icgTyp + "," + icgVal + "," + \ - str(tt) + "," + trbBas + "," + trbTop + "," + \ - trbTyp + "," + trbVal + "\n" -# pass single RMG back to the uengine. -return ResponseMessageGeneric(msg) +import a2dafcommon +import argparse +import sys + +from datetime import datetime +from ufpy.dataaccess import DataAccessLayer +from dynamicserialize.dstypes.com.raytheon.uf.common.time import TimeRange + + + +def get_args(): + parser = argparse.ArgumentParser(conflict_handler="resolve") + parser.add_argument("-h", action="store", dest="host", + help="EDEX server hostname (optional)", + metavar="hostname") + parser.add_argument("-b", action="store", dest="start", + help="The start of the time range in YYYY-MM-DD HH:MM", + metavar="start") + parser.add_argument("-e", action="store", dest="end", + help="The end of the time range in YYYY-MM-DD HH:MM", + metavar="end") + parser.add_argument("--match-legacy", action="store_true", dest="match", + help="If set, the legacy script output will be matched.", + default=False) + parser.add_argument("-t", action="store_true", dest="typecode", + help="If set, more type information is displayed.", + default=False) + return parser.parse_args() + + +def main(): + MULTI_DIM_PARAMS = set(["hazardType", + "turbType", "turbBaseHeight", "turbTopHeight", + "iceType", "iceBaseHeight", "iceTopHeight", + "skyCover1", "skyCover2", "skyBaseHeight", "skyTopHeight" + ]) + + user_args = get_args() + + if user_args.host: + DataAccessLayer.changeEDEXHost(user_args.host) + + start = user_args.start + end = user_args.end + + if not start or not end: + print >> sys.stderr, "Start or End date not provided" + return + + beginRange = datetime.strptime( start + ":00.0", "%Y-%m-%d %H:%M:%S.%f") + endRange = datetime.strptime( end + ":59.9", "%Y-%m-%d %H:%M:%S.%f") + timerange = TimeRange(beginRange, endRange) + + req = DataAccessLayer.newDataRequest("pirep") + req.setParameters('id', 'flightLevel', 'temp', 'windDirection', 'windSpeed', + 'horzVisibility', 'aircraftType', 'weatherGroup') + req.getParameters().extend(MULTI_DIM_PARAMS) + geometries = DataAccessLayer.getGeometryData(req, timerange) + + if not geometries : +# print "No data available." + return + + typecode = user_args.typecode + match = user_args.match + msg = "" + layerData = [] + combinedGeos = [] + for geoData in geometries : +# The DAF returns multi-dimensional parameters as separate results before +# the base result that contain the single-dimensional parameters. +# Because of the separation of parameters and known ordering of result +# types, we can easily figure out what each result is and correlate the +# ancillary data with the base data. + if set(geoData.getParameters()) & MULTI_DIM_PARAMS : + layerData.append(geoData) + continue + + combinedGeos.append({"base":geoData, "layers":layerData}) + layerData = [] + + combinedGeos.sort(key=lambda geoMap: str(geoMap['base'].getDataTime())) + + for geoMap in combinedGeos : + geoData = geoMap['base'] + layerData = geoMap['layers'] + + mytime = geoData.getDataTime() + if not mytime: + continue + mytime = mytime = a2dafcommon.datatime_to_string(mytime) + + geo = geoData.getGeometry() + if not geo: + continue + + mylon = geo.x + mylat = geo.y + if a2dafcommon.is_no_data(mylat) or a2dafcommon.is_no_data(mylon) : + continue + mylat = "%.4f"%mylat + mylon = "%.4f"%mylon + + myflvl = geoData.getNumber("flightLevel") + if a2dafcommon.is_no_data(myflvl) : + myflvl = "1e37" + else : + myflvl = "%d"%myflvl + +# Temp is not stored. +# mytemp = geoData.getNumber("temp") +# if a2dafcommon.is_no_data(mytemp) : +# mytemp = "1e37" +# else : +# mytemp = "%.1f"%float(mytemp) + mytemp = "1e37" + +# Wind Direction is not stored. +# mydir = geoData.getString("windDirection") +# if a2dafcommon.is_no_data(mydir) : +# mydir = "1e37" +# else : +# mydir = "%d"%int(mydir) + mydir = "1e37" + + myspd = geoData.getNumber("windSpeed") + if a2dafcommon.is_no_data(myspd) : + myspd = "1e37" + else : + myspd = "%.1f"%myspd + + myvis = geoData.getNumber("horzVisibility") + if a2dafcommon.is_no_data(myvis) : + myvis = "1e37" + else : + myvis = "%.1f"%myvis + + mycraft = geoData.getString("aircraftType") + if a2dafcommon.is_no_data(mycraft) : + mycraft = "" + + mywx = geoData.getString("weatherGroup") + if a2dafcommon.is_no_data(mywx) : + mywx = "" + + + cc = 0 + cldBas = "" + cldTop = "" + cldVal = "" + ii = 0 + icgBas = "" + icgTop = "" + icgTyp = "" + icgVal = "" + tt = 0 + trbBas = "" + trbTop = "" + trbTyp = "" + trbVal = "" + + if match : +# Speed, Horizontal Visibility, aircraft type, and weather group are +# not returned to the legacy script. Flightlevel of -9999 is output +# as such instead of being replaced by "1e37" + myspd = "1e37" + myvis = "-9999998.0" + mycraft = "" + mywx = "" + if geoData.getNumber("flightLevel") == -9999: + myflvl = "-9999" + else : + for pld in layerData: + sep = "" + ltyp = pld.getString("hazardType") + if a2dafcommon.is_no_data(ltyp) : + continue + + fval = pld.getString("skyCover1") + if fval == "None" : + fval = "" + + sval = pld.getString("skyCover2") + if sval == "None" : + sval = "" + if ltyp == "CLOUD" : + if fval == "TOP" : + fval = "" + if sval == "TOP" : + sval = "" + if sval != "" : + fval += "-"+sval + if typecode : + if fval == "CLR" : + fval = "0" + elif fval == "OVC" : + fval = "8" + elif fval == "SCT" : + fval = "11" + elif fval == "BKN" : + fval = "12" + elif fval == "FEW" : + fval = "13" + else : + continue + if cldBas != "" : + sep = "|" + + base = pld.getNumber("skyBaseHeight") + if a2dafcommon.is_no_data(base) or base == 99999 : + base = "1e37" + else : + base = "%.0f"%float(base) + + top = pld.getNumber("skyTopHeight") + if a2dafcommon.is_no_data(top) or top == 99999 : + top = "1e37" + else : + top = "%.0f"%float(top) + + cldBas += sep+base + cldTop += sep+top + cldVal += sep+fval + cc += 1 + elif ltyp == "ICING" : + dtyp = pld.getString("iceType") + if a2dafcommon.is_no_data(dtyp) : + dtyp = "" + + if sval != "" : + fval += "-"+sval + if icgBas != "" : + sep = "|" + if typecode : + if dtyp == "RIME" : + dtyp = "1" + elif dtyp == "CLR" : + dtyp = "2" + elif dtyp == "MXD" : + dtyp = "3" + else : + dtyp = "-9999" + if fval == "NEG" : + fval = "0"; + elif fval == "TRACE" : + fval = "1" + elif fval == "TRACE-LGT" : + fval = "2" + elif fval == "LGT" : + fval = "3" + elif fval == "LGT-MOD" : + fval = "4" + elif fval == "MOD" : + fval = "5" + elif fval == "MOD-SEV" : + fval = "7" + elif fval == "SEV" : + fval = "8" + else : + fval = "-9999" + if fval == "-9999" and dtyp == "-9999" : + continue + + base = pld.getNumber("iceBaseHeight") + if a2dafcommon.is_no_data(base) or base == 99999 : + base = "1e37" + else : + base = "%.0f"%float(base) + + top = pld.getNumber("iceTopHeight") + if a2dafcommon.is_no_data(top) or top == 99999 : + top = "1e37" + else : + top = "%.0f"%float(top) + + icgBas += sep+base + icgTop += sep+top + icgTyp += sep+dtyp + icgVal += sep+fval + ii += 1 + elif ltyp == "TURBC" : + dtyp = pld.getString("turbType") + if a2dafcommon.is_no_data(dtyp) : + dtyp = "" + + if sval != "" : + fval += "-"+sval + if typecode : + if dtyp == "CAT" : + dtyp = "1" + elif dtyp == "CHOP" : + dtyp = "2" + else : + dtyp = "-9999" + if fval == "NEG" : + fval = "0"; + elif fval == "LGT" : + fval = "2" + elif fval == "LGT-MOD" : + fval = "3" + elif fval == "MOD" : + fval = "4" + elif fval == "MOD-SEV" : + fval = "5" + elif fval == "SEV" : + fval = "6" + elif fval == "EXTRM" : + fval = "8" + else : + fval = "-9999" + if fval == "-9999" and dtyp == "-9999" : + continue + if trbBas != "" : + sep = "|" + + base = pld.getNumber("turbBaseHeight") + if a2dafcommon.is_no_data(base) or base == 99999 : + base = "1e37" + else : + base = "%.0f"%float(base) + + top = pld.getNumber("turbTopHeight") + if a2dafcommon.is_no_data(top) or top == 99999 : + top = "1e37" + else : + top = "%.0f"%float(top) + + trbBas += sep+base + trbTop += sep+top + trbTyp += sep+dtyp + trbVal += sep+fval + tt += 1 + + msg += mylat + "|" + mylon + "," + mytime + "," + myflvl + ",PIREP," + \ + mycraft + "," + mytemp + "," + mydir + "," + myspd + "," + \ + myvis + ",-1,-1,-1," + mywx + "," + \ + str(cc) + "," + cldBas + "," + cldTop + "," + cldVal + "," + \ + str(ii) + "," + icgBas + "," + icgTop + "," + \ + icgTyp + "," + icgVal + "," + \ + str(tt) + "," + trbBas + "," + trbTop + "," + \ + trbTyp + "," + trbVal + "\n" + + print msg.strip() + +if __name__ == '__main__': + main() diff --git a/pythonPackages/msaslaps/common/a2dafcommon.py b/pythonPackages/msaslaps/common/a2dafcommon.py new file mode 100644 index 0000000000..ee3a7b0a84 --- /dev/null +++ b/pythonPackages/msaslaps/common/a2dafcommon.py @@ -0,0 +1,43 @@ +## +# This software was developed and / or modified by Raytheon Company, +# pursuant to Contract DG133W-05-CQ-1067 with the US Government. +# +# U.S. EXPORT CONTROLLED TECHNICAL DATA +# This software product contains export-restricted data whose +# export/transfer/disclosure is restricted by U.S. law. Dissemination +# to non-U.S. persons whether in the United States or abroad requires +# an export license or other authorization. +# +# Contractor Name: Raytheon Company +# Contractor Address: 6825 Pine Street, Suite 340 +# Mail Stop B8 +# Omaha, NE 68106 +# 402.291.0100 +# +# See the AWIPS II Master Rights File ("Master Rights File.pdf") for +# further licensing information. +## + + +# +# Common functionality for MSAS/LAPS scripts using the Data Acess Framework. +# +# +# +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# 09/02/2014 3405 nabowle Initial creation. +# +# + +NO_DATA = [None, "None", -9999, -9999.0, "-9999", "-9999.0", ""] + +def is_no_data(val): + return val in NO_DATA + + +def datatime_to_string(datatime): + return str(datatime)[0:19].replace(" ","_")