; DCSMON.PRO
;
; This program reads in a hardware monitor log file as written by
; the DCS program.
;
; Based on a program written for HFBS by R.M.Dimeo (05/04/02).
;	Extensively modified and expanded for DCS by JRDC.
;
;;;;;;;;;;;;;;;;;;;;;;;;;
pro dcs_decode_onestep,unit,done,start_date=start_date,stop_date=stop_date,$
	date=date,chopPtr=chopPtr,instPtr=instPtr,skipstep=skipstep
;
compile_opt strictarr
;
if (ptr_valid(chopPtr)) then ptr_free,chopPtr
chopPtr=ptr_new({$
	DC:bytarr(7),$
	PG:bytarr(7),$
	SP:bytarr(7),$
	MB:bytarr(7),$
	SPEED:intarr(7),$
	RATIO:fltarr(7),$
	CUR:fltarr(7),$
	PHASE:fltarr(7),$
	WIND:fltarr(7),$
	MAXD:fltarr(7),$
	MNDEV:fltarr(7),$
	OUT:intarr(7),$
	DPHASE:fltarr(7),$
	NPHASE:fltarr(7),$
	AZV:fltarr(7),$
	STAT:intarr(7)})
;
if (ptr_valid(instPtr)) then ptr_free,instPtr
instPtr=ptr_new({$
	vg:fltarr(4),$
	temp:fltarr(3),$
	ms:0,$
	dfdt:0.0,$
	osens:fltarr(4),$
	tcpl:fltarr(4)})
;
done=0
line=""
skipstep=0
date=''
while (not eof(unit)) do begin
	readf,unit,line
	answer=strsplit(line,/extract)
	ans0=answer[0]
	if (ans0 eq "A") then begin
		now=answer[1]
		day=fix(strmid(now,0,2))
		month=month2num(strmid(now,3,3))
		year=fix(strmid(now,9,2))
		now=year*10000+month*100+day
		if (now lt start_date) then skipstep=-1
		if (now gt stop_date) then skipstep=1
	endif
	if (stregex(ans0,"^[1-7]",/boolean)) then ans0='0'
	if (skipstep eq 0) then begin
		case ans0 of
			'0':	begin
				k=fix(answer[0])-1 ;& print,answer
				for j=1,16 do begin
					if (stregex(answer[j],"\*",/boolean)) then answer[j]=0
					case j of
						1: (*chopPtr).(j-1)[k]=answer[j] eq "Y"
						2: (*chopPtr).(j-1)[k]=answer[j] eq "Y"
						3: (*chopPtr).(j-1)[k]=answer[j] eq "Y"
						4: (*chopPtr).(j-1)[k]=answer[j] eq "Y"
						6: begin
							parts=strsplit(answer[j],"/",/extract)
							if (n_elements(parts) eq 1 and parts[0] eq 0) then parts=[0,1]; added 12/17/02
							(*chopPtr).(j-1)[k]=float(parts[0])/float(parts[1])
						end
						7: (*chopPtr).(j-1)[k]=answer[j]*0.01
						16: (*chopPtr).(j-1)[k]=answer[j] eq "P"
						else: (*chopPtr).(j-1)[k]=answer[j]
					endcase
				endfor
			end
			"C":	begin
				date=systime(0,3600.0*float(answer[1]))
				(*instPtr).vg=float(answer[2:5])
				(*instPtr).temp=float(answer[6:8])
				(*instPtr).ms=float(answer[9])
				(*instPtr).dfdt=float(answer[10])
			end
			"E":	begin
				(*instPtr).osens=float(answer[1:4])
				(*instPtr).tcpl=float(answer[5:8])
			end
			else:
		endcase
	endif
	if (answer[0] eq '7') then return
endwhile
done=1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro dcs_read_log,file=file,start_date=start_date,stop_date=stop_date,$
	dcsStatePtr=dcsStatePtr,curswindow=curswindow
