Code Monkey home page Code Monkey logo

balrog-galsim's Introduction

Balrog-GalSim

Balrog is an image simulation tool for making randoms and characterizing systematics by embedding fake objects into real imaging to accurately characterize measurement biases. This is an extension of the work done by Suchyta et al. for science verification data of the Dark Energy Survey (DES). Check out the original repo here.

While Balrog is not specific to DES, the current version of this code only supports DES chip images and ngmix galaxy catalogs for injection inputs. Hopefully this generalization will be added soon; in the meantime, you can start a branch and one of the developers will help guide you on what small changes need to be made. Most changes can be made in the input GalSim config file.

The archived repository for the DES Year 3 (Y3) cosmology analysis calibration described in Everett et al. 2020 can be found here: DOI

Installation

The only non-standard Balrog dependency is GalSim. While it's a non-trivial install, the installation wiki found here outlines the steps in great detail. (edit - Galsim 2.0+ can now be installed with pip/conda!)

Once GalSim is installed, simply clone this repo:

git clone [email protected]:sweverett/Balrog-GalSim.git

Running Balrog

(Updated as of 4/5/18) Balrog is run with a python call to the script balrog_injection.py, with a few extra (required and optional) input arguments that can either be passed by command line:

python balrog_injection.py [config_file] [-l tile_list] [-g geom_file] [-t tile_dir] [-c config_dir] \
                           [-p psf_dir] [-o output_dir] [-v --verbose]

