netcdf file, delete first 1 and last 2 rows of lat and lon - netcdf

I have a netcdf input file of following header:
`netcdf file:/Volumes/NSF12KP3CTL_CLM45_surface.nc {
dimensions:
jx = 180;
iy = 165;
kz = 19;
nmon = 12;
lsmpft = 17;
nlevsoi = 10;
gridcell = 12194;
numurbl = 3;
nlevurb = 5;
numrad = 2;`
And I have another output file that has header:
`dimensions:
gridcell = 12194 ;
landunit = 24398 ;
column = 36632 ;
pft = 207348 ;
jx = 177 ;
iy = 162 ;
levgrnd = 15 ;
levurb = 5 ;
levlak = 10 ;
numrad = 2 ;
string_length = 8 ;
levdcmp = 1 ;
hist_interval = 2 ;
time = UNLIMITED ; // (30 currently)`
All I want is to cut the first 1 and last 2 rows of both jx and iy from input file so that I can merge it into the output file to convert together into 2d lat-lon grid.
Thank you,
Y
I tried with cdo, nco. I have a model executable to convert it into 2d.

Related

How to edit global attributes in netcdf file with NCO

I am trying to edit one of the global attributes in my netcdf file:
START_DATE = "2016-05-12_00:00:00"
I want to change the date string to another date. How do you do this with the nco package?
I've seen that I can use
ncatted [-a ...] [-D dbg_lvl] [-h] [-l path] [-O] [-o out.nc] [-p path] [-R] [-r] in.nc [[out.nc]]
I've read the docs, but there are limited examples shown.
This is how I used it:
ncatted -O -h -a START_DATE,,m,c,"2016-06-12_00:00:00" wrfchemi_d01.nc wrfnew.nc
Upon checking the output with ncdump, the global attribute did not change as seen here:
// global attributes:
:TITLE = " OUTPUT FROM * PROGRAM:WRF-Chem V4.1.2 MODEL" ;
:START_DATE = "2016-05-12_00:00:00" ;
:WEST-EAST_GRID_DIMENSION = 70 ;
:SOUTH-NORTH_GRID_DIMENSION = 70 ;
:BOTTOM-TOP_GRID_DIMENSION = 51 ;
:DX = 25000.f ;
:DY = 25000.f ;
:AERCU_OPT = 0 ;
:AERCU_FCT = 1.f ;
:IDEAL_CASE = 0 ;
:DIFF_6TH_SLOPEOPT = 0 ;
:AUTO_LEVELS_OPT = 2 ;
:DIFF_6TH_THRESH = 0.1f ;
:DZBOT = 50.f ;
:DZSTRETCH_S = 1.3f ;
:DZSTRETCH_U = 1.1f ;
:GRIDTYPE = "C" ;
:DIFF_OPT = 1 ;
:KM_OPT = 4 ;
:DAMP_OPT = 3 ;
:DAMPCOEF = 0.2f ;
:KHDIF = 0.f ;
:KVDIF = 0.f ;
:MP_PHYSICS = -1 ;
:RA_LW_PHYSICS = 1 ;
:RA_SW_PHYSICS = 1 ;
:SF_SFCLAY_PHYSICS = 2 ;
:SF_SURFACE_PHYSICS = 2 ;
:BL_PBL_PHYSICS = 2 ;
:CU_PHYSICS = 5 ;
:SF_LAKE_PHYSICS = 0 ;
:SURFACE_INPUT_SOURCE = 1 ;
:SST_UPDATE = 0 ;
:GRID_FDDA = 0 ;
:GFDDA_INTERVAL_M = 0 ;
:GFDDA_END_H = 0 ;
:GRID_SFDDA = 0 ;
:SGFDDA_INTERVAL_M = 0 ;
:SGFDDA_END_H = 0 ;
:HYPSOMETRIC_OPT = 2 ;
:USE_THETA_M = 1 ;
:GWD_OPT = 0 ;
:SF_URBAN_PHYSICS = 0 ;
:SF_SURFACE_MOSAIC = 0 ;
:SF_OCEAN_PHYSICS = 0 ;
:WEST-EAST_PATCH_START_UNSTAG = 1 ;
:WEST-EAST_PATCH_END_UNSTAG = 69 ;
:WEST-EAST_PATCH_START_STAG = 1 ;
:WEST-EAST_PATCH_END_STAG = 70 ;
:SOUTH-NORTH_PATCH_START_UNSTAG = 1 ;
:SOUTH-NORTH_PATCH_END_UNSTAG = 69 ;
:SOUTH-NORTH_PATCH_START_STAG = 1 ;
:SOUTH-NORTH_PATCH_END_STAG = 70 ;
:BOTTOM-TOP_PATCH_START_UNSTAG = 1 ;
:BOTTOM-TOP_PATCH_END_UNSTAG = 50 ;
:BOTTOM-TOP_PATCH_START_STAG = 1 ;
:BOTTOM-TOP_PATCH_END_STAG = 51 ;
:GRID_ID = 1 ;
:PARENT_ID = 1 ;
:I_PARENT_START = 1 ;
:J_PARENT_START = 1 ;
:PARENT_GRID_RATIO = 1 ;
:DT = 150.f ;
:CEN_LAT = 14.60003f ;
:CEN_LON = 120.98f ;
:TRUELAT1 = 14.6f ;
:TRUELAT2 = 14.6f ;
:MOAD_CEN_LAT = 14.60003f ;
:STAND_LON = 120.98f ;
:POLE_LAT = 90.f ;
:POLE_LON = 0.f ;
:GMT = 0.f ;
:JULYR = 2016 ;
:JULDAY = 133 ;
:MAP_PROJ = 1 ;
:MAP_PROJ_CHAR = "Lambert Conformal" ;
:MMINLU = "USGS" ;
:NUM_LAND_CAT = 28 ;
:ISWATER = 16 ;
:ISLAKE = 28 ;
:ISICE = 24 ;
:ISURBAN = 1 ;
:ISOILWATER = 14 ;
:HYBRID_OPT = 2 ;
:ETAC = 0.2f ;
Can someone show me how its done for this simple change?
Thanks!
It is a global attribute and the syntax you invoked will only change the attribute for all variable attributes of that name, not global attributes. Read the docs on that point and try
ncatted -O -h -a START_DATE,global,m,c,"2016-06-12_00:00:00" wrfchemi_d01.nc wrfnew.nc

