Exemple #1
0
def txt2UPD(Input, Output, Header, separator, x_col, y_col, z_col, r_col, g_col, b_col):
    '''
    A function to convert a text file into the UPD format.

    Input: input text file path. 
    Output: output UPD file path.
    separator: column separator/delimiter for the input text file.
    x_col: column index of the x coordinates.
    y_col: column index of the y coordinates.
    z_col: column index of the z coordinates.
    r_col: column index of the red color channel.
    g_col: column index of the green color channel.
    b_col: column index of the blue color channel.
    '''
    # try to open the input text file:
    try:
        f = open(Input, 'r')
        n_points = sum([1 for line in f])
        f.seek(0)
        if Header == True:
            f.readline()
    except Exception:
        sys.exit('Error: unable to read input text file.')

    print('Creating the output file: '+os.path.basename(Output))
    UPD = spdpy.createSPDFile(Output)
    spdWriter = spdpy.SPDPyNoIdxWriter()
    spdWriter.open(UPD, Output)
    UPD.setReceiveWaveformDefined(0)
    UPD.setTransWaveformDefined(0)
    UPD.setDecomposedPtDefined(0)
    UPD.setDiscretePtDefined(1)
    UPD.setOriginDefined(0)
    UPD.setHeightDefined(0)
    UPD.setRgbDefined(1)
    UPD.setGeneratingSoftware('Python.')
    UPD.setUserMetaField('Processed by Osian!')

    # iterate through each line in the input file:
    for idx, line in enumerate(f):
        line = line.strip('\n').split(separator)
        try:
            # create point:
            Point = spdpy.createSPDPointPy()
            Point.returnID = 1 # this is set to 1 as Photogrammetry cannot receive multiple-returns.
            Point.x = float(line[x_col])
            Point.y = float(line[y_col])
            Point.z = float(line[z_col])
            Point.height = 0.0
            Point.amplitudeReturn = (int(line[r_col]) + int(line[g_col]) + int(line[b_col])) / 3
            Point.red = int(line[r_col])
            Point.green = int(line[g_col])
            Point.blue = int(line[b_col])
            Point.classification = 1 # 1 = unclassified
            Point = [Point]

            # assign point to pulse:
            Pulse = spdpy.createSPDPulsePy()
            Pulse.numberOfReturns = 1 # this is set to 1 as Photogrammetry cannot receive multiple-returns.
            Pulse.pts = Point

            spdWriter.writeData([Pulse])
            del Pulse, Point
        except Exception:
            continue
        del line
        progress_bar(n_points, idx+1)

    # close the upd file:
    f.close()
    spdWriter.close(UPD)
    print('Done.')
Exemple #2
0
def main(cmdargs):
    """
    Convert the LGW and LGC files to SPD
    """
    # Create SPD file
    spdFile = cmdargs.lwfFile.replace(".lwf",".spd")
    spdObj = spdpy.createSPDFile(spdFile)
    spdWriter = spdpy.SPDPyNoIdxWriter()
    spdWriter.open(spdObj,spdFile)
    spdObj.setTransWaveformDefined(1)
    spdObj.setReceiveWaveformDefined(1)
    spdObj.setOriginDefined(1)
    spdObj.setTemporalBinSpacing(1.0)
    
    # Read binary data
    pulseBlockSize = 1e4
    lwfObj = open(cmdargs.lwfFile, "rb")    
    recordFormat = struct.Struct('Q d d d f f f f H H H B B')
    pulseID = 0
    pulses = list()
    pulsesInBuffer = 0
    with open(cmdargs.lgcFile, "rb") as lgcObj:
        while True:
            try:
                
                # Read pulse record
                dataStr = lgcObj.read(recordFormat.size)
                data = recordFormat.unpack_from(dataStr, 0)
                
                # Read waveform data
                lwfObj.seek(data[0],0)
                nSamples = data[9] + data[10]
                if data[11] > 0:
                    wfStr = lwfObj.read(nSamples * 2)
                    wfFormat = struct.Struct('%iH' % nSamples)
                else:
                    wfStr = lwfObj.read(nSamples)
                    wfFormat = struct.Struct('%iB' % nSamples)
                wfData = wfFormat.unpack_from(wfStr, 0)
                
                # Create the SPD record
                pulseID += 1
                pulse = createSPDPulse(data, wfData, pulseID)
                pulses.append(pulse)
                pulsesInBuffer += 1
                
                # Write pulses to file
                if pulsesInBuffer >= pulseBlockSize:
                    writeSPDPulses(spdObj, spdWriter, pulses)
                    pulses = list()
                    pulsesInBuffer = 0
                    if cmdargs.verbose:
                        sys.stdout.write("%i pulses imported\r" % pulseID)
                        sys.stdout.flush()
                    
            except:
                
                writeSPDPulses(spdObj, spdWriter, pulses)
                sys.stdout.write("%i pulses imported\n" % pulseID)
                sys.stdout.flush()
                break
    
    # Close files
    lwfObj.close()
    spdWriter.close(spdObj)