or explicitly in the config_file described below:

  • config_file: A GalSim config file (for now .yaml, but more types in future) that defines universal parameters for all injections. Chip-specific config parameters are appended to this file during processing. Each DES tile will produce a separate yaml config that handles all injections for all chips in all bands that overlap with the tile (see GalSim's Demo 6 to see how appended configs work / look). An example balrog config file is given in configs/bal_config.yaml. It also includes a description of how to pass these command-line input arguments in the config itself.
  • tile_list: A txt or csv file that contains a list of all tiles that are to be processed. Delimiter can be commas or newlines.
  • geom_file: The fits file containing tile geometry (e.g. Y3A2_COADDTILE_GEOM.fits).
  • tile_dir: Directory location that contains all desired DES tile files/folders (i.e. for N tiles, the location would contain at least the N directories /DES0001-0001, /DES0001-0002, etc.). Set to . by default.
  • config_dir: Directory location of the global GalSim config file. tile list file, and geometry file if not given in inputted filenames (the files only must be in the same directory if this is passed). Set to . by default. Cannot be set in config_file (for obvious reasons).
  • psf_dir: Relative directory path of a tile's psf from a given tile location (e.g. {tile_dir}/{TILE}/{psf_dir}). Set to psfs by default.
  • output_dir: Location of parent output directory for Balrog images and config files. Images are saved as {output_dir}/balrog_images/{realization}/{tilename}/{band}/{chipname}_balrog_inj.fits, and tile configs are saved to {output_dir}/configs/bal_config_{realization}_{tilename}.yaml.
  • verbose: Use -v for more verbose messages.

Required Directory Structures

Note that the current version of Balrog only supports DES injections. Part of this requirement is due to an assumption of how tiles and single exposure chips are are named and structured with respect to one another. Inside the tile_dir there should be a collection of directories with DES tilenames with each housing the nullweight chip images in their respective {tilename}/{nullwt-{band}} directories. Visually:

Balrog-Galsim
│   README.md    
│
└───balrog
|      ...
|
└───config
|      ...
└───inputs
│   │
│   └───tiles
|       |   
│       └───DES2329-5622
|       |    |
|       |    └───nullwt-g
|       |    |      gchip1.fits
|       |    |      gchip2.fits
|       |    |      ...
|       |    └───nullwt-r
|       |    |      rchip1.fits
|       |    |      rchip2.fits
|       |    |      ...
|       |    └───nullwt-i
|       |    |      ...
|       |    └───nullwt-z
|       |    |      ... 
|       |    └───psfs
|       |           psf1.fits 
|       |           psf2.fits 
|       |           ...
|       └───DES2349+1334
|       |       ...
|       └───DES0744+1126
|       |       ...
|       └───...
|   
└───output_dir
    |
    └───conifgs
    |       ...
    └───balrog_images
        |
        └───DES2329-5622
        └───DES2349+1334
        ...

Example Usage

Let's say you are running the standard DES Y3 setup for Balrog. Then running from the repo home you would use the following values for the above inputs:

  • config_file = configs/bal_config.yaml
  • tile_list = inputs/tilelist.csv
  • geom_file = inputs/Y3A2_COADDTILE_GEOM.fits
  • tile_dir = inputs/tiles
  • psf_dir = psfs (the default option, so not needed)
  • output_dir = outputs/ (or whatever you would like!)

and so the terminal command would be

python balrog/balrog_injection.py config/bal_config.yaml inputs/tilelist.csv inputs/Y3A2_COADDTILE_GEOM.fits \
-t inputs/tiles -o outputs/

Alternatively, these values could have been set in the image field of the config_file (except for output_dir; see example file) in which case you would simply type

python balrog/balrog_injection.py config/bal_config.yaml

Balrog Config

The global balrog config file is very similar to yaml config files used for GalSim. Check out the GalSim demo page for lots of examples of how to use the yaml files and how they are translated to python scripts. The important parts are summarized in the comments of the example config bal_config.yaml. (Note: You will need to change a few path names in the config file to work for your local machine!)

However, note that a Balrog config will not run successfully if called by the galsim executable; it only houses the global simulation variables while the individual chip injections parameters are set during the balrog_injection.py script. Each tile produces its own complete multi-output yaml config file that is sent to galsim at the end of processing.

There are a few config inputs specific to the image field of Balrog configs that are worth highlighting here:

  • n_objects: The total number of objects to be injected per DES tile per realization.
  • object_density: The injected object density in the tile field per realization.
  • n_realizations: The number of injection realizations used to reach the desired galaxy count or density.

Two things to note: (1) Only one of n_objects or object_density is allowed as an input; not both! (2) Either input should give the desired count or density per realization!. An older version of the code had this set to the desired final count/desnity, but this was counter-intuitive for users.

Input Catalogs

(more later - for now, ngmix_catalog, meds_catalog, des_star_catalog. See balinput.py and balobject.py)

(Fits file containing input objects to be injected into chip images. For now only ngmix catalogs are supported (gauss, cm, or mof photometry), but the code is designed to allow other input types in future including galaxy postage stamps. Some of the standard GalSim inputs may also work, but arent' currently supported.)

More to come...

Contributors

  • Spencer Everett (contact at [email protected])
  • Yuanyuan Zhang
  • Brian Yanny
  • Nikolay Kuropatkin
  • Erin Sheldon
  • Eric Huff
  • Ami Choi
  • Vinicious Busti
  • Eli Rykoff
  • Megan Splettstoesser
  • More to add!

balrog-galsim's People

Contributors

amichoi avatar emhuff avatar esheldon avatar mtabbutt avatar spletts avatar sweverett avatar vbusti avatar yyzhang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

balrog-galsim's Issues

Allow conditional injection types

This will be a bit tricky, but we should allow a given galaxy injection to decide between different injection types (e.g. postage stamp vs model fits). This will be useful for cases where the seeing of the deep-field coadd is worse than the SE chip we're injecting into.

move yaml files into /config

There is a directory config where we can put example config files (see config/balrog-test01.yaml which is an example full balrog config)

We can move e.g. single_epoch.yaml there

Fix HexGrid sampling issue

The latest HexGrid run seems to duplicate positions for every other column, adding multiple galaxies together. This is a recent change, and is likely due to the added center position in the HexGrid.

Implement Star Injection

We're going to start using issues again! To start off with, we need to implement star injection. Sahar's star lists are found at: /data/des20.b/data/sallam/Yanny-balrog/5sigma/, where we can select what star density we want (for our fiducial 10% realization density, we would grab the list from Extra_10_percent_16.5-26.5). There is a list with RA/DEC/MAG w/ zeropoint of 30 for all tiles.

Star injections will be done in SE same as galaxies. We will need new IO functions for Sahar's catalogs, write a new method for finding stars contained in a chip, and to update add_gs_injection() to take care of both (but allow for only one!).

The tricky part seems to be with the GalSim config file. We can set multiple galaxy types (w/ 'galaxy' type 2 being a star) with the following:

gal :
    type : List
    items : 
        - type : ngmixGalaxy
          # Existing galaxy injection
          #...
          index : [pos_1, pos_2, ...]
        
        - type: delta_function
           index : [pos_1, pos_2, ...]
           # Rest of star parameters, like mag/flux
    
    index : # Decide how to sample from type 1 vs type 2

But this also requires setting gal[index] to something sensible to determine when to injection from type 1 or type 2. So far, I haven't gotten the config to work using the above format while also specifying exact image coordinates for stars / galaxies.

Allow CSV for tile geometry file

To speed things up, we should allow CSV files to pass tile geometry information as well as check that each file has the necessary columns first.

Create Plotting Library and Standardize Plot Tests

To minimize code redundancy, we should have a main plotting library that everyone can use for data exploration and test making. We should also have a standardized plotting suite to produce all of the common figures.

Remove Stars not contained in unique tile region

Some of the stars in Sahar's catalogs lie outside of the unique tile region. They won't be rendered in the final coadd image but are still contained in the truth catalog, so they give misleading detection efficiencies. We should add a check in generate_stars that removes these objects.

Determine all flag and value cuts for Y3 DES run

By the end of the Balrog workshop at Fermilab next week, we should converge on all flag cuts (e.g. flags, obj_flags, mof_cm_flags, etc.) and value cuts (e.g. s2n, T, T_err, etc.) that will be used in the main DES Y3 run.

Allow realization subsets for injection

Large realization runs (~10) are approaching the maximum time limit on Fermi machines so we should split the job into single-realization chunks. We should allow bal_config to pass not just the total number of realizations n_realizations but also which ones are to be computed with that job in the following ways:
(1) The total number of realizations to produce (what we're currently doing),
(2) A range of realizations (e.g. 2-4),
(3) A list of realizations (e.g. [0, 3, 4, 7]).
This should mostly be an input parsing fix as the realization number is only important for names and directory structures.

Separate Balrog and Galsim configuration

As injection requests get more complicated, it may be a good idea to separate Balrog configuration from GalSim configuration. This could go a long way in modularizing Balrog, allowing for custom versions of all simulation steps, and making Balrog more general #7.

Handling 0 injection edge cases

While completing #5, I ran into a few test cases where there were no stars to be injected into a few chips. It now handles this correctly but there are a few misleading warnings that are printed (like the star catalog defaulting to using g-band even though no stars will be injected).

We need to (1) complete the same checks for galaxies (even though this should never occur) and (2) find a way around the misleading warnings while keeping the current injection structure.

Add optional shearing of input objects

Most of this is already handled by GalSim - but since we deal with 'modified' GalSim yaml files, we'll have to update a bit of the checks done in config._load_input_catalogs() to make sure we don't mess up the input indexing for add_gs_injection(). This isn't an issue for adding a constant shear but there are a few edge cases for PowerSpectrumShear, for example.

We should also add the relevant ellipticity-ellipticity (difference) correlation function to the standard plots (#19). There is a prototype plotting routine there but it needs some updating.

Speedups!

This will be open for a while - we will identify slow parts of the code that we can use to speed up injection. The latest run has injection taking nearly as long as runing SOF which is far too slow!

First up is handling large objects. I profiled the injection code and roughly half of the runtime is in _drawKImage(). Messing with max_T and min_T shows that a few very large objects (cm_T>10) can slow down a chip injection by well over 100% the mean time. This appears to be a bigger issue with the new combined catalog y3_balrog_test_input_mof as it has a larger cm_T tail.

We need to find a way to either:

  1. Make reasonable cuts combining cm_T and cm_T_err to reduce the size of the large T tail, or
  2. Make more aggressive cuts on max_T (possible selection issues), or
  3. Make a change to GalSim to allow error handling for the case of insufficient max_fft_size and explore its effect on selection.
  4. Some combination of all 3!

The other approach is to solve #6 which will certainly help speed up runtime, but it will have diminishing returns as 1% of objects can take ~90% of runtime in the worst cases.

Allow COSMOS galaxies as inputs

For the TAMU run, it would be better to use a deeper input catalog like the COSMOS catalog that ships with GalSim (or the DES mof catalog).

Add shot noise for bright objects

Currently we do not add noise. For faint objects, the existing sky noise is probably sufficient, but for bright objects, the current implementation will underestimate the actual noise.

Add postage stamps as allowed input types

We need to get ready for potential deep-field coadd injections. GalSim already supports real images, but it will take some linking to have it compatible with the current version of balrog_injection.py.

Only generate `index` fields if needed

Currently, an index array is generated for all Balrog injections given the number of injected objects. However, this causes issues for simulation runs for input types that are not catalogs. We should add a check that generates index only for classes that inherit from galsim.catalog (or something similar).

Add option to rotate grids

As CCD defects tend to be masked in rows or columns, it could be useful to rotate an injection grid off of the RA/DEC axis. We would simply add an additional (optional) parameter to grid initialization.

Make larger input test catalog

Right now we are using a single (randomly chosen) Y3 MOF catalog as inputs for testing. Now that we are larger tests with multiple tiles at (integrated) 100% DES density, we should have a larger input catalog to inject from. This could be as simple as a union of multiple Y3 MOF catalogs.

Make injection IO more general

Currently, balrog_injection.py expects a certain directory structure for the input nullweight images and can only do injections on a tile-wide basis. This was a design choice for the main survey-wide Balrog run, but there have already been requests for using Balrog for clusters and transient studies that don't conform to this structure.

We should think about how to implement the current structure to allow for more general injection strategies in the future. I think we have to live with full-tile injections to replicate the DESDM stack properly, but we should allow for tile-subset injections, different property (including RA,DEC) sampling methods, and possibly transient injections.

Any other thoughts?

Fix Injection Multiprocessing

balrog_injection.py has strange behavior when running using multiple processes on Fermi machines. Locally, I can run injection w/ nproc : 8 without issues; but on DES machines, running with nproc>2 quickly (~6 injections) leads to the following error:

Traceback (most recent call last):
  File "/cvmfs/des.opensciencegrid.org/eeups/fnaleups/Linux64/galsim/1.5.0alpha/bin/galsim", line 275, in <module>
    main()
  File "/cvmfs/des.opensciencegrid.org/eeups/fnaleups/Linux64/galsim/1.5.0alpha/bin/galsim", line 256, in main
    except_abort=args.except_abort)
  File "/cvmfs/des.opensciencegrid.org/eeups/fnaleups/Linux64/galsim/1.5.0alpha/lib/python2.7/site-packages/galsim/config/process.py", line 780, in Process
    except_abort=except_abort)
  File "/cvmfs/des.opensciencegrid.org/eeups/fnaleups/Linux64/galsim/1.5.0alpha/lib/python2.7/site-packages/galsim/config/output.py", line 144, in BuildFiles
    except_abort = except_abort)
  File "/cvmfs/des.opensciencegrid.org/eeups/fnaleups/Linux64/galsim/1.5.0alpha/lib/python2.7/site-packages/galsim/config/process.py", line 971, in MultiProcess
    result = job_func(**kwargs)
  File "/cvmfs/des.opensciencegrid.org/eeups/fnaleups/Linux64/galsim/1.5.0alpha/lib/python2.7/site-packages/galsim/config/output.py", line 222, in BuildFile
    data = builder.buildImages(output, config, file_num, image_num, obj_num, ignore, logger)
  File "/cvmfs/des.opensciencegrid.org/eeups/fnaleups/Linux64/galsim/1.5.0alpha/lib/python2.7/site-packages/galsim/config/output.py", line 473, in buildImages
    image = galsim.config.BuildImage(base, image_num, obj_num, logger=logger)
  File "/cvmfs/des.opensciencegrid.org/eeups/fnaleups/Linux64/galsim/1.5.0alpha/lib/python2.7/site-packages/galsim/config/image.py", line 237, in BuildImage
    image, current_var = builder.buildImage(cfg_image, config, image_num, obj_num, logger)
  File "./injector.py", line 44, in buildImage
    return super(BalrogImageBuilder, self).buildImage(config, base, image_num, obj_num, logger)
  File "./injector.py", line 14, in buildImage
    im, cv = super(AddOnImageBuilder, self).buildImage(config, base, image_num, obj_num, logger)
  File "/cvmfs/des.opensciencegrid.org/eeups/fnaleups/Linux64/galsim/1.5.0alpha/lib/python2.7/site-packages/galsim/config/image_scattered.py", line 118, in buildImage
    self.nobjects, base, logger=logger, obj_num=obj_num, do_noise=False)
  File "/cvmfs/des.opensciencegrid.org/eeups/fnaleups/Linux64/galsim/1.5.0alpha/lib/python2.7/site-packages/galsim/config/stamp.py", line 106, in BuildStamps
    except_func = except_func)
  File "/cvmfs/des.opensciencegrid.org/eeups/fnaleups/Linux64/galsim/1.5.0alpha/lib/python2.7/site-packages/galsim/config/process.py", line 939, in MultiProcess
    raise res
