packages feed

NGLess 1.4.0 → 1.4.1

raw patch · 12 files changed

+792/−12 lines, 12 files

Files

ChangeLog view
@@ -1,3 +1,7 @@+Version 1.4.1 2022-06-03 by luispedro+	* Fix bug with split mapping+	* Fix packaging for hackage+ Version 1.4.0 2022-05-30 by luispedro 	* Add --trace argument to all modes 	* Update --create-reference-pack mode to newer format (previous version worked, but
+ Html/index.html view
@@ -0,0 +1,86 @@+<!DOCTYPE html>+<html lang="en">+    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.1/angular.min.js"></script>+    <script src="https://code.angularjs.org/1.3.0-beta.1/angular-sanitize.js"></script>+    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css" rel="stylesheet">+    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css" rel="stylesheet">++    <link href="ngless.css" rel="stylesheet">+    <title>Ngless</title>++    <body>++        <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">+            <div class="navbar-collapse">+                <ul class="nav navbar-nav">+                    <li class="active"><a href="#">Home</a></li>+                    <li><a href="nglessQC.html">FastQ Quality Control</a></li>+                </ul>+            </div><!--/.nav-collapse -->+            </div>+        </nav>+++        <div class="bs-docs-header" id="content">+            <div class="container">+                <h1>NGLess Log</h1>+            </div>+        </div>+        <div ng-app="myApp" ng-controller="NGlessCtrl">+            <p>Result of running script file <tt>{{output.processed.name}}</tt> at <em>{{output.processed.time}}</em>.</p>+            <div class="container">+                <div class="panel-body">+                    <h2>Script</h2>+                    <div ng-repeat="line in output.processed.script" style="position: relative">+                        <p style="white-space: pre-wrap"><span ng-if="line[0] && line[0].info_type == 'has_QCInfo'" style="position: absolute; left: -4em"><a href="nglessQC.html#{{line[0].lno}}">QC</a> </span><span ng-if="line[0] && line[0].info_type == 'has_StatsInfo'" style="position: absolute; left: -4em"><a href="nglessMapStats.html#{{line[0].lno}}">Stats</a> </span> {{line[1]}}</p>+                    </div>+                </div>+            </div>+            <div class="container">++                <h3>NGLess Output</h3>+                <style>+                .output-info { color: #000000;}+                .output-debug { color: #336633;}+                .output-result { color: #663333;}+                </style>+                <p><a ng-show="!showtime" ng-click="showtime = !showtime;">Show timestamp</a><a ng-show="showtime" ng-click="showtime = !showtime;">Hide timestamp</a>.++                <p>+                <div ng-repeat="oline in output.output">+                    <span class="output-{{oline.otype}}"><strong>Line {{oline.lno}}</strong><span ng-show="showtime"> [{{oline.time}}]</span>: {{oline.message}}</span><br />+                </div>+            </div>+        </div><!-- /.container -->+++        <footer id="footer">+            <div class="container">+                <p>Happily designed by <a href="https://github.com/ngless-toolkit">Luis Pedro Coelho</a> and <a href="https://github.com/montoias">Paulo Monteiro</a>.</p>+            </div>+        </footer>+        <!-- Bootstrap core JavaScript+            ================================================== -->+            <!-- Placed at the end of the document so the pages load faster -->++            <script src="https://code.jquery.com/jquery-latest.min.js" ></script>+            <script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script>++            <script src="output.js"></script>++            <!-- Angular Script to load different URLs -->+            <script>+var app = angular.module('myApp', ['ngSanitize']);++app.factory('NGLessOutput', function() {+    return output;+});++function NGlessCtrl($scope, $sce, NGLessOutput){+    $scope.output = output;+}++            </script>++    </body>+</html>
+ Html/ngless.css view
@@ -0,0 +1,233 @@+.textTitle {+  padding: 80px 15px;+  text-align: center;+}++.frameFastQ {+  height: 900px;+  width: 100%; +  display: block;+}++.timetext {+  float:right ;+}++.titletext {+  float: left;+}++div.panel-title {+  padding-bottom: 30px;+  padding-top: 10px;+}++.panel-default>.panel-heading {+  color: #fff;+  background-color: #E8A10C;+  border-color: #ddd;+}+++/* Sidenav for Docs+-------------------------------------------------- */++.sidenav {+  width: 228px;+  margin: 30px 0 0;+  padding: 0;+  background-color: #fff;+  -webkit-border-radius: 6px;+     -moz-border-radius: 6px;+          border-radius: 6px;+  -webkit-box-shadow: 0 1px 4px rgba(0,0,0,.065);+     -moz-box-shadow: 0 1px 4px rgba(0,0,0,.065);+          box-shadow: 0 1px 4px rgba(0,0,0,.065);+}+.sidenav > li > a {+  display: block;+  width: 190px \9;+  margin: 0 0 -1px;+  padding: 8px 14px;+  border: 1px solid #e5e5e5;+}+.sidenav > li:first-child > a {+  -webkit-border-radius: 6px 6px 0 0;+     -moz-border-radius: 6px 6px 0 0;+          border-radius: 6px 6px 0 0;+}+.sidenav > li:last-child > a {+  -webkit-border-radius: 0 0 6px 6px;+     -moz-border-radius: 0 0 6px 6px;+          border-radius: 0 0 6px 6px;+}+.sidenav > .active > a {+  position: relative;+  z-index: 2;+  padding: 9px 15px;+  border: 0;+  text-shadow: 0 1px 0 rgba(0,0,0,.15);+  -webkit-box-shadow: inset 1px 0 0 rgba(0,0,0,.1), inset -1px 0 0 rgba(0,0,0,.1);+     -moz-box-shadow: inset 1px 0 0 rgba(0,0,0,.1), inset -1px 0 0 rgba(0,0,0,.1);+          box-shadow: inset 1px 0 0 rgba(0,0,0,.1), inset -1px 0 0 rgba(0,0,0,.1);+}++.bs-docs-masthead, .bs-docs-header {+    position: relative;+    padding: 30px 15px;+    color: #cdbfe3;+    text-align: center;+    text-shadow: 0 1px 0 rgba(0, 0, 0, .1);+    background-color: #53B4FF;+    background-image: -webkit-linear-gradient(top, #236DFF 0, #53B4FF 100%);+    background-image: linear-gradient(to bottom, #236DFF 0, #53B4FF 100%);+    background-repeat: repeat-x;+}+++.bs-docs-header h1 {+    color: #fff+}++@media (min-width:768px){+  .bs-docs-header {+        padding-top: 10px;+        padding-bottom: 10px;+        font-size: 16px;+        text-align: left+    }++    .bs-docs-header h1 {+        font-size: 60px;+        line-height: 1+    }+}++@media (min-width:992px){.bs-docs-header h1, .bs-docs-header p {+        margin-right: 380px+    }+}+++.navbar {+    position:relative;+    min-height:40px;+    margin:0px;+    /* Add padding: 0 */+    border:0px solid transparent;+}++#nav.affix {+    position: fixed;+    top: 70px;+    width: 100%+}++.headTemplate {+   color: #53B4FF;+}+++html,body {+  height: 100%;+  /* The html and body elements cannot have any padding or margin. */+}++/* Wrapper for page content to push down footer */+#wrap {+  min-height: 100%;+  height: auto !important;+  height: 100%;+  /* Negative indent footer by it's height */+  margin: 0 auto -60px;+}++/* Set the fixed height of the footer here */+#push,+#footer {+  height: 60px;+}++#footer {+  background-color: #f5f5f5;+  padding-top: 20px;+}++++.section-body {+    position: relative;+    padding: 30px 15px;+    color: #cdbfe3;+    text-align: center;+    text-shadow: 0 1px 0 rgba(0, 0, 0, .1);+    background-color: #fff;+    background-image: -webkit-linear-gradient(top, #fff 0, #fff 100%);+    background-image: linear-gradient(to bottom, #fff 0, #fff 100%);+    background-repeat: repeat-x;+}+++.section-body h1 {+    color: #000000+}++@media (min-width:768px){+  .section-body {+        padding-top: 60px;+        padding-bottom: 60px;+        font-size: 14px;+        text-align: center+    }++    .section-body h1 {+        font-size: 20px;+        line-height: 1+    }+}+++.sec-collapse{+    text-shadow: 0 1px 0 rgba(0, 0, 0, .1);+    background-color: #5CDBE5;+    background-image: -webkit-linear-gradient(bottom, #fff 0, #5CDBE5 100%);+    background-image: linear-gradient(to top, #fff 0, #5CDBE5 100%);+    background-repeat: repeat-x;+}++@media (min-width:768px){+  .sec-collapse {+        padding-top: 20px;+        padding-bottom: 60px;+    }++    .sec-collapse h1 {+        font-size: 20px;+        line-height: 1+    }+}++#leftcolumn {+  background-color: grey;+  font-size: 12px;+  text-align: left;+  color: white;+  width: 20%; +  float:left;+}++#rightCont {+  width: 70%; +  float:right;+  margin-left: 10px;+  margin-right: 50px;+}++#leftitem {+  margin-left: 6px;+  color: white;+}++#headList {+  text-align: center;+}
+ Html/nglessMapStats.html view
@@ -0,0 +1,66 @@+<!DOCTYPE html>+<html lang="en">+    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.1/angular.min.js"></script>+    <script src="https://code.angularjs.org/1.3.0-beta.1/angular-sanitize.js">/</script>+    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.1.6/d3.min.js"></script>+    <script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.1.14-beta/nv.d3.js"></script>++    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css" rel="stylesheet">+    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css" rel="stylesheet">+++    <link href="ngless.css" rel="stylesheet">+    <title>Mapping Statistics</title>+    <script src="output.js"></script>++    <body>+        <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">+            <div class="navbar-collapse">+                <ul class="nav navbar-nav">+                    <li><a href="index.html">Home</a></li>+                    <li><a href="nglessQC.html">FastQ Quality Control</a></li>+                </ul>+            </div><!--/.nav-collapse -->+            </div>+        </nav>+        <h1>Mapping Statistics</h1>+        <div ng-app="mapStatsApp" ng-controller="mapStatsCntrl">+            <div id="table" align="center">+                <table class="table table-bordered table-hover">+                    <thead>+                        <tr>+                            <th>Line Number</th>+                            <th>Reference</th>+                            <th>Input file</th>+                            <th>Total reads</th>+                            <th>Total aligned</th>+                            <th>Total unique</th>+                        </tr>+                    </thead>+                    <tbody>+                        <tr ng-repeat="m in mapStats">+                            <td>{{m.lno}}</td>+                            <td>{{m.reference}}</td>+                            <td>{{m.inputFile}}</td>+                            <td>{{m.totalReads}}</td>+                            <td>{{m.totalAligned}}</td>+                            <td>{{m.totalUnique}}</td>+                        </tr>+                    </tbody>+                </table>+            </div>++            <script>++var app = angular.module('mapStatsApp', []);+app.factory('mapStatsApp', function() {+    return output.mapStats;+});++function mapStatsCntrl($scope){+    $scope.mapStats = output.mapStats;+}+            </script>+        </div>+    </body>+</html>
+ Html/nglessQC.html view
@@ -0,0 +1,130 @@+<!DOCTYPE html>+<html lang="en">+    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.1/angular.min.js"></script>+    <script src="https://code.angularjs.org/1.3.0-beta.1/angular-sanitize.js"></script>+    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.1.6/d3.min.js"></script>+    <script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.1.14-beta/nv.d3.js"></script>++    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css" rel="stylesheet" />+    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css" rel="stylesheet" />++    <link href="ngless.css" rel="stylesheet" />+    <link rel="stylesheet" type="text/css" href="perBaseQualScores.css" media="screen" />++    <title>FastQ Quality Statistics</title>+    <script src="output.js"></script>++    <body>+        <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">+            <div class="navbar-collapse">+                <ul class="nav navbar-nav">+                    <li><a href="index.html">Home</a></li>+                    <li><a href="#">FastQ Quality Control</a></li>+                </ul>+            </div><!--/.nav-collapse -->+            </div>+        </nav>+        <div ng-app="fqStatsApp">+            <div ng-controller="FQInfoCtrl">+                <div id="table" align="center">+                    <table class="table table-bordered table-hover">+                        <thead>+                            <tr>+                                <th> </th>+                                <th ng-repeat="fq in fqStats">{{fq.fileName}}</th>+                            </tr>+                        </thead>+                        <tbody>+                            <tr>+                                <td> %GC: </td>+                                <td ng-repeat="fq in fqStats">{{fq.gcContent*100. | number : 1}}%</td>+                            </tr>+                            <tr>+                                <td> Encoding: </td>+                                <td ng-repeat="fq in fqStats">{{fq.encoding}}</td>+                            </tr>+                            <tr>+                                <td> Number of Sequences: </td>+                                <td ng-repeat="fq in fqStats">{{fq.numSeqs}}</td>+                            </tr>+                            <tr>+                                <td> Sequence length:  </td>+                                <td ng-repeat="fq in fqStats">{{fq.seqLength[0]}}&ndash;{{fq.seqLength[1]}}</td>+                            </tr>+                            <tr>+                                <td>Plot below</td>+                                <td ng-repeat="fq in fqStats"><button ng-click="doPlot($index);">Plot</button></td>+                            </tr>+                        </tbody>+                    </table>+                </div>++                <div id="offsetDiv">+                    <div class='with-3d-shadow with-transitions'>+                        <svg id="qualityPlot"></svg>+                    </div>+                </div>++                <script>+                function convertData (data) {+                    var newData = [],+                    shapes = ['triangle-up', 'triangle-down'],+                    tag = ['mean', 'median', 'lowerQuartile', 'upperQuartile'];++                    for (var i = 0; i < tag.length; i++) {+                        newData.push({+                            key: tag[i],+                            values: []+                        });++                        for (var j = 0; j < data.length; j++) {+                            newData[i].values.push({+                                x: j,+                                y: data[j][tag[i]],+                                shape: shapes[i % 2]+                            });+                        }+                    }+                    return newData;+                }+                var chart = nv.models.lineChart()+                        .showYAxis(true)+                        .showXAxis(true)+                        .useVoronoi(false)+                        .color(d3.scale.category10().range())+                        .transitionDuration(300)+                        ;++                chart.xAxis.tickFormat(d3.format('1'));+                chart.yAxis.tickFormat(d3.format('.02f'));+                chart.tooltipContent(function(key) {+                    return '<h4>' + key + '</h4>';+                });+++                nv.utils.windowResize(chart.update);++                chart.dispatch.on('stateChange', function(e) { ('New State:', JSON.stringify(e)); });++                var app = angular.module('fqStatsApp', []);+                app.factory('fqStats', function() {+                    return output.fqStats;+                });++                function FQInfoCtrl($scope, fqStats){+                    $scope.fqStats = fqStats;+                    $scope.doPlot = function (index) {+                        d3.select('#qualityPlot')+                            .datum(convertData(fqStats[index].perBaseQ))+                            .call(chart);+                    }+                }++                </script>++            </div>+        </div>+++    </body>+</html>
+ Html/perBaseQualScores.css view
@@ -0,0 +1,40 @@++#table {+  position: relative;+  top: 30px;+}++body {+  overflow-y:scroll;+  margin: 0;+  padding: 0;+}++svg {+  overflow: hidden;+}++div {+  border: 0;+  margin: 0;+}+++#offsetDiv {+  margin-left: 100px;+  margin-top: 100px;+  margin-right: 100px;+}+++.nv-legendWrap {+  margin-bottom: 300px;+}+++#qualityPlot {+  margin: 0;+  height: 500px;+  min-width: 800px;+}+
NGLess.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           NGLess-version:        1.4.0+version:        1.4.1 synopsis:       NGLess implements ngless, a DSL for processing sequencing data description:    NGLess implements a domain-specific language for processing next generation data, particularly metagenomics. category:       Domain Specific Language@@ -17,7 +17,14 @@ license-file:   COPYING build-type:     Simple extra-source-files:+    README.md     ChangeLog+    Html/index.html+    Html/ngless.css+    Html/nglessMapStats.html+    Html/nglessQC.html+    Html/perBaseQualScores.css+    NGLess/Interpretation/Count/RefSeqInfoVector.h  source-repository head   type: git
NGLess/Data/Fasta.hs view
@@ -49,7 +49,7 @@     getdata !n header toks = C.await >>= \case                                 Nothing -> C.yield $ FastaSeq header (B.concat $ reverse toks)                                 Just (ByteLine next)-                                    | B.null next -> throwDataError ("Unexpected empty string at line " ++ show (n+1) ++ " (expected header line).")+                                    | B.null next -> getdata (n+1) header toks                                     | B.head next == greaterThanSign -> do                                             C.yield $ FastaSeq header (B.concat $ reverse toks)                                             getdata (n+1) (B.drop 1 next) []
+ NGLess/Interpretation/Count/RefSeqInfoVector.h view
@@ -0,0 +1,71 @@+#include <vector>+#include <string>+#include <cstring>+#include <algorithm>++const unsigned block_size = 8192 - 64; // 64 is for padding+struct PoolC {+    PoolC():free_(0) { }+    ~PoolC() {+        for (std::vector<void*>::iterator it = data_.begin(), past = data_.end(); it != past; ++it) {+            operator delete(*it);+        }+    }+    const char* strdup(const char* input) {+        const unsigned int len = std::strlen(input) + 1;+        if (len > block_size) {+            char* n = static_cast<char*>(operator new(len));+            std::strcpy(n, input);+            data_.push_back(n);+            free_ = 0;+            return n;+        }+        if (len > free_) {+            data_.push_back(operator new(block_size));+            free_ = block_size;+        }+        char* r = static_cast<char*>(data_.back());+        r += block_size - free_;+        std::strcpy(r, input);+        free_ -= len;+        return r;+    }+    private:++    std::vector<void*> data_;+    size_t free_;+};+++struct RefSeqInfo {+    RefSeqInfo(const char* s, double v)+        :str(s)+        ,val(v) { }+    bool operator <(const RefSeqInfo& rhs) const { return strcmp(str, rhs.str) < 0; }+    const char* str;+    double val;+};+++struct RefSeqInfoVector {+    RefSeqInfoVector() { }+    ~RefSeqInfoVector() { }+    void insert(std::string f, double v) {+        data_.push_back(RefSeqInfo(pool_.strdup(f.c_str()), v));+    }+   RefSeqInfo& at(int ix) { return data_.at(ix); }+   int find(const char* f) {+       std::vector<RefSeqInfo>::const_iterator it = std::lower_bound(data_.begin(), data_.end(), RefSeqInfo(f, 0));+       if (it == data_.end() || strcmp(it->str, f)) { return -1; }+       return it - data_.begin();+   }+   void sort() { std::sort(data_.begin(), data_.end()); }+   unsigned size() const { return data_.size(); }+   std::vector<RefSeqInfo> data_;+   PoolC pool_;+};++extern "C" {+    void rsiv_free(void* p) { delete static_cast<RefSeqInfoVector*>(p); }+}+
NGLess/Interpretation/Map.hs view
@@ -1,4 +1,4 @@-{- Copyright 2013-2019 NGLess Authors+{- Copyright 2013-2022 NGLess Authors  - License: MIT  -} {-# LANGUAGE FlexibleContexts #-}@@ -24,7 +24,6 @@ import qualified Data.Conduit.Algorithms.Async as CAlg import           Data.Conduit ((.|)) import           Data.Conduit.Algorithms.Utils (awaitJust)-import           Data.Conduit.Algorithms.Async (conduitPossiblyCompressedFile) import           Control.Monad.Extra (unlessM) import           Data.List (sort) @@ -142,6 +141,7 @@     forM_ blocks (ensureIndexExists 0 mapper)     return blocks +ensureSplitsExist :: Int -> FilePath -> NGLessIO [FilePath] ensureSplitsExist blockSize fafile = do     fafile' <- getIndexOutput False fafile     let ofafile = FilePath.takeDirectory fafile' </> FilePath.takeBaseName fafile <.> "splits_" ++ show blockSize ++ "m"@@ -189,12 +189,12 @@                 , maxAge = 36 * 3000                 , whenExistsStrategy = IfLockedRetry { nrLockRetries = 120, timeBetweenRetries = 60 }                 , mtimeUpdate = True-                } $ C.runConduit $-            conduitPossiblyCompressedFile ifile-                .| faConduit-                .| splitWriter+                } $+            CAlg.withPossiblyCompressedFile ifile $ \ic ->+                C.runConduit (ic .| faConduit .| splitWriter)     where         maxBPS = 1000 * 1000 * megaBPS+        splitWriter :: C.ConduitT FastaSeq C.Void NGLessIO [FilePath]         splitWriter = splitWriter' [] (0 :: Int)         splitWriter' fs n = do             let f = ofileBase ++ "." ++ show n ++ ".fna"@@ -314,13 +314,13 @@ mergeSamFiles inputs = do     lift $ outputListLno' TraceOutput ["Merging SAM files: ", show inputs]     forM_ inputs $ \f ->-        CB.sourceFile f+        CAlg.conduitPossiblyCompressedFile f             .| linesC             .| readSamHeaders     -- This is sub-optimal as we reparse the file.     -- There are also obvious opportunities to make this code take advantage of parallelism     C.sequenceSources-            [CB.sourceFile f+            [CAlg.conduitPossiblyCompressedFile f                 .| linesVC 4096                 .| readSamGroupsC' 1 True                 .| CC.concat -- TODO: Remove this and adapt `mergeSAMGroups` to work directly on vectors
NGLess/Version.hs view
@@ -17,10 +17,10 @@ versionStr = showVersion version  versionStrLong :: String-versionStrLong = "1.4.0"+versionStrLong = "1.4.1"  dateStr :: String-dateStr = "May 30 2022"+dateStr = "June 3 2022"  embeddedStr :: String #ifdef NO_EMBED_SAMTOOLS_BWA
+ README.md view
@@ -0,0 +1,143 @@+# NGLess: NGS Processing with Less Work++![NGLess logo](NGLess-logo-128x64.png) Ngless is a domain-specific language for+NGS (next-generation sequencing data) processing.++[![Build Status](https://travis-ci.com/ngless-toolkit/ngless.svg?branch=master)](https://travis-ci.com/ngless-toolkit/ngless)+[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE)+[![Install with Bioconda](https://anaconda.org/bioconda/ngless/badges/installer/conda.svg)](https://anaconda.org/bioconda/ngless)+[![Install with Bioconda](https://anaconda.org/bioconda/ngless/badges/downloads.svg)](https://anaconda.org/bioconda/ngless)+[![Citation for NGLess](https://img.shields.io/badge/CITATION-DOI%3A10.1186%252Fs40168--019--0684--8-brightgreen.svg)](https://doi.org/10.1186/s40168-019-0684-8)+[![Join the chat at https://gitter.im/ngless-toolkit](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ngless-toolkit)+++For questions and discussions, please use the [ngless mailing+list](https://groups.google.com/forum/#!forum/ngless).++If you are using NGLess, please cite:++> _NG-meta-profiler: fast processing of metagenomes using NGLess, a+> domain-specific language_ by Luis Pedro Coelho, Renato Alves, Paulo Monteiro,+> Jaime Huerta-Cepas, Ana Teresa Freitas, Peer Bork, Microbiome (2019)+> [https://doi.org/10.1186/s40168-019-0684-8](https://doi.org/10.1186/s40168-019-0684-8)++![NGLess cartoon](docs/NGLess-cartoon.svg)++## Example++    ngless "1.4"+    input = fastq(['ctrl1.fq','ctrl2.fq','stim1.fq','stim2.fq'])+    input = preprocess(input) using |read|:+        read = read[5:]+        read = substrim(read, min_quality=26)+        if len(read) < 31:+            discard++    mapped = map(input,+                    reference='hg19')+    write(count(mapped, features=['gene']),+            ofile='gene_counts.csv',+            format={csv})++## Installing++See the [install documentation](https://ngless.embl.de/install.html) for more+information.++### Bioconda++The recommended way to install NGLess is through+[bioconda](https://bioconda.github.io):++    conda install -c bioconda ngless ++### Docker++Alternatively, a docker container with NGLess is available at+[docker hub](https://hub.docker.com/r/nglesstoolkit/ngless):++    docker run -v $PWD:/workdir -w /workdir -it nglesstoolkit/ngless:1.4.0 ngless --version++Adapt the mount flags (``-v``) as needed.++### Linux++You can download a [statically linked version of NGless+1.4.0](https://github.com/ngless-toolkit/ngless/releases/download/v1.4.0/NGLess-v1.4.0-Linux-static-full)++This should work across a wide range of Linux versions (please+[report](https://github.com/ngless-toolkit/ngless/issues) any issues you encounter):++    curl -L -O https://github.com/ngless-toolkit/ngless/releases/download/v1.4.0/NGLess-v1.4.0-Linux-static-full+    chmod +x NGLess-v1.4.0-Linux-static-full+    ./NGLess-v1.4.0-Linux-static-full++This downloaded file bundles bwa, samtools and megahit (also statically linked).++### From Source++Installing/compiling from source is also possible. Clone+[https://github.com/ngless-toolkit/ngless](https://github.com/ngless-toolkit/ngless)++#### Dependencies++The simplest way to get an environment with all the dependencies is to use conda:++    conda create -n ngless+    conda activate ngless+    conda config --add channels conda-forge+    conda install stack cairo bzip2 gmp zlib perl wget xz pkg-config make++You should have `gcc` installed (or another C-compiler).++The following sequence of commands should download and build the software++    git clone https://github.com/ngless-toolkit/ngless+    cd ngless+    stack setup+    make++To install, you can use the following command (replace `<PREFIX>` with+the directory where you wish to install, default is `/usr/local`):++    make make++## Running Sample Test Scripts on Local Machine++For developers who have successfully compiled and installed NGless, running the+test scripts in the `tests` folder would be the next line of action to have the+output of sample test cases.++    cd tests++Once in the `test` directory, select any of the test folders to run NGless.++For example, here we would run the `regression-fqgz` test:++    cd regression-fqgz+    ngless ungzip.ngl++After running this script open the newly generated folder `ungzip.ngl.output_ngless` and view the template in the **index.html** file.++For developers who have done this much more datasets for testing purposes can be referenced and used by reading these documentation links:+**[Human Gut Metagenomics Functional & Taxonomic Profiling](https://ngless.embl.de/tutorial-gut-metagenomics.html#)**+**[Ocean Metagenomics Functional Profiling](https://ngless.embl.de/tutorial-ocean-metagenomics.html)**+**[Ocean Metagenomics Assembly and Gene Prediction](https://ngless.embl.de/tutorial-assembly-gp.html)**+++## More information++- [Full documentation](https://ngless.embl.de/)+- [Frequently Asked Questions (FAQ)](https://ngless.embl.de/faq.html)+- [ngless mailing list](https://groups.google.com/forum/#!forum/ngless)+- [What's new log](https://ngless.embl.de/whatsnew.html)+- [NGless 1.4.0 Release Documentation](https://ngless.embl.de/whatsnew.html#version-1-4-0)++## Authors++- [Luis Pedro Coelho](https://luispedro.org) (email: [luispedro@big-data-biology.org](mailto:luispedro@big-data-biology.org)) (on twitter: [@luispedrocoelho](https://twitter.com/luispedrocoelho))+- Paulo Monteiro+-  Renato Alves+- [Ana Teresa Freitas](https://web.tecnico.ulisboa.pt/ana.freitas/)+-  Peer Bork+