Exemple #3
0
def main(cmdargs):
    """
    Read a CBL ascii file and write to a scan project SPD file
    Columns: Intensity, Azimuth, Zenith, Time of Flight and Return Number
    """    
    # Get file information
    zenith_resolution = 0.5
    azimuth_resolution = 0.25
    num_scanlines = 721
    num_scanlinepulses = 541    
    numrecords = file_len(cmdargs.infile)
    
    # Open output SPD file
    outfile = cmdargs.infile.replace(".txt",".spd")
    spdoutfile = spdpy.createSPDFile(outfile)
    spdoutfile.setNumBinsX(num_scanlinepulses)
    spdoutfile.setNumBinsY(num_scanlines)
    spdoutfile.setBinSize(1)
    spdwriter = spdpy.SPDPySeqWriter()
    spdwriter.open(spdoutfile, outfile)
    
    # Define the data present
    spdoutfile.setReceiveWaveformDefined(0)
    spdoutfile.setTransWaveformDefined(0)
    spdoutfile.setDecomposedPtDefined(0)
    spdoutfile.setDiscretePtDefined(1)
    spdoutfile.setOriginDefined(1)
    spdoutfile.setHeightDefined(0)
    spdoutfile.setRgbDefined(0)
    
    # Set header attributes
    spdoutfile.setSensorHeight(1.2)
    spdoutfile.setBeamDivergence(15.0)
    spdoutfile.setPulseIdxMethod(5)
    spdoutfile.setZenithMin(0)
    spdoutfile.setZenithMax(135) 
    spdoutfile.setAzimuthMin(0)
    spdoutfile.setAzimuthMax(360)
        
    # now read through the file
    pulsecount = 0
    zenithcoltemp = -1.0
    scanlineidxtemp = 1
    scanlinecount = 1
    scanline = list()
    f = open(cmdargs.infile, 'r')
    for i,line in enumerate(f):
        lparts = line.strip('\r\n').split()
        if len(lparts) > 0:
            
            # pulse - need to assume data is time sequential
            returnnum = int(float(lparts[4]))
            
            # Pulses with no returns
            if returnnum == 0:
                if i > 0:
                    scanline.append([pulse])                
                pulsecount += 1
                pulse = spdpy.createSPDPulsePy()            
                pulse.pulseID = pulsecount
                zenithcoltemp += 1              
                pulse.numberOfReturns = returnnum
                
                # If it's a new scan line, write out previous one and set up new one 
                if zenithcoltemp > 540:
                    spdwriter.writeDataRow(scanline, scanlinecount-1)
                    scanline = list()
                    scanlinecount += 1
                    scanlineidxtemp = 1
                    pulse.zenith = 135
                    zenithcoltemp = 0
                else:
                    scanlineidxtemp += 1
                    pulse.zenith = abs(float(zenithcoltemp)*zenith_resolution - 135)            
                
                # Calculate azimuth angle
                if zenithcoltemp > 270:
                    pulse.azimuth = float(lparts[1]) * azimuth_resolution + 180
                else:
                    pulse.azimuth = float(lparts[1]) * azimuth_resolution                
                
                pulse.xIdx = scanlineidxtemp
                pulse.yIdx = scanlinecount
                pulse.scanline = scanlinecount
                pulse.scanlineIdx = scanlineidxtemp
            
            # First return
            elif returnnum == 1:
                if i > 0:
                    scanline.append([pulse])
                
                # Initialise new pulse
                pulsecount += 1
                pulse = spdpy.createSPDPulsePy()            
                pulse.pulseID = pulsecount
                pulse.numberOfReturns = returnnum
                
                # If it's a new scan line, write out previous one and set up new one
                if float(lparts[2]) < zenithcoltemp: 
                    spdwriter.writeDataRow(scanline, scanlinecount-1)
                    scanline = list()
                    scanlinecount += 1
                    scanlineidxtemp = 1
                else:
                    scanlineidxtemp += 1
                
                # Calculate zenith angle
                pulse.zenith = abs(float(lparts[2]) * zenith_resolution - 135)
                
                # Calculate azimuth angle
                if zenithcoltemp > 270:
                    pulse.azimuth = float(lparts[1]) * azimuth_resolution + 180
                else: 
                    pulse.azimuth = float(lparts[1]) * azimuth_resolution
                
                pulse.xIdx = scanlineidxtemp
                pulse.yIdx = scanlinecount
                pulse.scanline = scanlinecount
                pulse.scanlineIdx = scanlineidxtemp             
                zenithcoltemp = float(lparts[2])
            
            # Second return
            elif returnnum == 2:
                pulse.numberOfReturns = returnnum
            
            # Create a return if one exists
            if returnnum > 0:
                tof = float(lparts[0])
                intensity = float(lparts[3])               
                point = create_point(tof,np.radians(pulse.zenith),np.radians(pulse.azimuth),intensity,returnnum)
                pulse.pts.append(point)
    
        # Let's monitor progress
        sys.stdout.write("Writing sequential SPD file %s (%i%%)\r" % (outfile, scanlinecount / float(num_scanlines) * 100))        
    
    
    # Write last scan line
    scanline.append([pulse])
    spdwriter.writeDataRow(scanline, scanlinecount-1)
    spdoutfile.setNumPulses(pulsecount)

    # Close the output file
    f.close()
    spdwriter.close(spdoutfile)
