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.')
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)
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)
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)
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)
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)
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)
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))