Create a GTFS realtime (vehicle positions) with R

I work on turning a dataframe into a GTFS realtime, and am struggling on the vehicle position part.
My data looks like that (stored in a dataframe called "vehicle"):
## Input data looks that way, one line per on-going vehicle
vehicle_id trip_id lat lon bear speed stop_time
52108 4.264930e+05 45.40 -71.92 1 9 2017-05-02 15:19:05
60105 4.273610e+05 45.40 -71.90 246 6 2017-05-02 15:18:59
59104 4.270150e+05 45.40 -71.87 81 7 2017-05-02 15:18:54
The details of my code is:
library(dplyr)
library(XML)
library(stringr)
library(RProtoBuf)
library(RODBC)
## Read the google gtfs proto file
readProtoFiles("gtfs-realtime.proto")
## List of current vehicles
current_vehicles <- unique(vehicle$vehicle_id)
## Create an empty list, 1 entry for each vehicle
protobuf_list <- vector(mode = "list", length = length(current_vehicles))
## Loop over all current vehicles
for(i in 1:length(current_vehicles)) {
## protobuf object
vehicle_position_update <- new(transit_realtime.VehiclePosition,
vehicle = vehicle$vehicle_id[i],
stop_id = vehicle$stop_id[i],
trip = vehicle$trip_id[i],
latitude = vehicle$lat[i],
longitude = vehicle$lon[i],
bearing = vehicle$bear[i],
speed = vehicle$speed[i])
## protobuf feed entity
e <- new(transit_realtime.FeedEntity,
id = as.character(vehicle$vehicle_id[i]),
vehicle = new(transit_realtime.VehiclePosition,
trip = new(transit_realtime.VehicleDescriptor,
id = vehicle$vehicle_id[i]),
VehiclePosition = vehicle_position_update))
## Fill the list
protobuf_list[[i]] <- e
}# Loop over vehicles
## GTFS header
header_object <- new(transit_realtime.FeedHeader,
gtfs_realtime_version = "1.0",
incrementality = "FULL_DATASET",
timestamp = as.numeric(as.POSIXlt(Sys.time())))
## Build the full GTFS
m <- new(transit_realtime.FeedMessage,
header = header_object,
entity = protobuf_list) # use entity_list
## Write the GTFS
writeLines(as.character(m))
## Turn it into binary
serialize(m, "vehiclePositions.pb")
When creating the protobuffer object vehicle_position_update, it crashes with the message:
type mismatch, expecting a 'Message' object
I went through the gtfs-realtime.proto, and my understanding of the different messages to include seems fine (well, obviously it'nt..).
Does anyone see why this protobuffer file cannot be created?
ADDED FOR A CLEAR SOLUTION:
My issue was that I was'nt following exactly the gtfs proto descriptions of the different messages. Once this point corrected, the loop over the vehicles becomes:
## Loop over all current vehicles
for(i in 1:length(current_vehicles)) {
## protobuf object
vehicle_position_update <- new(transit_realtime.Position,
latitude = vehicle$lat[i],
longitude = vehicle$lon[i],
bearing = vehicle$bear[i],
speed = vehicle$speed[i])
## protobuf feed entity
e <- new(transit_realtime.FeedEntity,
id = as.character(vehicle$vehicle_id[i]),
vehicle = new(transit_realtime.VehiclePosition,
trip = new(transit_realtime.TripDescriptor,
trip_id = vehicle$trip_id[i],
route_id = vehicle$route_id[i]),
stop_id = vehicle$stop_id[i],
position = vehicle_position_update))
## Fill the list
protobuf_list[[i]] <- e
}# Loop over vehicles
and it works
The message definition tells you what fields it requires, for example
writeLines(as.character(RProtoBuf::fileDescriptor(transit_realtime.FeedMessage)))
message FeedMessage {
required .transit_realtime.FeedHeader header = 1;
repeated .transit_realtime.FeedEntity entity = 2;
extensions 1000 to 1999;
}
message FeedHeader {
enum Incrementality {
FULL_DATASET = 0;
DIFFERENTIAL = 1;
}
required string gtfs_realtime_version = 1;
optional .transit_realtime.FeedHeader.Incrementality incrementality = 2 [default = FULL_DATASET];
optional uint64 timestamp = 3;
extensions 1000 to 1999;
}
message FeedEntity {
required string id = 1;
optional bool is_deleted = 2 [default = false];
optional .transit_realtime.TripUpdate trip_update = 3;
optional .transit_realtime.VehiclePosition vehicle = 4;
optional .transit_realtime.Alert alert = 5;
extensions 1000 to 1999;
}
... etc
Then, if you take a look at the Position message, you see the fields
message Position {
required float latitude = 1;
required float longitude = 2;
optional float bearing = 3;
optional double odometer = 4;
optional float speed = 5;
extensions 1000 to 1999;
}
So you define the Position using those values, e.g.
RProtoBuf::new(transit_realtime.Position, latitude = 0, longitude = 0)
And the VehiclePosition message is
message VehiclePosition {
enum VehicleStopStatus {
INCOMING_AT = 0;
STOPPED_AT = 1;
IN_TRANSIT_TO = 2;
}
enum CongestionLevel {
UNKNOWN_CONGESTION_LEVEL = 0;
RUNNING_SMOOTHLY = 1;
STOP_AND_GO = 2;
CONGESTION = 3;
SEVERE_CONGESTION = 4;
}
enum OccupancyStatus {
EMPTY = 0;
MANY_SEATS_AVAILABLE = 1;
FEW_SEATS_AVAILABLE = 2;
STANDING_ROOM_ONLY = 3;
CRUSHED_STANDING_ROOM_ONLY = 4;
FULL = 5;
NOT_ACCEPTING_PASSENGERS = 6;
}
optional .transit_realtime.TripDescriptor trip = 1;
optional .transit_realtime.VehicleDescriptor vehicle = 8;
optional .transit_realtime.Position position = 2;
optional uint32 current_stop_sequence = 3;
optional string stop_id = 7;
optional .transit_realtime.VehiclePosition.VehicleStopStatus current_status = 4 [default = IN_TRANSIT_TO];
optional uint64 timestamp = 5;
optional .transit_realtime.VehiclePosition.CongestionLevel congestion_level = 6;
optional .transit_realtime.VehiclePosition.OccupancyStatus occupancy_status = 9;
extensions 1000 to 1999;
}
So the message will be like
RProtoBuf::new(transit_realtime.VehiclePosition,
current_status = 1,
congestion_level = 0,
stop_id = "7",
current_stop_sequence = 1)

Invalid index error in a for loop

I've been working in this code for a while, it's pretty simple, just recursive calculation. At the while loop, in the first line I got an index error. Funny thing is before I start using the if statement in loop my index was fine and I could compile it. My believe my problem is the lack of familiarity with the scilab way of programming.
///CONSTANTES////
roh_H20 = 1030.00 // [kg/m^3] Água Salgada
roh_ar = 1.22 // [kg/m^3]
g = 9.81 // [m/s^2]
V_elo = 0.00041 // [m^3]
V_boia = 0.00811 // [m^3]
V_lastro = 0.00811 // [m^3]
D_corda = 0.030 // [m]
A_corda = 1/4*%pi*D_corda**2
L_corda = 30 // [m]
roh_corda = 905 // [kg/m^3] poliester
V_corda = A_corda*L_corda // [m^3]
roh_elo = 952 // [kg/m^3] PE Alta Densidade
m_elo = 0.38817 // [kg]
m_boia = 1.5654 // [Kg]
m_lastro = 2.5 // [kg] CHUTE
m_corda = roh_corda*V_corda; // [kg]
Cd = 1.3 // coeficiente de arrasto placa plana FOX pg 396
N_elo = 7*24 // conjuntos a cada 1 metro
N_corda = 4 // A definir
N_boia = 7 // 2 primeiros conjuntos
N_lastro = 7 // 2 últimos conjuntos
/// PROBLEMA ESTATICO ////
M = N_elo*m_elo + N_boia*(m_boia + m_lastro) // FALTA CORDA
P = M*g
Emp = g*(N_boia*V_boia + N_elo*V_elo + N_lastro*V_lastro)*roh_H20;
printf("\n*****PROBLEMA ESTATICO*****\n")
printf("\nO Peso do conjunto eh: %f N\n", P)
printf("\nO Empuxo eh: %f N\n", Emp)
/// PROBLEMA DINÂMICO ///
A_vela = 0.03230 // [m^2] dado pelo SolidWorks
N_vela = 7
printf("\n*****PROBLEMA DINAMICO*****\n")
a = zeros(0,1e3)
a(1)= (Emp-P)/ M
printf("\na_0 = %f [m/s^2]\n", a(1))
t=0
v= zeros(0,1e3)
dy = zeros(0,1e3)
Fd = zeros(0,1e3)
for i=1:50
// if i == 1 then
// a(i)= (Emp-P)/ M
// else
// 1+1
// end
v(i+1) = v(i) + a(i)*t
dy(i+1) = dy(i)+v(i+1)*t+ a(i)*t*t/2.0
Fd(i+1) = 0.5*roh_H20*Cd*N_vela*A_vela*v(i+1)**2
if v(i+1) > 0 then
a(i+1) = (Emp - P - Fd(i+1))/ M;
elseif v(i+1) <= 0 then
a(i+1) = (Emp - P + Fd(i+1))/ M;
end,
t=t+0.05
end
x = linspace(0,t,int(i))
// Grafico velocidade/aceleração
clf(0)
scf(0)
subplot(2,1,1)
plot(x,a,'ro-')
xlabel("Tempo [s]")
ylabel("Acelaração [m/s^2]")
legend("aceleração")
subplot(2,1,2)
plot(x,v,'bs:')
xlabel("Tempo [s]")
ylabel("velocidade [m/s]")
legend("velocidade")
// Grafico forca/deslocamento
clf(1)
scf(1)
subplot(2,1,1)
plot(x,Fd,'r--d')
xlabel("Tempo [s]")
ylabel("Força [N]")
legend("Força Arrasto")
subplot(2,1,2)
plot(x,dy,'m--^')
xlabel("Tempo [s]")
ylabel("Descolcamento [m]")
legend("deslocamento")
Whenever you have index error, there are two things to do in the console:
Check the value of the index variable (just by entering its name)
Check the size(s) of any arrays involved (using the command size)
In this case, checking the size of a would show it's not what you expected it to be. Why? Because of this:
a = zeros(0,1e3)
v= zeros(0,1e3)
dy = zeros(0,1e3)
Fd = zeros(0,1e3)
The arguments of zeros are the height and width of a matrix. You are asking for height 0... this means empty matrix, since it has no rows. What you want is a row vector, which is a matrix with one row.
After fixing this you'll run into a problem with
x = linspace(0,t,int(i))
plot(x,a,'ro-')
because x and a are not of the same size.
To keep sizes consistent, you could do something like this:
imax = 50;
a = zeros(1,imax)
v= zeros(1,imax)
dy = zeros(1,imax)
Fd = zeros(1,imax)
and later for i=1:imax and x = linspace(0,t,imax).
This way you are not creating oversized arrays, but only arrays of the size you want, which can be adjusted by changing the value of imax.

Converting ISO 6709 Formatted GPS Coordinates to Decimal Degrees in R

We have a piece of equipment that outputs its GPS coordinates as numeric values to file in an ISO 6709 lat/lon format of Lat = ±DDMM.MMMM & Lon = ±DDDMM.MMMM
Are there any packages with functions (or custom functions) in R that will convert this to a Decimal degrees format? (ie: ±DD.DDDDDD & ±DDD.DDDDDD)
An example would be that lat & lon (2433.056, -8148.443) would be converted to (24.55094, -81.80739).
You could read in the values from the file using something like read.csv or read.delim.
Then to convert from DDMM.MMMM and DDDMM.MMMM you could use something like this (of course modify as needed for the form of your input/outputs):
convertISO6709 <- function( lat, lon ) {
# will just do lat and lon together, as the process is the same for both
# It's simpler to do the arithmetic on positive numbers, we'll add the signs
# back in at the end.
latlon <- c(lat,lon)
sgns <- sign(latlon)
latlon <- abs(latlon)
# grab the MM.MMMM bit, which is always <100. '%%' is modular arithmetic.
mm <- latlon %% 100
# grab the DD bit. Divide by 100 because of the MM.MMMM bit.
dd <- (latlon - mm)/100
# convert to decimal degrees, don't forget to add the signs back!
out_latlon <- (dd+mm/60) * sgns
return(out_latlon)
}
This may not be the most elegant PHP code, but it does work:
function convertISO6709($coord)
{
$abs_coord = abs($coord);
$sign = ($abs_coord == $coord) ? 1 : -1;
$m = 2;
$dlen = 2;
$s = 0;
$seconds = 0;
switch (strlen($abs_coord)) {
case 4 :
break;
case 5 :
$dlen = 3;
$m = 3;
break;
case 6 :
$s = 4;
break;
}
$degrees = substr($abs_coord, 0, $dlen);
$minutes = substr($abs_coord, $m, 2);
if ($s != 0) {
$seconds = substr($abs_coord, $s, 2);
}
return ($degrees + ($minutes / 60) + ($seconds / 3600)) * $sign;
}
I has a similar issue getting coordinates from FedEx WS. I used this function to get the values from a string like +19.467945-99.14357/:
function convertCoordISO6709($coord)
{
//$coord example
//$coord = +19.467945-99.14357/
$returnArray[0] = 1;//result non 0 means error
$returnArray[1] = 0;//Lat
$returnArray[2] = 0;//long
$coord = trim($coord,"/"); //Strip / sign
//look for + - sign
$lat_sign = substr($coord,0,1); //strip and save the first sign (latitude value)
$sub_coord = substr($coord,1,strlen($coord));
if(count(explode("+",$sub_coord)) == 2) //Second value is + for the longitude
{
$coords=explode("+",$sub_coord);
$returnArray[0] = 0;
$returnArray[1] = $lat_sign.$coords[0];
$returnArray[2] = "+".$coords[1];
}
else //Second value is - for the longitude
{
$coords=explode("-",$sub_coord);
$returnArray[0] = 0;
$returnArray[1] = $lat_sign.$coords[0];
$returnArray[2] = "-".$coords[1];
}
return $returnArray;
}

Converting a decimal to a mixed-radix (base) number

How do you convert a decimal number to mixed radix notation?
I guess that given an input of an array of each of the bases, and the decimal number, it should output an array of the values of each column.
Pseudocode:
bases = [24, 60, 60]
input = 86462 #One day, 1 minute, 2 seconds
output = []
for base in reverse(bases)
output.prepend(input mod base)
input = input div base #div is integer division (round down)
Number -> set:
factors = [52,7,24,60,60,1000]
value = 662321
for i in n-1..0
res[i] = value mod factors[i]
value = value div factors[i]
And the reverse:
If you have the number like 32(52), 5(7), 7(24), 45(60), 15(60), 500(1000) and you want this converted to decimal:
Take number n, multiply it with the factor of n-1, continue for n-1..n=0
values = [32,5,7,45,15,500]
factors = [52,7,24,60,60,1000]
res = 0;
for i in 0..n-1
res = res * factors[i] + values[i]
And you have the number.
In Java you could do
public static int[] Number2MixedRadix(int[] base, int number) throws Exception {
//NB if the max number you want # a position is say 3 then the base# tha position
//in your base array should be 4 not 3
int[] RadixFigures = new int[base.length];
int[] PositionPowers = new int[base.length];
PositionPowers[base.length-1] = 1;
for (int k = base.length-2,pow = 1; k >-1; k--){
pow*=base[k+1];
PositionPowers[k]=pow;
}for (int k = 0; k<base.length; k++){
RadixFigures[k]=number/PositionPowers[k];
if(RadixFigures[k]>base[k])throw new Exception("RadixFigure#["+k+"] => ("+RadixFigures[k]+") is > base#["+k+"] => ("+base[k]+") | ( number is Illegal )");
number=number%PositionPowers[k];
}return RadixFigures;
}
Example
//e.g. mixed-radix base for 1day
int[] base = new int[]{1, 24, 60, 60};//max-day,max-hours,max-minutes,max-seconds
int[] MixedRadix = Number2MixedRadix(base, 19263);//19263 seconds
//this would give [0,5,21,3] => as per 0days 5hrs 21mins 3secs
Reversal
public static int MixedRadix2Number(int[] RadixFigures,int[] base) throws Exception {
if(RadixFigures.length!=base.length)throw new Exception("RadixFigures.length must be = base.length");
int number=0;
int[] PositionPowers = new int[base.length];
PositionPowers[base.length-1] = 1;
for (int k = base.length-2,pow = 1; k >-1; k--){
pow*=base[k+1];
PositionPowers[k]=pow;
}for (int k = 0; k<base.length; k++){
number+=(RadixFigures[k]*PositionPowers[k]);
if(RadixFigures[k]>base[k])throw new Exception("RadixFigure#["+k+"] => ("+RadixFigures[k]+") is > base#["+k+"] => ("+base[k]+") | ( number is Illegal )");
}return number;
}
I came up with a slightly different, and probably not as good method as the other ones here, but I thought I'd share anyway:
var theNumber = 313732097;
// ms s m h d
var bases = [1000, 60, 60, 24, 365];
var placeValues = []; // initialise an array
var currPlaceValue = 1;
for (var i = 0, l = bases.length; i < l; ++i) {
placeValues.push(currPlaceValue);
currPlaceValue *= bases[i];
}
console.log(placeValues);
// this isn't relevant for this specific problem, but might
// be useful in related problems.
var maxNumber = currPlaceValue - 1;
var output = new Array(placeValues.length);
for (var v = placeValues.length - 1; v >= 0; --v) {
output[v] = Math.floor(theNumber / placeValues[v]);
theNumber %= placeValues[v];
}
console.log(output);
// [97, 52, 8, 15, 3] --> 3 days, 15 hours, 8 minutes, 52 seconds, 97 milliseconds
I tried a few of the examples before and found an edge case they didn't cover, if you max out your scale you need to prepend the result from the last step
def intToMix(number,radix=[10]):
mixNum=[]
radix.reverse()
for i in range(0,len(radix)):
mixNum.append(number%radix[i])
number//=radix[i]
mixNum.append(number)
mixNum.reverse()
radix.reverse()
return mixNum
num=60*60*24*7
radix=[7,24,60,60]
tmp1=intToMix(num,radix)

Resources