Exemple #4
0
def main(cmdargs):

    # Open UPD file
    spdOutFile = spdpy.createSPDFile(cmdargs.outputFile)
    updWriter = spdpy.UPDWriter()
    updWriter.open(spdOutFile, cmdargs.outputFile)
    outPulses = list()

    # Define contents this lidar dataset
    spdOutFile.setReceiveWaveformDefined(0)
    spdOutFile.setTransWaveformDefined(0)
    spdOutFile.setDecomposedPtDefined(1)
    spdOutFile.setDiscretePtDefined(0)
    spdOutFile.setOriginDefined(1)

    # For the RIEGL ASCII format, we do not know what pulse each return
    # is linked to so each return is assigned to a unique pulse and we
    # set this attribute to TRUE so users know the return number are synthetic
    spdOutFile.setReturnNumsSynGen(1)

    # Define scanner properties
    spdOutFile.setSensorHeight(cmdargs.agh)
    spdOutFile.setWavelength(1550.0)

    # Open ASCII file and read header
    asciiObj = open(cmdargs.inputFile, 'r')
    header = asciiObj.readline().strip('\r\n').split(',')
    nPoints = int(asciiObj.readline().strip('\r\n'))
    spdOutFile.setNumPulses(nPoints)
    spdOutFile.setNumPts(nPoints)
    if (header.count("Red") > 0):
        spdOutFile.setRgbDefined(1)

    # Loop through each line of data
    outPulses = list()
    pulsesInBuffer = 0
    for i in range(nPoints):

        # Read and parse line
        line = asciiObj.readline().strip('\r\n')
        asciiData = parseLine(header, line)

        # Create pulse and add attributes
        pulse = spdpy.createSPDPulsePy()
        pulse.pulseID = asciiData["ID"]
        pulse.x0 = cmdargs.x0
        pulse.y0 = cmdargs.y0
        pulse.z0 = cmdargs.z0
        pulse.azimuth = asciiData["Phi"]
        pulse.zenith = asciiData["Theta"]

        # Create point and add attributes
        point = spdpy.createSPDPointPy()
        point.returnID = 0
        point.x = asciiData["X"]
        point.y = asciiData["Y"]
        point.z = asciiData["Z"]
        pulse.xIdx = asciiData["X"]
        pulse.yIdx = asciiData["Y"]
        point.range = asciiData["Range"]
        point.amplitudeReturn = asciiData["Amplitude"]
        #if asciiData.has_key("Reflectance"):
        #    point.user = asciiData["Reflectance"]
        if asciiData.has_key("Deviation"):
            point.widthReturn = asciiData["Deviation"]
        if asciiData.has_key("Red"):
            point.red = asciiData["Red"]
            point.green = asciiData["Green"]
            point.blue = asciiData["Blue"]

        # Add point data to the pulse
        pulse.pts.append(point)
        pulse.numberOfReturns = 1
        pulse.pts_start_idx = i

        # Update global statistics
        if i > 0:
            spdOutFile.setXMin(min(spdOutFile.xMin, asciiData["X"]))
            spdOutFile.setXMax(max(spdOutFile.xMax, asciiData["X"]))
            spdOutFile.setYMin(min(spdOutFile.yMin, asciiData["Y"]))
            spdOutFile.setYMax(max(spdOutFile.yMax, asciiData["Y"]))
            spdOutFile.setZMin(min(spdOutFile.zMin, asciiData["Z"]))
            spdOutFile.setZMax(max(spdOutFile.zMax, asciiData["Z"]))
            spdOutFile.setZenithMin(
                min(spdOutFile.zenithMin, asciiData["Theta"]))
            spdOutFile.setZenithMax(
                max(spdOutFile.zenithMax, asciiData["Theta"]))
            spdOutFile.setAzimuthMin(
                min(spdOutFile.azimuthMin, asciiData["Phi"]))
            spdOutFile.setAzimuthMax(
                max(spdOutFile.azimuthMax, asciiData["Phi"]))
            spdOutFile.setRangeMin(min(spdOutFile.rangeMin,
                                       asciiData["Range"]))
            spdOutFile.setRangeMax(max(spdOutFile.rangeMax,
                                       asciiData["Range"]))
        else:
            spdOutFile.setXMin(asciiData["X"])
            spdOutFile.setXMax(asciiData["X"])
            spdOutFile.setYMin(asciiData["Y"])
            spdOutFile.setYMax(asciiData["Y"])
            spdOutFile.setZMin(asciiData["Z"])
            spdOutFile.setZMax(asciiData["Z"])
            spdOutFile.setZenithMin(asciiData["Theta"])
            spdOutFile.setZenithMax(asciiData["Theta"])
            spdOutFile.setAzimuthMin(asciiData["Phi"])
            spdOutFile.setAzimuthMax(asciiData["Phi"])
            spdOutFile.setRangeMin(asciiData["Range"])
            spdOutFile.setRangeMax(asciiData["Range"])

        # If buffer size is reached, write out pulses
        outPulses.append(pulse)
        pulsesInBuffer += 1
        if (pulsesInBuffer == spdOutFile.pulseBlockSize or i == (nPoints - 1)):
            try:
                updWriter.writeData(outPulses)
            except:
                raise IOError, "Error writing UPD File."
            pulsesInBuffer = 0
            outPulses = list()

        # Let's monitor progress
        sys.stdout.write(
            "Writing UPD file %s (%i%%)\r" %
            (cmdargs.outputFile, int((i + 1) / float(nPoints) * 100.0)))

    # Close the input and output files
    asciiObj.close()
    updWriter.close(spdOutFile)
