services module
def get_version_service(request): """get_version_service runs the getVersionService.py service. Inputs: request (ignored) Returns a single line of text, with the version in the form <major_version_int>.<minor_version_int>[.<sub_version_int>] """ rePattern = r'\[[0-9\.]*\]' # create MadrigalDB obj madDBObj = madrigal.metadata.MadrigalDB() # create cmd f = open(os.path.join(madDBObj.getMadroot(), 'source/configure.ac')) lines = f.readlines() f.close() for line in lines: if line.find('AC_INIT') == -1: continue if line.find('Madrigal') == -1: continue result = re.findall(rePattern, line) if len(result) != 1: raise IOError, 'problem parsing MADROOT/source/configure.ac' version = result[0][1:-1] return render_to_response('madweb/service.html', {'text': version}) # should not get here raise IOError, 'problem parsing MADROOT/source/configure.ac' def get_instruments_service(request): """get_instruments_service runs the getInstrumentsService.py service. Inputs: request (ignored) Returns comma-delimited data, one line for each experiment, with the following fields: 1. instrument.name Example: 'Millstone Hill Incoherent Scatter Radar' 2. instrument.code Example: 30 3. instrument.mnemonic (3 char string) Example: 'mlh' 4. instrument.latitude Example: 45.0 5. instrument.longitude Example: 110.0 6. instrument.altitude Example: 0.015 (km) 7. instrument.category Example: 'Incoherent Scatter Radars' 8. contact name 9. contact email """ # create MadrigalDB obj madDBObj = madrigal.metadata.MadrigalDB() # create MadrigalInstument object madInst = madrigal.metadata.MadrigalInstrument(madDBObj) # get instrument list instList = madInst.getInstrumentList() # loop through each instrument instStr = '' for inst in instList: name = inst[0] code = inst[2] mnemonic = inst[1] latitude = madInst.getLatitude(code) if latitude == None: latitude = 0.0 longitude = madInst.getLongitude(code) if longitude == None: longitude = 0.0 altitude = madInst.getAltitude(code) if altitude == None: altitude = 0.0 category = madInst.getCategory(code) if category == None: category = '' # print data contactName = madInst.getContactName(code) contactEmail = madInst.getContactEmail(code) instStr += '%s,%i,%s,%f,%f,%f,%s,%s,%s\n' % (name, code, mnemonic, latitude, longitude, altitude, category, str(contactName), str(contactEmail)) return render_to_response('madweb/service.html', {'text': instStr}) def get_experiments_service(request): """get_experiments_service runs the getExperimentsService.py service. Inputs: request/url - contains arguments: code - one or more kindat values startyear, startmonth, startday, starthour, startmin, startsec endyear, endmonth, endday, endhour, endmin, endsec local (defaults to True) Returns comma-delimited data, one line for each experiment, with the following fields: 1. experiment.id (int) Example: 10000111 2. experiment.url (string) Example: 'http://www.haystack.mit.edu/cgi-bin/madtoc/1997/mlh/03dec97' 3. experiment.name (string) Example: 'Wide Latitude Substorm Study' 4. experiment.siteid (int) Example: 1 5. experiment.sitename (string) Example: 'Millstone Hill Observatory' 6. experiment.instcode (int) Code of instrument. Example: 30 7. experiment.instname (string) Instrument name. Example: 'Millstone Hill Incoherent Scatter Radar' 8. experiment.start year (int) year of experiment start 9. experiment.start month (int) month of experiment start 10. experiment.start day (int) day of experiment start 11. experiment.start hour (int) hour of experiment start 12. experiment.start minute (int) min of experiment start 13. experiment.start second (int) sec of experiment start 14. experiment.end year (int) year of experiment end 15. experiment.end month (int) month of experiment end 16. experiment.end day (int) day of experiment end 17. experiment.end hour (int) hour of experiment end 18. experiment.end minute (int) min of experiment end 19. experiment.end second (int) sec of experiment end 20. experiment.isLocal (int) 1 if local, 0 if not 21.experiment.PI (string) Experiment PI name Example: 'Phil Erickson' 22. experiment.PIEmail (string) Experiment PI email Example: 'perickson@haystack.mit.edu' 23. utc timestamp of last update to experiment 24. security value """ codeList = request.GET.getlist('code') codeList = [int(code) for code in codeList] startyear = int(request.GET['startyear']) startmonth = int(request.GET['startmonth']) startday = int(request.GET['startday']) starthour = int(request.GET['starthour']) startmin = int(request.GET['startmin']) startsec = int(request.GET['startsec']) endyear = int(request.GET['endyear']) endmonth = int(request.GET['endmonth']) endday = int(request.GET['endday']) endhour = int(request.GET['endhour']) endmin = int(request.GET['endmin']) endsec = int(request.GET['endsec']) try: local = int(request.GET['local']) except: local = 1 # if startsec or endsec in (60, 61), handle correctly if startsec in (60, 61): tmpTime = datetime.datetime(startyear, startmonth, startday, starthour, startmin, 59) tmpTime += datetime.timedelta(0, startsec - 59) startyear = tmpTime.year startmonth = tmpTime.month startday = tmpTime.day starthour = tmpTime.hour startmin = tmpTime.minute startsec = tmpTime.second if endsec in (60, 61): tmpTime = datetime.datetime(endyear, endmonth, endday, endhour, endmin, 59) tmpTime += datetime.timedelta(0, endsec - 59) endyear = tmpTime.year endmonth = tmpTime.month endday = tmpTime.day endhour = tmpTime.hour endmin = tmpTime.minute endsec = tmpTime.second # if codeList is empty or contains 0, change it to only contain 0 if len(codeList) == 0 or 0 in codeList: codeList = [0] retStr = '' # create MadrigalDB obj madDBObj = madrigal.metadata.MadrigalDB() # get the local site id localSiteId = madDBObj.getSiteID() # create MadrigalInstrument obj to convert kinst to instrument names madInstObj = madrigal.metadata.MadrigalInstrument(madDBObj) # create MadrigalSite obj to convert site id to site name madSiteObj = madrigal.metadata.MadrigalSite(madDBObj) madWebObj = madrigal.ui.web.MadrigalWeb(madDBObj) trusted = madWebObj.isTrusted() # create starttime for filter, if possible if startyear != None: startTimeFilter = datetime.datetime(startyear, startmonth, startday, starthour, startmin, startsec) else: startTimeFilter = None # create endtime for filter, if possible if endyear != None: endTimeFilter = datetime.datetime(endyear, endmonth, endday, endhour, endmin, endsec) else: endTimeFilter = None # create MadrigalExperiments for local or all files if local == 1: madExpObj = madrigal.metadata.MadrigalExperiment(madDBObj) else: # use file expTabAll.txt to get all experiments filename = madDBObj.getMadroot() if filename[-1] != '/': filename += '/' filename += 'metadata/expTabAll.txt' madExpObj = madrigal.metadata.MadrigalExperiment(madDBObj, filename) # loop through the data position = 0 while 1: thisId = madExpObj.getExpIdByPosition(position) # check for end if thisId == None: break thisUrl = madExpObj.getExpUrlByPosition(position) thisName = madExpObj.getExpNameByPosition(position) thisSiteId = madExpObj.getExpSiteIdByPosition(position) thisSiteName = madSiteObj.getSiteName(thisSiteId) thisInstCode = madExpObj.getKinstByPosition(position) thisInstName =madInstObj.getInstrumentName(thisInstCode) thisStart = madExpObj.getExpStartDateTimeByPosition(position) thisEnd = madExpObj.getExpEndDateTimeByPosition(position) thisSecurity = madExpObj.getSecurityByPosition(position) if thisSiteId == localSiteId: thisLocal = 1 else: thisLocal = 0 thisPI = madExpObj.getPIByPosition(position) if thisPI in (None, ''): thisPI = madInstObj.getContactName(thisInstCode) thisPIEmail = madExpObj.getPIEmailByPosition(position) if thisPIEmail in (None, ''): thisPIEmail = madInstObj.getContactEmail(thisInstCode) expDir = madExpObj.getExpDirByPosition(position) position += 1 # some experiments set the end of the day to 24:00:00 - not # technically correct - reset to 23:59:59 if (thisStart[3] == 24 and thisStart[4] == 0 and thisStart[5] == 0): thisStart[3] = 23 thisStart[4] = 59 thisStart[5] = 59 if (thisEnd[3] == 24 and thisEnd[4] == 0 and thisEnd[5] == 0): thisEnd[3] = 23 thisEnd[4] = 59 thisEnd[5] = 59 # apply filters # first apply instrument code filter if codeList[0] != 0: if thisInstCode not in codeList: continue # apply starttime and endtime filters thisStartTime = datetime.datetime(thisStart[0], thisStart[1], thisStart[2], thisStart[3], thisStart[4], thisStart[5]) thisEndTime = datetime.datetime(thisEnd[0], thisEnd[1], thisEnd[2], thisEnd[3], thisEnd[4], thisEnd[5]) if startTimeFilter != None: if thisEndTime < startTimeFilter: continue if endTimeFilter != None: if thisStartTime > endTimeFilter: continue # apply local filer if local == 1 and thisLocal == 0: continue # apply security filter if trusted == 0 and thisSecurity not in (0,2): continue # create exp timestamp if local == 1: thisUTTimestamp = long(os.stat(expDir).st_mtime + time.timezone) else: thisUTTimestamp = 0 # add this experiment retStr += '%i,%s,%s,%i,%s,%i,%s,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%s,%s,%i,%i\n' % \ (thisId, thisUrl, thisName, thisSiteId, thisSiteName, thisInstCode, thisInstName, thisStart[0], thisStart[1], thisStart[2], thisStart[3], thisStart[4], thisStart[5], thisEnd[0], thisEnd[1], thisEnd[2], thisEnd[3], thisEnd[4], thisEnd[5], thisLocal, str(thisPI), str(thisPIEmail), thisUTTimestamp, thisSecurity) return render_to_response('madweb/service.html', {'text': retStr}) def get_experiment_files_service(request): """get_experiment_files_service runs the getExperimentFilesService.py service. Inputs: request/url - contains arguments: id - local experiment id Returns comma-delimited data, one line for each experiment file, with the following fields: 1. file.name (string) Example '/opt/mdarigal/blah/mlh980120g.001' 2. file.kindat (int) Kindat code. Example: 3001 3. file.kindat desc (string) Kindat description: Example 'Basic Derived Parameters' 4. file.category (int) (1=default, 2=variant, 3=history, 4=real-time) 5. file.status (string)('preliminary', 'final', or any other description) 6. file.permission (int) 0 for public, 1 for private. For now will not return private files. Returns empty string if experiment id not found """ id = int(request.GET['id']) # create MadrigalDB obj madDBObj = madrigal.metadata.MadrigalDB() # create MadrigalExperiments object to get full file name madExpObj = madrigal.metadata.MadrigalExperiment(madDBObj) # create Madrigal Kindat to get Kindat descriptions madKindatObj = madrigal.metadata.MadrigalKindat(madDBObj) # create Madrigal File object madFileObj = madrigal.metadata.MadrigalMetaFile(madDBObj) madWebObj = madrigal.ui.web.MadrigalWeb(madDBObj) trusted = madWebObj.isTrusted() # loop through the experiments to get url position = 0 kinst = None while 1: thisId = madExpObj.getExpIdByPosition(position) # check for end if thisId == None: sys.exit(-1) thisId = int(thisId) # check for right id if thisId == id: thisUrl = madExpObj.getExpUrlByPosition(position) # add end of url to exp path index = thisUrl.find('/madtoc/') expPath = madDBObj.getFullPathFromPartial(thisUrl[index+8:]) kinst = madExpObj.getKinstByPosition(position) break position += 1 # loop though files to find all with right experiment id position = 0 retStr = '' while 1: thisId = madFileObj.getExpIdByPosition(position) if thisId == None: break thisId = int(thisId) if thisId != id: position += 1 continue # get data name = os.path.join(expPath, madFileObj.getFilenameByPosition(position)) kindat = madFileObj.getKindatByPosition(position) kindatdesc = madKindatObj.getKindatDescription(kindat, kinst) category = madFileObj.getCategoryByPosition(position) status = madFileObj.getStatusByPosition(position) permission = madFileObj.getAccessByPosition(position) # skip private files if not trusted if trusted == 0 and int(permission) != 0: position += 1 continue retStr += '%s,%i,%s,%i,%s,%i\n' % \ (name, kindat, kindatdesc, category, status, permission) position += 1 return render_to_response('madweb/service.html', {'text': retStr}) def get_parameters_service(request): """get_parameters_service runs the getParametersService.py service. Inputs: request/url - contains arguments: filename=<full path to data file> Returns backslash-delimited data, one for each parameter either measured or derivable, with the following fields: 1. parameter.mnemonic (string) Example 'dti' 2. parameter.description (string) Example: "F10.7 Multiday average observed (Ott)" 3. parameter.isError (int) 1 if error parameter, 0 if not 4. parameter.units (string) Example "W/m2/Hz" 5. parameter.isMeasured (int) 1 if measured, 0 if derivable 6. parameter.category (string) Example: "Time Related Parameter" 7. parameter.isSure (int) - 1 if parameter can be found for every record, 0 if can only be found for some. Not relevant to Madrigal 3, where always 1 8. parameter.isAddIncrement - 1 if additional increment, 0 if normal (Added in Madrigal 2.5) Not relevant to Madrigal 3, where always -1 """ filename = request.GET['filename'] # create MadrigalDB obj madDBObj = madrigal.metadata.MadrigalDB() # create Madrigal File object madFileObj = madrigal.data.MadrigalFile(filename, madDBObj) # create Madrigal Parameter object madParmObj = madrigal.data.MadrigalParameters(madDBObj) # create Madrigal web object madWebObj = madrigal.ui.web.MadrigalWebFormat() # create lists of parameters measParmList = [] derivedParmList = [] allParmList = [] sureParmList = [] # use the comprehensive list of parameters to check if derivable parmList = madWebObj.getFormat('Comprehensive') # populate lists madFileObj.getMeasDervBothParmLists(parmList, measParmList, derivedParmList, allParmList, sureParmList) retStr = '' # loop through allParmList and output results for parm in allParmList: description = madParmObj.getSimpleParmDescription(parm) isNorm = madParmObj.getParmType(parm) if isNorm == 1: isError = 0 else: isError = 1 units = madParmObj.getParmUnits(parm) if parm in measParmList: isMeasured = 1 else: isMeasured = 0 if parm in sureParmList: isSure = 1 else: isSure = 0 category = madParmObj.getParmCategory(parm) try: if madParmObj.isAddIncrement(parm): isAddIncrement = 1 else: isAddIncrement = 0 except: isAddIncrement = -1 # print out this parm retStr += '%s\%s\%i\%s\%i\%s\%i\%i\n' % (parm, description, isError, units, isMeasured, category, isSure, isAddIncrement) return render_to_response('madweb/service.html', {'text': retStr}) def isprint_service(request): """isprint_service runs the isprintService.py service. Inputs: request/url - contains arguments: 'file': The full path to the file to be analyzed by isprint. 'parms': Multiple requested parameters. 'filters': Multiple of filters desired, as in isprint command 'user_fullname' user name 'user_email' user email 'user_affiliation' user affiliation 'output' - option argument specifying output file basename. Will be Hdf5 format if extension in ('hdf5', 'h5', 'hdf'). Will be netCDF4 is extension is '.nc'. Otherwise ascii. If not given, output is ascii. 'header': t for headers, f for no header. Defaults to no header. Ignored if not ascii output Returns data as either column delimited ascii, Hdf5, or netCDF4. """ madDB = madrigal.metadata.MadrigalDB() madWebObj = madrigal.ui.web.MadrigalWeb(madDB) # get required arguments thisFile = request.GET['file'] parms = request.GET.getlist('parms') filters = request.GET.getlist('filters') user_fullname = request.GET['user_fullname'] user_email = request.GET['user_email'] user_affiliation = request.GET['user_affiliation'] # get optional arguments try: output = os.path.basename(request.GET['output']) filename, file_extension = os.path.splitext(output) if file_extension in ('.hdf5', '.h5', '.hdf'): format = 'Hdf5' elif file_extension in ('.nc',): format = 'netCDF4' else: format = 'ascii' except: format = 'ascii' output = None if not output is None: # we need to write to a download file downloadFile = os.path.join('/tmp', output) try: header = request.GET['header'] if header not in ('t', 'f'): raise ValueError, 'Unknown header value <%s>' % (header) except: header = 'f' # log data access madWebObj.logDataAccess(thisFile, user_fullname, user_email, user_affiliation) # run isprint command cmd = '%s/bin/isprint file=%s ' % (madDB.getMadroot(), thisFile) if not output is None: cmd += 'output=%s ' % (downloadFile) delimiter = ' ' cmd += delimiter.join(parms) + ' ' cmd += delimiter.join(filters) + ' ' if format == 'ascii': cmd += 'summary=f ' cmd += 'header=%s ' % (header) if output is None: # text response result = subprocess.check_output(cmd.split()) if header == 'f': index = result.find('\n') result = result[index+1:] return render_to_response('madweb/service.html', {'text': result}) else: # file download response subprocess.check_call(cmd.split()) f = open(downloadFile, 'r') thisFile = django.core.files.File(f) response = HttpResponse(thisFile, content_type='application/x-octet-stream') response['Content-Disposition'] = 'attachment; filename="' + os.path.basename(downloadFile) + '"' response['Content-Length'] = os.path.getsize(downloadFile) response['Set-Cookie'] = 'fileDownload=true; path=/' os.remove(downloadFile) return(response) def get_madfile_service(request): """get_madfile_service runs the getMadfile.cgi service. Inputs: request/url - contains arguments: 'fileName': The full path to the file to be downloaded as. 'fileType': -1 for ascii, -2 for Hdf5, -3 for netCDF4. No other values supported 'user_fullname' user name 'user_email' user email 'user_affiliation' user affiliation Returns file as either column delimited ascii, Hdf5, or netCDF4. """ madDB = madrigal.metadata.MadrigalDB() madWebObj = madrigal.ui.web.MadrigalWeb(madDB) # get required arguments fileName = request.GET['fileName'] fileType = int(request.GET['fileType']) user_fullname = request.GET['user_fullname'] user_email = request.GET['user_email'] user_affiliation = request.GET['user_affiliation'] if fileType not in (-1, -2, -3): raise ValueError, 'fileType %i not allowed: -1 for ascii, -2 for Hdf5, -3 for netCDF4' % (fileType) # log data access madWebObj.logDataAccess(fileName, user_fullname, user_email, user_affiliation) if fileType in (-1, -3): # need to create temp file filepath, file_extension = os.path.splitext(fileName) basename = os.path.basename(filepath) cedarObj = madrigal.cedar.MadrigalCedarFile(fileName) if fileType == -1: tmpFile = os.path.join('/tmp', basename + '.txt') cedarObj.writeText(tmpFile) else: tmpFile = os.path.join('/tmp', basename + '.nc') cedarObj.write('netCDF4', tmpFile) else: tmpFile = fileName f = open(tmpFile, 'r') thisFile = django.core.files.File(f) response = HttpResponse(thisFile, content_type='application/x-octet-stream') response['Content-Disposition'] = 'attachment; filename="' + os.path.basename(tmpFile) + '"' response['Content-Length'] = os.path.getsize(tmpFile) response['Set-Cookie'] = 'fileDownload=true; path=/' if fileType in (-1, -3): os.remove(tmpFile) return(response) def mad_calculator_service(request): """mad_calculator_service runs the madCalculator service. Inputs: request/url - contains arguments: year, month, day, hour, min, sec startLat - Starting geodetic latitude, -90 to 90 (float) endLat - Ending geodetic latitude, -90 to 90 (float) stepLat - Latitude step (0.1 to 90) (float) startLong - Starting geodetic longitude, -180 to 180 (float) endLong - Ending geodetic longitude, -180 to 180 (float) stepLong - Longitude step (0.1 to 180) (float) startAlt - Starting geodetic altitude, >= 0 (float) endAlt - Ending geodetic altitude, > 0 (float) stepAlt - Altitude step (>= 0.1) (float) parms - comma delimited string of Madrigal parameters desired oneD - zero or more mnemonics,float values to set input 1D values Returns comma-delimited data, one line for each combination of lat, long, and alt, with the following fields: 1. latitude 2. longitude 3. altitude 4. Values for each Madrigal parameter listed in argument parms, separated by whitespace """ year = int(request.GET['year']) month = int(request.GET['month']) day = int(request.GET['day']) hour = int(request.GET['hour']) minute = int(request.GET['min']) second = int(request.GET['sec']) dt = datetime.datetime(year, month, day, hour, minute, second) startLat = float(request.GET['startLat']) endLat = float(request.GET['endLat']) if startLat == endLat: endLat += 0.001 elif startLat > endLat: raise ValueError, 'startLat cannot be greater than endLat' stepLat = float(request.GET['stepLat']) if stepLat < 0.0: raise ValueError, 'stepLat cannot be less than zero' elif stepLat == 0.0: stepLat = 0.001 latList = list(numpy.arange(startLat, endLat, stepLat)) startLong = float(request.GET['startLong']) endLong = float(request.GET['endLong']) if startLong == endLong: endLong += 0.001 elif startLong > endLong: raise ValueError, 'startLong cannot be greater than endLong' stepLong = float(request.GET['stepLong']) if stepLong < 0.0: raise ValueError, 'stepLong cannot be less than zero' elif stepLong == 0.0: stepLong = 0.001 lonList = list(numpy.arange(startLong, endLong, stepLong)) startAlt = float(request.GET['startAlt']) endAlt = float(request.GET['endAlt']) if startAlt == endAlt: endAlt += 0.001 elif startAlt > endAlt: raise ValueError, 'startAlt cannot be greater than endAlt' stepAlt = float(request.GET['stepAlt']) if stepAlt < 0.0: raise ValueError, 'stepAlt cannot be less than zero' elif stepAlt == 0.0: stepAlt = 0.01 altList = list(numpy.arange(startAlt, endAlt, stepAlt)) parms = request.GET['parms'] desiredParmList = [item.encode('ascii', 'ignore').strip() for item in ['gdlat','glon','gdalt'] + parms.split(',')] oneDList = request.GET.getlist('oneD') oneDParmDict = {} for oneDStr in oneDList: mnem, strValue = oneDStr.encode('ascii', 'ignore').split(',') oneDParmDict[mnem] = [float(strValue)] # capture stdout old_stdout = sys.stdout sys.stdout = mystdout = cStringIO.StringIO() madrigal.isprint.MadCalculatorGrid(None, desiredParmList, [dt], latList, lonList, altList, oneDParmDict, summary=None) text = mystdout.getvalue() sys.stdout = old_stdout return render_to_response('madweb/service.html', {'text': text}) def mad_time_calculator_service(request): """mad_time_calculator_service runs the madTimeCalculator service. Input parameters must not be location dependent Inputs: request/url - contains arguments: 1. startyear - int 2. startmonth - int 3. startday - int 4. starthour - int 5. startmin - int 6. startsec - int 7. endyear - int 8. endmonth - int 9. endday - int 10. endhour - int 11. endmin - int 12. endsec - int 13. stephours - float - number of hours per time step 14. parms - comma delimited string of Madrigal parameters desired (must not depend on location) Returns comma-delimited data, one line for each year, month, day, hour, minute, and second, with the following fields: 1-6: year, month, day, hour, minute, and second 2. requested parm fields """ startyear = int(request.GET['startyear']) startmonth = int(request.GET['startmonth']) startday = int(request.GET['startday']) starthour = int(request.GET['starthour']) startminute = int(request.GET['startmin']) startsecond = int(request.GET['startsec']) endyear = int(request.GET['endyear']) endmonth = int(request.GET['endmonth']) endday = int(request.GET['endday']) endhour = int(request.GET['endhour']) endminute = int(request.GET['endmin']) endsecond = int(request.GET['endsec']) dt1 = datetime.datetime(startyear, startmonth, startday, starthour, startminute, startsecond) dt2 = datetime.datetime(endyear, endmonth, endday, endhour, endminute, endsecond) if dt1 > dt2: raise ValueError, 'End Datetime %s cannot be before start datetime %s' % (str(dt2), str(dt1)) stephours = float(request.GET['stephours']) if stephours <= 0.0: raise ValueError, 'stephours cannot be non-positive: %f' % (stephours) dtList = [] while dt1 <= dt2: dtList.append(dt1) dt1 += datetime.timedelta(hours=stephours) parms = request.GET['parms'] desiredParmList = [item.encode('ascii', 'ignore').strip() for item in ['year','month','day','hour','min','sec'] + parms.split(',')] # no spatial data latList = lonList = altList = [] # capture stdout old_stdout = sys.stdout sys.stdout = mystdout = cStringIO.StringIO() madrigal.isprint.MadCalculatorGrid(None, desiredParmList, dtList, latList, lonList, altList, summary=None) text = mystdout.getvalue() sys.stdout = old_stdout return render_to_response('madweb/service.html', {'text': text}) def mad_calculator2_service(request): """mad_calculator2_service runs the madCalculator2 service. Differs from madCalulator in that positions are a list rather than a grid. Inputs: request/url - contains arguments: year, month, day, hour, min, sec lats - comma separated list of latitudes to analyze longs - comma separated list of longitudes to analyze. Len must == len(lats) alts - comma separated list of altitudes to analyze. Len must == len(lats) parms - comma delimited string of Madrigal parameters desired oneD - zero or more mnemonics,float values to set input 1D values Example: &oneD=kinst,31.0&oneD=elm,45.0 twoD - zero or more mnemonics,comma-separate float list of len(lats) to set input 2D values Example: twoD=te,1000,1100,1200 twoD=ti,1000,1000,1000 where there are 3 lats Returns comma-delimited data, one line for each lat value, with the following fields: 1. latitude 2. longitude 3. altitude 4. Values for each Madrigal parameter listed in argument parms, separated by whitespace """ if request.method == 'POST': reqDict = request.POST else: reqDict = request.GET year = int(reqDict.get('year')) month = int(reqDict['month']) day = int(reqDict['day']) hour = int(reqDict['hour']) minute = int(reqDict['min']) second = int(reqDict['sec']) dt = datetime.datetime(year, month, day, hour, minute, second) latsStr = reqDict['lats'] lats = [float(item) for item in latsStr.split(',')] longsStr = reqDict['longs'] longs = [float(item) for item in longsStr.split(',')] altsStr = reqDict['alts'] alts = [float(item) for item in altsStr.split(',')] parms = reqDict['parms'] desiredParmList = [item.encode('ascii', 'ignore').strip() for item in ['gdlat','glon','gdalt'] + parms.split(',')] oneDList = reqDict.getlist('oneD') oneDParmDict = {} for oneDStr in oneDList: mnem, strValue = oneDStr.encode('ascii', 'ignore').split(',') oneDParmDict[mnem] = [float(strValue)] twoDList = reqDict.getlist('twoD') twoDParmDict = {} for twoDStr in twoDList: items = twoDStr.encode('ascii', 'ignore').split(',') if len(items) != 1 + len(lats): raise ValueError, 'twoDstr %s not correct number of points' % (str(twoDStr)) mnem = items[0] floatValues = [float(item) for item in items[1:]] # now we need to expand these values to be two dimensional 1 x len(lats) values = numpy.zeros((1,len(lats)), dtype=numpy.float) values[0][:] = floatValues twoDParmDict[mnem] = values # capture stdout old_stdout = sys.stdout sys.stdout = mystdout = cStringIO.StringIO() madrigal.isprint.MadCalculatorList(None, desiredParmList, [dt], lats, longs, alts, oneDParmDict, twoDParmDict, summary=None) text = mystdout.getvalue() sys.stdout = old_stdout return render_to_response('madweb/service.html', {'text': text}) def mad_calculator3_service(request): """mad_calculator3_service runs the madCalculator3 service. Differs from madCalulator in that multiple times, each with a unique list of positions, can be passed in. Inputs: request/url - contains arguments: year - a comma-separated list of years - (required) month - a comma-separated list of months - (required) day - a comma-separated list of days - (required) hour - a comma-separated list of hours - (required) min - a comma-separated list of minutes - (required) sec - a comma-separated list of seconds - (required) numPos - a comma-sepatated list of the number of positions for each time - (required) lats - a comma-separated list of geodetic latitudes, -90 to 90 (required). Listed for first time, then second, etc. Total must be equal to the sum of numPos. longs - a comma-separated list of longitudes (required) Listed for first time, then second, etc. Total must be equal to the sum of numPos. alts - a comma-separated list of geodetic altitudes in km (required) Listed for first time, then second, etc. Total must be equal to the sum of numPos. parms - comma delimited string of Madrigal parameters desired (required) oneD - string in form <parm>,<comma-separated values> This argument allows the user to set any number of one-D parameters to be used in the calculation. Value must be parameter name, comma, list of values as double, where length of list is equal to number of times. Example: &oneD=kinst,31.0,31.0&oneD=elm,45.0,50 (optional - 0 or more allowed) twoD=<parm>,<values> (optional - 0 or more allowed) This argument allows the user to set any number of two-D parameters to be used in the calculation. Value must be parameter name, comma, comma-separated values. Number of values must equal the sum of numPos. Order is first time values first, then second time values, etc Example: twoD=te,1000,1100,1200,1000,1100,1200 &twoD=ti,1000,1000,1000,1000,1000,1000 where numPos=3,3 Returns comma-delimited data, one line for each location. Separate times are delimited by line TIME MM/DD/YYYY HH:MM:SS Data lines have the following fields: 1. latitude 2. longitude 3. altitude 4. Values for each Madrigal parameter listed in argument parms, separated by whitespace """ if request.method == 'POST': reqDict = request.POST else: reqDict = request.GET yearList = [int(item) for item in reqDict.get('year').split(',')] monthList = [int(item) for item in reqDict.get('month').split(',')] dayList = [int(item) for item in reqDict.get('day').split(',')] hourList = [int(item) for item in reqDict.get('hour').split(',')] minList = [int(item) for item in reqDict.get('min').split(',')] secList = [int(item) for item in reqDict.get('sec').split(',')] dtList = [datetime.datetime(yearList[i], monthList[i], dayList[i], hourList[i], minList[i], secList[i]) for i in range(len(yearList))] numPosStr = reqDict['numPos'] numPosList = [int(item) for item in numPosStr.split(',')] totalPos = 0 for numPos in numPosList: totalPos += numPos latsStr = reqDict['lats'] lats = [float(item) for item in latsStr.split(',')] if len(lats) != totalPos: raise IOError, 'wrong number of lats, expected %i' % (totalPos) longsStr = reqDict['longs'] longs = [float(item) for item in longsStr.split(',')] if len(longs) != totalPos: raise IOError, 'wrong number of longs, expected %i' % (totalPos) altsStr = reqDict['alts'] alts = [float(item) for item in altsStr.split(',')] if len(alts) != totalPos: raise IOError, 'wrong number of alts, expected %i' % (totalPos) parms = reqDict['parms'] desiredParmList = [item.encode('ascii', 'ignore').strip() for item in ['gdlat','glon','gdalt'] + parms.split(',')] oneDList = reqDict.getlist('oneD') twoDList = reqDict.getlist('twoD') # since the positions can change with each call, we need to call madrigal.isprint.MadCalculatorGrid once for each time startIndex = 0 endIndex = 0 fullText = '' for timeIndex, numPos in enumerate(numPosList): startIndex = endIndex endIndex += numPos thisLats = lats[startIndex:endIndex] thisLongs = longs[startIndex:endIndex] thisAlts = alts[startIndex:endIndex] oneDParmDict = {} for oneDStr in oneDList: values = oneDStr.encode('ascii', 'ignore').split(',') if len(values) != 1+len(dtList): raise ValueError, 'wrong number of values given for 1D parm %s' % (values[0]) oneDParmDict[values[0]] = [float(values[timeIndex+1])] twoDParmDict = {} for twoDStr in twoDList: values = twoDStr.encode('ascii', 'ignore').split(',') if len(values) != 1 + totalPos: raise ValueError, 'twoDstr %s not correct number of points' % (str(twoDStr)) mnem = values[0] floatValues = [float(item) for item in values[1+startIndex:1+endIndex]] # now we need to expand these values to be two dimensional - 1,len(thisLats) values2D = numpy.zeros((1,len(thisLats)), dtype=numpy.float) values2D[0][:] = floatValues twoDParmDict[mnem] = values2D # capture stdout old_stdout = sys.stdout sys.stdout = mystdout = cStringIO.StringIO() madrigal.isprint.MadCalculatorList(None, desiredParmList, [dtList[timeIndex]], thisLats, thisLongs, thisAlts, oneDParmDict, twoDParmDict, summary=None) text = mystdout.getvalue() sys.stdout = old_stdout fullText += 'TIME %s\n' % (dtList[timeIndex].strftime('%m/%d/%Y %H:%M:%S')) fullText += text return render_to_response('madweb/service.html', {'text': fullText}) def geodetic_to_radar_service(request): """geodetic_to_radar_service runs the geodeticToRadar service. Inputs: request/url - contains arguments: slatgd - radar geodetic latitude slon - radar longitude saltgd - radar geodetic altitude gdlat - a comma-separated list of geodetic latitude of point glon - a comma-separated list of longitude of point. Len must be same as gdlat gdalt - a comma-separated list of geodetic altitude of point. Len must be same as gdlat Returns comma-delimited data, one line for point in lists (points treated as individual combinations, not grids): 1. radar azimuth in degrees (0 = north) 2. radar elevation in degrees 3. radar range in km """ slatgd = float(request.GET['slatgd']) slon = float(request.GET['slon']) saltgd = float(request.GET['saltgd']) oneDParmDict = {'GDLATR': [slatgd], 'GDLONR': [slon], 'GALTR': [saltgd]} gdlatStr = request.GET['gdlat'] gdlatList = [float(item) for item in gdlatStr.split(',')] glonStr = request.GET['glon'] glonList = [float(item) for item in glonStr.split(',')] gdaltStr = request.GET['gdalt'] gdaltList = [float(item) for item in gdaltStr.split(',')] desiredParmList = ['azm', 'elm', 'range'] dtList = [datetime.datetime(2001,1,1)] # not relevant if len(gdlatList) != len(glonList) or len(gdlatList) != len(gdaltList): raise ValueError, 'all point list lengths must be equal' fullText = '' delimiter = ',' for i in range(len(gdlatList)): # capture stdout old_stdout = sys.stdout sys.stdout = mystdout = cStringIO.StringIO() madrigal.isprint.MadCalculatorGrid(None, desiredParmList, dtList, [gdlatList[i]], [glonList[i]], [gdaltList[i]], summary=None, oneDParmDict=oneDParmDict) text = mystdout.getvalue() sys.stdout = old_stdout for line in text.split('\n'): items = line.split() fullText += delimiter.join(items) + '\n' return render_to_response('madweb/service.html', {'text': fullText}) def radar_to_geodetic_service(request): """radar_to_geodetic_service runs the radarToGeodetic service. Inputs: request/url - contains arguments: slatgd - radar geodetic latitude slon - radar longitude saltgd - radar geodetic altitude azs - a comma-separated list of azimuths of point els - a comma-separated list of elevations of point. Len must be same as azs ranges - a comma-separated list of ranges to point. Len must be same as azs Returns comma-delimited data, one line for point in lists (points treated as individual combinations, not grids): 1. geodetic latitude 2. longitude (-180 to 180) 3. geodetic altitude in km """ slatgd = float(request.GET['slatgd']) slon = float(request.GET['slon']) saltgd = float(request.GET['saltgd']) azStr = request.GET['az'] azList = [float(item) for item in azStr.split(',')] elStr = request.GET['el'] elList = [float(item) for item in elStr.split(',')] rangeStr = request.GET['range'] rangeList = [float(item) for item in rangeStr.split(',')] if len(azList) != len(elList) or len(azList) != len(rangeList): raise ValueError, 'all point list lengths must be equal' fullText = '' for i in range(len(azList)): gdlat,glon,gdalt = madrigal._derive.radarToGeodetic(slatgd, slon, saltgd, azList[i], elList[i], rangeList[i]) fullText += '%f,%f,%f\n' % (gdlat,glon,gdalt) return render_to_response('madweb/service.html', {'text': fullText}) def list_file_times_service(request): """list_file_times_service runs the listFileTimes service. Inputs: request/url - contains arguments: Optional: expDir - experiment directory to list. Can be absolute or relative to experiments[0-9]*. Default is all files in $MADROOT/experiments* Returns comma-delimited data, one for each file: 1. Full path of file 2. File modification time in form YYYY-MM-DD HH:MM:SS (UT time) """ expDir = None try: expDir = request.GET['expDir'] except: pass madDB = madrigal.metadata.MadrigalDB() fileList = madDB.listFileTimes(expDir) fullText = '\n\n' for filename, filetime in fileList: fullText += "\'%s\', %s\n" % (filename, filetime.strftime('%Y-%m-%d %H:%M:%S')) return render_to_response('madweb/service.html', {'text': django.utils.safestring.mark_safe(fullText)}) def trace_magnetic_field_service(request): """trace_magnetic_field_service runs the traceMagneticField service. Inputs: request/url - contains arguments: year, month, day, hour, min, sec inputType (0 for geodetic, 1 for GSM) outputType (0 for geodetic, 1 for GSM) The following parameter depend on inputType: in1 - a comma-separated list of geodetic altitudes or ZGSMs of starting point in2 - a comma-separated list of geodetic latitudes or XGSMs of starting point in3 - a comma-separated list of longitude or YGSM of starting point Length of all three lists must be the same model - 0 for Tsyganenko, 1 for IGRF qualifier - 0 for conjugate, 1 for north_alt, 2 for south_alt, 3 for apex, 4 for GSM XY plane stopAlt - altitude in km to stop trace at, if qualifier is north_alt or south_alt. If other qualifier, this parameter is not required. Returns comma-delimited data, one line for point in in lists: 1. geodetic altitude or ZGSM of ending point 2. geodetic latitude or XGSM of ending point 3. longitude or YGSM of ending point """ year = int(request.GET['year']) month = int(request.GET['month']) day = int(request.GET['day']) hour = int(request.GET['hour']) minute = int(request.GET['min']) second = int(request.GET['sec']) dt = datetime.datetime(year, month, day, hour, minute, second) inputType = int(request.GET['inputType']) if inputType not in (0,1): raise ValueError, 'inputType must be 0 or 1, not %i' % (inputType) outputType = int(request.GET['outputType']) if outputType not in (0,1): raise ValueError, 'outputType must be 0 or 1, not %i' % (outputType) in1Str = request.GET['in1'] in1List = [float(item) for item in in1Str.split(',')] in2Str = request.GET['in2'] in2List = [float(item) for item in in2Str.split(',')] in3Str = request.GET['in3'] in3List = [float(item) for item in in3Str.split(',')] if len(in1List) != len(in2List) or len(in1List) != len(in3List): raise ValueError, 'All three in* lists must have same length' model = int(request.GET['model']) if model not in (0,1): raise ValueError, 'model must be 0 or 1, not %i' % (model) qualifier = int(request.GET['qualifier']) if qualifier not in (0,1,2,3,4): raise ValueError, 'model must be in 0,1,2,3,4 not %i' % (model) try: stopAlt = float(request.GET['stopAlt']) except: stopAlt = 0.0 fullText = '' resultArr = numpy.zeros((3,), dtype='f8') madDB = madrigal.metadata.MadrigalDB() madDeriveObj = madrigal.derivation.MadrigalDerivationMethods(madDB.getMadroot()) for i in range(len(in1List)): madDeriveObj.traceMagneticField(year, month, day, hour, minute, second, inputType, outputType, in1List[i], in2List[i], in3List[i], model, qualifier, stopAlt, resultArr) fullText += '%f,%f,%f\n' % (resultArr[0], resultArr[1], resultArr[2]) return render_to_response('madweb/service.html', {'text': fullText})
Functions
def geodetic_to_radar_service(
request)
geodetic_to_radar_service runs the geodeticToRadar service.
Inputs: request/url - contains arguments:
slatgd - radar geodetic latitude slon - radar longitude saltgd - radar geodetic altitude gdlat - a comma-separated list of geodetic latitude of point glon - a comma-separated list of longitude of point. Len must be same as gdlat gdalt - a comma-separated list of geodetic altitude of point. Len must be same as gdlat
Returns comma-delimited data, one line for point in lists (points treated as individual combinations, not grids):
1. radar azimuth in degrees (0 = north) 2. radar elevation in degrees 3. radar range in km
def geodetic_to_radar_service(request): """geodetic_to_radar_service runs the geodeticToRadar service. Inputs: request/url - contains arguments: slatgd - radar geodetic latitude slon - radar longitude saltgd - radar geodetic altitude gdlat - a comma-separated list of geodetic latitude of point glon - a comma-separated list of longitude of point. Len must be same as gdlat gdalt - a comma-separated list of geodetic altitude of point. Len must be same as gdlat Returns comma-delimited data, one line for point in lists (points treated as individual combinations, not grids): 1. radar azimuth in degrees (0 = north) 2. radar elevation in degrees 3. radar range in km """ slatgd = float(request.GET['slatgd']) slon = float(request.GET['slon']) saltgd = float(request.GET['saltgd']) oneDParmDict = {'GDLATR': [slatgd], 'GDLONR': [slon], 'GALTR': [saltgd]} gdlatStr = request.GET['gdlat'] gdlatList = [float(item) for item in gdlatStr.split(',')] glonStr = request.GET['glon'] glonList = [float(item) for item in glonStr.split(',')] gdaltStr = request.GET['gdalt'] gdaltList = [float(item) for item in gdaltStr.split(',')] desiredParmList = ['azm', 'elm', 'range'] dtList = [datetime.datetime(2001,1,1)] # not relevant if len(gdlatList) != len(glonList) or len(gdlatList) != len(gdaltList): raise ValueError, 'all point list lengths must be equal' fullText = '' delimiter = ',' for i in range(len(gdlatList)): # capture stdout old_stdout = sys.stdout sys.stdout = mystdout = cStringIO.StringIO() madrigal.isprint.MadCalculatorGrid(None, desiredParmList, dtList, [gdlatList[i]], [glonList[i]], [gdaltList[i]], summary=None, oneDParmDict=oneDParmDict) text = mystdout.getvalue() sys.stdout = old_stdout for line in text.split('\n'): items = line.split() fullText += delimiter.join(items) + '\n' return render_to_response('madweb/service.html', {'text': fullText})
def get_experiment_files_service(
request)
get_experiment_files_service runs the getExperimentFilesService.py service.
Inputs: request/url - contains arguments:
id - local experiment id Returns comma-delimited data, one line for each experiment file, with the following fields: 1. file.name (string) Example '/opt/mdarigal/blah/mlh980120g.001' 2. file.kindat (int) Kindat code. Example: 3001 3. file.kindat desc (string) Kindat description: Example 'Basic Derived Parameters' 4. file.category (int) (1=default, 2=variant, 3=history, 4=real-time) 5. file.status (string)('preliminary', 'final', or any other description) 6. file.permission (int) 0 for public, 1 for private. For now will not return private files. Returns empty string if experiment id not found
def get_experiment_files_service(request): """get_experiment_files_service runs the getExperimentFilesService.py service. Inputs: request/url - contains arguments: id - local experiment id Returns comma-delimited data, one line for each experiment file, with the following fields: 1. file.name (string) Example '/opt/mdarigal/blah/mlh980120g.001' 2. file.kindat (int) Kindat code. Example: 3001 3. file.kindat desc (string) Kindat description: Example 'Basic Derived Parameters' 4. file.category (int) (1=default, 2=variant, 3=history, 4=real-time) 5. file.status (string)('preliminary', 'final', or any other description) 6. file.permission (int) 0 for public, 1 for private. For now will not return private files. Returns empty string if experiment id not found """ id = int(request.GET['id']) # create MadrigalDB obj madDBObj = madrigal.metadata.MadrigalDB() # create MadrigalExperiments object to get full file name madExpObj = madrigal.metadata.MadrigalExperiment(madDBObj) # create Madrigal Kindat to get Kindat descriptions madKindatObj = madrigal.metadata.MadrigalKindat(madDBObj) # create Madrigal File object madFileObj = madrigal.metadata.MadrigalMetaFile(madDBObj) madWebObj = madrigal.ui.web.MadrigalWeb(madDBObj) trusted = madWebObj.isTrusted() # loop through the experiments to get url position = 0 kinst = None while 1: thisId = madExpObj.getExpIdByPosition(position) # check for end if thisId == None: sys.exit(-1) thisId = int(thisId) # check for right id if thisId == id: thisUrl = madExpObj.getExpUrlByPosition(position) # add end of url to exp path index = thisUrl.find('/madtoc/') expPath = madDBObj.getFullPathFromPartial(thisUrl[index+8:]) kinst = madExpObj.getKinstByPosition(position) break position += 1 # loop though files to find all with right experiment id position = 0 retStr = '' while 1: thisId = madFileObj.getExpIdByPosition(position) if thisId == None: break thisId = int(thisId) if thisId != id: position += 1 continue # get data name = os.path.join(expPath, madFileObj.getFilenameByPosition(position)) kindat = madFileObj.getKindatByPosition(position) kindatdesc = madKindatObj.getKindatDescription(kindat, kinst) category = madFileObj.getCategoryByPosition(position) status = madFileObj.getStatusByPosition(position) permission = madFileObj.getAccessByPosition(position) # skip private files if not trusted if trusted == 0 and int(permission) != 0: position += 1 continue retStr += '%s,%i,%s,%i,%s,%i\n' % \ (name, kindat, kindatdesc, category, status, permission) position += 1 return render_to_response('madweb/service.html', {'text': retStr})
def get_experiments_service(
request)
get_experiments_service runs the getExperimentsService.py service.
Inputs: request/url - contains arguments:
code - one or more kindat values startyear, startmonth, startday, starthour, startmin, startsec endyear, endmonth, endday, endhour, endmin, endsec local (defaults to True)
Returns comma-delimited data, one line for each experiment, with the following fields:
1. experiment.id (int) Example: 10000111 2. experiment.url (string) Example: 'http://www.haystack.mit.edu/cgi-bin/madtoc/1997/mlh/03dec97' 3. experiment.name (string) Example: 'Wide Latitude Substorm Study' 4. experiment.siteid (int) Example: 1 5. experiment.sitename (string) Example: 'Millstone Hill Observatory' 6. experiment.instcode (int) Code of instrument. Example: 30 7. experiment.instname (string) Instrument name. Example: 'Millstone Hill Incoherent Scatter Radar' 8. experiment.start year (int) year of experiment start 9. experiment.start month (int) month of experiment start 10. experiment.start day (int) day of experiment start 11. experiment.start hour (int) hour of experiment start 12. experiment.start minute (int) min of experiment start 13. experiment.start second (int) sec of experiment start 14. experiment.end year (int) year of experiment end 15. experiment.end month (int) month of experiment end 16. experiment.end day (int) day of experiment end 17. experiment.end hour (int) hour of experiment end 18. experiment.end minute (int) min of experiment end 19. experiment.end second (int) sec of experiment end 20. experiment.isLocal (int) 1 if local, 0 if not 21.experiment.PI (string) Experiment PI name Example: 'Phil Erickson' 22. experiment.PIEmail (string) Experiment PI email Example: 'perickson@haystack.mit.edu' 23. utc timestamp of last update to experiment 24. security value
def get_experiments_service(request): """get_experiments_service runs the getExperimentsService.py service. Inputs: request/url - contains arguments: code - one or more kindat values startyear, startmonth, startday, starthour, startmin, startsec endyear, endmonth, endday, endhour, endmin, endsec local (defaults to True) Returns comma-delimited data, one line for each experiment, with the following fields: 1. experiment.id (int) Example: 10000111 2. experiment.url (string) Example: 'http://www.haystack.mit.edu/cgi-bin/madtoc/1997/mlh/03dec97' 3. experiment.name (string) Example: 'Wide Latitude Substorm Study' 4. experiment.siteid (int) Example: 1 5. experiment.sitename (string) Example: 'Millstone Hill Observatory' 6. experiment.instcode (int) Code of instrument. Example: 30 7. experiment.instname (string) Instrument name. Example: 'Millstone Hill Incoherent Scatter Radar' 8. experiment.start year (int) year of experiment start 9. experiment.start month (int) month of experiment start 10. experiment.start day (int) day of experiment start 11. experiment.start hour (int) hour of experiment start 12. experiment.start minute (int) min of experiment start 13. experiment.start second (int) sec of experiment start 14. experiment.end year (int) year of experiment end 15. experiment.end month (int) month of experiment end 16. experiment.end day (int) day of experiment end 17. experiment.end hour (int) hour of experiment end 18. experiment.end minute (int) min of experiment end 19. experiment.end second (int) sec of experiment end 20. experiment.isLocal (int) 1 if local, 0 if not 21.experiment.PI (string) Experiment PI name Example: 'Phil Erickson' 22. experiment.PIEmail (string) Experiment PI email Example: 'perickson@haystack.mit.edu' 23. utc timestamp of last update to experiment 24. security value """ codeList = request.GET.getlist('code') codeList = [int(code) for code in codeList] startyear = int(request.GET['startyear']) startmonth = int(request.GET['startmonth']) startday = int(request.GET['startday']) starthour = int(request.GET['starthour']) startmin = int(request.GET['startmin']) startsec = int(request.GET['startsec']) endyear = int(request.GET['endyear']) endmonth = int(request.GET['endmonth']) endday = int(request.GET['endday']) endhour = int(request.GET['endhour']) endmin = int(request.GET['endmin']) endsec = int(request.GET['endsec']) try: local = int(request.GET['local']) except: local = 1 # if startsec or endsec in (60, 61), handle correctly if startsec in (60, 61): tmpTime = datetime.datetime(startyear, startmonth, startday, starthour, startmin, 59) tmpTime += datetime.timedelta(0, startsec - 59) startyear = tmpTime.year startmonth = tmpTime.month startday = tmpTime.day starthour = tmpTime.hour startmin = tmpTime.minute startsec = tmpTime.second if endsec in (60, 61): tmpTime = datetime.datetime(endyear, endmonth, endday, endhour, endmin, 59) tmpTime += datetime.timedelta(0, endsec - 59) endyear = tmpTime.year endmonth = tmpTime.month endday = tmpTime.day endhour = tmpTime.hour endmin = tmpTime.minute endsec = tmpTime.second # if codeList is empty or contains 0, change it to only contain 0 if len(codeList) == 0 or 0 in codeList: codeList = [0] retStr = '' # create MadrigalDB obj madDBObj = madrigal.metadata.MadrigalDB() # get the local site id localSiteId = madDBObj.getSiteID() # create MadrigalInstrument obj to convert kinst to instrument names madInstObj = madrigal.metadata.MadrigalInstrument(madDBObj) # create MadrigalSite obj to convert site id to site name madSiteObj = madrigal.metadata.MadrigalSite(madDBObj) madWebObj = madrigal.ui.web.MadrigalWeb(madDBObj) trusted = madWebObj.isTrusted() # create starttime for filter, if possible if startyear != None: startTimeFilter = datetime.datetime(startyear, startmonth, startday, starthour, startmin, startsec) else: startTimeFilter = None # create endtime for filter, if possible if endyear != None: endTimeFilter = datetime.datetime(endyear, endmonth, endday, endhour, endmin, endsec) else: endTimeFilter = None # create MadrigalExperiments for local or all files if local == 1: madExpObj = madrigal.metadata.MadrigalExperiment(madDBObj) else: # use file expTabAll.txt to get all experiments filename = madDBObj.getMadroot() if filename[-1] != '/': filename += '/' filename += 'metadata/expTabAll.txt' madExpObj = madrigal.metadata.MadrigalExperiment(madDBObj, filename) # loop through the data position = 0 while 1: thisId = madExpObj.getExpIdByPosition(position) # check for end if thisId == None: break thisUrl = madExpObj.getExpUrlByPosition(position) thisName = madExpObj.getExpNameByPosition(position) thisSiteId = madExpObj.getExpSiteIdByPosition(position) thisSiteName = madSiteObj.getSiteName(thisSiteId) thisInstCode = madExpObj.getKinstByPosition(position) thisInstName =madInstObj.getInstrumentName(thisInstCode) thisStart = madExpObj.getExpStartDateTimeByPosition(position) thisEnd = madExpObj.getExpEndDateTimeByPosition(position) thisSecurity = madExpObj.getSecurityByPosition(position) if thisSiteId == localSiteId: thisLocal = 1 else: thisLocal = 0 thisPI = madExpObj.getPIByPosition(position) if thisPI in (None, ''): thisPI = madInstObj.getContactName(thisInstCode) thisPIEmail = madExpObj.getPIEmailByPosition(position) if thisPIEmail in (None, ''): thisPIEmail = madInstObj.getContactEmail(thisInstCode) expDir = madExpObj.getExpDirByPosition(position) position += 1 # some experiments set the end of the day to 24:00:00 - not # technically correct - reset to 23:59:59 if (thisStart[3] == 24 and thisStart[4] == 0 and thisStart[5] == 0): thisStart[3] = 23 thisStart[4] = 59 thisStart[5] = 59 if (thisEnd[3] == 24 and thisEnd[4] == 0 and thisEnd[5] == 0): thisEnd[3] = 23 thisEnd[4] = 59 thisEnd[5] = 59 # apply filters # first apply instrument code filter if codeList[0] != 0: if thisInstCode not in codeList: continue # apply starttime and endtime filters thisStartTime = datetime.datetime(thisStart[0], thisStart[1], thisStart[2], thisStart[3], thisStart[4], thisStart[5]) thisEndTime = datetime.datetime(thisEnd[0], thisEnd[1], thisEnd[2], thisEnd[3], thisEnd[4], thisEnd[5]) if startTimeFilter != None: if thisEndTime < startTimeFilter: continue if endTimeFilter != None: if thisStartTime > endTimeFilter: continue # apply local filer if local == 1 and thisLocal == 0: continue # apply security filter if trusted == 0 and thisSecurity not in (0,2): continue # create exp timestamp if local == 1: thisUTTimestamp = long(os.stat(expDir).st_mtime + time.timezone) else: thisUTTimestamp = 0 # add this experiment retStr += '%i,%s,%s,%i,%s,%i,%s,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%s,%s,%i,%i\n' % \ (thisId, thisUrl, thisName, thisSiteId, thisSiteName, thisInstCode, thisInstName, thisStart[0], thisStart[1], thisStart[2], thisStart[3], thisStart[4], thisStart[5], thisEnd[0], thisEnd[1], thisEnd[2], thisEnd[3], thisEnd[4], thisEnd[5], thisLocal, str(thisPI), str(thisPIEmail), thisUTTimestamp, thisSecurity) return render_to_response('madweb/service.html', {'text': retStr})
def get_instruments_service(
request)
get_instruments_service runs the getInstrumentsService.py service.
Inputs: request (ignored)
Returns comma-delimited data, one line for each experiment, with the following fields: 1. instrument.name Example: 'Millstone Hill Incoherent Scatter Radar' 2. instrument.code Example: 30 3. instrument.mnemonic (3 char string) Example: 'mlh' 4. instrument.latitude Example: 45.0 5. instrument.longitude Example: 110.0 6. instrument.altitude Example: 0.015 (km) 7. instrument.category Example: 'Incoherent Scatter Radars' 8. contact name 9. contact email
def get_instruments_service(request): """get_instruments_service runs the getInstrumentsService.py service. Inputs: request (ignored) Returns comma-delimited data, one line for each experiment, with the following fields: 1. instrument.name Example: 'Millstone Hill Incoherent Scatter Radar' 2. instrument.code Example: 30 3. instrument.mnemonic (3 char string) Example: 'mlh' 4. instrument.latitude Example: 45.0 5. instrument.longitude Example: 110.0 6. instrument.altitude Example: 0.015 (km) 7. instrument.category Example: 'Incoherent Scatter Radars' 8. contact name 9. contact email """ # create MadrigalDB obj madDBObj = madrigal.metadata.MadrigalDB() # create MadrigalInstument object madInst = madrigal.metadata.MadrigalInstrument(madDBObj) # get instrument list instList = madInst.getInstrumentList() # loop through each instrument instStr = '' for inst in instList: name = inst[0] code = inst[2] mnemonic = inst[1] latitude = madInst.getLatitude(code) if latitude == None: latitude = 0.0 longitude = madInst.getLongitude(code) if longitude == None: longitude = 0.0 altitude = madInst.getAltitude(code) if altitude == None: altitude = 0.0 category = madInst.getCategory(code) if category == None: category = '' # print data contactName = madInst.getContactName(code) contactEmail = madInst.getContactEmail(code) instStr += '%s,%i,%s,%f,%f,%f,%s,%s,%s\n' % (name, code, mnemonic, latitude, longitude, altitude, category, str(contactName), str(contactEmail)) return render_to_response('madweb/service.html', {'text': instStr})
def get_madfile_service(
request)
get_madfile_service runs the getMadfile.cgi service.
Inputs: request/url - contains arguments:
'fileName': The full path to the file to be downloaded as. 'fileType': -1 for ascii, -2 for Hdf5, -3 for netCDF4. No other values supported 'user_fullname' user name 'user_email' user email 'user_affiliation' user affiliation
Returns file as either column delimited ascii, Hdf5, or netCDF4.
def get_madfile_service(request): """get_madfile_service runs the getMadfile.cgi service. Inputs: request/url - contains arguments: 'fileName': The full path to the file to be downloaded as. 'fileType': -1 for ascii, -2 for Hdf5, -3 for netCDF4. No other values supported 'user_fullname' user name 'user_email' user email 'user_affiliation' user affiliation Returns file as either column delimited ascii, Hdf5, or netCDF4. """ madDB = madrigal.metadata.MadrigalDB() madWebObj = madrigal.ui.web.MadrigalWeb(madDB) # get required arguments fileName = request.GET['fileName'] fileType = int(request.GET['fileType']) user_fullname = request.GET['user_fullname'] user_email = request.GET['user_email'] user_affiliation = request.GET['user_affiliation'] if fileType not in (-1, -2, -3): raise ValueError, 'fileType %i not allowed: -1 for ascii, -2 for Hdf5, -3 for netCDF4' % (fileType) # log data access madWebObj.logDataAccess(fileName, user_fullname, user_email, user_affiliation) if fileType in (-1, -3): # need to create temp file filepath, file_extension = os.path.splitext(fileName) basename = os.path.basename(filepath) cedarObj = madrigal.cedar.MadrigalCedarFile(fileName) if fileType == -1: tmpFile = os.path.join('/tmp', basename + '.txt') cedarObj.writeText(tmpFile) else: tmpFile = os.path.join('/tmp', basename + '.nc') cedarObj.write('netCDF4', tmpFile) else: tmpFile = fileName f = open(tmpFile, 'r') thisFile = django.core.files.File(f) response = HttpResponse(thisFile, content_type='application/x-octet-stream') response['Content-Disposition'] = 'attachment; filename="' + os.path.basename(tmpFile) + '"' response['Content-Length'] = os.path.getsize(tmpFile) response['Set-Cookie'] = 'fileDownload=true; path=/' if fileType in (-1, -3): os.remove(tmpFile) return(response)
def get_parameters_service(
request)
get_parameters_service runs the getParametersService.py service.
Inputs: request/url - contains arguments:
filename=<full path to data file> Returns backslash-delimited data, one for each parameter either measured or derivable, with the following fields: 1. parameter.mnemonic (string) Example 'dti' 2. parameter.description (string) Example: "F10.7 Multiday average observed (Ott)" 3. parameter.isError (int) 1 if error parameter, 0 if not 4. parameter.units (string) Example "W/m2/Hz" 5. parameter.isMeasured (int) 1 if measured, 0 if derivable 6. parameter.category (string) Example: "Time Related Parameter" 7. parameter.isSure (int) - 1 if parameter can be found for every record, 0 if can only be found for some. Not relevant to Madrigal 3, where always 1 8. parameter.isAddIncrement - 1 if additional increment, 0 if normal (Added in Madrigal 2.5) Not relevant to Madrigal 3, where always -1
def get_parameters_service(request): """get_parameters_service runs the getParametersService.py service. Inputs: request/url - contains arguments: filename=<full path to data file> Returns backslash-delimited data, one for each parameter either measured or derivable, with the following fields: 1. parameter.mnemonic (string) Example 'dti' 2. parameter.description (string) Example: "F10.7 Multiday average observed (Ott)" 3. parameter.isError (int) 1 if error parameter, 0 if not 4. parameter.units (string) Example "W/m2/Hz" 5. parameter.isMeasured (int) 1 if measured, 0 if derivable 6. parameter.category (string) Example: "Time Related Parameter" 7. parameter.isSure (int) - 1 if parameter can be found for every record, 0 if can only be found for some. Not relevant to Madrigal 3, where always 1 8. parameter.isAddIncrement - 1 if additional increment, 0 if normal (Added in Madrigal 2.5) Not relevant to Madrigal 3, where always -1 """ filename = request.GET['filename'] # create MadrigalDB obj madDBObj = madrigal.metadata.MadrigalDB() # create Madrigal File object madFileObj = madrigal.data.MadrigalFile(filename, madDBObj) # create Madrigal Parameter object madParmObj = madrigal.data.MadrigalParameters(madDBObj) # create Madrigal web object madWebObj = madrigal.ui.web.MadrigalWebFormat() # create lists of parameters measParmList = [] derivedParmList = [] allParmList = [] sureParmList = [] # use the comprehensive list of parameters to check if derivable parmList = madWebObj.getFormat('Comprehensive') # populate lists madFileObj.getMeasDervBothParmLists(parmList, measParmList, derivedParmList, allParmList, sureParmList) retStr = '' # loop through allParmList and output results for parm in allParmList: description = madParmObj.getSimpleParmDescription(parm) isNorm = madParmObj.getParmType(parm) if isNorm == 1: isError = 0 else: isError = 1 units = madParmObj.getParmUnits(parm) if parm in measParmList: isMeasured = 1 else: isMeasured = 0 if parm in sureParmList: isSure = 1 else: isSure = 0 category = madParmObj.getParmCategory(parm) try: if madParmObj.isAddIncrement(parm): isAddIncrement = 1 else: isAddIncrement = 0 except: isAddIncrement = -1 # print out this parm retStr += '%s\%s\%i\%s\%i\%s\%i\%i\n' % (parm, description, isError, units, isMeasured, category, isSure, isAddIncrement) return render_to_response('madweb/service.html', {'text': retStr})
def get_version_service(
request)
get_version_service runs the getVersionService.py service.
Inputs: request (ignored)
Returns a single line of text, with the version in the form <major_version_int>.<minor_version_int>[.<sub_version_int>]
def get_version_service(request): """get_version_service runs the getVersionService.py service. Inputs: request (ignored) Returns a single line of text, with the version in the form <major_version_int>.<minor_version_int>[.<sub_version_int>] """ rePattern = r'\[[0-9\.]*\]' # create MadrigalDB obj madDBObj = madrigal.metadata.MadrigalDB() # create cmd f = open(os.path.join(madDBObj.getMadroot(), 'source/configure.ac')) lines = f.readlines() f.close() for line in lines: if line.find('AC_INIT') == -1: continue if line.find('Madrigal') == -1: continue result = re.findall(rePattern, line) if len(result) != 1: raise IOError, 'problem parsing MADROOT/source/configure.ac' version = result[0][1:-1] return render_to_response('madweb/service.html', {'text': version}) # should not get here raise IOError, 'problem parsing MADROOT/source/configure.ac'
def isprint_service(
request)
isprint_service runs the isprintService.py service.
Inputs: request/url - contains arguments:
'file': The full path to the file to be analyzed by isprint. 'parms': Multiple requested parameters. 'filters': Multiple of filters desired, as in isprint command 'user_fullname' user name 'user_email' user email 'user_affiliation' user affiliation 'output' - option argument specifying output file basename. Will be Hdf5 format if extension in ('hdf5', 'h5', 'hdf'). Will be netCDF4 is extension is '.nc'. Otherwise ascii. If not given, output is ascii. 'header': t for headers, f for no header. Defaults to no header. Ignored if not ascii output
Returns data as either column delimited ascii, Hdf5, or netCDF4.
def isprint_service(request): """isprint_service runs the isprintService.py service. Inputs: request/url - contains arguments: 'file': The full path to the file to be analyzed by isprint. 'parms': Multiple requested parameters. 'filters': Multiple of filters desired, as in isprint command 'user_fullname' user name 'user_email' user email 'user_affiliation' user affiliation 'output' - option argument specifying output file basename. Will be Hdf5 format if extension in ('hdf5', 'h5', 'hdf'). Will be netCDF4 is extension is '.nc'. Otherwise ascii. If not given, output is ascii. 'header': t for headers, f for no header. Defaults to no header. Ignored if not ascii output Returns data as either column delimited ascii, Hdf5, or netCDF4. """ madDB = madrigal.metadata.MadrigalDB() madWebObj = madrigal.ui.web.MadrigalWeb(madDB) # get required arguments thisFile = request.GET['file'] parms = request.GET.getlist('parms') filters = request.GET.getlist('filters') user_fullname = request.GET['user_fullname'] user_email = request.GET['user_email'] user_affiliation = request.GET['user_affiliation'] # get optional arguments try: output = os.path.basename(request.GET['output']) filename, file_extension = os.path.splitext(output) if file_extension in ('.hdf5', '.h5', '.hdf'): format = 'Hdf5' elif file_extension in ('.nc',): format = 'netCDF4' else: format = 'ascii' except: format = 'ascii' output = None if not output is None: # we need to write to a download file downloadFile = os.path.join('/tmp', output) try: header = request.GET['header'] if header not in ('t', 'f'): raise ValueError, 'Unknown header value <%s>' % (header) except: header = 'f' # log data access madWebObj.logDataAccess(thisFile, user_fullname, user_email, user_affiliation) # run isprint command cmd = '%s/bin/isprint file=%s ' % (madDB.getMadroot(), thisFile) if not output is None: cmd += 'output=%s ' % (downloadFile) delimiter = ' ' cmd += delimiter.join(parms) + ' ' cmd += delimiter.join(filters) + ' ' if format == 'ascii': cmd += 'summary=f ' cmd += 'header=%s ' % (header) if output is None: # text response result = subprocess.check_output(cmd.split()) if header == 'f': index = result.find('\n') result = result[index+1:] return render_to_response('madweb/service.html', {'text': result}) else: # file download response subprocess.check_call(cmd.split()) f = open(downloadFile, 'r') thisFile = django.core.files.File(f) response = HttpResponse(thisFile, content_type='application/x-octet-stream') response['Content-Disposition'] = 'attachment; filename="' + os.path.basename(downloadFile) + '"' response['Content-Length'] = os.path.getsize(downloadFile) response['Set-Cookie'] = 'fileDownload=true; path=/' os.remove(downloadFile) return(response)
def list_file_times_service(
request)
list_file_times_service runs the listFileTimes service.
Inputs: request/url - contains arguments:
Optional: expDir - experiment directory to list. Can be absolute or relative to experiments[0-9]*. Default is all files in $MADROOT/experiments*
Returns comma-delimited data, one for each file:
1. Full path of file 2. File modification time in form YYYY-MM-DD HH:MM:SS (UT time)
def list_file_times_service(request): """list_file_times_service runs the listFileTimes service. Inputs: request/url - contains arguments: Optional: expDir - experiment directory to list. Can be absolute or relative to experiments[0-9]*. Default is all files in $MADROOT/experiments* Returns comma-delimited data, one for each file: 1. Full path of file 2. File modification time in form YYYY-MM-DD HH:MM:SS (UT time) """ expDir = None try: expDir = request.GET['expDir'] except: pass madDB = madrigal.metadata.MadrigalDB() fileList = madDB.listFileTimes(expDir) fullText = '\n\n' for filename, filetime in fileList: fullText += "\'%s\', %s\n" % (filename, filetime.strftime('%Y-%m-%d %H:%M:%S')) return render_to_response('madweb/service.html', {'text': django.utils.safestring.mark_safe(fullText)})
def mad_calculator2_service(
request)
mad_calculator2_service runs the madCalculator2 service.
Differs from madCalulator in that positions are a list rather than a grid.
Inputs: request/url - contains arguments:
year, month, day, hour, min, sec lats - comma separated list of latitudes to analyze longs - comma separated list of longitudes to analyze. Len must == len(lats) alts - comma separated list of altitudes to analyze. Len must == len(lats) parms - comma delimited string of Madrigal parameters desired oneD - zero or more mnemonics,float values to set input 1D values Example: &oneD=kinst,31.0&oneD=elm,45.0 twoD - zero or more mnemonics,comma-separate float list of len(lats) to set input 2D values Example: twoD=te,1000,1100,1200 twoD=ti,1000,1000,1000 where there are 3 lats
Returns comma-delimited data, one line for each lat value, with the following fields:
1. latitude 2. longitude 3. altitude 4. Values for each Madrigal parameter listed in argument parms, separated by whitespace
def mad_calculator2_service(request): """mad_calculator2_service runs the madCalculator2 service. Differs from madCalulator in that positions are a list rather than a grid. Inputs: request/url - contains arguments: year, month, day, hour, min, sec lats - comma separated list of latitudes to analyze longs - comma separated list of longitudes to analyze. Len must == len(lats) alts - comma separated list of altitudes to analyze. Len must == len(lats) parms - comma delimited string of Madrigal parameters desired oneD - zero or more mnemonics,float values to set input 1D values Example: &oneD=kinst,31.0&oneD=elm,45.0 twoD - zero or more mnemonics,comma-separate float list of len(lats) to set input 2D values Example: twoD=te,1000,1100,1200 twoD=ti,1000,1000,1000 where there are 3 lats Returns comma-delimited data, one line for each lat value, with the following fields: 1. latitude 2. longitude 3. altitude 4. Values for each Madrigal parameter listed in argument parms, separated by whitespace """ if request.method == 'POST': reqDict = request.POST else: reqDict = request.GET year = int(reqDict.get('year')) month = int(reqDict['month']) day = int(reqDict['day']) hour = int(reqDict['hour']) minute = int(reqDict['min']) second = int(reqDict['sec']) dt = datetime.datetime(year, month, day, hour, minute, second) latsStr = reqDict['lats'] lats = [float(item) for item in latsStr.split(',')] longsStr = reqDict['longs'] longs = [float(item) for item in longsStr.split(',')] altsStr = reqDict['alts'] alts = [float(item) for item in altsStr.split(',')] parms = reqDict['parms'] desiredParmList = [item.encode('ascii', 'ignore').strip() for item in ['gdlat','glon','gdalt'] + parms.split(',')] oneDList = reqDict.getlist('oneD') oneDParmDict = {} for oneDStr in oneDList: mnem, strValue = oneDStr.encode('ascii', 'ignore').split(',') oneDParmDict[mnem] = [float(strValue)] twoDList = reqDict.getlist('twoD') twoDParmDict = {} for twoDStr in twoDList: items = twoDStr.encode('ascii', 'ignore').split(',') if len(items) != 1 + len(lats): raise ValueError, 'twoDstr %s not correct number of points' % (str(twoDStr)) mnem = items[0] floatValues = [float(item) for item in items[1:]] # now we need to expand these values to be two dimensional 1 x len(lats) values = numpy.zeros((1,len(lats)), dtype=numpy.float) values[0][:] = floatValues twoDParmDict[mnem] = values # capture stdout old_stdout = sys.stdout sys.stdout = mystdout = cStringIO.StringIO() madrigal.isprint.MadCalculatorList(None, desiredParmList, [dt], lats, longs, alts, oneDParmDict, twoDParmDict, summary=None) text = mystdout.getvalue() sys.stdout = old_stdout return render_to_response('madweb/service.html', {'text': text})
def mad_calculator3_service(
request)
mad_calculator3_service runs the madCalculator3 service.
Differs from madCalulator in that multiple times, each with a unique list of positions, can be passed in.
Inputs: request/url - contains arguments:
year - a comma-separated list of years - (required) month - a comma-separated list of months - (required) day - a comma-separated list of days - (required) hour - a comma-separated list of hours - (required) min - a comma-separated list of minutes - (required) sec - a comma-separated list of seconds - (required) numPos - a comma-sepatated list of the number of positions for each time - (required) lats - a comma-separated list of geodetic latitudes, -90 to 90 (required). Listed for first time, then second, etc. Total must be equal to the sum of numPos. longs - a comma-separated list of longitudes (required) Listed for first time, then second, etc. Total must be equal to the sum of numPos. alts - a comma-separated list of geodetic altitudes in km (required) Listed for first time, then second, etc. Total must be equal to the sum of numPos. parms - comma delimited string of Madrigal parameters desired (required) oneD - string in form <parm>,<comma-separated values> This argument allows the user to set any number of one-D parameters to be used in the calculation. Value must be parameter name, comma, list of values as double, where length of list is equal to number of times. Example: &oneD=kinst,31.0,31.0&oneD=elm,45.0,50 (optional - 0 or more allowed) twoD=<parm>,<values> (optional - 0 or more allowed) This argument allows the user to set any number of two-D parameters to be used in the calculation. Value must be parameter name, comma, comma-separated values. Number of values must equal the sum of numPos. Order is first time values first, then second time values, etc Example: twoD=te,1000,1100,1200,1000,1100,1200 &twoD=ti,1000,1000,1000,1000,1000,1000 where numPos=3,3
Returns comma-delimited data, one line for each location. Separate times are delimited by line
TIME MM/DD/YYYY HH:MM:SS
Data lines have the following fields:
-
latitude
-
longitude
-
altitude
-
Values for each Madrigal parameter listed in argument parms, separated by whitespace
def mad_calculator3_service(request): """mad_calculator3_service runs the madCalculator3 service. Differs from madCalulator in that multiple times, each with a unique list of positions, can be passed in. Inputs: request/url - contains arguments: year - a comma-separated list of years - (required) month - a comma-separated list of months - (required) day - a comma-separated list of days - (required) hour - a comma-separated list of hours - (required) min - a comma-separated list of minutes - (required) sec - a comma-separated list of seconds - (required) numPos - a comma-sepatated list of the number of positions for each time - (required) lats - a comma-separated list of geodetic latitudes, -90 to 90 (required). Listed for first time, then second, etc. Total must be equal to the sum of numPos. longs - a comma-separated list of longitudes (required) Listed for first time, then second, etc. Total must be equal to the sum of numPos. alts - a comma-separated list of geodetic altitudes in km (required) Listed for first time, then second, etc. Total must be equal to the sum of numPos. parms - comma delimited string of Madrigal parameters desired (required) oneD - string in form <parm>,<comma-separated values> This argument allows the user to set any number of one-D parameters to be used in the calculation. Value must be parameter name, comma, list of values as double, where length of list is equal to number of times. Example: &oneD=kinst,31.0,31.0&oneD=elm,45.0,50 (optional - 0 or more allowed) twoD=<parm>,<values> (optional - 0 or more allowed) This argument allows the user to set any number of two-D parameters to be used in the calculation. Value must be parameter name, comma, comma-separated values. Number of values must equal the sum of numPos. Order is first time values first, then second time values, etc Example: twoD=te,1000,1100,1200,1000,1100,1200 &twoD=ti,1000,1000,1000,1000,1000,1000 where numPos=3,3 Returns comma-delimited data, one line for each location. Separate times are delimited by line TIME MM/DD/YYYY HH:MM:SS Data lines have the following fields: 1. latitude 2. longitude 3. altitude 4. Values for each Madrigal parameter listed in argument parms, separated by whitespace """ if request.method == 'POST': reqDict = request.POST else: reqDict = request.GET yearList = [int(item) for item in reqDict.get('year').split(',')] monthList = [int(item) for item in reqDict.get('month').split(',')] dayList = [int(item) for item in reqDict.get('day').split(',')] hourList = [int(item) for item in reqDict.get('hour').split(',')] minList = [int(item) for item in reqDict.get('min').split(',')] secList = [int(item) for item in reqDict.get('sec').split(',')] dtList = [datetime.datetime(yearList[i], monthList[i], dayList[i], hourList[i], minList[i], secList[i]) for i in range(len(yearList))] numPosStr = reqDict['numPos'] numPosList = [int(item) for item in numPosStr.split(',')] totalPos = 0 for numPos in numPosList: totalPos += numPos latsStr = reqDict['lats'] lats = [float(item) for item in latsStr.split(',')] if len(lats) != totalPos: raise IOError, 'wrong number of lats, expected %i' % (totalPos) longsStr = reqDict['longs'] longs = [float(item) for item in longsStr.split(',')] if len(longs) != totalPos: raise IOError, 'wrong number of longs, expected %i' % (totalPos) altsStr = reqDict['alts'] alts = [float(item) for item in altsStr.split(',')] if len(alts) != totalPos: raise IOError, 'wrong number of alts, expected %i' % (totalPos) parms = reqDict['parms'] desiredParmList = [item.encode('ascii', 'ignore').strip() for item in ['gdlat','glon','gdalt'] + parms.split(',')] oneDList = reqDict.getlist('oneD') twoDList = reqDict.getlist('twoD') # since the positions can change with each call, we need to call madrigal.isprint.MadCalculatorGrid once for each time startIndex = 0 endIndex = 0 fullText = '' for timeIndex, numPos in enumerate(numPosList): startIndex = endIndex endIndex += numPos thisLats = lats[startIndex:endIndex] thisLongs = longs[startIndex:endIndex] thisAlts = alts[startIndex:endIndex] oneDParmDict = {} for oneDStr in oneDList: values = oneDStr.encode('ascii', 'ignore').split(',') if len(values) != 1+len(dtList): raise ValueError, 'wrong number of values given for 1D parm %s' % (values[0]) oneDParmDict[values[0]] = [float(values[timeIndex+1])] twoDParmDict = {} for twoDStr in twoDList: values = twoDStr.encode('ascii', 'ignore').split(',') if len(values) != 1 + totalPos: raise ValueError, 'twoDstr %s not correct number of points' % (str(twoDStr)) mnem = values[0] floatValues = [float(item) for item in values[1+startIndex:1+endIndex]] # now we need to expand these values to be two dimensional - 1,len(thisLats) values2D = numpy.zeros((1,len(thisLats)), dtype=numpy.float) values2D[0][:] = floatValues twoDParmDict[mnem] = values2D # capture stdout old_stdout = sys.stdout sys.stdout = mystdout = cStringIO.StringIO() madrigal.isprint.MadCalculatorList(None, desiredParmList, [dtList[timeIndex]], thisLats, thisLongs, thisAlts, oneDParmDict, twoDParmDict, summary=None) text = mystdout.getvalue() sys.stdout = old_stdout fullText += 'TIME %s\n' % (dtList[timeIndex].strftime('%m/%d/%Y %H:%M:%S')) fullText += text return render_to_response('madweb/service.html', {'text': fullText})
def mad_calculator_service(
request)
mad_calculator_service runs the madCalculator service.
Inputs: request/url - contains arguments:
year, month, day, hour, min, sec startLat - Starting geodetic latitude, -90 to 90 (float) endLat - Ending geodetic latitude, -90 to 90 (float) stepLat - Latitude step (0.1 to 90) (float) startLong - Starting geodetic longitude, -180 to 180 (float) endLong - Ending geodetic longitude, -180 to 180 (float) stepLong - Longitude step (0.1 to 180) (float) startAlt - Starting geodetic altitude, >= 0 (float) endAlt - Ending geodetic altitude, > 0 (float) stepAlt - Altitude step (>= 0.1) (float) parms - comma delimited string of Madrigal parameters desired oneD - zero or more mnemonics,float values to set input 1D values
Returns comma-delimited data, one line for each combination of lat, long, and alt, with the following fields:
1. latitude 2. longitude 3. altitude 4. Values for each Madrigal parameter listed in argument parms, separated by whitespace
def mad_calculator_service(request): """mad_calculator_service runs the madCalculator service. Inputs: request/url - contains arguments: year, month, day, hour, min, sec startLat - Starting geodetic latitude, -90 to 90 (float) endLat - Ending geodetic latitude, -90 to 90 (float) stepLat - Latitude step (0.1 to 90) (float) startLong - Starting geodetic longitude, -180 to 180 (float) endLong - Ending geodetic longitude, -180 to 180 (float) stepLong - Longitude step (0.1 to 180) (float) startAlt - Starting geodetic altitude, >= 0 (float) endAlt - Ending geodetic altitude, > 0 (float) stepAlt - Altitude step (>= 0.1) (float) parms - comma delimited string of Madrigal parameters desired oneD - zero or more mnemonics,float values to set input 1D values Returns comma-delimited data, one line for each combination of lat, long, and alt, with the following fields: 1. latitude 2. longitude 3. altitude 4. Values for each Madrigal parameter listed in argument parms, separated by whitespace """ year = int(request.GET['year']) month = int(request.GET['month']) day = int(request.GET['day']) hour = int(request.GET['hour']) minute = int(request.GET['min']) second = int(request.GET['sec']) dt = datetime.datetime(year, month, day, hour, minute, second) startLat = float(request.GET['startLat']) endLat = float(request.GET['endLat']) if startLat == endLat: endLat += 0.001 elif startLat > endLat: raise ValueError, 'startLat cannot be greater than endLat' stepLat = float(request.GET['stepLat']) if stepLat < 0.0: raise ValueError, 'stepLat cannot be less than zero' elif stepLat == 0.0: stepLat = 0.001 latList = list(numpy.arange(startLat, endLat, stepLat)) startLong = float(request.GET['startLong']) endLong = float(request.GET['endLong']) if startLong == endLong: endLong += 0.001 elif startLong > endLong: raise ValueError, 'startLong cannot be greater than endLong' stepLong = float(request.GET['stepLong']) if stepLong < 0.0: raise ValueError, 'stepLong cannot be less than zero' elif stepLong == 0.0: stepLong = 0.001 lonList = list(numpy.arange(startLong, endLong, stepLong)) startAlt = float(request.GET['startAlt']) endAlt = float(request.GET['endAlt']) if startAlt == endAlt: endAlt += 0.001 elif startAlt > endAlt: raise ValueError, 'startAlt cannot be greater than endAlt' stepAlt = float(request.GET['stepAlt']) if stepAlt < 0.0: raise ValueError, 'stepAlt cannot be less than zero' elif stepAlt == 0.0: stepAlt = 0.01 altList = list(numpy.arange(startAlt, endAlt, stepAlt)) parms = request.GET['parms'] desiredParmList = [item.encode('ascii', 'ignore').strip() for item in ['gdlat','glon','gdalt'] + parms.split(',')] oneDList = request.GET.getlist('oneD') oneDParmDict = {} for oneDStr in oneDList: mnem, strValue = oneDStr.encode('ascii', 'ignore').split(',') oneDParmDict[mnem] = [float(strValue)] # capture stdout old_stdout = sys.stdout sys.stdout = mystdout = cStringIO.StringIO() madrigal.isprint.MadCalculatorGrid(None, desiredParmList, [dt], latList, lonList, altList, oneDParmDict, summary=None) text = mystdout.getvalue() sys.stdout = old_stdout return render_to_response('madweb/service.html', {'text': text})
def mad_time_calculator_service(
request)
mad_time_calculator_service runs the madTimeCalculator service. Input parameters must not be location dependent
Inputs: request/url - contains arguments:
1. startyear - int 2. startmonth - int 3. startday - int 4. starthour - int 5. startmin - int 6. startsec - int 7. endyear - int 8. endmonth - int 9. endday - int 10. endhour - int 11. endmin - int 12. endsec - int 13. stephours - float - number of hours per time step 14. parms - comma delimited string of Madrigal parameters desired (must not depend on location)
Returns comma-delimited data, one line for each year, month, day, hour, minute, and second, with the following fields:
1-6: year, month, day, hour, minute, and second 2. requested parm fields
def mad_time_calculator_service(request): """mad_time_calculator_service runs the madTimeCalculator service. Input parameters must not be location dependent Inputs: request/url - contains arguments: 1. startyear - int 2. startmonth - int 3. startday - int 4. starthour - int 5. startmin - int 6. startsec - int 7. endyear - int 8. endmonth - int 9. endday - int 10. endhour - int 11. endmin - int 12. endsec - int 13. stephours - float - number of hours per time step 14. parms - comma delimited string of Madrigal parameters desired (must not depend on location) Returns comma-delimited data, one line for each year, month, day, hour, minute, and second, with the following fields: 1-6: year, month, day, hour, minute, and second 2. requested parm fields """ startyear = int(request.GET['startyear']) startmonth = int(request.GET['startmonth']) startday = int(request.GET['startday']) starthour = int(request.GET['starthour']) startminute = int(request.GET['startmin']) startsecond = int(request.GET['startsec']) endyear = int(request.GET['endyear']) endmonth = int(request.GET['endmonth']) endday = int(request.GET['endday']) endhour = int(request.GET['endhour']) endminute = int(request.GET['endmin']) endsecond = int(request.GET['endsec']) dt1 = datetime.datetime(startyear, startmonth, startday, starthour, startminute, startsecond) dt2 = datetime.datetime(endyear, endmonth, endday, endhour, endminute, endsecond) if dt1 > dt2: raise ValueError, 'End Datetime %s cannot be before start datetime %s' % (str(dt2), str(dt1)) stephours = float(request.GET['stephours']) if stephours <= 0.0: raise ValueError, 'stephours cannot be non-positive: %f' % (stephours) dtList = [] while dt1 <= dt2: dtList.append(dt1) dt1 += datetime.timedelta(hours=stephours) parms = request.GET['parms'] desiredParmList = [item.encode('ascii', 'ignore').strip() for item in ['year','month','day','hour','min','sec'] + parms.split(',')] # no spatial data latList = lonList = altList = [] # capture stdout old_stdout = sys.stdout sys.stdout = mystdout = cStringIO.StringIO() madrigal.isprint.MadCalculatorGrid(None, desiredParmList, dtList, latList, lonList, altList, summary=None) text = mystdout.getvalue() sys.stdout = old_stdout return render_to_response('madweb/service.html', {'text': text})
def radar_to_geodetic_service(
request)
radar_to_geodetic_service runs the radarToGeodetic service.
Inputs: request/url - contains arguments:
slatgd - radar geodetic latitude slon - radar longitude saltgd - radar geodetic altitude azs - a comma-separated list of azimuths of point els - a comma-separated list of elevations of point. Len must be same as azs ranges - a comma-separated list of ranges to point. Len must be same as azs
Returns comma-delimited data, one line for point in lists (points treated as individual combinations, not grids):
1. geodetic latitude 2. longitude (-180 to 180) 3. geodetic altitude in km
def radar_to_geodetic_service(request): """radar_to_geodetic_service runs the radarToGeodetic service. Inputs: request/url - contains arguments: slatgd - radar geodetic latitude slon - radar longitude saltgd - radar geodetic altitude azs - a comma-separated list of azimuths of point els - a comma-separated list of elevations of point. Len must be same as azs ranges - a comma-separated list of ranges to point. Len must be same as azs Returns comma-delimited data, one line for point in lists (points treated as individual combinations, not grids): 1. geodetic latitude 2. longitude (-180 to 180) 3. geodetic altitude in km """ slatgd = float(request.GET['slatgd']) slon = float(request.GET['slon']) saltgd = float(request.GET['saltgd']) azStr = request.GET['az'] azList = [float(item) for item in azStr.split(',')] elStr = request.GET['el'] elList = [float(item) for item in elStr.split(',')] rangeStr = request.GET['range'] rangeList = [float(item) for item in rangeStr.split(',')] if len(azList) != len(elList) or len(azList) != len(rangeList): raise ValueError, 'all point list lengths must be equal' fullText = '' for i in range(len(azList)): gdlat,glon,gdalt = madrigal._derive.radarToGeodetic(slatgd, slon, saltgd, azList[i], elList[i], rangeList[i]) fullText += '%f,%f,%f\n' % (gdlat,glon,gdalt) return render_to_response('madweb/service.html', {'text': fullText})
def trace_magnetic_field_service(
request)
trace_magnetic_field_service runs the traceMagneticField service.
Inputs: request/url - contains arguments:
year, month, day, hour, min, sec inputType (0 for geodetic, 1 for GSM) outputType (0 for geodetic, 1 for GSM) The following parameter depend on inputType: in1 - a comma-separated list of geodetic altitudes or ZGSMs of starting point in2 - a comma-separated list of geodetic latitudes or XGSMs of starting point in3 - a comma-separated list of longitude or YGSM of starting point Length of all three lists must be the same model - 0 for Tsyganenko, 1 for IGRF qualifier - 0 for conjugate, 1 for north_alt, 2 for south_alt, 3 for apex, 4 for GSM XY plane stopAlt - altitude in km to stop trace at, if qualifier is north_alt or south_alt. If other qualifier, this parameter is not required.
Returns comma-delimited data, one line for point in in lists:
1. geodetic altitude or ZGSM of ending point 2. geodetic latitude or XGSM of ending point 3. longitude or YGSM of ending point
def trace_magnetic_field_service(request): """trace_magnetic_field_service runs the traceMagneticField service. Inputs: request/url - contains arguments: year, month, day, hour, min, sec inputType (0 for geodetic, 1 for GSM) outputType (0 for geodetic, 1 for GSM) The following parameter depend on inputType: in1 - a comma-separated list of geodetic altitudes or ZGSMs of starting point in2 - a comma-separated list of geodetic latitudes or XGSMs of starting point in3 - a comma-separated list of longitude or YGSM of starting point Length of all three lists must be the same model - 0 for Tsyganenko, 1 for IGRF qualifier - 0 for conjugate, 1 for north_alt, 2 for south_alt, 3 for apex, 4 for GSM XY plane stopAlt - altitude in km to stop trace at, if qualifier is north_alt or south_alt. If other qualifier, this parameter is not required. Returns comma-delimited data, one line for point in in lists: 1. geodetic altitude or ZGSM of ending point 2. geodetic latitude or XGSM of ending point 3. longitude or YGSM of ending point """ year = int(request.GET['year']) month = int(request.GET['month']) day = int(request.GET['day']) hour = int(request.GET['hour']) minute = int(request.GET['min']) second = int(request.GET['sec']) dt = datetime.datetime(year, month, day, hour, minute, second) inputType = int(request.GET['inputType']) if inputType not in (0,1): raise ValueError, 'inputType must be 0 or 1, not %i' % (inputType) outputType = int(request.GET['outputType']) if outputType not in (0,1): raise ValueError, 'outputType must be 0 or 1, not %i' % (outputType) in1Str = request.GET['in1'] in1List = [float(item) for item in in1Str.split(',')] in2Str = request.GET['in2'] in2List = [float(item) for item in in2Str.split(',')] in3Str = request.GET['in3'] in3List = [float(item) for item in in3Str.split(',')] if len(in1List) != len(in2List) or len(in1List) != len(in3List): raise ValueError, 'All three in* lists must have same length' model = int(request.GET['model']) if model not in (0,1): raise ValueError, 'model must be 0 or 1, not %i' % (model) qualifier = int(request.GET['qualifier']) if qualifier not in (0,1,2,3,4): raise ValueError, 'model must be in 0,1,2,3,4 not %i' % (model) try: stopAlt = float(request.GET['stopAlt']) except: stopAlt = 0.0 fullText = '' resultArr = numpy.zeros((3,), dtype='f8') madDB = madrigal.metadata.MadrigalDB() madDeriveObj = madrigal.derivation.MadrigalDerivationMethods(madDB.getMadroot()) for i in range(len(in1List)): madDeriveObj.traceMagneticField(year, month, day, hour, minute, second, inputType, outputType, in1List[i], in2List[i], in3List[i], model, qualifier, stopAlt, resultArr) fullText += '%f,%f,%f\n' % (resultArr[0], resultArr[1], resultArr[2]) return render_to_response('madweb/service.html', {'text': fullText})