* *************/ 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 {
/** * 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; }
* *************/ 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); }
* 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);
* 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();
} } // 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)) {
/** * 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; }