Exemple #5
0
def main(cmdargs):
    """
    Convert TEW files to SPD
    """
    # Create SPD file
    if cmdargs.spdFile is None:
        spdFile = cmdargs.tewFile.replace(".tew", ".spd")
    else:
        spdFile = cmdargs.spdFile
    spdObj = spdpy.createSPDFile(spdFile)
    spdWriter = spdpy.SPDPyNoIdxWriter()
    spdWriter.open(spdObj,spdFile)

    # Set SPD header values
    spdObj.setTransWaveformDefined(1)
    spdObj.setReceiveWaveformDefined(1)
    spdObj.setOriginDefined(1)


    # Read tew-header
    tewObj = open(cmdargs.tewFile, "rb")

    recordFormat115 = struct.Struct('=4c B B H H H I B d I h d d d d d d d d d d d d B 32c f f f B d') #= is to have exact size of the data type.

    if (recordFormat115.size != 181):
        sys.stderr.write( "\nWrong size (" + str(recordFormat115.size) + " bytes) of Python defined header for TEW 1.15. Should be 181 bytes. Please check source code.\n" )
        sys.exit()

    headerStr115 = tewObj.read(recordFormat115.size)
    headerTuple115 = recordFormat115.unpack_from(headerStr115, 0)

    if (headerTuple115[5] == 20):
        recordFormat120 = struct.Struct('=f f 256H 256H')
        headerStr120 = tewObj.read(recordFormat120.size)
        headerTuple120 = recordFormat120.unpack_from(headerStr120, 0)
        tewHeader = header(headerTuple115, headerTuple120)
    else:
        tewHeader = header(headerTuple115)

    tewHeader.summary()


    # Set SPD header values
    spdObj.setSystemIdentifier(tewHeader.systemIdentifier)
    spdObj.setTemporalBinSpacing(tewHeader.sampleLengthNs)
    spdObj.setYearOfCapture(tewHeader.scanYear)
    spdObj.setMonthOfCapture(tewHeader.scanMonth)
    spdObj.setDayOfCapture(tewHeader.scanDay)
    spdObj.setHourOfCapture(0)
    spdObj.setMinuteOfCapture(0)
    spdObj.setSecondOfCapture(0)


    spdPulsesInBuffer = 0 #Count number of spdPulses in buffer before saving to file.
    spdPulseBlockSize = 10000 #Number of pulses before saving to file.
    spdPulses = list()
    time0 = time.time() #Timers used to calculate time to finish.
    time1 = 0 #Timers used to calculate time to finish.

    #Number of pulses to convert.
    numPulsesToConvert = tewHeader.noOfWaveformDataRecs
    if cmdargs.numPulses!=0:
        numPulsesToConvert = min(cmdargs.numPulses, numPulsesToConvert)

    print "Converting", numPulsesToConvert, "pulses"

    #Formats to read from pulse
    pulse4Format = struct.Struct('=d f f H H H 3l 3l B')
    wfHeaderFormat = struct.Struct('=B H') #Block length / Block offset.

    for pulseId in xrange(0, numPulsesToConvert):
        #Pulses
        pulses = list()
        pulsesInBuffer = 0


        # Read tew-pulse header
        pulse4str = tewObj.read(pulse4Format.size)
        pulse4 = pulse4Format.unpack_from(pulse4str, 0)

        #Create and set pulse
        tewPulse = pulse(pulse4)


        # Read tew trigger pulse header
        triggerHeaderStr = tewObj.read(wfHeaderFormat.size)
        triggerHeader = wfHeaderFormat.unpack_from(triggerHeaderStr, 0)

        # Read tew trigger waveform
        triggerWfFormat = array.array('B')
        triggerWfFormat.read(tewObj, triggerHeader[0])
        triggerWf = np.array(triggerWfFormat, dtype=np.uint)

        #Apply correction table (should not be done for trigger wf?)
        #triggerWf = np.zeros(len(triggerWfTemp), dtype=np.uint)
        #for j in xrange(0, len(triggerWfTemp)):
        #    triggerWf[j] = tewHeader.ch1CorrectionTable[triggerWfTemp[j ]]

        #Store header and pulse for trigger waveform
        tewPulse.setTriggerWf(triggerHeader[0], triggerHeader[1], triggerWf)


        # Received waveform ch1
        recWf1Header = list()
        recWf1 = list()
        for i in xrange(0, tewPulse.noOfWfBlocksCh1):
            # Read tew received waveform 1 (low ch) header
            recWf1HeaderStr = tewObj.read(wfHeaderFormat.size)
            recWf1Header.append(wfHeaderFormat.unpack_from(recWf1HeaderStr, 0))

            # Read tew received waveform 1 (low ch = sensitive)
            recWf1Format = array.array('B')
            recWf1Format.read(tewObj, recWf1Header[i][0])
            recWf1Temp = np.array(recWf1Format, dtype=np.uint)

            # Apply correction table
            recWf1.append(np.zeros(len(recWf1Temp), dtype=np.uint))
            for j in xrange(0, len(recWf1Temp)):
                recWf1[i][j] = tewHeader.ch1CorrectionTable[recWf1Temp[j]]

        #Store header and pulse for received waveform #TODO: Need to combine many blocks into one. At the moment, only the last block is stored.
        tewPulse.setWf1(recWf1Header[i][0], recWf1Header[i][1], recWf1[i])



        recWf2Header = list()
        recWf2 = list()
        for i in xrange(0, tewPulse.noOfWfBlocksCh2): #TODO: Add something that combines multiple blocks. And after that combines ch 1 and 2.
            # Read tew received waveform 2 (high ch) header
            recWf2HeaderStr = tewObj.read(wfHeaderFormat.size)
            recWf2Header = wfHeaderFormat.unpack_from(recWf2HeaderStr, 0)

            # Read tew received waveform 2 (high ch)
            recWf2Format = array.array('B')
            recWf2Format.read(tewObj, recWf2Header[0])
            recWf2Temp = np.array(recWf2Format, dtype=np.uint)

            # Apply correction table
            recWf2 = np.zeros(len(recWf2Temp), dtype=np.uint)
            for j in xrange(0, len(recWf2Temp)):
                recWf2[j] = tewHeader.ch2CorrectionTable[recWf2Temp[j]]

            #Store header and pulse for received waveform
            tewPulse.setWf2(recWf2Header[0], recWf2Header[1], recWf2)

        tewPulse.combineRecWf(tewHeader) #Combine ch1 and ch2. TODO: Only take ch 1 at the moment.


        #Print summary about the tew-pulse header if verbosePulses is true.
        if cmdargs.verbosePulses:
            tewPulse.summary()


        #####################################
        #Store the waveform as SPDPulse.
        #####################################
        spdPulse = createSPDPulse(tewHeader, tewPulse, pulseId)
        spdPulses.append(spdPulse)
        spdPulsesInBuffer += 1

        # Write pulses to file
        if spdPulsesInBuffer >= spdPulseBlockSize:
            writeSPDPulses(spdObj, spdWriter, spdPulses)
            spdPulses = list()
            spdPulsesInBuffer = 0
            if cmdargs.verbose:
                pulsesImported = pulseId + 1
                time1 = time.time()
                estimatedTimeToFinish = ((time1-time0)/spdPulseBlockSize * (numPulsesToConvert-pulsesImported))/60.0
                sys.stdout.write("%i pulses imported" % pulsesImported)
                sys.stdout.write(" (Estimated %0.1f min to finish)\r" % estimatedTimeToFinish)
                sys.stdout.flush()
                time0 = time.time()

    #End of for reading pulses.

    sys.stdout.write("\n") #New line before exiting compilation.
    print "Pulses still in buffer:", spdPulsesInBuffer

    #Write SPDPulses that still are in memory (if any)
    if spdPulsesInBuffer>0:
        writeSPDPulses(spdObj, spdWriter, spdPulses)
        print "Just wrote the last pulses in buffer."


    # Close files
    tewObj.close()
    spdWriter.close(spdObj)