EOFError

However: It always runs successfully for nproc=2 ! This is baffling to me, but w/ 2 processors galaxy injection is fast enough that it hasn't been a pressing issue. Should still look into soon.

Grid galaxy image failures

When making the grid image, a few (~3 or so out of 4,000) of the objects have a smaller postage stamp added on top:
image
image
I have no idea what could be causing this! We should look for similar cases in non-grid images.

Have injector grab fits HDU extension for initial image

@mcclearyj found the following error when using image files with the image not in HDU extension 0:

ValueError: WCS does not have longitude type of 'RA', therefore (ra, dec) data can not be returned

While GalSim natively can handle this case with ext : 1, for example, this doesn't currently propagate to injector.py. I believe the fix is simply to add the following to injector.AddOnImageBuilder.buildImage():

try:
    ext = config['wcs']['ext']
except KeyError:
    ext = 0
initial_image = galsim.fits.read(initial_image_name, hdu=ext)

@mcclearyj: Can you confirm that this solved your issue? Thanks!

Move all input command-line arguments to `bal_config`

The most convenient way to implement #5 is to have all star-related inputs and variables be set in the bal_config fields input and image : Balrog. We should make this uniform for all other inputs; e.g. tilelist, geom_file, tile_dir, etc.

This will also help with #7.