;
compile_opt strictarr
;
;res=ptr_valid(count=n)
;print,"On entry to dcs_read_log, ",n," pointers"
;
compressed=strmid(file,2,/reverse_offset) eq ".gz"
openr,unit,file,/get_lun,compress=compressed
;
record=-1
entry=-1
while (1) do begin
	dcs_decode_onestep,unit,done,start_date=start_date,stop_date=stop_date,$
		date=date,chopPtr=chopPtr,instPtr=instPtr,skipstep=skipstep
	if (skipstep eq 1) then break
	entry=entry+1
	if (skipstep eq -1) then begin
		if (entry/50*50 eq entry) then widget_control,curswindow,$
			set_value=strcompress(string(entry))+" entries read so far."
	endif else begin
		if (record/50*50 eq record) then widget_control,curswindow,set_value=date
		if (done) then begin
			if (ptr_valid(chopPtr)) then ptr_free,chopPtr
			if (ptr_valid(instPtr)) then ptr_free,instPtr
			break
		endif
		record=record+1
		if (record eq 0) then begin
			*dcsStatePtr[0]=date
			for j=0,15 do *dcsStatePtr[j+1]=(*chopPtr).(j)
			for j=0,5 do *dcsStatePtr[j+17]=(*instPtr).(j)
			newptrs=dcsstateptr
		endif else begin
			ptrs0=ptr_valid(count=n0)
			ptrs0=ptrs0[sort(ptrs0)]
			dcsStatePtr[0]=ptr_new([*dcsStatePtr[0],date],/no_copy)
			for j=0,15 do dcsStatePtr[j+1]=ptr_new([*dcsStatePtr[j+1],(*chopPtr).(j)],/no_copy)
			for j=0,5 do dcsStatePtr[j+17]=ptr_new([*dcsStatePtr[j+17],(*instPtr).(j)],/no_copy)
			ptrs=ptr_valid(count=n)
			ptrs=ptrs[sort(ptrs)]
			ptr_free,newptrs
			newptrs=ptrs[n0:n-1]
		endelse
	endelse
endwhile
;
if (record eq -1) then return
;
record=record+1
dcsStatePtr[0]=ptr_new(reform(*dcsStatePtr[0],1,record),/no_copy)
for j=0,15 do dcsStatePtr[j+1]=ptr_new(reform(*dcsStatePtr[j+1],7,record),/no_copy)
dcsStatePtr[17]=ptr_new(reform(*dcsStatePtr[17],4,record),/no_copy)
dcsStatePtr[18]=ptr_new(reform(*dcsStatePtr[18],3,record),/no_copy)
dcsStatePtr[19]=ptr_new(reform(*dcsStatePtr[19],1,record),/no_copy)
dcsStatePtr[20]=ptr_new(reform(*dcsStatePtr[20],1,record),/no_copy)
dcsStatePtr[21]=ptr_new(reform(*dcsStatePtr[21],4,record),/no_copy)
dcsStatePtr[22]=ptr_new(reform(*dcsStatePtr[22],4,record),/no_copy)
ptr_free,newptrs
free_lun,unit
;
;res=ptr_valid(count=n)
;print,"On leaving dcs_read_log, ",n," pointers"
;
end
;;;;;;;;;;;;;;;;;;;;;;;;;
function month2num,month
;
compile_opt strictarr
;
case month of
'Jan':	num = 1
'Feb':  num = 2
'Mar':  num = 3
'Apr':  num = 4
'May':  num = 5
'Jun':  num = 6
'Jul':  num = 7
'Aug':  num = 8
'Sep':  num = 9
'Oct':  num = 10
'Nov':  num = 11
'Dec':  num = 12
else:   num = 0
endcase
return,num
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro dcsmonCleanup,tlb
;
compile_opt strictarr
;
widget_control,tlb,get_uvalue = pState
wdelete,(*pState).winState.winPix
ptr_free,(*pState).datePtr
ptr_free,(*pState).julPtr
for k=0,21 do ptr_free,(*pState).dcsStatePtr[k]
ptr_free,(*pState).dcsTitlePtr
ptr_free,(*pState).winState.xPtr
ptr_free,(*pState).winState.yPtr
ptr_free,pState
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro dcsmonQuit,event
;
compile_opt strictarr
;
widget_control,event.top,/destroy
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro dcsmonPlot,event
;
compile_opt strictarr
;
widget_control,event.top,get_uvalue = pState
widget_control,(*pState).siggroup,get_value = type

x = *(*pState).julPtr
nx = n_elements(x)
xtitle = 'Date'
y = *(*pState).dcsStatePtr[type]
ytitle = (*(*pState).dcstitlePtr)[type]

if (*pState).winState.autoscale eq 1 or $
	(*pState).winState.autoscale eq 2 then begin
  dx = 0.025*(max(x)-min(x))
  if (dx eq 0.0) then dx = min(x)*0.2
  (*pState).winState.xrange = [min(x)-dx,max(x)+dx]
endif

if (*pState).winState.autoscale eq 1 or $
	(*pState).winState.autoscale eq 3 then begin
  dy = 0.05*(max(y)-min(y))
  if (dy eq 0.0) then dy = min(y)*0.2
  (*pState).winState.yrange = [min(y)-dy,max(y)+dy]
endif