Exemple #6
0
import spdpy

spdFileOut = spdpy.createSPDFile("test.spd")

spdFileOut.setNumBinsX(20)
spdFileOut.setNumBinsY(20)
spdFileOut.setBinSize(1)

spdWriter = spdpy.SPDPySeqWriter()
spdWriter.open(spdFileOut, "test.spd")

pulses = list()
for row in range(spdFileOut.numBinsY):
    print "Row:", str(row)
    for col in range(spdFileOut.numBinsX):
        spdWriter.writeDataColumn(pulses, col, row)

spdWriter.close(spdFileOut)
Exemple #7
0
def main(cmdargs):

    # Open UPD file
    spdOutFile = spdpy.createSPDFile(cmdargs.outputFile);
    updWriter = spdpy.UPDWriter()
    updWriter.open(spdOutFile,cmdargs.outputFile)
    outPulses = list()

    # Define contents this lidar dataset
    spdOutFile.setReceiveWaveformDefined(1)
    spdOutFile.setTransWaveformDefined(1)
    spdOutFile.setDecomposedPtDefined(0)
    spdOutFile.setDiscretePtDefined(0)
    spdOutFile.setOriginDefined(1)

    # Define scanner properties
    spdOutFile.setWavelength(1550.0)
    spdOutFile.setTemporalBinSpacing(1)

    # Open ASCII file and read header
    asciiObj = open(cmdargs.inputFile, 'r')

    transmittedWaveform = []
    receivedWaveform = []

    i = 0
    for eachLine in asciiObj:
        if i == 0:
            transmittedWaveform = parseLine(eachLine)
        elif i == 1:
            receivedWaveform = parseLine(eachLine)
        i = i + 1

    linearVals = parseFileToList(cmdargs.linearFile)
    delogVals = parseFileToList(cmdargs.delogFile)

    transmittedWaveformScale = []
    for val in transmittedWaveform:
        transmittedWaveformScale.append(delogVals[val])

    receivedWaveformScale = []
    for val in receivedWaveform:
        receivedWaveformScale.append(linearVals[val])

    pulse = spdpy.createSPDPulsePy()
    pulse.pulseID = 0
    pulse.x0 = 0
    pulse.y0 = 0
    pulse.z0 = 0
    pulse.azimuth = 0
    pulse.zenith = 0
    pulse.numOfTransmittedBins = len(transmittedWaveformScale)
    pulse.transmitted = transmittedWaveformScale
    pulse.transWaveGain = 1
    pulse.transWaveOffset = 0
    pulse.numOfReceivedBins = len(receivedWaveformScale)
    pulse.received = receivedWaveformScale
    pulse.receiveWaveGain = 1
    pulse.receiveWaveOffset = 0
    pulse.waveNoiseThreshold = 9

    outPulses.append(pulse)
    updWriter.writeData(outPulses)
    updWriter.close(spdOutFile)
