Python Forum
How to pass multiple values from one sample to nc variable?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to pass multiple values from one sample to nc variable?
#1
I am using the following script to write the date and the snow cover values from each of the 258 files into a single NetCDF file. But python is not letting me add these for some reason. The code is using scipy.io.netcdf. and is as follows:
#!/usr/bin/env python

#----------------------------------------------------
# Program to convert VIC fluxes files to NetCDF file
# will ask the user wich variable he wants to export
# and also for wich years. Assumes there is data
# for the entire time period, from 1-jan to 31-dec
# SET UP FOR DAILY TIME STEP. FLUX FILE SHOUD NOT
# CONTAIN HOUR RECORD!!
#----------------------------------------------------

#------------------------------------------------
# Writen by Daniel de Castro Victoria
# [email protected] or [email protected]
# 03-dec-2004
#
# 13-mar-2018: Code update. Change libraries and treat
# header lines. Changes done by Stuart Smith (smit1770 at purdue dot edu)
#-------------------------------------------------

import os
import sys
# handle dates...
import datetime
# SciPy netCDF and NumPy
from scipy.io.netcdf import *
from numpy import *

# In case flux files contains header lines
# set the variable according to the number of lines
skip_lines = 6

# checking user input
print len(sys.argv)
if len(sys.argv) != 2:
    print "Wrong user input"
    print "Convert VIC fluxes files to NetCDF"
    print "usage flux2cdf.py <vic flux dir>"
    print "VIC FLUX DIR SHOULD CONTAIN TRAILING /"
    sys.exit()

if sys.argv[1][-1] != "/":
    print "VIC FLUX DIR SHOULD CONTAIN TRAILING /"
    print "fixing it for you..."
    sys.argv[1] = sys.argv[1] + "/"

print "IMPORTANT: "+sys.argv[1]+" SHOULD CONTAIN ONLY FLUXES FILES!!!"

# building file list and sorted lat lon list
file_list = os.listdir(sys.argv[1])

lat_t = []
lon_t = []
lat = []
lon = []

for f in file_list:
    lat_t.append(float(f.split("_")[1]))
    lon_t.append(float(f.split("_")[2]))

for i in lat_t:
    if i not in lat:
        lat.append(i)

for i in lon_t:
    if i not in lon:
        lon.append(i)


# putting in order. Lat should be from top to botom
# lon from left to rigth
lon.sort()
lat.sort()
lat.reverse()

del(lat_t)
del(lon_t)

#determining the parameter to use
print "Choose output parameter"
print "1 - Snow_Cover"
print "2 - Surface_Temperature"
print "3 - Runoff"
print "4 - Base flow"
print "5 - SWE"
print "6 - Precipitation"
print "7 - Evaporation"
print "8 - Soil Moisture"

varini = input('Choose output (1 a 8)>')

#getting the collumn right
if int (varini) < 8:
    var = varini + 2
elif varini == 8:        #more than one soil layer...
    camada = input('which soil layer?>')
    var = varini + 1 + camada

#set name of out_file. Named after parameter choice
if var == 3:
    var_txt = "Snow_Cover"
    var_name = "Snow_Cover"
elif var == 4:
    var_txt = "Surf_Temp"
    var_name = "Surface_Temperature"
elif var == 5:
    var_txt = "Runoff"
    var_name = "Runoff"
elif var == 6:
    var_txt = "base"
    var_name = "Baseflow"
elif var == 7:
    var_txt = "SWE"
    var_name = "SWE"
elif var == 8:
    var_txt = "Precipitation"
    var_name = "Precipitation"
elif var == 9:
    var_txt = "Evaporation"
    var_name = "Evaporation"
else:
    var_txt = "soil_"+str(camada)
    var_name = "Soil moisture, layer %i", camada

# for what date?
start_year = input("Enter start year:")
end_year = input("End year:")

inidate = datetime.date(start_year,1,1)
enddate = datetime.date(end_year,12,31)

days = enddate.toordinal() - inidate.toordinal()+1

print "Go grab a coffe, this could take a while..."

#
# create array containig all data
# This is going to be huge. Create an array with -9999 (NoData)
# Then populate the array by reading each flux file
#

all_data = zeros([days,len(lat),len(lon)], float)-9999

c = len(file_list)

# for each file in list
for f in file_list:
    # get lat & lon and it's index
    latitude = float(f.split("_")[1])
    longitude = float(f.split("_")[2])
    lat_id = lat.index(latitude)
    lon_id = lon.index(longitude)

    print "%i files to write." % c
    c = c -1

    infile = open(sys.argv[1]+f, "r")
    # here we skip the number of header lines
    # variable set at the begining of the code
    lixo = infile.readlines()[skip_lines:]
    infile.close()
    dado = []
    previousLine = []

    for l in lixo:
        if int(l.split("\t")[0]) in range(inidate.year, enddate.year+1):
            if var==3:
                lnSplit=l.split("\t")
                if len(previousLine)==0:                    
                    previousLine=array([int(lnSplit[0]),int(lnSplit[1]),int(lnSplit[2]),float(lnSplit[var])], dtype=object)
                else:
                    currentLine=array([int(lnSplit[0]),int(lnSplit[1]),int(lnSplit[2]),float(lnSplit[var])], dtype=object)
                    if currentLine[3]==0 and previousLine[3]>0:
                        dado.append(previousLine)
                        dado.append(currentLine)
                    previousLine=currentLine[:]
            else:
                dado.append(float(l.split("\t")[var]))
        # putting data inside array.
        # Since data has lat & lon fixed uses dimension [:,lat_index,lon_index]

    #print dado
    if var==3:
        all_data = zeros([len(dado),len(lat),len(lon)], float)-9999
        print dado
        all_data[:,lat_id,lon_id] = dado[:]
    else:
        all_data[:,lat_id,lon_id] = dado

