Ejemplo n.º 1
0
 *
 *************/
define('ROOT_PATH', '../');
require ROOT_PATH . 'inc-init.php';
session_write_close();
$aGenes = lovd_getGeneList();
if (empty($_GET['variant']) || !preg_match('/^([A-Z]{2}_\\d{6,9}\\.\\d{1,2}(\\([A-Za-z0-9-]+_v\\d{3}\\))?:[cn])|(chr.{0,2}:[gm])\\..+$/', $_GET['variant']) || empty($_GET['gene']) || !in_array($_GET['gene'], $aGenes)) {
    die(AJAX_DATA_ERROR);
}
// Requires at least LEVEL_SUBMITTER, anything lower has no $_AUTH whatsoever.
if (!$_AUTH) {
    // If not authorized, die with error message.
    die(AJAX_NO_AUTH);
}
require ROOT_PATH . 'class/soap_client.php';
$_Mutalyzer = new LOVD_SoapClient();
$sGene = $_GET['gene'];
// If the gene is defined in the mito_genes_aliases in inc-init.php, use the NCBI gene symbol.
if (isset($_SETT['mito_genes_aliases'][$_GET['gene']])) {
    $sGene = $_SETT['mito_genes_aliases'][$_GET['gene']];
}
try {
    $oOutput = $_Mutalyzer->numberConversion(array('build' => $_CONF['refseq_build'], 'variant' => $_GET['variant'], 'gene' => $sGene))->numberConversionResult;
} catch (SoapFault $e) {
    // FIXME: Perhaps indicate an error? Like in the check_hgvs script?
    die(AJAX_FALSE);
}
if ($oOutput && isset($oOutput->string)) {
    $sVariants = implode(';', $oOutput->string);
    die($sVariants);
} else {
Ejemplo n.º 2
0
/**
 * Predict a protein description of a variant and given transcript using the
 * Mutalyzer webservice.
 * @param $sReference
 * @param string $sGene
 * @param $sNCBITranscriptID
 * @param string $sVariant
 * @return array $aMutalyzerData
 */
function lovd_getRNAProteinPrediction($sReference, $sGene, $sNCBITranscriptID, $sVariant)
{
    global $_CONF, $_SETT;
    // Needs to be a require_once in case other code has already included this, and also for repeated calls to this function.
    require_once ROOT_PATH . 'class/soap_client.php';
    $aMutalyzerData = array();
    // Regex pattern to match a reference accession number in variant description.
    $sRefseqPattern = '(UD_\\d{12}|N(?:C|G)_\\d{6,}\\.\\d{1,2})';
    if (isset($sGene) && isset($_SETT['mito_genes_aliases'][$sGene])) {
        // This is a mitochondrial gene.
        if (empty($sNCBITranscriptID) || empty($sVariant)) {
            $aMutalyzerData['mutalyzer_error'] = 'No valid transcript ID or variant specified.';
            return $aMutalyzerData;
        }
        // Gene is defined in the mito_genes_aliases in file inc-init.php: use the NCBI gene symbol.
        $sNCBITranscriptID = str_replace($sGene, $_SETT['mito_genes_aliases'][$sGene], $sNCBITranscriptID);
        // For mitochondrial genes, Mutalyzer specifies the NCBI transcript ID actually
        // as an NC_ accession number with NCBI gene alias (e.g. 'NC_012920.1(TRNF_v001)')
        // We can use that directly as a reference in the variant description.
        $sFullVariantDescription = $sNCBITranscriptID . ':' . $sVariant;
    } else {
        // Non-mitochondrial gene, use normal reference, transcript ID and variant.
        if (empty($sReference) || empty($sNCBITranscriptID) || empty($sVariant) || !preg_match('/^' . $sRefseqPattern . '$/', $sReference)) {
            $aMutalyzerData['mutalyzer_error'] = 'No valid input given for reference, transcript id or variant.';
            return $aMutalyzerData;
        }
        $sFullVariantDescription = $sReference . '(' . $sNCBITranscriptID . '):' . $sVariant;
    }
    // Build URL for protein prediction to be shown in interface.
    $aMutalyzerData['mutalyzer_url'] = str_replace('services', 'check', $_CONF['mutalyzer_soap_url']) . '?name=' . urlencode($sFullVariantDescription) . '&standalone=1';
    // Make call to mutalyzer to check variant description.
    $_Mutalyzer = new LOVD_SoapClient();
    try {
        $oOutput = $_Mutalyzer->runMutalyzer(array('variant' => $sFullVariantDescription))->runMutalyzerResult;
    } catch (SoapFault $e) {
        $aMutalyzerData['mutalyzer_error'] = 'Unexpected response from Mutalyzer. Please try again later.';
        return $aMutalyzerData;
    }
    // When transcript is not found, attempt fallback to newer version of transcript
    foreach (getMutalyzerMessages($oOutput) as $oSoapMessage) {
        if ($oSoapMessage->errorcode === 'EINVALIDTRANSVAR') {
            // Invalid transcript variant.
            if (isset($oOutput->legend) && !empty($oOutput->legend->LegendRecord)) {
                // Check if a newer version of the transcript is available from the legend.
                list($sAccession, $sVersion) = explode('.', $sNCBITranscriptID);
                foreach ($oOutput->legend->LegendRecord as $oRecord) {
                    $aRecordFields = explode('.', $oRecord->id);
                    if (count($aRecordFields) != 2) {
                        continue;
                    }
                    list($sAltAccession, $sAltVersion) = $aRecordFields;
                    if ($sAccession == $sAltAccession && intval($sAltVersion) > intval($sVersion)) {
                        // Found a newer version of the transcript. Try to do protein
                        // prediction using that record instead.
                        $aAltMutalyzerOutput = lovd_getRNAProteinPrediction($sReference, $sGene, $oRecord->id, $sVariant);
                        if (!isset($aAltMutalyzerOutput['mutalyzer_error']) && !isset($aAltMutalyzerOutput['error']) && !empty($aAltMutalyzerOutput['predict'])) {
                            // Prediction with alternative transcript record went well, return it
                            // with an added warning.
                            $aAltMutalyzerOutput['warning']['DEPRECATED TRANSCRIPT'] = 'The provided transcript is outdated, the given prediction is ' . 'based on the latest version of the transcript: ' . $sAltAccession . '.' . $sAltVersion;
                            return $aAltMutalyzerOutput;
                        }
                    }
                }
                // Could not find a newer version of the transcript.
                $aMutalyzerData['error'][$oSoapMessage->errorcode] = trim($oSoapMessage->message);
                return $aMutalyzerData;
            }
        }
    }
    // Find protein prediction in mutalyzer output.
    if (isset($oOutput->legend) && !empty($oOutput->legend->LegendRecord) && !empty($oOutput->proteinDescriptions->string)) {
        $sMutProteinName = null;
        // Loop over legend records to find transcript name (v-number).
        foreach ($oOutput->legend->LegendRecord as $oRecord) {
            if (isset($oRecord->id) && $oRecord->id == $sNCBITranscriptID && substr($oRecord->name, -4, 1) == 'v') {
                // Generate protein isoform name (i-number) from transcript name (v-number)
                $sMutProteinName = str_replace('_v', '_i', $oRecord->name);
                break;
            }
        }
        if (isset($sMutProteinName)) {
            // Select protein description based on protein isoform (i-number).
            $sProteinDescriptions = implode('|', $oOutput->proteinDescriptions->string);
            preg_match('/' . $sRefseqPattern . '\\(' . preg_quote($sMutProteinName) . '\\):(p\\..+?)(\\||$)/', $sProteinDescriptions, $aProteinMatches);
            if (isset($aProteinMatches[2])) {
                $aMutalyzerData['predict']['protein'] = $aProteinMatches[2];
            }
        }
    }
    foreach (getMutalyzerMessages($oOutput) as $oSoapMessage) {
        if ($oSoapMessage->errorcode === 'ERANGE') {
            // Ignore 'ERANGE' as an actual error, because we can always interpret this as p.(=), p.? or p.0.
            $sDNAChange = substr($sVariant, strpos($sVariant, ':') + 1);
            $aVariantRange = explode('_', $sDNAChange);
            // Check what the variant looks like and act accordingly.
            if (count($aVariantRange) === 2 && preg_match('/-\\d+/', $aVariantRange[0]) && preg_match('/-\\d+/', $aVariantRange[1])) {
                // Variant has 2 positions. Variant has both the start and end positions upstream of the transcript, we can assume that the product will not be affected.
                $sPredictR = 'r.(=)';
                $sPredictP = 'p.(=)';
            } elseif (count($aVariantRange) === 2 && preg_match('/-\\d+/', $aVariantRange[0]) && preg_match('/\\*\\d+/', $aVariantRange[1])) {
                // Variant has 2 positions. Variant has an upstream start position and a downstream end position, we can assume that the product will not be expressed.
                $sPredictR = 'r.0?';
                $sPredictP = 'p.0?';
            } elseif (count($aVariantRange) == 2 && preg_match('/\\*\\d+/', $aVariantRange[0]) && preg_match('/\\*\\d+/', $aVariantRange[1])) {
                // Variant has 2 positions. Variant has both the start and end positions downstream of the transcript, we can assume that the product will not be affected.
                $sPredictR = 'r.(=)';
                $sPredictP = 'p.(=)';
            } elseif (count($aVariantRange) == 1 && preg_match('/-\\d+/', $aVariantRange[0]) || preg_match('/\\*\\d+/', $aVariantRange[0])) {
                // Variant has 1 position and is either upstream or downstream from the transcript, we can assume that the product will not be affected.
                $sPredictR = 'r.(=)';
                $sPredictP = 'p.(=)';
            } else {
                // One of the positions of the variant falls within the transcript, so we can not make any assumptions based on that.
                $sPredictR = 'r.?';
                $sPredictP = 'p.?';
            }
            // Fill in our assumption in aData to forge that this information came from Mutalyzer.
            $aMutalyzerData['predict']['protein'] = $sPredictP;
            $aMutalyzerData['predict']['RNA'] = $sPredictR;
            continue;
        } elseif ($oSoapMessage->errorcode === 'WSPLICE') {
            // Mutalyzer now (2012-12-07) returns a WSPLICE for <= 5 nucleotides from the site,
            // even though there internally is a difference between variants in splice sites,
            // and variants close to splice sites.
            // Most likely, they will include two different types of errors in the future.
            $aMutalyzerData['predict']['protein'] = 'p.?';
            $aMutalyzerData['predict']['RNA'] = 'r.spl?';
        }
        if (isset($oSoapMessage->errorcode) && substr($oSoapMessage->errorcode, 0, 1) === 'E') {
            $aMutalyzerData['error'][trim($oSoapMessage->errorcode)] = trim($oSoapMessage->message);
        } elseif (isset($oSoapMessage->errorcode)) {
            $aMutalyzerData['warning'][trim($oSoapMessage->errorcode)] = trim($oSoapMessage->message);
        }
    }
    if ($oOutput->errors === 0 && empty($aMutalyzerData['predict']['RNA'])) {
        // RNA not filled in yet.
        if (!isset($aMutalyzerData['predict']['protein'])) {
            // Non-coding transcript, Mutalyzer does not return a protein field, but also no error.
            // FIXME: Check for intronic variants here, that do not span over an exon, and give them r.(=).
            $aMutalyzerData['predict']['RNA'] = 'r.(?)';
            $aMutalyzerData['predict']['protein'] = '-';
        } elseif ($aMutalyzerData['predict']['protein'] == 'p.?') {
            $aMutalyzerData['predict']['RNA'] = 'r.?';
        } elseif ($aMutalyzerData['predict']['protein'] == 'p.(=)') {
            // FIXME: Not correct in case of substitutions e.g. in the third position of the codon, not leading to a protein change.
            $aMutalyzerData['predict']['RNA'] = 'r.(=)';
        } else {
            // RNA will default to r.(?).
            $aMutalyzerData['predict']['RNA'] = 'r.(?)';
        }
    }
    return $aMutalyzerData;
}
Ejemplo n.º 3
0
 *
 *************/
define('ROOT_PATH', '../');
session_cache_limiter('public');
// Stops the session from sending any cache or no-cache headers. Alternative: ini_set() session.cache_limiter.
require ROOT_PATH . 'inc-init.php';
header('Expires: ' . date('r', time() + 24 * 60 * 60));
// HGVS syntax check result expires in a day.
session_write_close();
if (empty($_GET['variant']) || !preg_match('/^(c:[c|n]|g:g)\\..+$/', $_GET['variant'])) {
    die(AJAX_DATA_ERROR);
}
// Take the c. or g. off.
$_GET['variant'] = substr($_GET['variant'], 2);
// Requires at least LEVEL_SUBMITTER, anything lower has no $_AUTH whatsoever.
if (!$_AUTH) {
    // If not authorized, die with error message.
    die(AJAX_NO_AUTH);
}
require ROOT_PATH . 'class/soap_client.php';
$_Mutalyzer = new LOVD_SoapClient();
try {
    $aOutput = $_Mutalyzer->checkSyntax(array('variant' => $_GET['variant']))->checkSyntaxResult;
} catch (SoapFault $e) {
    die(AJAX_UNKNOWN_RESPONSE);
}
if (isset($aOutput->valid) && $aOutput->valid) {
    die(AJAX_TRUE);
} else {
    die(AJAX_FALSE);
}
Ejemplo n.º 4
0
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * LOVD is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with LOVD.  If not, see <http://www.gnu.org/licenses/>.
 *
 *************/
define('ROOT_PATH', '../');
require ROOT_PATH . 'inc-init.php';
session_write_close();
if (!ACTION || count($_GET) <= 1) {
    echo 'Insufficient arguments given.';
    exit;
}
require ROOT_PATH . 'class/soap_client.php';
$_Mutalyzer = new LOVD_SoapClient();
$aArgs = array();
foreach ($_GET as $key => $value) {
    if ($value) {
        $aArgs[$key] = $value;
    }
}
// I don't understand why I need to put an array() around the arguments array, but oh, well...
$aOutput = $_Mutalyzer->__soapCall(ACTION, array($aArgs));
var_dump($aOutput);
Ejemplo n.º 5
0
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with LOVD.  If not, see <http://www.gnu.org/licenses/>.
 *
 *************/
define('ROOT_PATH', '../');
require ROOT_PATH . 'inc-init.php';
require ROOT_PATH . 'inc-lib-actions.php';
require ROOT_PATH . 'inc-lib-genes.php';
require ROOT_PATH . 'inc-lib-form.php';
require ROOT_PATH . 'class/soap_client.php';
require ROOT_PATH . 'inc-lib-variants.php';
$_Mutalyzer = new LOVD_SoapClient();
define('LOG_EVENT', 'AutomaticMapping');
//header('Content-type: text/javascript; charset=UTF-8'); // When this header is enabled, jQuery doesn't like the script anymore because it assumes JSON, see the dataType setting.
//$tStart = microtime(true);
//var_dump(__LINE__ . ':' . (microtime(true) - $tStart));
// We want to finish the mapping, even if the connection with the browser is lost while working.
ignore_user_abort(true);
// Process only a limited number of variants at once.
$nRange = 100000;
$nMaxVariants = 25;
// Log errors only once every 5 minutes.
$tLogInterval = 300;
// PHP may lose the current working directory once it starts calling shutdown functions.
// Let's remember it.
define('WORKING_DIRECTORY', getcwd());
$aVariantUpdates = array();
Ejemplo n.º 6
0
     }
 }
 // Mandatory fields.
 if (empty($_POST['password'])) {
     lovd_errorAdd('password', 'Please fill in the \'Enter your password for authorization\' field.');
 } elseif (!lovd_verifyPassword($_POST['password'], $_AUTH['password'])) {
     // User had to enter his/her password for authorization.
     lovd_errorAdd('password', 'Please enter your correct password for authorization.');
 }
 if (!lovd_error()) {
     $_DB->beginTransaction();
     $aNewTranscripts = array();
     $aToRemove = array();
     $aVariantDescriptions = array();
     require ROOT_PATH . 'class/soap_client.php';
     $_Mutalyzer = new LOVD_SoapClient();
     $aGenesUpdated = array();
     foreach ($_POST['transcripts'] as $nTranscript) {
         if ($nTranscript && !isset($aCurrentTranscripts[$nTranscript])) {
             // If the transcript is not already present in the database connected to this variant, we will add it now.
             $aNewTranscripts[] = $nTranscript;
             // Gather all necessary info from this transcript.
             $zTranscript = $_DB->query('SELECT id, geneid, name, id_ncbi FROM ' . TABLE_TRANSCRIPTS . ' WHERE id = ?', array($nTranscript))->fetchAssoc();
             // Call the numberConversion module of mutalyzer to get the VariantOnTranscript/DNA value for this variant on this transcript.
             // Check if we already have the converted positions for this gene, if so, we won't have to call mutalyzer again for this information.
             if (!array_key_exists($zTranscript['geneid'], $aVariantDescriptions)) {
                 try {
                     $oOutput = $_Mutalyzer->numberConversion(array('build' => $_CONF['refseq_build'], 'variant' => 'chr' . $zData['chromosome'] . ':' . $zData['VariantOnGenome/DNA'], 'gene' => $zTranscript['geneid']))->numberConversionResult;
                 } catch (Exception $e) {
                 }
                 if (isset($oOutput) && isset($oOutput->string)) {
Ejemplo n.º 7
0
 /**
  * This method returns transcripts and info from mutalyzer.
  * Note that transcripts that are already in the LOVD database are skipped.
  * @param string $sRefseqUD Genomic reference.
  * @param string $sSymbol HGNC gene symbol.
  * @param string $sGeneName HGNC gene name.
  * @param float $nProgress Variable is passed by reference and used to keep up the progress of the progress bar.
  * If the progress bar is initialized before this method is called, you can keep track of the progress with this variable.
  * The progress bar will start at zero when this variable is not set.
  * @return array $aTranscriptInfo Transcript information from mutalyzer.
  **/
 public function getTranscriptPositions($sRefseqUD, $sSymbol, $sGeneName, &$nProgress = 0.0)
 {
     global $_BAR, $_SETT, $_DB;
     $_Mutalyzer = new LOVD_SoapClient();
     $aTranscripts = array('id' => array(), 'name' => array(), 'mutalyzer' => array(), 'positions' => array(), 'protein' => array(), 'added' => array());
     $sAliasSymbol = $sSymbol;
     $aTranscripts['added'] = $_DB->query('SELECT id_ncbi FROM ' . TABLE_TRANSCRIPTS . ' WHERE geneid = ? ORDER BY id_ncbi', array($sSymbol))->fetchAllColumn();
     if (isset($_SETT['mito_genes_aliases'][$sSymbol])) {
         // For mitochondrial genes, an alias must be used to get the transcripts and info.
         // List of aliases are hard-coded in inc-init.php.
         $sAliasSymbol = $_SETT['mito_genes_aliases'][$sSymbol];
     }
     try {
         // Can throw notice when TranscriptInfo is not present (when a gene recently has been renamed, for instance).
         $aTranscripts['info'] = @$_Mutalyzer->getTranscriptsAndInfo(array('genomicReference' => $sRefseqUD, 'geneName' => $sAliasSymbol))->getTranscriptsAndInfoResult->TranscriptInfo;
     } catch (SoapFault $e) {
         lovd_soapError($e);
     }
     if (empty($aTranscripts['info'])) {
         // No transcripts found.
         $aTranscripts['info'] = array();
         return $aTranscripts;
     }
     $nTranscripts = count($aTranscripts['info']);
     foreach ($aTranscripts['info'] as $oTranscript) {
         $nProgress += (100 - $nProgress) / $nTranscripts;
         $_BAR->setMessage('Collecting ' . $oTranscript->id . ' info...');
         if (isset($_SETT['mito_genes_aliases'][$sSymbol])) {
             // For mitochondrial genes, we won't be able to get any proper transcript information. Fake one.
             // FIXME: This code only works, if there is just one transcript. Can we assume there is only one?
             //   Perhaps it's better to use the same array construction as for normal genes, which is shorter, faster, and more flexible.
             $sRefseqNM = $sRefseqUD . '(' . $sAliasSymbol . '_v001)';
             if (in_array($sRefseqNM, $aTranscripts['added'])) {
                 // Transcript already exists; continue to the next transcript.
                 continue;
             }
             $aTranscripts['id'] = array($sRefseqNM);
             $aTranscripts['protein'] = array($sRefseqNM => '');
             // Until revision 679 the transcript version was not used in the index. The version number was removed with preg_replace.
             // Can not figure out why version is not included. Therefore, for now we will do without preg_replace.
             $aTranscripts['mutalyzer'] = array($sRefseqNM => '001');
             $aTranscripts['name'] = array($sRefseqNM => 'transcript variant 1');
             // FIXME: Perhaps indicate this transcript is a fake one, reconstructed from the CDS?
             $aTranscripts['positions'] = array($sRefseqNM => array('chromTransStart' => isset($oTranscript->gTransStart) ? $oTranscript->gTransStart : 0, 'chromTransEnd' => isset($oTranscript->gTransEnd) ? $oTranscript->gTransEnd : 0, 'cTransStart' => isset($oTranscript->cTransStart) ? $oTranscript->cTransStart : 0, 'cTransEnd' => isset($oTranscript->sortableTransEnd) ? $oTranscript->sortableTransEnd : 0, 'cCDSStop' => isset($oTranscript->cCDSStop) ? $oTranscript->cCDSStop : 0));
         } else {
             if (in_array($oTranscript->id, $aTranscripts['added'])) {
                 // Transcript already exists; continue to the next transcript.
                 continue;
             }
             $aTranscripts['id'][] = $oTranscript->id;
             // Until revision 679 the transcript version was not used in the index. The version number was removed with preg_replace.
             // Can not figure out why version is not included. Therefore, for now we will do without preg_replace.
             $aTranscripts['name'][$oTranscript->id] = str_replace($sGeneName . ', ', '', $oTranscript->product);
             $aTranscripts['mutalyzer'][$oTranscript->id] = str_replace($sSymbol . '_v', '', $oTranscript->name);
             $aTranscripts['positions'][$oTranscript->id] = array('chromTransStart' => isset($oTranscript->chromTransStart) ? $oTranscript->chromTransStart : 0, 'chromTransEnd' => isset($oTranscript->chromTransEnd) ? $oTranscript->chromTransEnd : 0, 'cTransStart' => $oTranscript->cTransStart, 'cTransEnd' => $oTranscript->sortableTransEnd, 'cCDSStop' => $oTranscript->cCDSStop);
             $aTranscripts['protein'][$oTranscript->id] = !isset($oTranscript->proteinTranscript) ? '' : $oTranscript->proteinTranscript->id;
         }
         $_BAR->setProgress($nProgress);
     }
     return $aTranscripts;
 }