示例#1
0
文件: Data.py 项目: dylanosaur/PFL
class Data:
    """Class providing an interface to the raw data NetCDF files."""
    def __init__(self):
        """Constructor."""
        self.filename    = None # The filename the data was loaded from.

        # Laser fire times come from the laser diode data in mdsplus. 
        self.laserFireTimes = None

        self.shotNum = None
        self.data = {}
        self.polyList = None
        self.segments = None
        self.prelasing = None
 

    def loadData(self, shotNum, skipAPD = 1):
        """Load all the data for the given shot.

        Parameters:
        shotNum -- The shot number to load.
        skipAPD -- Set to 1 to skip the first APD (because of saturation).
        """
        from numpy import arange
        self.shotNum = shotNum

        self.data = {} # Clear old data.

        self.filename = util.getDataFilePath(shotNum)

        nc = pycdf.CDF(self.filename)
        #print "Loading Raw Data\n"
        str_rawData = nc.var('str_rawdata').get()
        str_voltsPerBit = nc.var('str_voltsperbit').get()
        str_deltat = nc.var('str_deltat').get()
        str_zeroBit = nc.var('str_offset').get()

        acq_rawData = nc.var('rawdata').get()
        acq_voltsPerBit = nc.var('voltsperbit').get()
        acq_deltat = nc.var('deltat').get()
        acq_offset = nc.var('offset').get()

        roa = nc.var('roa').get()

        # take the poly list from the netCDF file (one entry for each channel) and unique-ify it
        # to have only one entry per poly
        plist_long = nc.var('poly').get()
        seen = {}
        for item in plist_long:
            seen[item] = 1
            plist_short = seen.keys()
            plist_short.sort()	# probably unnecessary, but just in case
            self.polyList = plist_short

        # load the calibration data after the file data, so that the poly list can be loaded for this shot
        self.calib = Calibration()
        self.calib.loadCalibration(shotNum, plist_short, skipAPD)

        # The number of data segments is one less than the total number of 
        # segments. The last segment in the data file is used for calculating
        # the amplifier offsets.
        self.segments = arange(str_rawData.shape[1] - 1)

        apdIndex = 0

        for poly in self.polyList:
            self.data[poly] = {}
            calib = self.calib.getPolyCalibration(poly)

            for segment in self.segments:
                numAPD = calib.numAPD
                ps = PolySegData()

                ps.calib = calib
                ps.poly = poly
                ps.segment = segment
                ps.shotNum=self.shotNum

                # If calib.skipAPD is 1, then we don't load the data for the
                # first APD.
                start = apdIndex + calib.skipAPD
                end = apdIndex + numAPD
                ps.str_voltsPerBit = str_voltsPerBit[start:end]
                ps.str_deltat = str_deltat[start:end]
                ps.str_zeroBit = str_zeroBit[start:end]

                ps.acq_voltsPerBit = acq_voltsPerBit[start:end]
                ps.acq_deltat = acq_deltat[start:end]
                ps.acq_offset = acq_offset[start:end]

                ps.roa = roa[start]
                # correction because p20 and p21 were flipped in the calib file
                # for Fall 2012 only, radial calib redone in December
                #if poly == 20:
                #    ps.roa = 0.6030
                #elif poly == 21:
                #    ps.roa = 0.5181

                ps.str_rawData = str_rawData[start:end, segment]
                ps.acq_rawData = acq_rawData[start:end, segment]

                # It's a bit inefficient to store the offset data with each 
                # PolySegData object, but it is simple.
                ps.str_offsetRaw = str_rawData[start:end, len(self.segments)]
                ps.acq_offsetRaw = acq_rawData[start:end, len(self.segments)]

                # Set the usability flags for the DC and AC channels
                # The AC channels are set to be unused until AC calib is figured out
                ps.chanFlagDC = ones(numAPD - calib.skipAPD)
                #ps.chanFlagAC = ones(numAPD - calib.skipAPD)
                ps.chanFlagAC = zeros(numAPD - calib.skipAPD)

                self.data[poly][segment] = ps
            apdIndex += numAPD


    
    
    def getSegments(self):
        """Return a list of available segment numbers."""
        return self.segments



    def getPolyList(self):
        """Return the list of polys to fit."""
        return self.polyList


    
    def getPolyListSortedROA(self):
        """Return the list of polys in order of increasing ROA."""
        def sortFn(p1, p2):
            ps1 = self.getPolySegData(p1, 0)
            ps2 = self.getPolySegData(p2, 0)
            if ps1.roa == ps2.roa:
                return 0
            elif ps1.roa > ps2.roa:
                return 1
            else:
                return -1

        tmpList = list(self.getPolyList())
        tmpList.sort(sortFn)
        return tmpList




    def getPolySegData(self, poly, segment):
        """Get the data for a given poly and segment combination.

        Parameters:
        poly    -- The poly number.
        segment -- The segment number.

        Returns: The data for the given poly and segment in the form of a
        PolySegData object.
        """
        return self.data[poly][segment]


    
    def setPolySegData(self, poly, segment, ps):
        """Set the data for a given poly and segment to the given PolySegData
        object.

        Parameters:
        poly    -- The poly number.
        segment -- The segment number.
        ps      -- The PolySegData object.
    
        Returns: Nothing.
        """
        self.data[poly][segment] = ps



    def getReadme(self, bCompact=True):
        """Return a string to save to the readme variable in mdsplus."""
        ret = ''
        for segment in self.getSegments():
            for poly in self.getPolyList():
                ps = self.getPolySegData(poly, segment)
                st = None
                if bCompact:
                    st = ps.getCompactErrWarnStr()
                else:
                    st = ps.getErrWarnStr()
                    
                if st != None:
                    ret += '%s\n' % st
        return ret