Allow all native GalSim types in Balrog code

When the code was first written, we were extremely conservative about what sorts of input and config types were allowed to be passed in the bal_config to ensure that we were doing things correctly.

However, this is too conservative: It leads to some unexpected and unnecessary compatibility issues when doing simple tests using typical galsim types.

We should change all of the allowed_types into safe_types or supported_types and only warn the user if using one of the unsupported types. This shifts some of the responsibility to the user to do reasonable things, but this is an ok compromise for flexibility.

Add `sof` as a valid Ngmix input catalog type

The title says it all - we want to do MOF vs SOF tests, so sof needs to (1) be added as a valid input for ngmix_catalog, and (2) any flag or column specifics need to be accounted for.

Choose and implement noise model for injections

Currently, Balrog galaxies are injected without noise. Most noise contributions will be inherited from the existing image but we still need to include shot noise with the injections.

Importantly, we should pick a single seed for this and save to the truth catalog metadata for future reference.

Truth tables should contain simulation metadata

Now that we have many injection runs it is easy to get confused which run came from which version (as Nikolay's pipeline needs the same directory structure). The easiest solution is to add simulation metadata (including which injection output dir run it came from) to the truth table header.

Grab chip zeropoints and correctly scale flux

Currently injections are all (incorrectly) assuming zeropoints of 30, which is consistent with the input catalog. See Brian's slack comment:

For example for tile DES0347-5540, there's a list file here: /data/des71.a/data/kuropat/balrog_test/y3v02/DES0347-5540/lists/DES0347-5540_r_nullwt-flist-y3v02.dat
The first line of this file is: /data/des71.a/data/kuropat/balrog_test/y3v02/DES0347-5540/nullwt-r/D00253910_r_c54_r2366p01_immasked_nullwt.fits 31.70017433166504
So for any r-band flux laid down on expnum 253910 ccnum=54, that flux should be multiplied by pow(10,(31.70017-30)/2.5) = 4.787 and so forth.

This means we need the following changes:

  • Pass data version in bal_config : image
  • New chip method to grab the zeropoint from the .dat file
  • Either scale flux explicitly, or tell galsim to do so (which I prefer)
    All of this is making me think about how to make Balrog IO more general (see #7), but for now we can assume that the current Balrog image class will really become a Balrog_DES class, or something similar.

Change meanings of `n_galaxies` and `gal_density`

The current definitions of these input parameters is the total/final number of galaxies or galaxy density after all injection realizations. This has shown to be counterintuitive, and we should change the definitions to be the injection number/density per realization.

We should update the docs to reflect this as well.

Correctly handle grid/blank-test chips with no injections

There is currently a small issue with the grid and blank tests in which nullwt chips that do not contain any injections are correctly skipped - but then their values are not reset for the test! We should think of the right way to handle this without having to trick GalSim into running over a chip with no injections.

Allow more grid input parameters

The first pass implementation of pos_sampling : grid was not very flexible. We should allow additional inputs to configure how the grid is constructed.

Looking to the future, we may also want to add some kind of rejection sampling on the grid given the shapes / sizes of certain grid objects.

Change grid tests to inject onto BKG images

One possible issue for the grid test is that the SCI images no longer match the BKG images. Instead of adding onto a blank background and adding noise consistent with the WGT map, we could instead inject on top of the BKG images and pass these along to MEDs, along with the original BKG images.

Fix object rotation angles for all bands

Currently, setting the simulation header with

gal :
    rotate : Random

Will cause different rotation angles of the same object between different bands. This will have to be set in generate_galaxies so it can be called consistently in add_gs_injection().

Relative paths in `bal_config` are broken

It looks like one of the previous updates for handling directory path inputs has broken the parsing of relative paths set in bal_config. The constructor of Config now converts all paths to be absolute, so it is likely just a change of which os function is being used to concatenate paths.

DESDM stack first pass

Let's try and get a simple script that runs:
i) Downloading necessary input images (desmeds prep tile command)
ii) Galsim (can start with a dummy Galsim run i.e. just copy the SE images to a different directory iii) Swarp
iv) SExtractor light - some comparison of resulting SExtractor catalogs to the DESDM ones would be good here.

