;*******************************************************************************
function header
html = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"' $
+ string(10B) + '"
http://www.w3.org/TR/html4/loose.dtd">' $
+ string(10B) + '<HTML LANG="en-US">' + string(10B)
return, html
end
;*******************************************************************************
function start_html, title=title, bgcolor=bgcolor
html = '<HEAD>' $
+ '<TITLE>' + title + '</TITLE>' $
+ '</HEAD>' $
+ '<BODY BGCOLOR="' + bgcolor + '">' + string(10B)
return, html
end
;*******************************************************************************
function end_html
html = '</BODY></HTML>' + string(10B)
return, html
end
;*******************************************************************************
function a, href=href, content=content
html = '<A HREF="' + href + '">' + content + '</A>' + string(10B)
return, html
end
;*******************************************************************************
function br
html = '<BR>' + string(10B)
return, html
end
;*******************************************************************************
function h1, align=align, content
if keyword_set(align) then begin
html = '<H1 ALIGN = "' + align + '">' + content + '</H1>' + string(10B)
endif else begin
html = '<H1>' + content + '</H1>' + string(10B)
endelse
return, html
end
;*******************************************************************************
function h2, align=align, content
if keyword_set(align) then begin
html = '<H2 ALIGN = "' + align + '">' + content + '</H2>' + string(10B)
endif else begin
html = '<H2>' + content + '</H2>' + string(10B)
endelse
return, html
end
;*******************************************************************************
function h3, align=align, content
if keyword_set(align) then begin
html = '<H3 ALIGN = "' + align + '">' + content + '</H3>' + string(10B)
endif else begin
html = '<H3>' + content + '</H3>' + string(10B)
endelse
return, html
end
;*******************************************************************************
function h4, align=align, content
if keyword_set(align) then begin
html = '<H4 ALIGN = "' + align + '">' + content + '</H4>' + string(10B)
endif else begin
html = '<H4>' + content + '</H4>' + string(10B)
endelse
return, html
end
;*******************************************************************************
function h5, align=align, content
if keyword_set(align) then begin
html = '<H5 ALIGN = "' + align + '">' + content + '</H5>' + string(10B)
endif else begin
html = '<H5>' + content + '</H5>' + string(10B)
endelse
return, html
end
;*******************************************************************************
function table, align=align, border=border, cellpadding=cellpadding, width=width, $
bgcolor=bgcolor, content=content
html = '<TABLE ALIGN="' + align + '" BORDER="' + border + '" CELLPADDING="' + cellpadding + $
'" WIDTH="' + width + '" BGCOLOR="' + bgcolor + '">' + string(10B) $
+ content + '</TABLE>' + string(10B)
return, html
end
;*******************************************************************************
function tr, align=align, valign=valign, content=content
html = '<TR ALIGN="' + align + '" VALIGN="' + valign + '">' + string(10B) $
+ content + '</TR>' + string(10B)
return, html
end
;*******************************************************************************
function th, content
html = '<TH>' + content + '</TH>' + string(10B)
return, html
end
;*******************************************************************************
function img, src=src, alt=alt, content=content, border=border
html = '<IMG SRC="' + src + '" ALT="' + alt + '" BORDER="' + border + '">' + string(10B)
return, html
end
;*******************************************************************************
pro doDataRequest, outputTypes, component, beginDateTime, endDateTime, stations, $
inputPathPrefix, inputURLPrefix, outputPathPrefix, outputURLPrefix, $
sessionID, htmlFilePath
; globals
common HtmlFileCommons, gHtmlFile, gHtmlFileLUN
common OutputsCommons, gMakeBin, gMakeIAGA, gMakePNG, gMakePS, gBx, gBy, gBz
; ===== CONSTANTS
; kMaxInputFiles = total number of binary data files for all stations; if, for
; example, 9 stations are selected and two days of data are requested, then 18
; files would be needed...
kMaxInputFiles = 100
; ===== STRUCTURE DEFINITIONS
; StationPropStruct - station properties (name, IAGA code, etc.)
stationProp = {StationPropStruct, maccsName:, maccsCode:, iagaName:, iagaCode:, latitude:0.0D, longitude:0.0D}
; InputFileStruct - data file properties (name, path, associated station, Julian day number of file, etc)
inputFile = {InputFileStruct, exists:0, name:, pathPrefix:, urlPrefix:, jdn:0.0D, stationProp:stationProp}
; ===== OUTPUT TYPES
; convert comma-delimited outputTypes list to array
outputs = str_sep(outputTypes, ', ')
gMakeBin = 0
gMakeIAGA = 0
gMakePNG = 0
gMakePS = 0
foo = where(outputs, outputsCount)
if outputsCount ne 0 then begin
for i = 0, outputsCount - 1 do begin
case outputs[i] of
'bin': begin
gMakeBin = 1
end
'iaga': begin
gMakeIAGA = 1
end
'png': begin
gMakePNG = 1
end
'ps': begin
gMakePS = 1
end
endcase
endfor
endif
; ===== COMPONENT
gBx = 0
gBy = 0
gBz = 0
case component of
'Bx': begin
gBx = 1
end
'By': begin
gBy = 1
end
'Bz': begin
gBz = 1
end
endcase
; ===== STATIONS
; convert comma-delimited station code list to stations array
stations = str_sep(stations, ', ')
foo = where(stations, stationsCount)
if stationsCount ne 0 then begin
;; prepare array of StationPropStruct structures
stationProps = replicate(stationProp, stationsCount)
for i = 0, stationsCount - 1 do begin
stationName = stations[i]
;; fill in the rest of the information
case stationName of
'Cape Dorset': begin
maccsName = stationName
maccsCode = 'CDR'
iagaName = stationName + ', Canada'
iagaCode = 'CDR'
latitude = '64.2'
longitude = '283.4'
end
'Coral Harbour': begin
maccsName = stationName
maccsCode = 'CHB'
iagaName = stationName + ', Canada'
iagaCode = 'CHB'
latitude = '64.1'
longitude = '276.8'
end
'Clyde River': begin
maccsName = stationName
maccsCode = 'CRV'
iagaName = stationName + ', Canada'
iagaCode = 'CRV'
latitude = '70.5'
longitude = '291.4'
end
'Gjoa Haven': begin
maccsName = stationName
maccsCode = 'GJO'
iagaName = stationName + ', Canada'
iagaCode = 'GJO'
latitude = '68.6'
longitude = '264.1'
end
'Igloolik': begin
maccsName = stationName
maccsCode = 'IGL'
iagaName = stationName + ', Canada'
iagaCode = 'IGL'
latitude = '69.3'
longitude = '278.2'
end
'Nain': begin
maccsName = stationName
maccsCode = 'NAN'
iagaName = stationName + ', Canada'
iagaCode = 'NAN'
latitude = '56.4'
longitude = '298.3'
end
'Pelly Bay': begin
maccsName = stationName
maccsCode = 'PEB'
iagaName = stationName + ', Canada'
iagaCode = 'PEB'
latitude = '68.5'
longitude = '270.3'
end
'Pangnirtung': begin
maccsName = stationName
maccsCode = 'PGG'
iagaName = stationName + ', Canada'
iagaCode = 'PGG'
latitude = '66.1'
longitude = '294.2'
end
'Repulse Bay': begin
maccsName = stationName
maccsCode = 'RBY'
iagaName = stationName + ', Canada'
iagaCode = 'RBY'
latitude = '66.5'
longitude = '273.8'
end
else: begin
maccsName = 'Unknown'
maccsCode = '???'
iagaName = 'Unknown'
iagaCode = '???'
latitude = '999.9'
longitude = '999.9'
end
endcase
stationProps[i].maccsName = maccsName
stationProps[i].maccsCode = maccsCode
stationProps[i].iagaName = iagaName
stationProps[i].iagaCode = iagaCode
stationProps[i].latitude = latitude
stationProps[i].longitude = longitude
endfor
endif
; ===== DATE-TIMES
; prepare begining and ending julian day numbers
beginDT = str_sep(beginDateTime, ', ')
beginJDN = julday(beginDT[1], beginDT[2], beginDT[0], beginDT[3])
caldat, beginJDN, month, day, year, hour
endDT = str_sep(endDateTime, ', ')
endJDN = julday(endDT[1], endDT[2], endDT[0], endDT[3])
caldat, endJDN, month, day, year, hour
; ===== INPUT FILES
; prepare array of InputFileStruct structures
inputFilesArrayTemp = replicate(inputFile, kMaxInputFiles)
; fill the 'inputFilesArrayTemp' array
fillInputFileArray, inputFilesArrayTemp, inputPathPrefix, inputURLPrefix, $
stationProps, beginJDN, endJDN
; get 'inputFilesArrayTemp' array size
inputsCount = 0
for i = 0, kMaxInputFiles - 1 do begin
if inputFilesArrayTemp[i].stationProp.maccsCode ne then begin
inputsCount = inputsCount + 1
endif
endfor
; resize the 'inputFilesArray' array to simplify results of sort()
if inputsCount gt 0 then begin
inputFilesArray = replicate(inputFile, inputsCount)
stationFilesCount = 0
for i = 0, inputsCount - 1 do begin
inputFilesArray[i] = inputFilesArrayTemp[i]
if inputFilesArray[i].exists then begin
stationFilesCount = stationFilesCount + 1
endif
endfor
endif
; ===== HTML OUTPUT
gHtmlFile = htmlFilePath
openw, gHtmlFileLUN, gHtmlFile, /get_lun
printf, gHtmlFileLUN, header()
printf, gHtmlFileLUN, start_html(title="MACCS Data Request Results", bgcolor="#ffffff")
printf, gHtmlFileLUN, h3("MACCS Data Request Results", align = "center")
if stationFilesCount eq 0 then begin
printf, gHtmlFileLUN, h5('No data were found for the specified stations and times.')
endif else begin
kMaxStationFiles = 20
if (stationFilesCount gt kMaxStationFiles) and (gMakeIAGA) then begin
stationFilesCountString = string(format='(i)', kMaxStationFiles)
stationFilesHtmlString = 'No more than ' + stationFilesCountString + ' ' $
+ 'station-days can be processed for IAGA ASCII output. Please ' $
+ 'return to the form and select fewer stations or a smaller time interval.'
printf, gHtmlFileLUN, h5(stationFilesHtmlString)
endif else begin
processInputFiles, inputFilesArray, beginJDN, endJDN, $
outputPathPrefix, outputURLPrefix, sessionID
endelse
endelse
printf, gHtmlFileLUN, end_html()
close, gHtmlFileLUN
end
;*******************************************************************************
pro fillInputFileArray, inputFilesArray, inputPathPrefix, inputURLPrefix, $
stationProps, beginJDN, endJDN
; construct data file names; here's a sample to illustrate:
;
————-path prefi————->
; <-url prefix ->
; /var/apache/htdocs/space/webdata/cd/92/cd92223.bin
; data file extension
inputFileExtension = '.bin'
sizeArray = size(inputFilesArray)
numInputFiles = sizeArray[1]
if numInputFiles eq 0 then goto, TheEnd
sizeStationProps = size(stationProps)
numStationProps = sizeStationProps[1]
if numStationProps eq 0 then goto, TheEnd
fileIndex = 0
for stationIndex = 0, numStationProps - 1 do begin
caldat, beginJDN, month, day, year
theJDN = julday(month, day, year, 0, 0, 0)
; non-inclusive of end julian day number
while theJDN lt endJDN do begin
;; day of year 001 to 365 or so...remembering to round down the julian day
;; number to the nearest day
caldat, theJDN, month, day, year
;; for julian day numbers, 0.0 corresponds to noon; hence, we need to subtract 0.5
dayNumber = floor(theJDN - 0.5) - floor(julday(1, 1, year, 0, 0, 0) - 0.5) + 1
dayOfYear = string(format='(i3.3)', dayNumber)
twoDigitYear = strmid(string(format='(i4)', year), 2, 2)
;; construct file name
;; Unix
kDirDelimiter = '/'
;; Windows
; kDirDelimiter = '\'
maccsCode = strlowcase(stationProps[stationIndex].maccsCode)
inputPathSuffix = maccsCode + kDirDelimiter + twoDigitYear + kDirDelimiter
inputURLSuffix = maccsCode + '/' + twoDigitYear + '/'
fileName = maccsCode + twoDigitYear + dayOfYear + inputFileExtension
filePath = inputPathPrefix + inputPathSuffix + fileName
;; test for existence of file; use get_lun and free_lun since openr,
;; /get_lun might not give us a valid LUN with which to use close,...
get_lun, ourLUN
openr, ourLUN, filePath, error=err
free_lun, ourLUN
if err eq 0 then begin
;; no error occurred; assume file exists
inputFilesArray[fileIndex].exists = 1
endif
inputFilesArray[fileIndex].name = fileName
inputFilesArray[fileIndex].pathPrefix = inputPathPrefix + inputPathSuffix
inputFilesArray[fileIndex].urlPrefix = inputURLPrefix + inputPathSuffix
inputFilesArray[fileIndex].jdn = theJDN
inputFilesArray[fileIndex].stationProp = stationProps[stationIndex]
fileIndex = fileIndex + 1
;; make sure we have engough space to put our stations and files
if fileIndex ge numInputFiles then goto, TheEnd
;; increment day
theJDN = theJDN + 1
endwhile
endfor
TheEnd:
end
;*******************************************************************************
pro processInputFiles, inputFilesArray, beginJDN, endJDN, $
outputPathPrefix, outputURLPrefix, sessionID
common HtmlFileCommons
common OutputsCommons
sizeArray = size(inputFilesArray)
numInputFiles = sizeArray[1]
; HTML strings for each of the table cells
dummyString =
kMaxStationDays = 100
stationHtml = replicate(dummyString, kMaxStationDays)
binHtml = replicate(dummyString, kMaxStationDays)
iagaHtml = replicate(dummyString, kMaxStationDays)
; loop over input files; group stations together
kNumStations = 9
requestedStations = strarr(kNumStations)
availableStations = strarr(kNumStations)
availableStationIndex = -1
stationCode = 'InitialNonEmptyStationCode'
stationIndex = -1
firstFileForThisStation = 1
lastFileForThisStation = 0
fileNumberForThisStation = 0
sizeArray = size(inputFilesArray)
numInputFiles = sizeArray[1]
firstFileIndex = 0
lastFileIndex = numInputFiles - 1
for fileIndex = firstFileIndex, lastFileIndex do begin
thisFile = inputFilesArray[fileIndex]
thisMaccsCode = thisFile.stationProp.maccsCode
thisMaccsName = thisFile.stationProp.maccsName
fileNumberForThisStation = fileNumberForThisStation + 1
;; see if this file exists
if thisFile.exists then begin
thisFileExists = 1
endif else begin
thisFileExists = 0
endelse
;; see if this is the last file for this station
if fileIndex lt lastFileIndex then begin
nextFile = inputFilesArray[fileIndex + 1]
nextMaccsCode = nextFile.stationProp.maccsCode
nextMaccsName = nextFile.stationProp.maccsName
if nextMaccsCode ne thisMaccsCode then begin
lastFileForThisStation = 1
endif
endif else begin
lastFileForThisStation = 1
endelse
;; see if this is the first file for this station
if firstFileForThisStation then begin
stationIndex = stationIndex + 1
requestedStations[stationIndex] = thisMaccsCode
stationHtml[stationIndex] = stationHtml[stationIndex] + h5(thisMaccsName)
firstFileForThisStation = 0
endif
if thisFile.exists then begin
thisStationIsAvailableAndItsNotInTheListOfAvailableStations = 1
for index = 0, kNumStations - 1 do begin
if availableStations[index] eq thisMaccsCode then begin
thisStationIsAvailableAndItsNotInTheListOfAvailableStations = 0
endif
endfor
if thisStationIsAvailableAndItsNotInTheListOfAvailableStations then begin
availableStationIndex = availableStationIndex + 1
availableStations[availableStationIndex] = thisMaccsCode
endif
endif
jdn1 = thisFile.jdn
caldat, jdn1, month1, day1, year1
jdn2 = jdn1 + 1
caldat, jdn2, month2, day2, year2
;; new file (same station or new station)
if gMakeBin then begin
fileName = thisFile.name
;; ammend html
href = thisFile.urlPrefix + fileName
if thisFile.exists then begin
binHtml[stationIndex] = binHtml[stationIndex] + a(href=href, content=fileName)
binHtml[stationIndex] = binHtml[stationIndex] + br()
endif else begin
binHtml[stationIndex] = binHtml[stationIndex] + fileName + ' (unavailable)'
binHtml[stationIndex] = binHtml[stationIndex] + br()
endelse
endif
if gMakeIAGA then begin
;; build IAGA-format file name
iagaCode = thisFile.stationProp.iagaCode
iagaFileName = string(format='(i4.4,i2.2,i2.2,i2.2)', year1, month1, day1, day2) + 'SC.' + iagaCode
iagaFilePath = outputPathPrefix + iagaFileName
;; ammend html
href = outputURLPrefix + iagaFileName
if thisFile.exists then begin
iagaHtml[stationIndex] = iagaHtml[stationIndex] + a(href=href, content=iagaFileName)
iagaHtml[stationIndex] = iagaHtml[stationIndex] + br()
;; process data
writeIAGAFile, iagaFilePath, thisFile
endif else begin
iagaHtml[stationIndex] = iagaHtml[stationIndex] + iagaFileName + ' (unavailable)'
iagaHtml[stationIndex] = iagaHtml[stationIndex] + br()
endelse
endif
if lastFileForThisStation then begin
;; ...when i get to the bottom i go back to the top of the slide...
firstFileForThisStation = 1
lastFileForThisStation = 0
endif
endfor
caldat, beginJDN, month1, day1, year1, hour1
caldat, endJDN, month2, day2, year2, hour2
if gMakePNG or gMakePS then begin
;; build a string of station names
stationString =
for index = 0, kNumStations - 1 do begin
if requestedStations[index] ne then begin
stationString = stationString + requestedStations[index] + '_'
endif
endfor
if gBx eq 1 then begin
compName = 'Bx'
endif
if gBy eq 1 then begin
compName = 'By'
endif
if gBz eq 1 then begin
compName = 'Bz'
endif
plotFileName = stationString $
+ string(format='(i4.4,i2.2,i2.2,i2.2)', year1, month1, day1, hour1) + '-' $
+ string(format='(i4.4,i2.2,i2.2,i2.2)', year2, month2, day2, hour2) + '_' $
+ compName
endif
if gMakePNG then begin
pngFileName = plotFileName + '.png'
pngFilePath = outputPathPrefix + pngFileName
pngFileURL = outputURLPrefix + pngFileName
content = img(src=pngFileURL, alt=pngFileName, border='0')
pngHtml = '<CENTER>' + a(href=pngFileURL, content=content) + '</CENTER>'
;; process data
writePlotFile, 'PNG', pngFilePath, inputFilesArray, beginJDN, endJDN, availableStations
endif
if gMakePS then begin
psFileName = plotFileName + '.ps'
psFilePath = outputPathPrefix + psFileName
psFileURL = outputURLPrefix + psFileName
psHtml = a(href=psFileURL, content=psFileName)
;; process data
writePlotFile, 'PS', psFilePath, inputFilesArray, beginJDN, endJDN, availableStations
endif
if gMakeBin or gMakeIAGA then begin
columnHeadings = th('Station')
if gMakeBin then begin
columnHeadings = columnHeadings + th('Binary Data File')
endif
if gMakeIAGA then begin
columnHeadings = columnHeadings + th('IAGA ASCII Data File')
endif
tableContent = tr(align='center', valign='top', content=columnHeadings)
index = 0
while stationHtml[index] ne do begin
columnContent = th(stationHtml[index])
if gMakeBin then begin
columnContent = columnContent + th(binHtml[index])
endif
if gMakeIAGA then begin
columnContent = columnContent + th(iagaHtml[index])
endif
tableContent = tableContent + tr(align='left', valign='top', content=columnContent)
index = index + 1
endwhile
tableHtml = table(align='center', border='1', cellpadding='10', width='768', $
bgcolor='#ffffff', content=tableContent)
printf, gHtmlFileLUN, tableHtml
endif
if gMakePNG then begin
printf, gHtmlFileLUN, pngHtml
endif
if gMakePS then begin
printf, gHtmlFileLUN, psHtml
endif
end
;*******************************************************************************
pro writeIAGAFile, iagaFilePath, inFileStruct
;; open IAGA output file
openw, iagaFileLUN, iagaFilePath, /get_lun
stationProp = inFileStruct.stationProp
iagaName = stationProp.iagaName
iagaCode = stationProp.iagaCode
latitude = string(format='(f5.1)', stationProp.latitude)
longitude = string(format='(f5.1)', stationProp.longitude)
; data column headings
Hx = " " + iagaCode + "X"
Hy = " " + iagaCode + "Y"
Hz = " " + iagaCode + "Z"
time = systime(0)
; pad with spaces
totalChars = 36
padString, iagaName, totalChars
padString, iagaCode, totalChars
padString, latitude, totalChars
padString, longitude, totalChars
totalChars = 40
padString, time, totalChars
printf, iagaFileLUN, " Format | IAGA2000 |"
printf, iagaFileLUN, " Station | " + iagaName + "|"
printf, iagaFileLUN, " IAGA Code | " + iagaCode + "|"
printf, iagaFileLUN, " Geodetic Latitude | " + latitude + "|"
printf, iagaFileLUN, " Geodetic Longitude | " + longitude + "|"
printf, iagaFileLUN, " Elevation | |"
printf, iagaFileLUN, " Observed | XYZ |"
printf, iagaFileLUN, " Digital Sampling | 0.5 seconds |"
printf, iagaFileLUN, " Data Interval | Average 5-second centered |"
printf, iagaFileLUN, " Data type | Variation |"
printf, iagaFileLUN, " Variables | 9 |"
printf, iagaFileLUN, " # This file was written by the MACCS Data Request Web |"
printf, iagaFileLUN, " # Application on " + time + "|"
printf, iagaFileLUN, " # For more information visit
http://space.augsburg.edu |"
; " Year| MT| DY| HR| MN| SC| ???X| ???Y| ???Z|"
; " 2000| 1| 1| 0| 0| 0| 15262.9| 974.9| 48404.2|"
printf, iagaFileLUN, " Year| MT| DY| HR| MN| SC|" + Hx + "|" + Hy + "|" + Hz + "|"
fillMagneticFieldArrays, bx, by, bz, hour, minute, second, inFileStruct
sizeArray = size(bx)
count = sizeArray[1]
month = indgen(count)
day = indgen(count)
year = indgen(count)
caldat, inFileStruct.jdn, m, d, y
month[*] = m
day[*] = d
year[*] = y
table = findgen(9, count)
table[0, *] = year
table[1, *] = month
table[2, *] = day
table[3, *] = hour
table[4, *] = minute
table[5, *] = second
table[6, *] = bx
table[7, *] = by
table[8, *] = bz
printf, format='(((x, i4, "|"), 5(x, i2, "|"), 3(x, f9.2, "|")))', iagaFileLUN, $
table
printf, iagaFileLUN, "EOF"
free_lun, iagaFileLUN
end
;*******************************************************************************
; plotType is 'PNG' or 'PS'
;
pro writePlotFile, plotType, plotFilePath, inputFilesArray, beginJDN, endJDN, availableStations
common OutputsCommons
kMissing = 32767.0
kRecordCount = 17280
if plotType eq 'PNG' then begin
;; prepare PNG
openw, pngFileLUN, plotFilePath, /get_lun
set_plot, 'z'
device, set_resolution=[700,550], set_colors=2
!p.font=0
!p.charsize=1
!p.background=255
!p.color=0
endif
if plotType eq 'PS' then begin
;; prepare PostScript
xs = 8.5*2.54
ys = 11.0*2.54
set_plot, 'ps'
device, filename=plotFilePath, /portrait, xoffset=1, yoffset=1, xsize=xs-2, ysize=ys-2, font_size=15
!p.font=-1
psxdpi = !d.x_size/8.5
psydpi = !d.y_size/11.0
endif
caldat, beginJDN, month1, day1, year1, hour1, minute1
caldat, endJDN, month2, day2, year2, hour2, minute2
hours = round((endJDN - beginJDN)*24.0)
case 1 of
(hours gt 0) and (hours le 6): begin
;; tph = ticks per hour
tph = 1.0
majors = round(tph * hours)
minors = 4
end
(hours gt 6) and (hours le 12): begin
tph = 1.0
majors = round(tph * hours)
minors = 4
end
(hours gt 12) and (hours le 18): begin
tph = 1.0
majors = round(tph * hours)
minors = 2
end
(hours gt 18) and (hours le 24): begin
tph = 0.5
majors = round(tph * hours)
minors = 4
end
(hours gt 24) and (hours le 36): begin
tph = 0.5
majors = round(tph * hours)
minors = 2
end
(hours gt 24) and (hours le 48): begin
tph = 0.5
majors = round(tph * hours)
minors = 2
end
(hours gt 48) and (hours le 72): begin
tph = 0.25
majors = round(tph * hours)
minors = 2
end
(hours gt 72) and (hours le 96): begin
tph = 0.125
majors = round(tph * hours)
minors = 4
end
(hours gt 96) and (hours le 120): begin
tph = 0.1
majors = round(tph * hours)
minors = 2
end
else: begin
;; ten days max
hours = 240
tph = 0.1
majors = round(tph * hours)
minors = 2
end
endcase
step = round(1/tph)
for i=0, majors do begin
hour = (hour1 + step*i)
hourmod = hour mod 24
if hourmod eq 0 then begin
hourname = string(format='(i1)', hourmod)
jdn = beginJDN + round(hour/24)
xtickname = '!S' + ' ' + hourname + '!R!L' + string(format='(C(CMOI2.2, "/", CDI2.2))', jdn)
endif else begin
if hourmod lt 10 then begin
hourname = string(format='(i1)', hourmod)
endif else begin
hourname = string(format='(i2)', hourmod)
endelse
xtickname = hourname
endelse
!x.tickname[i] = xtickname
endfor
!x.range = [hour1, hour1 + hours]
!x.ticks=majors
!x.minor=minors
!x.style=1
sizeArray = size(availableStations)
numAvailableStations = sizeArray[1]
stationCount = 0
for index = 0, (numAvailableStations - 1) do begin
if availableStations[index] ne then begin
stationCount = stationCount + 1
endif
endfor
yticks = stationCount + 1
yticknames = strarr(yticks + 1)
yticknames[0] = ' '
yticknames[yticks] = ' '
orderedTicknames = ['CHB', 'CDR', 'PGG', 'RBY', 'PEB', 'GJO', 'IGL', 'CRV', 'NAN']
yticknameIndex = 1
for orderIndex = 0, 8 do begin
for stationIndex = 0, (numAvailableStations - 1) do begin
station = availableStations[stationIndex]
if station eq orderedTicknames[orderIndex] then begin
yticknames[yticknameIndex] = station
yticknameIndex = yticknameIndex + 1
endif
endfor
endfor
yscale = 200 ; todo calculate yscale?
yrange = yscale*yticks
!y.ticks=yticks
!y.tickname=yticknames
!y.range=[0, yrange]
!y.minor=-1
!y.style=1
plotInitialized = 0
firstFileForThisStation = 1
lastFileForThisStation = 0
fileNumberForThisStation = 0
sizeArray = size(inputFilesArray)
numInputFiles = sizeArray[1]
firstFileIndex = 0
lastFileIndex = numInputFiles - 1
for fileIndex = firstFileIndex, lastFileIndex do begin
thisFile = inputFilesArray[fileIndex]
thisMaccsCode = thisFile.stationProp.maccsCode
fileNumberForThisStation = fileNumberForThisStation + 1
;; see if this file exists
if thisFile.exists then begin
thisFileExists = 1
endif else begin
thisFileExists = 0
endelse
;; see if this is the last file for this station
if fileIndex lt lastFileIndex then begin
nextFile = inputFilesArray[fileIndex + 1]
nextMaccsCode = nextFile.stationProp.maccsCode
if nextMaccsCode ne thisMaccsCode then begin
lastFileForThisStation = 1
endif
endif else begin
lastFileForThisStation = 1
endelse
if thisFileExists then begin
;; get data
fillMagneticFieldArrays, bx, by, bz, hour, minute, second, thisFile
if gBx eq 1 then begin
b = bx
endif
if gBy eq 1 then begin
b = by
endif
if gBz eq 1 then begin
b = bz
endif
sizeArray = size(b)
bCount = sizeArray[1]
x = findgen(bCount)
day = fileNumberForThisStation - 1
x = day*24.0 + hour + minute/(60.0) + second/(60.0 * 60.0)
endif else begin
b = findgen(kRecordCount)
b[*] = kMissing
x = findgen(kRecordCount)
day = fileNumberForThisStation - 1
x = day*24.0 + x*24.0/kRecordCount
endelse
;; figure out which tick mark this data corresponds to
ytick = 1
for i=1, yticks - 1 do begin
if yticknames[i] eq thisMaccsCode then begin
ytick = i
endif
endfor
if firstFileForThisStation then begin
;; assuming b and x arrays have same size
samplingRate = 1.0/5.0
lag = beginJDN - thisFile.jdn
firstIndex = round(lag * 24.0 * 60.0 * 60.0 * samplingRate)
bAll = b[firstIndex:*]
xAll = x[firstIndex:*]
firstFileForThisStation = 0
endif else begin
bAll = [bAll, b]
xAll = [xAll, x]
endelse
if lastFileForThisStation then begin
bGood = where(bAll ne kMissing, bGoodCount)
if (bGoodCount ne 0) then begin
bAvg = total(bAll(bGood))/bGoodCount
endif else begin
bAvg = !values.d_nan
endelse
;; filter out missing data by assigning NaN
bBad = where(bAll eq kMissing, bBadCount)
if (bBadCount ne 0) then begin
bAll(bBad) = !values.d_nan
endif
kMaxVal = 10000.0
kMinVal = -10000.0
if plotInitialized then begin
oplot, xAll, (bAll - bAvg + ytick*yscale), max_value=kMaxVal, min_value=kMinVal
endif else begin
if plotType eq 'PS' then begin
;; We need to specify 6.5" time axis width, but there's no
;; apparently easy way to do this. The 'xmargin' keyword of
;; the 'axis' procedure allows the width to be specified in
;; character units only. The 'position' keyword in 'plot'
;; procedure doesn't specify actual axis length since it
;; includes the label areas. We'll just have to fudge.
;; Using a ruler, the label area was measured to be 5/8 of
;; an inch. We'll just excise it from the right margin...
fudge = 5.0/8.0
pos = [1.0*psxdpi, 1.0*psydpi, (7.5 + fudge)*psxdpi, 10.0*psydpi]
plot, xAll, (bAll - bAvg + ytick*yscale), position=pos, /device, max_value=kMaxVal, min_value=kMinVal
endif else begin
plot, xAll, (bAll - bAvg + ytick*yscale), max_value=kMaxVal, min_value=kMinVal
endelse
plotInitialized = 1
endelse
endif ;;lastFileForThisStation
if lastFileForThisStation then begin
;; ...when i get to the bottom i go back to the top of the slide...
firstFileForThisStation = 1
lastFileForThisStation = 0
fileNumberForThisStation = 0
endif
endfor
TheEnd:
if gBx eq 1 then begin
compName = 'Bx'
endif
if gBy eq 1 then begin
compName = 'By'
endif
if gBz eq 1 then begin
compName = 'Bz'
endif
title = 'MACCS ' + compName + ' ' $
+ string(format='(C(CYI4.4, "/", CMOI2.2, "/", CDI2.2, X, CHI2.2))', beginJDN) $
+ ' to ' $
+ string(format='(C(CYI4.4, "/", CMOI2.2, "/", CDI2.2, X, CHI2.2))', endJDN)
xyouts, 0.50, 0.98, '!N!3'+title, align=0.5, /normal
xyouts, 0.06, 0.50, '!N!3' + 'Station Code', orientation=90, align=0.5, size=1.0, /normal
xyouts, 0.50, 0.02, '!N!3' + 'UT', align=0.5, size=1.0, /normal
xyouts, 0.04, 0.00, '!N!3'+'SCALE: '+strcompress(string(yscale))+'nT/TickMark', align=0.0, size=0.8, /normal
xyouts, 0.98, 0.02, '!N!3BOSTON UNIVERSITY', align=1.0, size=0.8, /normal
xyouts, 0.98, 0.00, '!N!3AUGSBURG COLLEGE', align=1.0, size=0.8, /normal
if plotType eq 'PNG' then begin
;; toggle top-to-bottom transfer order
; !order = not !order ; bug fixed in IDL 5.4
theImage=tvrd()
;; retore top-to-bottom transfer order
; !order = not !order ; bug fixed in IDL 5.4
write_png, plotFilePath, theImage
free_lun, pngFileLUN
device, /close
endif
if plotType eq 'PS' then begin
device, /close_file
endif
end
;*******************************************************************************
; returns bx, by, and bz arrays for the specified input file
pro fillMagneticFieldArrays, bx, by, bz, hour, minute, second, inFileStruct
kRecordSize=15
kRecordCount=17280
; to speed up for testing...
; kRecordCount=kRecordCount/12
inFileName = inFileStruct.pathPrefix + inFileStruct.name
openr, inFileLUN, inFileName, /get_lun
data = bytarr(kRecordSize, kRecordCount)
readu, inFileLUN, data
free_lun, inFileLUN
; extract time value arrays from the file data array
hour = data(0,*)
minute = data(1,*)
second = data(2,*)
; extract field value arrays from the file data array
bx = long(data( 3: 6, *), 0, 1, kRecordCount)
by = long(data( 7:10, *), 0, 1, kRecordCount)
bz = long(data(11:14, *), 0, 1, kRecordCount)
; swap bytes if big-endian (necessary for solaris on sparc since data is little
;
; non-student version
;
byteorder, bx, /lswap, /swap_if_big_endian
byteorder, by, /lswap, /swap_if_big_endian
byteorder, bz, /lswap, /swap_if_big_endian
; divide field values by 1000. to get nanotesla
bx = bx/1000.
by = by/1000.
bz = bz/1000.
; flatten arrays into one dimension
hour = reform(hour, kRecordCount, /overwrite)
minute = reform(minute, kRecordCount, /overwrite)
second = reform(second, kRecordCount, /overwrite)
bx = reform(bx, kRecordCount, /overwrite)
by = reform(by, kRecordCount, /overwrite)
bz = reform(bz, kRecordCount, /overwrite)
end
;*******************************************************************************
; pads the specified string with spaces
pro padString, str, chars
if strlen(str) gt chars then begin
;; truncate
str = strmid(str, 0, chars)
goto, TheEnd
endif else begin
;; pad
while strlen(str) lt chars do begin
str = str + ' '
endwhile
endelse
TheEnd:
theString = str
end