y0=y[0,*]
numticks = 5
plot,x,y0,psym = 0,ytitle = ytitle,$
     xrange = (*pState).winState.xrange,xstyle = 1,$
     yrange = (*pState).winState.yrange,ystyle = 1,$
     xtick_get = tickvalues, position = [0.15,0.25,0.925,0.95],$
     xtickformat = '(A1)',xticks = numticks, /nodata, color=1
sy=size(y)
for j=0,sy[1]-1 do begin
	oplot,x,y[j,*],color=j+2,thick=2
	xc=[0.95,0.975]
	yc=0.88-j*0.1
	if (sy[1] gt 1) then begin
		plots,xc,yc,/normal,color=j+2,thick=2
		xyouts,xc[0],yc[0]+0.02,strtrim(string(j+1),2),$
			/normal,alignment=0.0,charsize=2,charthick=1,color=1
	endif
endfor

ypos = replicate(!y.window[0]-0.04,numticks+1)
xpos = !x.window[0]+(!x.window[1]-!x.window[0])*findgen(numticks+1)/numticks
for j = 0,numticks-1 do begin
	caldat,tickvalues[j],mon,day,year,hour,minute
	datestring=dcs_clean_date(mon,day,year,hour,minute)
	xyouts,xpos[j],ypos[j],$
    datestring,alignment = 0.0,charsize=1.2,$
    orientation = -45.0,/normal,color=1
endfor

return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro dcsmonRead,event
;
compile_opt strictarr
;
widget_control,event.top,get_uvalue = pState
;
file = dialog_pickfile(file = (*pstate).file, path = (*pstate).path,$
	dialog_parent = event.top,title = 'Select a log file')
if file eq '' or file eq ' ' then return
;
value=['1/1/00','12/31/09']
dave_get_values,'Supply dates as m/d/y',['Start date','Stop date'],value,$
	group_leader=event.top,checkall=0
;
date=value[0]
if (date eq '') then start_date=1 else begin
	slash=strpos(date,'/')
	if (slash eq 1) then month=fix(strmid(date,0,1))
	if (slash eq 2) then month=fix(strmid(date,0,2))
	date=strmid(date,slash+1)
	slash=strpos(date,'/')
	if (slash eq -1) then begin
		day=fix(date)
		year=strmid(systime(),22)
	endif else begin
		if (slash eq 1) then day=fix(strmid(date,0,1))
		if (slash eq 2) then day=fix(strmid(date,0,2))
		year=strmid(date,slash+1)
	endelse
	start_date=year*10000l+month*100+day
endelse
;
date=value[1]
if (date eq '') then stop_date=99999l else begin
	slash=strpos(date,'/')
	if (slash eq 1) then month=fix(strmid(date,0,1))
	if (slash eq 2) then month=fix(strmid(date,0,2))
	date=strmid(date,slash+1)
	slash=strpos(date,'/')
	if (slash eq -1) then begin
		day=fix(date)
		year=strmid(systime(),22)
	endif else begin
		if (slash eq 1) then day=fix(strmid(date,0,1))
		if (slash eq 2) then day=fix(strmid(date,0,2))
		year=strmid(date,slash+1)
	endelse
	stop_date=year*10000l+month*100+day
endelse
;
(*pstate).winstate.autoscale=1
;
dcsstatePtr = ptrarr(23)
dcsStatePtr[0] = ptr_new("")
for j=0,21 do dcsStatePtr[j+1] = (*pState).dcsStatePtr[j]
;
dcs_read_log,file=file,start_date=start_date,stop_date=stop_date,$
	dcsStatePtr=dcsStatePtr,curswindow=(*pState).curswindow
;
if ((*dcsStatePtr[0])[0] eq "") then begin
	res=dialog_message($
		"There are no log entries between the specified start and stop dates.")
endif else begin
;
	dates = *dcsStatePtr[0]
	count=n_elements(dates)

; Now reformat the date so that it is a julian date
; which will allow us to plot it with nice axis labels
; using LABEL_DATE.PRO
	jul = dblarr(count)

	for i = 0L,count-1 do begin
	  dayStr = strmid(dates[i],8,2)
	  monthStr = strmid(dates[i],4,3)
	  yearStr = strmid(dates[i],20,4)

  	day = fix(dayStr)
	  month = month2num(monthStr)
	  year = fix(yearStr)

	  hourStr = strmid(dates[i],11,2)
	  minStr = strmid(dates[i],14,2)
	  secStr = strmid(dates[i],17,2)
	  hour = fix(hourStr)
	  minutes = fix(minStr)
	  seconds = fix(secStr)

	  jul[i] = julday(month,day,year,hour,minutes,seconds)
	endfor

	*(*pState).julPtr = jul
	for j=0,21 do (*pState).dcsStatePtr[j] = dcsStatePtr[j+1]
	ptr_free,dcsStatePtr[0]
	*(*pState).datePtr = dates[UNIQ(dates)]

	wset,(*pState).winState.winPix
	dcsmonPlot,event
	wset,(*pState).winState.winVis
	device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winState.winPix]
	empty
