Git Product home page Git Product logo

biorad's Introduction

bioRad

CRAN status R-CMD-check repo status codecov DOI

bioRad provides standardized methods for extracting and reporting biological signals from weather radars. It includes functionality to inspect low-level radar data, process these data into meaningful biological information on animal speeds and directions at different altitudes in the atmosphere, visualize these biological extractions, and calculate further summary statistics.

To get started, see:

More vignettes:

  • Range correction: estimate spatial images of vertically integrated density corrected for range effects.

Documentation for the latest development version can be found here.

Installation

Install system libraries

For OS X and Linux the GNU Scientific Library (GSL), PROJ and HDF5 libraries need to be installed as system libraries prior to installation, which are required by dependency package vol2birdR:

System Command
OS X (using Homebrew) brew install hdf5 proj gsl
Debian-based systems (including Ubuntu) sudo apt-get install libhdf5-dev libproj-dev gsl-bin libgsl-dev
Systems supporting yum and RPMs sudo yum install hdf5-devel proj-devel gsl gsl-devel
Additional required system libraries on Linux (Ubuntu)

The following system libraries are required before installing bioRad on Linux systems. In terminal, install these with:

sudo apt install libcurl4-openssl-dev
sudo apt install libssl-dev
sudo apt install libgdal-dev

Install bioRad

You can install the released version of bioRad from CRAN with:

install.packages("bioRad")

Alternatively, you can install the latest development version from GitHub with:

# install.packages("devtools")
devtools::install_github("adokter/bioRad")

Then load the package with:

library(bioRad)
#> Welcome to bioRad version 0.7.3
#> using vol2birdR version 1.0.1 (MistNet installed)

(optional) Enable MistNet

To enable MistNet, the following vol2birdR commands should be executed:

vol2birdR::install_mistnet()
vol2birdR::install_mistnet_model()

Read the vol2birdR documentation for more details.

Usage

Radar data example

bioRad can read weather radar data (= polar volumes) in the ODIM format and formats supported by the RSL library, such as NEXRAD data. NEXRAD data (US) are available as open data and on AWS.

Here we read an example polar volume data file with read_pvolfile(), extract the scan/sweep at elevation angle 3 with get_scan(), project the data to a plan position indicator with project_as_ppi() and plot the radial velocity of detected targets with plot():

library(tidyverse) # To pipe %>% the steps below
system.file("extdata", "volume.h5", package = "bioRad") %>%
  read_pvolfile() %>%
  get_scan(3) %>%
  project_as_ppi() %>%
  plot(param = "VRADH") # VRADH = radial velocity in m/s

Radial velocities towards the radar are negative, while radial velocities away from the radar are positive, so in this plot there is movement from the top right to the bottom left.

Vertical profile data example

Weather radar data can be processed into vertical profiles of biological targets using calculate_vp(). This type of data is available as open data for over 100 European weather radars.

Once vertical profile data are loaded into bioRad, these can be bound into time series using bind_into_vpts(). Here we read an example time series, project it on a regular time grid with regularize_vpts() and plot it with plot():

example_vpts %>%
  regularize_vpts() %>%
  plot()

The gray bars in the plot indicate gaps in the data.

The altitudes in the profile can be integrated with integrate_profile() resulting in a dataframe with rows for datetimes and columns for quantities. Here we plot the quantity migration traffic rate (column mtr) with plot():

my_vpi <- integrate_profile(example_vpts)

plot(my_vpi, quantity = "mtr") # mtr = migration traffic rate

To know the total number of birds passing over the radar during the full time series, we use the last value of the cumulative migration traffic (column mt):

my_vpi %>%
  pull(mt) %>% # Extract column mt as a vector
  last()
#> [1] 129491.5

For more exercises, see this tutorial.

Meta

  • We welcome contributions including bug reports.
  • License: MIT
  • Get citation information for bioRad in R doing citation("bioRad").
  • Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

biorad's People

Contributors