(Once step iv) looks ok, move on to making meds files and running MOF)

All bands are being injected into each chip!

Stolen from slack:
The ngmix_catalog should know which band to inject in given the nullwt name. But it is being overwritten by the global config that is passed in bal_config.yaml. It was copied over a long time ago when ngmix_catalog simulations were done in a slightly different way. So the global

input : ngmix_catalog
    bands : 'griz'
    ....

(which is being used to determine how many bands to iterate over) is also overwriting each chip injection to inject all bands at every injection

Restructure `n_realizations` and star injection between multiple runs

Star injection is currently handled by dividing up the total star catalog for a given tile into n_realizations=len(reals) groups. However, this doesn't allow for consistent star injection across multiple single realization runs as the star groups are randomly shuffled.

We should allow n_realizations to be a simultaneous config input along with realizations, and n_realizations>len(realizations) would indicate that the star catalog should not be shuffled so future runs can complete the total catalog injection.

Blank and Grid runs need to add background noise

Blank and Grid runs ignore the initial images but don't currently change the background noise in the header! This leads to some significant diagnostics issues:
Blank Run:
image
Normal Run:
image
We should read the background noise for each chip and then add the noise level for blank and grid runs.

Implement HexGrid

Moved this from #36 to distinguish issues. We now have a base Grid class and an implemented RectGrid that take inputted grid parameters as well as tile metadata. We now should implement HexGrid which does the same on a hexagonal grid. This will likely be used for the positions of the main Balrog run if we do not use uniform scatter to minimize Balrog blends.

Screen strars out of input galaxy ngmix catalog

Now that we are adding stars, we need to be more careful to screen out stars from the input galaxy catalog. This can be done by adding some additional checks (modest_cuts?) in the ngmix_catalog initialization.

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.