endelse

return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro dcsmonDraw,event
;
compile_opt strictarr
;
widget_control,event.top,get_uvalue = pState
widget_control,(*pState).siggroup,get_value = type
sigtypes = ['DC','PG','SP','MB','SPEED','RATIO','CUR','PHASE',$
	'WIND','MAXD','MNDEV','OUT','DPHASE','NPHASE','AZV','STAT',$
	'VG','TEMP','MS','DFDT','OSENS','TCPL']
case type of
	0: format="(i4)"
	1: format="(i4)"
	2: format="(i4)"
	3: format="(i4)"
	4: format="(i7)"
	5: format="(f7.3)"
	6: format="(f7.2)"
	7: format="(f10.2)"
	8: format="(f10.2)"
	9: format="(f10.2)"
	10: format="(f10.2)"
	11: format="(i6)"
	12: format="(f10.2)"
	13: format="(f10.2)"
	14: format="(f10.2)"
	15: format="(i4)"
	16: format="(f10.2)"
	17: format="(f10.2)"
	18: format="(i7)"
	19: format="(f6.2)"
	20: format="(f10.2)"
	21: format="(f10.2)"
	else: format="(f10.3)"
endcase
case event.type of
0:	begin		; button press
	  (*pState).winState.mouse = event.press
	  if (*pState).winState.mouse eq 4 then begin
	    (*pState).winState.autoscale = 1
	    return
	  endif
	  if (*pState).winState.mouse eq 1 then begin
	    (*pState).winState.xbox[0] = event.x
	    (*pState).winState.ybox[0] = event.y
	    wset,(*pState).winState.winVis
	    device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winState.winPix]
	    empty
	    (*pState).winState.autoscale = 0
	  endif
	end
1:	begin	; button release
	  xll = (*pState).winState.xbox[0] < (*pState).winState.xbox[1]
	  yll = (*pState).winState.ybox[0] < (*pState).winState.ybox[1]
	  w = abs((*pState).winState.xbox[1] - (*pState).winState.xbox[0])
	  h = abs((*pState).winState.ybox[1] - (*pState).winState.ybox[0])
	  xur = xll + w
	  yur = yll + h
	  ll = convert_coord(xll,yll,/device,/to_data,/double)
	  ur = convert_coord(xur,yur,/device,/to_data,/double)
	  (*pState).winState.xrange = [ll[0],ur[0]]
	  (*pState).winState.yrange = [ll[1],ur[1]]
	  wset,(*pState).winState.winPix
	  dcsmonPlot,event
	  wset,(*pState).winState.winVis
	  device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winState.winPix]
	  (*pState).winState.mouse = 0B
	end
2:	begin	; mouse motion
	  wset, (*pState).winState.winVis	;in case that saving to ps file change the current window
	  result=convert_coord(event.x,event.y,/device,/to_data,/double)
	  caldat,result[0],mon,day,year,hour,minute
		xcurs_info=dcs_clean_date(mon,day,year,hour,minute)
		ycurs_info=string(result[1],format=format)
		info=xcurs_info+ycurs_info
		widget_control,(*pState).curswindow,set_value=info
	  if (*pState).winState.mouse eq 1 then begin
	  	(*pState).winState.xbox[1] = event.x
	  	(*pState).winState.ybox[1] = event.y
	  	xc = [(*pState).winState.xbox[0],event.x,event.x,(*pState).winState.xbox[0],$
	  	      (*pState).winState.xbox[0]]
	  	yc = [(*pState).winState.ybox[0],(*pState).winState.ybox[0],event.y,event.y,$
	  	      (*pState).winState.ybox[0]]
	  	wset,(*pState).winState.winVis
	  	device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winState.winPix]
	  	plots,xc,yc,/device,color=1
	  	empty
	  endif
	end
else:
endcase
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro dcsmonPrint,event
;
compile_opt strictarr
;
thisDevice = !d.name
deviceKeywords = ps_form(Cancel = canceled,parent = event.top,/color)
if canceled ne 1 then begin
  SET_PLOT, 'PS'
  DEVICE, _Extra = deviceKeywords
  dcsmonPlot,event
  DEVICE, /CLOSE_FILE
  set_plot,thisDevice
