Overview

Namespaces

  • AnalyseModule
    • Models
  • BaseModule
    • Exceptions
    • Models
    • Repository
    • Services
  • DispatchModule
    • Helpers
    • Models
    • Tools
  • PredictModule
  • SearchModule

Classes

  • AnalyseModule\AnalysePresenter
  • AnalyseModule\ConservancyPresenter
  • AnalyseModule\Models\BaseTool
  • AnalyseModule\Models\ConservancyComparator
  • BaseModule\BasePresenter
  • BaseModule\DiscoveredViewReflection
  • BaseModule\ErrorPresenter
  • BaseModule\Form
  • BaseModule\HomepagePresenter
  • BaseModule\Models\BaseModel
  • BaseModule\Models\FileModel
  • BaseModule\PesekPresenter
  • BaseModule\Repository\BaseRepository
  • BaseModule\Repository\TestRepository
  • BaseModule\RouterFactory
  • BaseModule\RssPresenter
  • BaseModule\Services\Authenticator
  • BaseModule\Services\BaseService
  • BaseModule\Services\DbService
  • DispatchModule\BaseMatch
  • DispatchModule\BaseParser
  • DispatchModule\BlastMatch
  • DispatchModule\BlatMatch
  • DispatchModule\Helpers\RnaplotHelper
  • DispatchModule\Helpers\TravelerHelper
  • DispatchModule\Models\BaseModel
  • DispatchModule\Models\BlastModel
  • DispatchModule\Models\BlastXMLParser
  • DispatchModule\Models\BlatModel
  • DispatchModule\Models\Cppredict2Model
  • DispatchModule\Models\CppredictModel
  • DispatchModule\Models\FastaModel
  • DispatchModule\Models\FileModel
  • DispatchModule\PredictParser
  • DispatchModule\ResultSet
  • DispatchModule\SearchParser
  • DispatchModule\Sequence
  • DispatchModule\Tools\AnnotationDbTool
  • DispatchModule\Tools\BaseTool
  • DispatchModule\Tools\Cppredict2Tool
  • DispatchModule\Tools\DbTool
  • DispatchModule\Tools\SimilarityTool
  • DispatchModule\Tools\TaxonomyDbTool
  • PredictModule\PredictPresenter
  • SearchModule\SearchPresenter

Interfaces

  • DispatchModule\Tools\ToolInterface

Exceptions

  • BaseModule\Exceptions\BaseException
  • BaseModule\Exceptions\NotFoundException
  • BaseModule\Exceptions\ToolException
  • Overview
  • Namespace
  • Class
  1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369: 370: 371: 372: 
<?php

namespace DispatchModule\Tools;

/**
 * Cppredict2 tool
 */
class Cppredict2Tool extends \DispatchModule\Tools\BaseTool implements \DispatchModule\Tools\ToolInterface {

    /**
     * @var string fast file header
     */
    protected $header = '> no header';

    /**
     * @var string input sequence
     */
    protected $sequence;

    /**
     * @var string path to template
     */
    protected $template;

    /**
     * @var bool compute z-score
     */
    protected $zscore = false;

    /**
     * @var string path to template
     */
    protected $templates = array();

    /**
     * @var string path to template
     */
    protected $inputFile = 'input.fasta';

    /**
     * @var string path to template
     */
    protected $validatedFile = 'validated.fasta';

    /**
     * @var array array of wanted parameters
     */
    protected $wantedParameters;

    /**
     * @var string short description of the tool
     */
    public $description = 'Cppredict2 is a custom rRNA prediction tool that returns the predicted structure in dot-parent notation.';

    /**
     * Constructor used to save container
     *
     * @param \Nette\DI\Container $container
     */
    public function __construct(\Nette\DI\Container $container) {
        parent::__construct($container);

        $files = glob(CPPREDICT2_TEMPLATES . '/*.br');
        if (count($files) > 1) {
            $this->templates['automatic'] = 'automatic';
        }
        foreach ($files as $file) {
            $f = basename($file, '.br');
            $this->templates[$f] = str_replace('-', ' - ', str_replace('_', ' ', $f));
        }

        $this->wantedParameters = array(
            'sequence' => array('textarea', 'Sequence', array('placeholder' => 'AGUUCGGCACCACGGUGCAA')),
            'header' => array('text', 'Fasta header (optional)', array('placeholder' => 'BugIFoundInMyBackYard')),
            'template' => array('select', 'Template', array("items" =>
                    $this->templates)),
            'zscore' => array('checkbox', 'Compute z-score (slow)'),
        );
    }

    /**
     * Adds search criteria
     * 
     * @param string $name
     * @param mixed $value
     * @return boolean
     */
    public function addCriteria($name, $value) {
        if (property_exists($this, $name)) {
            // check for empty header
            if ($name == 'header') {
                if (!empty($value) && $value[0] !== '>') {
                    $value = '>' . $value;
                }
            }
            $this->$name = $value;
        }
        return true;
    }

