Main Page | Packages | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | Related Pages

HskGuiReceiver.py

00001 #!/usr/local/bin/python
00002 #
00003 #                               Copyright 2004
00004 #                                     by
00005 #                        The Board of Trustees of the
00006 #                     Leland Stanford Junior University.
00007 #                            All rights reserved.
00008 #
00009 
00010 __facility__ = "Online"
00011 __abstract__ = "GLAST LAT Housekeeping server infrastructure"
00012 __author__   = "Jim Panetta <panetta@slac.stanford.edu> SLAC - GLAST I&T"
00013 __date__     = "07/28/04"
00014 __version__  = "$Revision: 1.9 $"
00015 __release__  = "$Name: R04-12-00 $"
00016 __credits__  = "SLAC"
00017 
00018 import LATTE.copyright_SLAC
00019 
00020 from LATTE.monitoring.HskReceiver import HskCfgTextReceiver
00021 from LATTE.client.gOptions        import Options
00022 
00023 import logging
00024 import gc,sys
00025 from   linecache import *
00026 import time
00027 import qt
00028 from sihippo import Observer
00029 import sihippo
00030 
00031 second  = 1
00032 minute  = 60 * second
00033 hour    = minute * 60
00034 day     = hour * 24
00035 era     = 10**9
00036 
00037 timeFmt      = '%H:%M:%S'
00038 dataFile     = None
00039 timeDepth    = 2*hour
00040 
00041 class QtReceiver(qt.QObject,HskCfgTextReceiver):
00042 
00043   class TrendUpdateEvent(qt.QCustomEvent):
00044     def __init__(self,trendMap):
00045       qt.QCustomEvent.__init__(self,qt.QEvent.MaxUser-20)
00046       self.trendMap = trendMap
00047 
00048   def __init__(self, flatFile, startTime, trendList):
00049     HskCfgTextReceiver.__init__(self, flatFile, startTime, trendList)
00050     qt.QObject.__init__(self)
00051 
00052   def process(self,trendMap):
00053     qt.QApplication.postEvent(self,QtReceiver.TrendUpdateEvent(trendMap))
00054 
00055   def customEvent(self,event):
00056     self.emit(qt.PYSIGNAL('TrendUpdate(trendMap)'),(event.trendMap,))
00057 
00058 
00059 
00060 class TrendPlotter(qt.QWidget):
00061   def __init__(self,keyList,*args):
00062     qt.QWidget.__init__(self,*args)
00063 
00064     self.__ntuples       = {}
00065     self.__plots         = {}
00066     self.__views         = {}
00067     self.__gen           = {}
00068     self.__defaultDepth  = 500                 # assuming 1 hz data rate
00069     self.__defaultLabels = ['Time','']
00070 
00071     self.__dynamic       = True
00072     self.__keyList       = keyList
00073 
00074     self.grid            = qt.QGridLayout(self,3,2)
00075     self.grid.setAutoAdd(1)
00076     self.true            = True
00077 
00078   def isDynamic(self):
00079     return self.__dynamic
00080   def setDynamic(self,bool):
00081     self.__dynamic=bool
00082 
00083   def addPlot(self, key):
00084     labels  = self.__defaultLabels
00085     depth   = self.__defaultDepth
00086     name    = self.__keyList[key]
00087 
00088     # Create the Circular buffer to store the data
00089     ntc     = sihippo.NTupleController.instance()
00090     nt      = ntc.createCircularBuffer(labels)
00091     nt.reserve(depth)
00092     nt.setTitle(name)
00093     nt.setName(name)
00094 
00095     # Create the Plot
00096     dc      = sihippo.DisplayController.instance()
00097     plot=dc.createDisplay('XY Plot',nt,labels)
00098     # plot    = dc.createDisplay('Strip Chart',nt,labels)
00099 
00100     # kludge so that the range is initialized, and autoscales when we need.
00101     plot.setRange('x',0,1)
00102     plot.setAutoRanging('x',True)
00103 
00104     # Add the time axis observer
00105     gen     = TimeAxisGen()
00106     gen.setPlotter(plot, key)
00107     plot.addObserver(gen)
00108 
00109     # Add the plot to the screen
00110     view    = sihippo.QtViewWidget(self)
00111     view.setPlotter(plot)
00112     view.setDoubleBuffering(1)
00113     view.resize(200,100)
00114     view.setMinimumSize(qt.QSize(100,50))
00115     # self.grid.addWidget(view)
00116     view.show()
00117 
00118     # Maintain a reference to the created objects to prevent garbage collection
00119     self.__ntuples[key]  = nt
00120     self.__plots[key]    = plot
00121     self.__views[key]    = view
00122     self.__gen[key]      = gen
00123 
00124   def update(self, trendMap):
00125     # if not self.true: return
00126     self.true=False
00127     # trendMap has timestamp, val1, val2, val3...
00128     timeStamp = trendMap['TimeStamp']
00129     for key in trendMap:
00130       if key == 'TimeStamp': continue
00131       if key not in self.__views.keys() and self.__dynamic:
00132         self.addPlot(key)
00133       if key not in self.__views.keys():
00134         return
00135       x=timeStamp
00136       y=trendMap[key]
00137       if y is None:
00138         continue
00139       self.__ntuples[key].addRow([x,y])
00140 
00141 class TimeAxisGen ( Observer ) :
00142   __labelFmt   = '%Y/%m/%d'
00143   __tickFmt    = '%H:%M'
00144   __stepSet    = [ 1*second, 5*second, 10*second, 30*second,
00145                    1*minute, 2*minute, 5*minute, 10*minute, 15*minute, 20*minute, 30*minute,
00146                    1*hour, 2*hour, 6*hour, 12*hour,
00147                    1*day, 3*day, 7*day, 30*day, 90*day, 180*day, 364*day,
00148                    era]
00149 
00150   def setPlotter ( self, plotter, name ) :
00151     self.plotter = plotter
00152     self.name    = name
00153     self.__goodStep = 0
00154 
00155   def update ( self, obs ) :
00156     # return
00157     lowTime = self.plotter.getLowRangeOnX()
00158     highTime = self.plotter.getHighRangeOnX()
00159 
00160     if ((highTime - lowTime)/TimeAxisGen.__stepSet[self.__goodStep]) < 1:
00161       # print "reset of goodStep", self.name, self.__goodStep , highTime, lowTime,  ((highTime - lowTime)/TimeAxisGen.__stepSet[self.__goodStep])
00162       self.__goodStep -= 1
00163     if ((highTime - lowTime)/TimeAxisGen.__stepSet[self.__goodStep]) > 6:
00164       # print self.name, highTime, lowTime,  ((highTime - lowTime)/TimeAxisGen.__stepSet[self.__goodStep])
00165       step = 0
00166       while ((highTime - lowTime)/TimeAxisGen.__stepSet[step]) > 5:
00167         # print "step:", step
00168         step += 1
00169       self.__goodStep = step
00170     step = TimeAxisGen.__stepSet[self.__goodStep]
00171 
00172     lowTick = lowTime - (lowTime % step) + step
00173     values = []
00174     values.append( lowTick )
00175 
00176     labels = []
00177     labels.append( time.strftime(TimeAxisGen.__tickFmt, time.localtime(lowTick)) )
00178     tick = lowTick
00179     tick += step
00180     while tick < highTime:
00181       values.append ( tick )
00182       labels.append ( time.strftime(TimeAxisGen.__tickFmt, time.localtime(tick)) )
00183       tick += step
00184 
00185     self.plotter.setAutoTicksOnX( False )
00186     self.plotter.setTicksOnX( values, labels )
00187 
00188     # REALLY REALLY don't do this:
00189     #   setLabel calls "notifyObservers", which brings us back here...
00190     # xlabel = time.strftime(TimeAxisGen.__labelFmt, time.localtime(highTime))
00191     # self.plotter.setLabel( 'x', xlabel )
00192 
00193 def memget():
00194   import win32pdh
00195   hq = win32pdh.OpenQuery()
00196   # ch = win32pdh.AddCounter(hq, "\\\\gitow1\\Process(python)\\Private Bytes")
00197   ch = win32pdh.AddCounter(hq, "\\\\gitow1\\Process(python#1)\\Private Bytes")
00198   win32pdh.CollectQueryData(hq)
00199   type, val =win32pdh.GetFormattedCounterValue(ch,win32pdh.PDH_FMT_LONG)
00200   return val
00201 
00202 def startup():
00203   # print memget()
00204   logging.basicConfig()
00205   logging.root.setLevel(logging.DEBUG)
00206   gc.set_debug(gc.DEBUG_LEAK)
00207   print "Garbage collection: ", gc.isenabled()#, gc.get_objects()
00208 
00209 def startQT(dataFile, startTime, keyList):
00210   import sys
00211 
00212   app=qt.QApplication(sys.argv)
00213   r=QtReceiver(dataFile, startTime, keyList.keys())
00214 
00215   gui=TrendPlotter(keyList)
00216   gui.connect(r,qt.PYSIGNAL('TrendUpdate(trendMap)'),gui.update)
00217 
00218   app.connect(app,qt.SIGNAL("lastWindowClosed()"),
00219               app,qt.SLOT("quit()"))
00220 
00221   app.setMainWidget(gui)
00222   gui.show()
00223 
00224   r.setReceiving(1)
00225   app.exec_loop()
00226   r.shutdown()
00227 
00228 def usage():
00229   return """
00230 
00231 HskGuiReceiver Usage:
00232 
00233 Mandatory options:
00234 --dataFile  define the flat file that contains housekeeping data.
00235 
00236 Optional options:
00237 --timeDepth define the time depth of the housekeeping plots.  Default is 2 hours.
00238             Units are in seconds
00239 --keyFile   define the file of variables to plot
00240             Note: keyFile format is "KEY  :  Plot title"
00241 
00242 Example:
00243 $ HskGuiReceiver --dataFile c:\TEMP\lat-elf11.dat --timeDepth 3600 --keyFile keys.dat
00244 
00245 """
00246 
00247 
00248 if __name__ == '__main__':
00249   startup()
00250 
00251   # Options, first list mandatory, second list optional
00252   options = Options(['dataFile'], ['timeDepth', 'keyFile'])
00253   try:
00254     options.parse()
00255   except Exception, msg:
00256     options.usage()
00257     raise Exception, msg
00258 
00259   dataFile = options.dataFile
00260   if options.timeDepth is not None:
00261     timeDepth = int(options.timeDepth)
00262   else:
00263     timeDepth = 2*hour
00264   startTime = time.time() - timeDepth
00265 
00266   if options.keyFile is not None:
00267     keyFile = options.keyFile
00268     from HskReceiver import parseKeyFile
00269     keyList = parseKeyFile(keyFile)
00270   else:  # really really basic set of histos.
00271     keyList = {'LHKAEMDAQB33V':'AEM DAQ board 3.3 V',
00272                'LHKAEMFR11T'  :'AEM Free board 11 Temp',
00273                'LHKAEMDAQBT'  :'AEM DAQ board Temp',
00274                'LHKAEMFR11V1' :'AEM Free 11 HV 1',
00275                'LHKAEMFR11V2' :'AEM Free 11 HV 2',
00276                'LHKAEMFR11VD' :'AEM Free 11 VDD',
00277                }
00278 
00279   startQT(dataFile, startTime, keyList)
00280 

Generated on Fri Jul 21 13:26:29 2006 for LATTE R04-12-00 by doxygen 1.4.3