endif
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro dcsmon_event,event
;
compile_opt strictarr
;
widget_control,event.top,get_uvalue = pState
if event.id eq (*pState).siggroup then begin
  (*pState).winState.autoscale = 3
	widget_control,event.top,set_uvalue = pState
  wset,(*pState).winState.winPix
  dcsmonPlot,event
  wset,(*pState).winState.winVis
  device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winState.winPix]
  empty
endif
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro dcsmon,event
; Widget definition module
;
compile_opt strictarr
;
res=dialog_message(["This program is obsolete.","Use DCS_HDWMON instead."])
return
;res=ptr_valid(count=n)
;print,"At start, ",n," pointers"
;
;path = 'c:\data\'
;path = 'k:\logs\'
drives=['a','b','c','d','e','f','g','h','i','j','k','l']
for k=0,11 do begin
	path=drives[k]+':\logs\'
	if (file_test(path)) then goto,done
endfor
path=''
done:
logfiles=file_search(path+"hdwmon_200*.log")
if (logfiles[0] eq "") then begin
	file=''
endif else begin
	logfiles=reverse(logfiles[sort(logfiles)])
	file=logfiles[0]
endelse
;
amcolor = {color, $ ; name
red:   [255,0,255,  0,  0,  0,255,255,152,128,128,128,255,178,255],$ ; red values
green: [255,0,  0,255,  0,255,  0,255,120,128,128,128, 54,192,128],$ ; green values
blue:  [255,0,  0,  0,255,255,255,  0,103,220, 60,128, 54,220,128] $ ; blue values
}
colorset
oldct=dcs_getctinfo()
tvlct,amcolor.red,amcolor.green,amcolor.blue
;
if (n_elements(event) eq 0) then begin
	tlb = widget_base(/row,title = 'DCS Monitor Log Display',mbar = bar)
endif else begin
	tlb = widget_base(/row,title = 'DCS Monitor Log Display',mbar = bar,group_leader=event.top)
endelse
;
filemenu = widget_button(bar,value = 'File',/menu)
void = widget_button(filemenu,value = 'Load log file',event_pro = 'dcsmonRead')
void = widget_button(filemenu,value = 'Print to a postscript file',$
       event_pro = 'dcsmonPrint')
void = widget_button(filemenu,value = 'Quit',event_pro = 'dcsmonQuit')
base1 = widget_base(tlb,/col)
sigtypes = ['DC','PG','SP','MB','SPEED','RATIO','CUR','PHASE',$
	'WIND','MAXD','MNDEV','OUT','DPHASE','NPHASE','AZV','STAT',$
	'VG','TEMP','MS','DFDT','OSENS','TCPL']
siggroup = cw_bgroup(base1, sigtypes, /col, /exclusive,$
         label_top='Selection',/no_release,$
         frame=1,set_value=17,/return_index)

base2 = widget_base(tlb,/col)
base3 = widget_base(base2,/align_center)
curswindow =widget_text(base3,xsize=26,ysize=1,/editable,font="COURIER*20")
xsize = 500 & ysize = 450
win = widget_draw(base2,xsize = xsize,ysize = ysize,/button_events,$
      event_pro = 'dcsmonDraw',/motion_events)

centertlb,tlb
widget_control,tlb,/realize
widget_control,win,get_value = winVis
window,/free,/pixmap,xsize = xsize,ysize = ysize
winPix = !d.window

dcstitles=sigtypes

winState =  {winPix:winPix,$
             winVis:winVis,$
             win:win,$
             xbox:[0.0,1.0],$
             xrange:[0.0d0,1.0d0],$
             ybox:[0.0,1.0],$
             yrange:[0.0d0,1.0d0],$
             xPtr:ptr_new(/allocate_heap),$
             yPtr:ptr_new(/allocate_heap),$
             xtitle:'',$
             ytitle:'',$
             title:'',$
             mouse:0B,$
             autoscale:1}

state = {path:path,$
         file:file,$
         curswindow:curswindow,$
         winState:winState,$
         siggroup:siggroup,$
         dcsStatePtr:ptrarr(22,/allocate_heap),$
         dcstitlePtr:ptr_new(dcstitles),$
         datePtr:ptr_new(/allocate_heap),$
         julPtr:ptr_new(/allocate_heap)}

pstate=ptr_new(state)
widget_control,tlb,set_uvalue = pstate
dcsmonRead,{event,id:void,top:tlb,handler:0l}
xmanager,'dcsmon',tlb,cleanup = 'dcsmonCleanup',/no_block
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