Exemple #8
0
def main(cmdargs):
    # debugging
    # import pdb; pdb.set_trace()
    
    driver=gdal.GetDriverByName('ENVI')
    """
    Read a DWEL ENVI file and write to SPD
    """    
    # Open the data cube files and read header
    cds = gdal.Open(cmdargs.cubefile, gdal.GA_ReadOnly)
    ads = gdal.Open(cmdargs.ancillaryfile, gdal.GA_ReadOnly)
    
    # Get basic metadata from the ENVI .hdr file
    metaStr = ads.GetMetadata('')
    import pdb; pdb.set_trace()
    # Get the ENVI header file name
    tmpstr = cmdargs.ancillaryfile.rsplit('.')
    if os.path.isfile(tmpstr[0]+'.hdr'):
      hdrname = tmpstr[0]+'.hdr'
    else:
      hdrname = cmdargs.ancillaryfile + '.hdr'
    # Get all metadata including EVI/DWEL defined metadata from the ENVI .hdr file
    hdr = envi_header.ENVI_HDR(hdrname, 'r')
    metaDict = hdr.getmetadata()

    # Open output SPD file
    spdoutfile = spdpy.createSPDFile(cmdargs.outfile)
    spdoutfile.setNumBinsX(cds.RasterXSize)
    spdoutfile.setNumBinsY(cds.RasterYSize)
    spdoutfile.setBinSize(1)
    spdwriter = spdpy.SPDPySeqWriter()
    spdwriter.open(spdoutfile, cmdargs.outfile)
    
    # Define the data present
    spdoutfile.setReceiveWaveformDefined(1)
    spdoutfile.setTransWaveformDefined(0)
    spdoutfile.setDecomposedPtDefined(0)
    spdoutfile.setDiscretePtDefined(0)
    spdoutfile.setOriginDefined(1)
    spdoutfile.setHeightDefined(0)
    spdoutfile.setRgbDefined(0)
    
    # Set header attributes
    spdoutfile.setSensorHeight(metaDict['evi_scan_info']['EVI Height'])
    spdoutfile.setTemporalBinSpacing(1.0 / metaDict['evi_scan_info']['Digitiser Sampling Rate'])
    spdoutfile.setBeamDivergence(metaDict['evi_scan_info']['Beam Divergence'] * 1e-3 / np.pi * 180.0) # unit: degree
    spdoutfile.setPulseIdxMethod(5)
    spdoutfile.setNumPulses(cds.RasterXSize*cds.RasterYSize)
    # The time of captured should be read from the header file later.
    # Now because the DWEL raw data does not give any meta data, the time of capture
    # is manually populated according to the name of field campaign
    if cmdargs.cubefile.lower().find('brisbane') > -1:
      spdoutfile.setYearOfCapture(2013)
      spdoutfile.setMonthOfCapture(7)
    if cmdargs.cubefile.find('CA') > -1:
      spdoutfile.setYearOfCapture(2013)
      spdoutfile.setMonthOfCapture(6)
    spdoutfile.setWaveformBitRes(16)
    # spdoutfile.setNumOfWavelengths(int(metaDict['dwel_adaptation']['Wavelength']))
    spdoutfile.setPulseRepetitionFreq(2000)
    spdoutfile.setMaxScanAngle(180.0)
    if metaDict['evi_scan_info']['Beam Divergence'] == 2.5:
      spdoutfile.setPulseAngularSpacingAzimuth(2.0 * 1e-3 / np.pi * 180.0) # unit: degree
      spdoutfile.setPulseAngularSpacingZenith(2.0 * 1e-3 / np.pi * 180.0) # unit: degree
    if metaDict['evi_scan_info']['Beam Divergence'] == 1.25:
      spdoutfile.setPulseAngularSpacingAzimuth(1.0 * 1e-3 / np.pi * 180.0) # unit: degree
      spdoutfile.setPulseAngularSpacingZenith(1.0 * 1e-3 / np.pi * 180.0) # unit: degree

    # Set user-defined header attribute string with JSON string format
    json_str = '{"evi_scan_info":{"Scan Duration":"' + metaDict['evi_scan_info']['Scan Duration'] + \
        '","Bearing":"' + metaDict['evi_scan_info']['Bearing'] + \
        '","Scan Description":"' + metaDict['evi_scan_info']['Scan Description'] + \
        '","More Description":"'
    json_str = json_str + ','.join(s.replace('"', '\\"') for s in metaDict['evi_scan_info']['descript_str']) 
    json_str = json_str + '"},"dwel_adaptation":{"More Description":"'
    json_str = json_str + ','.join(s.replace('"', '\\"') for s in metaDict['dwel_adaptation']['descript_str']) + '"}}'
    spdoutfile.setUserMetaField(json_str)

    minAz = 360.0
    maxAz = 0.0
    minZen = 180.0
    maxZen = 0.0
    # now read through the image blocks
    for y in range(cds.RasterYSize):
        
        # Read as scan line
        cdata = cds.ReadAsArray(xoff=0, yoff=y, xsize=cds.RasterXSize, ysize=1)
        adata = ads.ReadAsArray(xoff=0, yoff=y, xsize=ads.RasterXSize, ysize=1)
        scanline = list()
        
        for x in range(cds.RasterXSize):
                        
            pulse = spdpy.createSPDPulsePy()
            
            pulse.x0, pulse.y0, pulse.z0 = 0.0, 0.0, 0.0
            pulse.numberOfReturns = 0
            # band 7 (index 6 here) in ancillary is mask, index to bands here
            # starts from 0.
            if adata[6,0,x] == 0: pulse.ignore = 1
            # band 8 (index 7 here) in ancillary is zenith angle.
            pulse.zenith = adata[7,0,x]/10.0
            # band 9 (index 8 here) in ancillary is azimuth angle.
            pulse.azimuth = adata[8,0,x]/10.0            
            
            if pulse.azimuth > maxAz: maxAz = pulse.azimuth
            if pulse.azimuth < minAz: minAz = pulse.azimuth
            if pulse.zenith > maxZen: maxZen = pulse.zenith
            if pulse.zenith < minZen: minZen = pulse.zenith
            
            pulse.numOfReceivedBins = cdata[:,0,x].size

            pulse.received = [int(w) for w in cdata[:,0,x]]
            pulse.wavelength = int(metaDict['dwel_adaptation']['Wavelength'])

            pulse.pulseID = y * x + x
            pulse.xIdx = x
            pulse.yIdx = y
            pulse.scanline = y
            pulse.scanlineIdx = x
        
            #scanline.append(pulse)
            scanline.append([pulse])
        
        # Write scan line
        spdwriter.writeDataRow(scanline, y)
        
        # Let's monitor progress
        # sys.stdout.write("Writing sequential SPD file %s (%i%%)\r" % (cmdargs.outfile, y / float(cds.RasterYSize) * 100.0))
    
    # set more header attributes
    spdoutfile.setZenithMin(minZen)
    spdoutfile.setZenithMax(maxZen)
    spdoutfile.setAzimuthMin(minAz)
    spdoutfile.setAzimuthMax(maxAz)

    # set more header attributes
    # the time of creation will be populated by the spdlib itself. 
    # timenow = datetime.datetime.now()
    # spdoutfile.setYearOfCreation(timenow.year)
    # spdoutfile.setMonthOfCreation(timenow.month)
    # spdoutfile.setDayOfCreation(timenow.day)
    # spdoutfile.setHourOfCreation(timenow.hour)
    # spdoutfile.setMinuteOfCreation(timenow.minute)
    # spdoutfile.setSecondOfCreation(timenow.second)

    # Close the output file
    spdwriter.close(spdoutfile)
    
    # report it's finished
    sys.stdout.write("Writing sequential SPD file %s finished\n" % (cmdargs.outfile))