actions-user avatar adokter avatar baptischmi avatar bart1 avatar barthoekstra avatar berendwijers avatar cecilianilsson709 avatar iskandari avatar peterdesmet avatar pietrh avatar plieper avatar rafnuss avatar stijnvanhoey avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

biorad's Issues

Split R code over files by function

For better readability, maintenance and collaboration, I'd suggest to split bioRad.R (and the other R files) in logical files: one per function (and its helper functions), with the same name as that function.

@adokter these are all the functions I found, per current file. It's quite the list 😅 At first glance, think it would be better to group these by what they do (e.g. bind, vintegrate) that their data type (vp, vplist).

bioRad.R

function remarks new file reference section
checkDocker in NAMESPACE docker.R docker interface
updateDocker in NAMESPACE docker.R docker interface
startContainer docker.R
readOdimProfileData hdf5.R
quantityName hdf5.R
readvp in NAMESPACE vp.R vertical profile
is.vpfile in NAMESPACE vp.R vertical profile
is.pvolfile in NAMESPACE pvol.R polar volume
h5ODIMobject in NAMESPACE hdf5.R loading data
is.ODIMfile hdf5.R
readvp.list in NAMESPACE vp.R loading data
c.vp in NAMESPACE vp.R vertical profile
bind in NAMESPACE profile.R vertical profile time series
bind.vp bind.R
bind.vplist bind.R
bind.vpts bind.R
summary.vplist vplist.R
print.vplist vplist.R
vpts in NAMESPACE vpts.R vertical profile time series
vptsHelper vpts.R
vintegrate in NAMESPACE vintegrate.R migration traffic and vertical integration
vintegrate.vp vintegrate.R
vintegrate.vplist vintegrate.R
vintegrate.vpts vintegrate.R
print.vpts vpts.R
vol2bird in NAMESPACE vol2bird.R processing vertical profiles from polar volume data
rsl2odim in NAMESPACE vol2bird.R processing vertical profiles from polar volume data
rsl2odim_tempfile   vol2bird.R
readvp.table in NAMESPACE vp.R loading data
regularize in NAMESPACE vpts.R vertical profile time series
mtr in NAMESPACE traffic.R migration traffic and vertical integration
summary.vp vp.R
is.vp in NAMESPACE vp.R vertical profile
is.vplist in NAMESPACE vplist.R vertical profile
summary.vpts vpts.R
is.vpts in NAMESPACE vpts.R vertical profile time series
dim.vpts vpts.R
[.vpts vpts.R
vpts2vp vpts.R
rcs in NAMESPACE rcs.R vertical profile attributes
rcs.vp rcs.R
rcs.vplist rcs.R
rcs.vpts rcs.R
rcs.vivp rcs.R
rcs<- in NAMESPACE rcs.R vertical profile attributes
rcs<-.vp rcs.R
rcs<-.vplist rcs.R
rcs<-.vpts rcs.R
rcs<-.vivp rcs.R
sd_vvp in NAMESPACE sd_vvp.R thresholding attributes
sd_vvp.vp sd_vvp.R
sd_vvp.vplist sd_vvp.R
sd_vvp.vpts sd_vvp.R
sd_vvp<-  in NAMESPACE sd_vvp.R thresholding attributes
sd_vvp<-.vp sd_vvp.R
sd_vvp<-.vplist sd_vvp.R
sd_vvp<-.vpts sd_vvp.R
mt in NAMESPACE traffic.R migration traffic and vertical integration
cmt in NAMESPACE traffic.R migration traffic and vertical integration
suntime in NAMESPACE suntime.R sunrise and sunset functions
night in NAMESPACE suntime.R sunrise and sunset functions
day in NAMESPACE suntime.R sunrise and sunset functions
day.vp   suntime.R
day.vplist suntime.R
day.vpts suntime.R
day.pvol suntime.R
beamheight in NAMESPACE beam.R radar and scan geometry
earthradius  beam.R
beamwidth in NAMESPACE beam.R radar and scan geometry
dbz2eta in NAMESPACE dbz_eta.R converting reflectivity and reflectivity factor
eta2dbz  in NAMESPACE dbz_eta.R converting reflectivity and reflectivity factor
fetch in NAMESPACE dispatch.R extracting data from bioRad objects
fetch.vp  fetch.R
fetch.vplist  fetch.R
fetch.vpts  fetch.R
as.data.frame.vpts in NAMESPACE vpts.R extracting data from bioRad objects

bioRad.plot.R

function remarks new file reference section
is.na2 plot_profile.R
plot.vp in NAMESPACE plot_profile.R vertical profile
plot.vivp in NAMESPACE  plot_profile.R migration traffic and vertical integration
plot.vpts in NAMESPACE  plot_profile.R vertical profile time series
plot_wind_barbs    plot_profile.R

bioRad.ppi.R

function remarks new file reference section
read.pvol  in NAMESPACE pvol.R polar volume
read.scan scan.R
read.quantity scan.R
print.pvol pvol.R
print.scan  scan.R
print.param  param.R
summary.pvol  pvol.R
is.pvol in NAMESPACE pvol.R polar volume
summary.scan scan.R
is.scan in NAMESPACE scan.R polar scan
dim.scan  in NAMESPACE  scan.R polar scan
summary.param   param.R
is.param in NAMESPACE param.R polar scan parameter
elangle in NAMESPACE elangle.R radar and scan geometry
elangle.scan elangle.R
elangle.pvol elangle.R
getscan in NAMESPACE pvol.R polar scan
ppi in NAMESPACE ppi.R projecting scans as a plan position indicator
[.ppi    ppi.R
ppi.param ppi.R
ppi.scan  ppi.R
composite in NAMESPACE composite.R compositing
samplePolar  ppi.R
wgs2proj  ppi.R
proj2wgs  ppi.R
cartesian2polar  ppi.R
safeSubset ppi.R
polar2index ppi.R
get_colorscale  colorscale.R
get_colorscale_fill    colorscale.R
get_zlim  param.R
plot.ppi in NAMESPACE  ppi.R
basemap in NAMESPACE map.R overlaying radar scans on a map
map in NAMESPACE map.R overlaying radar scans on a map
add.alpha map.R
map.ppi  map.R
print.ppi  ppi.R
summary.ppi  ppi.R
is.ppi in NAMESPACE ppi.R projecting scans as a plan position indicator
dim.ppi in NAMESPACE ppi.R projecting scans as a plan position indicator

download_vp.R

function remarks new file reference section
url_existence in NAMESPACE vp_repo.R loading data
download_vp in NAMESPACE vp_repo.R loading data
match_filenames in NAMESPACE vp_repo.R loading data
retrieve_vp_paths in NAMESPACE vp_repo.R loading data

Bug in readvp.table function

When using the readvp.table function on a vol2bird text output, I got the following error:

Warning message: In Ops.factor(heights[-1], heights[-length(heights)]) : '-' not meaningful for factors

This heights seems to be a factor, the problem can be solved by putting heights = as.numeric(as.character(heights)) under heights = data[[1]]$HGHTin the function.

param class needs additional attributes

scan class needs:

  • radar
  • datetime (nominal time)
  • wavelength

param class needs all essential attributes needed for merging parameters into a scan object
We need at least:

  • NI
  • startdate,endate,starttime,endtime

extend functionality composite function

composite now requires specification of one scan parameter by argument param. Change to default to generate composite for all scan parameters when param left unspecified.

Stick to one naming convention

While listing the functions in #50, I noticed there are a lot of name conventions used (lowerCamelCase, period.separated , underscore_separated ) for those functions. Not sure if we want to tackle this now (but better now than later), but the it would be good to stick to 1. 😄 The link suggests underscore_separated.

R error: Object dataset1/how does not exist in this HDF5 file.

Reading in a pvol from Baltrad (so real life data) gives the error that dataset1 does not contain 'how', which is true.

filename <- read.pvol("bewid_pvol_20170110T0900Z.h5")
Error in h5readAttributes(filename, paste(scan, "/how", sep = "")) : Object dataset1/how does not exist in this HDF5 file.

Possible that the read.pvol function needs to be adapted to the current structure of the ODIM h5's?

Issue reading in real life vol2bird vp.h5 output

I can read vol2bird output vp.h5 files, though cannot convert them to a time series. I get following error:
Error in radars == radar : comparison of these types is not implemented

When looking what is inside the vplist, I get the following:
List of vertical profiles (class vplist)
radars: Error in cat(list(...), file, sep, fill, labels, append) : argument 2 (type 'list') cannot be handled by 'cat'

Looking in a single vp gives me this:
Vertical profile (class vp)
radar:
source: WMO:11480,NOD:czbrd
nominal time: 2017-01-07 23:30:00
generated by: vol2bird 0.3.6

So it seems to me that the readvp function does not read in the radar ID properly, making that no time series can be made eventually?

typo's

README.md:
install note 1:
add 'reboot R' after
install_github("hadley/ggplot2")
install_github("dkahle/ggmap")

COMMANDS:
cmt:
twice "of" in first sentence: ... cumulative sum of OF the..
missing "of" in last sentence: ... as a function OF time ...

is.scan (and other commands with 'geo' element in de description)
it's should be its:
... geo element of it's parent ...

[.vplist and [.vpts
are these commands?

change application of gap criterium on bird density

Suggest to change the application of the gap criterium. The gap detection in the birds-only loop (iProfile=1) is used, while it makes more sense to use the gap detection of the all-scatterers loop (iProfile=2).

In mixed birds/precipitation events, you can then have a valid bird density, but not a valid bird speed.

Could also leave the gap criterium like this (maybe more conservative), but then we should set bird density to UNDETECT instead of zero, i.e.

if (hasGap && birdDensity>0 && alldata->misc.scatterersAreNotBirds[iLayer] == FALSE){
       alldata->profiles.profile[iLayer*alldata->profiles.nColsProfile + 12] = NODATA;
}

eta and dbz have sd_vvp not applied

the radial velocity standard deviation threshold is only applied to the bird density quantity, not to the reflectivity and reflectivity factor.

This is confusing, as people may extract these quantities for further analysis.

Possible solution: book-keeping of eta both with and without sd_vvp applied, which adds an extra quantities. Using wavelength information, dbz could be recalculated from eta

Another option is to only adjust the plotting functions, but that has a higher risk of confusion

list of vertical profiles is not assigned vplist class

Seems to be related to lapply:

vpFromVptsList=function(vptslist,date,dt=60,trim=T){
  vps=lapply(vptslist,vpFromVpts,date=date,trim=trim)
  idx.dt=sapply(vps,function(x) abs(as.double(x$datetime-date,unit="mins"))<dt)
  vps[idx.dt]
}

add function extracting radar metadata

for vplist class:

radarpos.vplist=function(x){
  stopifnot(inherits(x,"vplist"))
  lat=sapply(vpl, function(x) x$attributes$where$lat)
  lon=sapply(vpl, function(x) x$attributes$where$lon)
  radar=sapply(vpl, function(x) x$radar)  
  data.frame(radar=radar,lat=lat,lon=lon)
}

read.pvol: velocity stored as VRAD instead of VRADH

The function read.pvol allows parameters param = c("DBZH", "VRADH", "RHOHV", "ZDR", "PHIDP", "CELL"), however in the OPERA polar volumes, velocity is stored under the name VRAD. As a consequence, VRAD-scans are not read by read.pvol. Simply adding "VRAD" to the parameter list solves the problem. See also issue #39 for another problem with the same function.

Speed-up read_vpfiles

I was just wandering if we could make readvp.list and/or readvp faster.

Replacing

profile=as.data.frame(lapply(groups,function(x) readOdimProfileData(filename,x)))

with

x=h5read(filename,'/')
profile = data.frame(matrix(unlist(x$dataset1),nrow=length(x$dataset1$data1$data)))

can reduce 1/3 of the running time with my quick test. But I'm not sure if it's really valid for all the radar file. Also, do we really need to read all the attribute when using readvp.list ?

Structure tutorials

  1. pvol exploration: structure of pvol
  2. ppi: ppi plot
  3. vol2bird: pvol → vp, docker
  4. vp exploration: structure of vp
  5. vpts exploration: vp → vpts, timeseries plots
  6. vpts filtering: df + yaml
  7. vpts aggregation

vol2bird function should not terminate for loops

Suggested improvement by Baptiste Schmidt:

If processing a non-existing or broken file, vol2bird function now gives a hard exit, terminating all processes. Instead it would be better to have a warning message, as then it won't terminate for-loops in which the vol2bird function is called.

regularize_vpts arg error

KBGM_origauto=regularize(KBGM_A_orig)
projecting on 360 seconds interval grid...
 Hide Traceback
 
 Rerun with Debug
 Error in match.arg(units) : 'arg' must be of length 1 
9.
stop("'arg' must be of length 1") 
8.
match.arg(units) 
7.
difftime(e1, e2) 
6.
`-.POSIXt`(ts$dates, x) 
5.
which.min(abs(ts$dates - x)) at bioRad.R#972
4.
FUN(X[[i]], ...) 
3.
lapply(X = X, FUN = FUN, ...) 
2.
sapply(grid, function(x) which.min(abs(ts$dates - x))) at bioRad.R#972
1.
regularize(KBGM_A_orig) 

integrate vp-processing repo in bioRad

Aim:

Add the functionality of vp-processing in selecting data and outputting a simple data.frame for multiple radars, that you can easily write to a text file.

Several steps in vp-processing's extract_vp.Rmd have already been integrated in bioRad, with the advantage that people have the benefits of the vp-processing examples, while still making use of the 'bioRad' objects and the their class functions.

New functionality (to be) added:

  • function to go from vplist class object, to a list of vpts objects, implemented in the bind() function. This allows users to organize a list of single profiles into a collection of vertical profile time series organized by radar
  • A function that converts a vertical profile time series object (class 'vpts') to a simple 'data.frame' that people can use for own analyses. A as.data.frame class function as been added for for vpts objects (as.data.frame.vpts)
  • have as.data.frame optionally add day/night binary indicator
  • hvae as.data.frame optionally add sunrise/sunset time
  • take a yaml configuration file and filter the data.frame generated by as.data.frame according to the specified selections.

package dependencies not installing automatically

while installing bioRad in R I recieved the following error:

> install_github("adokter/bioRad")
Downloading GitHub repo adokter/bioRad@master
from URL https://api.github.com/repos/adokter/bioRad/zipball/master
Installing bioRad
"C:/PROGRA~1/R/R-33~1.0/bin/x64/R" --no-site-file --no-environ --no-save --no-restore --quiet CMD INSTALL  \
  "C:/Users/jshamou1/AppData/Local/Temp/RtmpsjV7bM/devtools17344a633b4/adokter-bioRad-df64641" --library="C:/Program Files/R/R-3.3.0/library" --install-tests 

* installing *source* package 'bioRad' ...
** R
** data
*** moving datasets to lazyload DB
** inst
** preparing package for lazy loading
Error in loadNamespace(i, c(lib.loc, .libPaths()), versionCheck = vI[[i]]) : 
  there is no package called 'spam'
ERROR: lazy loading failed for package 'bioRad'
* removing 'C:/Program Files/R/R-3.3.0/library/bioRad'
Error: Command failed (1)

I tried rerunning this after installing Docker but still recieved the same error

mountpoint error on Windows

> profile=vol2bird("~/volume.h5")
Error in vol2bird("~/volume.h5") : 
  mountpoint 'mount' has to be a parent directory of input file 'vol.in'

make /how attribute of scans in read.pvol() optional

It looks like quite some countries (NL, BE, FR for example) do not have a subfolder how under dataset1/2/3/.... However, the function read.pvol() requires this and trying to read in pvols that do not have the how subfolder makes the function crash with the error: Error in h5readAttributes(filename, paste(scan, "/how", sep = "")) : Object dataset1/how does not exist in this HDF5 file.

One way to solve this would be to make the how attribute optional in the function read.pvol().

add mass download function

suggested function attached to download NEXRAD 2 .gz files from AWS

NEXRAD_L2_massdownload.txt

##SET STATION ID - four letter character string
STATION <- "KOAX"

##vector of dates as a string in the YYMMDD format (
#DATES <- c("20150708","20150715", "20150722", "20150730", "20150905", "20150912","20150919", "20150927")
DATES <- c("20150722", "20150905")
##Start and end hours of interest for each day (must be same for all days) as integer 0-23
startHOUR <- 0
endHOUR <- 14

##folder to save radard.gz files to
saveLoc <- "./Bioscatter_data"

AWSbucket = "https://noaa-nexrad-level2.s3.amazonaws.com/"

system.time(
AWS_objects <- get_NEXRAD2(STATION,DATES,saveLoc,startHOUR,endHOUR)
)

# Function to download NEXRAD2 files from AWS -----------------------------
##version: 0.1.1
##Author: Michael Whitby
##EMAIL: [email protected]
##July 28, 2017 


get_NEXRAD2 <- function(STATION,##SET STATION ID - four letter character string
                        DATES,##vector of dates as a string in the YYMMDD format
                        saveLoc=getwd(),
                        startHOUR = 00,##Start and end hours of interest for each day (must be same for all days) as integer 0-23
                        endHOUR = 23,
                        AWSbucket = "https://noaa-nexrad-level2.s3.amazonaws.com/"
                        ) {

dates.year <- substring(DATES, 1, 4)
dates.month <- substring(DATES, 5, 6)
dates.day <- substring(DATES, 7,9)

times <- seq(startHOUR, endHOUR)

times <- stringr::str_pad(times, 2, pad="0")

#files <- paste0(STATION,DATES,"_", times)
files <- c(t(outer(DATES, times, paste)))
files <- sub(" ", "_", files)
files <- paste0(STATION, files)
location <- paste0(dates.year, "/", dates.month, "/", dates.day, "/", STATION, "/")
obj <- c(t(outer(location, files, paste0)))

library(aws.s3)
all <- list()
  all <- lapply( obj, function(o){
    get_bucket_df(bucket = "noaa-nexrad-level2", o)
  }
  )

toDWNLD <- plyr::ldply(all)$Key

DWNLDURLS <- c(t(outer(AWSbucket, toDWNLD, paste0)))

saveLoc=paste0(saveLoc, "/", STATION, "/")
saveFile=substr(toDWNLD, 17, 42)
dub <- (saveFile  %in% list.files(saveLoc))
saveFile = saveFile[!dub]

saveFile=paste0(saveLoc, saveFile)
toDWNLD =toDWNLD[!dub]


lapply(1:length(DWNLDURLS), function (i){ 
  download.file(DWNLDURLS[i], destfile = saveFile[i])
})

}

How to access v speed data from a vplist object

I can access v data for a single vp file:

bioRad::fetch(vp_files[1], quantity = "v")

But if I want to access it for 4 vp files (= vplist object):

bioRad::fetch(vp_files, quantity = "v")

I get the dens values back instead of v (which is not even the first attribute), even though according to the bioRad documentation, the fetch function should work on 3 class types:

Arguments

x: a vp,vplist or vpts object
quantity: a profile quantity, one of "HGHT","u","v","w","ff", "dd","sd_vvp","gap","dbz","eta", "dens","DBZH","n","n_all","n_dbz","n_dbz_all".

I know I can get at the data with vp_files[1]$data, but fetch is the recommended function... is the fact that dens is returned a bug or am I doing something wrong?

permission denied while trying to connect to the Docker daemon socket

This is the error I get in my terminal (I'm using Ubuntu 14.04)

checkDocker()
docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.26/containers/create?name=hello-world: dial unix /var/run/docker.sock: connect: permission denied.
See 'docker run --help'.

Thanks

--
Sergio Cabrera

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.