#
# writing NetCDF
#

ncfile = netcdf_file(var_txt+".nc", "w")

ncfile.Conventions = "COARDS"
ncfile.history = "Created using flux2cdf.py. " + datetime.date.today().isoformat()
ncfile.production = "VIC output"

ncfile.start_date = inidate.isoformat()
ncfile.end_date = enddate.isoformat()

#create dimensions
ncfile.createDimension("X", len(lon))
ncfile.createDimension("Y", len(lat))
ncfile.createDimension("T", days)

#create variables
latvar = ncfile.createVariable("Y", "f4", ("Y",))
latvar.long_name = "Latitude"
latvar.units = "degrees_north"
latvar[:] = lat

lonvar = ncfile.createVariable("X", "f4", ("X",))
lonvar.long_name = "Longitude"
lonvar.units = "degrees_east"
lonvar[:] = lon

timevar = ncfile.createVariable("T", "f4", ("T",))
timevar.long_name = "Time"
timevar.units = "days since " + inidate.isoformat()
timevar[:] = range(0, days)

data_var = ncfile.createVariable(var_txt, "f4", ("T","Y","X"))
data_var.long_name = var_name+" calculated by VIC"
data_var.missing_value = -9999.0
data_var.units = "milimeters"
data_var[:] = all_data

ncfile.close()
Part of the file (ASCII) being used as input by the code is as follows:

# NRECS: 1096
# DT: 24
# STARTDATE: 1999-01-01 00:00:00
# ALMA_OUTPUT: 0
# NVARS: 10
# YEAR  MONTH   DAY OUT_SNOW_COVER   OUT_SURF_TEMP   OUT_RUNOFF  OUT_BASEFLOW    OUT_SWE     OUT_EVAP    OUT_PREC
1999    01  01  0.0000   -0.6910     0.0000  1.7175  0.0000  1.2187  1.2250
1999    01  02  0.0000   -8.1983     0.0000  1.7042  0.0000  0.0132  0.0000
So the intent is to write year month day (date in one variable) and snow cover from the 258 such files into a single NetCDF file. As for the error, it is as follows:
Error:
Go grab a coffe, this could take a while... 258 files to write. [array([1999, 5, 31, 0.1452], dtype=object), array([1999, 6, 1, 0.0], dtype=object), array([1999, 10, 19, 0.6025], dtype=object), array([1999, 10, 20, 0.0], dtype=object), array([1999, 11, 5, 0.3194], dtype=object), array([1999, 11, 6, 0.0], dtype=object), array([2000, 5, 24, 0.3056], dtype=object), array([2000, 5, 25, 0.0], dtype=object), array([2000, 9, 27, 0.0781], dtype=object), array([2000, 9, 28, 0.0], dtype=object)] Traceback (most recent call last): File "D:\Spring_2020\VIC\VIC_4.2d\VIC-support-VIC.4.2.d\src\flux2nc_Snow_Cover.py", line 186, in <module> all_data[:,lat_id,lon_id] = dado[:] ValueError: setting an array element with a sequence.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  __init__() got multiple values for argument 'schema' dawid294 4 1,888 Jan-03-2024, 09:42 AM
Last Post: buran
  Multiple variable inputs when only one is called for ChrisDall 2 449 Oct-20-2023, 07:43 PM
Last Post: deanhystad
  How to pass encrypted pass to pyodbc script tester_V 0 803 Jul-27-2023, 12:40 AM
Last Post: tester_V
  store all variable values into list and insert to sql_summary table mg24 3 1,097 Sep-28-2022, 09:13 AM
Last Post: Larz60+
  How to combine multiple column values into 1? cubangt 15 2,631 Aug-11-2022, 08:25 PM
Last Post: cubangt
  Multiple Loop Statements in a Variable Dexty 1 1,175 May-23-2022, 08:53 AM
Last Post: bowlofred
  Compare variable with values in a file paulo79 1 1,079 Apr-22-2022, 03:16 AM
Last Post: Pedroski55
  Pass variable to subprocess paulo79 4 9,957 Apr-12-2022, 12:35 PM
Last Post: DeaD_EyE
  How to add for loop values in variable paulo79 1 1,411 Mar-09-2022, 07:20 PM
Last Post: deanhystad
  How to pass list of values to a API request URL chetansaip99 0 3,474 Sep-28-2021, 07:37 AM
Last Post: chetansaip99

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020