    /**
     * Remove whitespaces from the sequence
     *
     * @return array $sequences array of sequences where sequences are in the format [header; trimmed sequence; sequence without whitespaces]
     */
    private function removeWhitespaces() {
        if ($this->header === '') {
            if (!empty($this->sequence) && substr($this->sequence, 0, 1) !== '>') {
                $this->sequence = ">No header\n" . $this->sequence;
            }
        } else {
            $this->sequence = $this->header . "\n" . $this->sequence;
        }
        $output = array();
        $splitted = preg_split('/((?<=[\r\n])(?=>))/', $this->sequence, null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
        foreach ($splitted as $sequence) {
            $pair = explode("\n", $sequence, 2);
            $item = array($pair[0]);
            if (count($pair) > 1) {
                $trimmed = trim($pair[1]);
                if (strlen($trimmed) > 0) {
                    $item[] = $trimmed;
                    $cleaned = preg_replace('/\s+/', '',$trimmed);
                    if (!empty($cleaned)) {
                        $item[] = $cleaned;
                    }
                }
            }
            $output[] = $item;
        }
        return $output;
    }

    /**
     * Validates template selection and assigns templates in the case of automatic choice
     *
     * @param String $input Path to FASTA file
     * @return array $sequences dictionary where keys are sequence identifiers and values are template identifiers
     */
    private function validateTemplate($input) {
        if (array_key_exists($this->template, $this->templates) && $this->template !== 'automatic') {
            $ret = array();
            $lines = file($input, FILE_SKIP_EMPTY_LINES);
            foreach ($lines as $line) {
                if (substr($line, 0, 1) === '>') {
                    $ret[trim(substr($line, 1))] = $this->template;
                }
            }
            $this->template = array($this->template => basename($input));
            return $ret;
        } else {
/* BLAST version *
            $blast = new \DispatchModule\Models\BlastModel($input);
            $result = $blast->executeBlastSearch("", "6 sseqid pident ppos qcovhsp", CPPREDICT2_TEMPLATES . TEMPLATES_DATABASE);
            $stats = array();
            foreach ($result as $line) {
                $parts = explode("\t", $line);
                if (count($parts) == 4) {
                    if (!array_key_exists($parts[0], $stats)) {
                        $stats[$parts[0]] = 0;
                    }
                    $stats[$parts[0]] += ($parts[1] + $parts[2]) * $parts[3];
                }
            }
            if (empty($stats)) {
                return "No available template is sufficiently similar for automatic assignment.";
            }
            $this->template = array_search(max($stats),$stats);
            if (!array_key_exists($this->template, $this->templates)) {
                return "Database of templates does not correspond to available templates.\nPlease contact the webadmin.";
            }
*/
            // Search Templates db for similar sequences
            $fasta = new \DispatchModule\Models\FastaModel($input);
            $result = $fasta->executeFastaSearch();
            $ret = array();
            foreach ($result as $line) {
                $parts = explode('  ', $line, 2);
                if (count($parts) === 2) {
                    if (!array_key_exists($parts[1], $this->templates)) {
                        return "Database of templates does not correspond to available templates.\nPlease contact the webadmin.";
                    }
                    $ret[$parts[0]] = $parts[1];
                }
            }
            if (empty($ret)) {
                unlink($input);
                return "No available template is sufficiently similar for automatic assignment.";
            }
            // Splits query sequences according their templates
            $lines = file($input, FILE_SKIP_EMPTY_LINES);
            $file = '';
            $dir = dirname($input) . '/';
            $this->template = array();
            foreach ($lines as $line) {
                if (substr($line, 0, 1) === '>') {
                    if (!empty($file)) {
                        fclose($file);
                    }
                    $id = trim(substr($line, 1));
                    if (array_key_exists($id, $ret)) {
                        $template = $ret[$id];
                        $filename = $template . ".fasta";
                        $this->template[$template] = $filename;
                        $file = fopen($dir . $filename, 'a');
                        fwrite($file, $line);
                    } else {
                        $file = '';
                    }
                } else {
                    fwrite($file, $line);
                }
            }
            if (!empty($file)) {
                fclose($file);
            }
            unlink($input);
            return $ret;
        }
    }

    /**
     * Creates temporary file
     *
     * @param array $sequences
     * @return string directory where the file is stored
     */
    private function createFastaFile($sequences) {
        $dirname = TEMP_PATH . '/cppredict2/' . (session_id() ? session_id() : time()) . '.' . rand() . '/';
        if (!mkdir($dirname)) {
          return false;
        }
        $filename = $dirname . $this->inputFile;
        if (file_put_contents($filename, '') === false) {
            rmdir($dirname);
            return false;
        }
        foreach ($sequences as $index => $sequence) {
            if (count($sequence) > 2) {
                file_put_contents($filename, '>' . $index . PHP_EOL . $sequence[2] . PHP_EOL, FILE_APPEND);
            }
        }
        return $dirname;
    }

    /**
     * Executes query
     * 
     * @return ResultSet
     */
    public function execute() {
        // Split in particular sequences and remove whitespaces
        $input = $this->removeWhitespaces();
        
        // Initialization of the output
        $output = array();
        // Prints basic info: header, input sequence and validated sequence
        foreach ($input as $index => $sequence) {
            $item = array();
            $item['header'] = $sequence[0];
            if (count($sequence) > 1) {
                $item['sequence'] = $sequence[1];
                if (count($sequence) > 2) {
                    $item['cleaned'] = $sequence[2];
                }
            }
            $item['other'] = array();
            $output[] = $item;
        }

        if (count($input) > 10) {
            array_unshift($output, array('header' => 'General message', 'error' => 'Too many sequences!'));
            return $output;
        }
        $dir = $this->createFastaFile($input);
        if ($dir === false) {
            array_unshift($output, array('error' => 'Everything is conspiring against you and we are unable to accommodate your request due to unexpected errors.'));
            return $output;
        }

        $inputFile = $dir . '/' . $this->inputFile;
        if (filesize($inputFile) === false) {
            $output = array(array('error' => 'Everything is conspiring against you and we are unable to accommodate your request due to unexpected errors.'));
        } elseif (filesize($inputFile) === 0) {
            $output = array(array('error' => 'No input sequence is specified'));
            unlink($inputFile);
        } else {
            $validatedFile = $dir . '/' . $this->validatedFile;
            $outputValidate = shell_exec('cd ' . $dir . ' && ' . WILDCARDS_PATH . ' ' . $this->inputFile . ' 2>&1 > ' . $this->validatedFile);
            unlink($inputFile);
            // Prints additional info from validation: Substitutions
            foreach (preg_split('/(^|[\r\n])>/', $outputValidate, NULL, PREG_SPLIT_NO_EMPTY) as $line) {
                $parts = preg_split('/[\r\n]+/', $line, NULL, PREG_SPLIT_NO_EMPTY);
                $item = &$output[$parts[0]];
                for ($i = 1; $i < count($parts); $i++) {
                    $pair = explode(':', $parts[$i], 2);
                    if ($pair[0] === 'Error') {
                        if (count($pair) < 2) {
                            $item['error'] = '';
                        } else {
                            $item['error'] = trim($pair[1]);
                        }
                    } elseif (count($pair) == 2 && $pair[0] !== 'Sequence') {
                        $value = trim($pair[1]);
                        if (!empty($value)) {
                            $item['other'][strtolower(trim($pair[0]))] = $value;
                        }
                    }
                }
            }

            if (filesize($validatedFile) !== false) {
                if (filesize($validatedFile) > 0) {
                    $outputTemplate = $this->validateTemplate($validatedFile);
                    if (is_array($outputTemplate)) {
                        // Prints info about template
                        foreach ($outputTemplate as $index => $template) {
                            $output[$index]['other']['template'] = $this->templates[$template];
                        }

                        foreach ($this->template as $template => $queries) {
                            $outputPredict = shell_exec('cd ' . $dir . ' && ' . CPPREDICT2_PATH . ' -sqs="' . $queries . '" -str="' . CPPREDICT2_TEMPLATES . $template . '.br" -ALM=clustalw2 -EXTEND_MECHANICALLY_LONELY_PAIRS=0 -BOOTSTRAP=' . ($this->zscore ? '1' : '0') . ' 2>&1');
                            // Prints info from prediction: predicted structure and statistics
                            $position = strrpos($outputPredict, ']]');
                            if ($position !== false) {
                                foreach (explode(PHP_EOL, substr($outputPredict, $position+2)) as $line) {
                                    if (stripos($line, '    ') !== false) {
                                        $parts = explode('  ', $line);
                                        $index = $parts[0];
                                        $item = &$output[$index];
                                        $item['other']['sequenceSimilarity'] = $parts[1] . '%';
                                        $item['other']['lengthRatio'] = $parts[2];
                                        $item['other']['lengthDifference'] = $parts[3];
                                        $item['other']['rnadistanceScore'] = $parts[4];
                                        if ($this->zscore) {
                                            $item['other']['zScore'] = $parts[5];
                                        }
                                        $tmpFile = $dir . '/' . $index . '.br';
                                        if (file_exists($tmpFile)) {
                                            $file = file($tmpFile, FILE_IGNORE_NEW_LINES);
                                            $item['dotParent'] = $file[2];
                                            unlink($tmpFile);
                                        }
                                    }
                                }
                            }
                            unlink($dir . '/' . $queries);
                        }
                    } elseif (is_string($outputTemplate)) {
                        array_unshift($output, array('header' => 'General message', 'error' => $outputTemplate));
                    }
                }
            }

        }
        rmdir($dir);

        return $output;
    }

    /**
     * Gets human-readable short description (name) of the tool
     *
     * @return string human-readable short description of the tools
     */
    public function getLabel() {
        return 'Cp-predict2';
    }

}

API documentation generated by ApiGen