/** * This is the uber-validation function that calls everything below. * It is suited for use from either the web or command line interface. * This only makes sense in terms of an active session. * modelID ID code for model to process * opts has the following keys mapped to boolean flags: * doKinemage make the multi-criterion kinemage at all? * kinClashes show clash dots? * kinHbonds show H-bond dots? * kinContacts show contact dots? * kinRama show Rama outliers? * kinRota show rotamer outliers? * kinGeom show bond length and angle outliers? * kinCBdev show C-beta deviations? * kinBaseP show base-phosphate perpendiculars? * kinSuite show RNA backbone conformational outliers? * kinAltConfs show alternate conformations? * kinBfactor show B-factor color model? * kinOccupancy show occupancy color model? * kinRibbons show ribbons? * kinForceViews force running clashlist, etc to provide @views of bad spots? * doCharts make the multi-criterion chart and other plots/tables/lists? * chartClashlist run clashlistcluster? * chartRama do Rama plots and analysis? * chartRota do rotamer analysis? * chartGeom do bond length and angle outliers? * chartCBdev do CB dev plots and analysis? * chartBaseP check base-phosphate perpendiculars? * chartSuite check RNA backbone conformations? * chartHoriz do horizontal chart? * chartCoot do coot chart? * chartMulti do html multi chart? * chartNotJustOut include residues that have no problems in the list? * chartAltloc remove redundant residue rows when altlocs present? * chartImprove compare to reduce -(no)build results to show improvement? * * This function returns some HTML suitable for using in a lab notebook entry. */ function runAnalysis($modelID, $opts) { //{{{ Set up file/directory vars and the task list // If doKinemage or doCharts is off, turn off all their subordinates if (!$opts['doKinemage']) { foreach ($opts as $k => $v) { if (startsWith($k, 'kin')) { $opts[$k] = false; } } } if (!$opts['doCharts']) { foreach ($opts as $k => $v) { if (startsWith($k, 'chart')) { $opts[$k] = false; } } } if ($opts['kinForceViews']) { foreach ($opts as $k => $v) { if (startsWith($k, 'chart')) { $opts[$k] = true; } } } $model = $_SESSION['models'][$modelID]; $modelDir = $_SESSION['dataDir'] . '/' . MP_DIR_MODELS; $modelURL = $_SESSION['dataURL'] . '/' . MP_DIR_MODELS; $kinDir = $_SESSION['dataDir'] . '/' . MP_DIR_KINS; $kinURL = $_SESSION['dataURL'] . '/' . MP_DIR_KINS; if (!file_exists($kinDir)) { mkdir($kinDir, 0777); } $rawDir = $_SESSION['dataDir'] . '/' . MP_DIR_RAWDATA; if (!file_exists($rawDir)) { mkdir($rawDir, 0777); } $chartDir = $_SESSION['dataDir'] . '/' . MP_DIR_CHARTS; $chartURL = $_SESSION['dataURL'] . '/' . MP_DIR_CHARTS; if (!file_exists($chartDir)) { mkdir($chartDir, 0777); } $xrayDir = $_SESSION['dataDir'] . '/' . MP_DIR_XRAYDATA; $infile = "{$modelDir}/{$model['pdb']}"; $reduce_blength = $_SESSION['reduce_blength']; if (isset($model['mtz_file'])) { $mtz_file = $model['mtz_file']; } else { $mtz_file = $_SESSION['models'][$model['parent']]['mtz_file']; } if ($opts['chartRama']) { $tasks['rama'] = "Do Ramachandran analysis and make plots (<code>ramalyze</code>)"; } if ($opts['chartRota']) { $tasks['rota'] = "Do rotamer analysis (<code>rotalyze</code>)"; } if ($opts['chartCBdev']) { $tasks['cbeta'] = "Do Cβ deviation analysis and make kins (<code>cbetadev</code>)"; } if ($opts['chartOmega']) { $tasks['omega'] = "Do cis-peptide analysis (<code>omegalyze</code>)"; } if ($opts['chartCablamLow']) { $tasks['cablam'] = "Do CaBLAM analysis (<code>cablam_validate</code>)"; } if ($opts['chartBaseP']) { $tasks['base-phos'] = "Do RNA sugar pucker analysis"; } if ($opts['chartSuite']) { $tasks['suitename'] = "Do RNA backbone conformations analysis"; } if ($model['stats']['use_cdl']) { $geomsg = "Using CDL"; } else { $geomsg = ""; } if ($opts['chartGeom']) { $tasks['geomValidation'] = "Do bond length and angle geometry analysis (<code>mp_geo</code>) {$geomsg}"; } if ($opts['chartClashlist']) { $tasks['clashlist'] = "Run <code>clashscore</code> to find bad clashes and clashscore"; } if ($opts['chartImprove']) { $tasks['improve'] = "Suggest / report on fixes"; } if ($opts['doCharts'] && !$opts['chartMulti']) { $tasks['chartsummary'] = "Create summary chart"; } if ($opts['chartMulti']) { $tasks['multichart'] = "Create multi-criterion chart"; } if ($opts['chartHoriz']) { $tasks['runRSCC'] = "Run real-space correlation"; $tasks['charthoriz'] = "Create horizontal RSCC chart"; } if ($opts['chartCoot']) { $tasks['cootchart'] = "Create chart for use in Coot"; } if ($opts['doKinemage']) { $tasks['multikin'] = "Create multi-criterion kinemage"; } //if($opts['doLowRes']) $tasks['lowResKin'] = "Create low-resolution multi-criterion kinemage"; //$doRem40 = $opts['chartClashlist'] || $opts['chartRama'] || $opts['chartRota']; //if($doRem40) $tasks['remark40'] = "Create REMARK 40 record for the PDB file"; //}}} Set up file/directory vars and the task list //{{{ Run geometry programs and offer kins to user //{{{ Ramachandran if ($opts['chartRama']) { $startTime = time(); setProgress($tasks, 'rama'); // updates the progress display if running as a background job $outfile = "{$rawDir}/{$model['prefix']}rama.data"; runRamachandran($infile, $outfile); $rama = loadRamachandran($outfile); makeRamachandranKin($infile, "{$kinDir}/{$model['prefix']}rama.kin"); $tasks['rama'] .= " - preview <a href='viewking.php?{$_SESSION['sessTag']}&url={$kinURL}/{$model['prefix']}rama.kin' target='_blank'>kinemage</a>"; setProgress($tasks, 'rama'); // so the preview link is visible makeRamachandranPDF($infile, "{$chartDir}/{$model['prefix']}rama.pdf"); $tasks['rama'] .= " | <a href='{$chartURL}/{$model['prefix']}rama.pdf' target='_blank'>PDF</a>\n"; setProgress($tasks, 'rama'); // so the preview link is visible echo "Ramachandran ran for " . (time() - $startTime) . " seconds\n"; } //}}} //{{{ Rotamers if ($opts['chartRota']) { $startTime = time(); setProgress($tasks, 'rota'); // updates the progress display if running as a background job $outfile = "{$rawDir}/{$model['prefix']}rota.data"; runRotamer($infile, $outfile); $rota = loadRotamer($outfile); echo "Rotamers ran for " . (time() - $startTime) . " seconds\n"; } //}}} //{{{ C-beta deviations if ($opts['chartCBdev']) { $startTime = time(); setProgress($tasks, 'cbeta'); // updates the progress display if running as a background job $outfile = "{$rawDir}/{$model['prefix']}cbdev.data"; runCbetaDev($infile, $outfile); $cbdev = loadCbetaDev($outfile); makeCbetaDevPlot($infile, "{$kinDir}/{$model['prefix']}cbetadev.kin"); $tasks['cbeta'] .= " - <a href='viewking.php?{$_SESSION['sessTag']}&url={$kinURL}/{$model['prefix']}cbetadev.kin' target='_blank'>preview</a>"; setProgress($tasks, 'cbeta'); // so the preview link is visible echo "C-beta ran for " . (time() - $startTime) . " seconds\n"; } //}}} //{{{ Omega peptides if ($opts['chartOmega']) { $startTime = time(); setProgress($tasks, 'omega'); $outfile = "{$rawDir}/{$model['prefix']}omega.data"; //$outfile = "$rawDir/$model[prefix]omega-clashlist.txt"; runOmegalyze($infile, $outfile); $omega = loadOmegalyze($outfile); echo "Omegalyze ran for " . (time() - $startTime) . " seconds\n"; } //}}} //{{{ CaBLAM if ($opts['chartCablamLow']) { setProgress($tasks, 'cablam'); $outfile = "{$rawDir}/{$model['prefix']}cablam.data"; runCablam($infile, $outfile); $cablam = loadCablam($outfile); } //}}} //{{{ Run nucleic acid geometry programs and offer kins to user //{{{ Base-phosphate perpendiculars if ($opts['chartBaseP']) { setProgress($tasks, 'base-phos'); // updates the progress display if running as a background job $outfile = "{$rawDir}/{$model['prefix']}pperp.data"; runBasePhosPerp($infile, $outfile); $pperp = loadBasePhosPerp($outfile); } //}}} //{{{ Suitename if ($opts['chartSuite']) { setProgress($tasks, 'suitename'); // updates the progress display if running as a background job $outfile = "{$chartDir}/{$model['prefix']}suitename.txt"; runSuitenameReport($infile, $outfile); $suites = loadSuitenameReport($outfile); $tasks['suitename'] .= " - <a href='viewtext.php?{$_SESSION['sessTag']}&file={$outfile}&mode=plain' target='_blank'>preview</a>\n"; setProgress($tasks, 'suitename'); // so the preview link is visible $outfile = "{$chartDir}/{$model['prefix']}suitestring.txt"; runSuitenameString($infile, $outfile); makeSuitenameKin($infile, "{$kinDir}/{$model['prefix']}suitename.kin"); } //}}} //}}} Run nucleic acid geometry programs and offer kins to user //{{{ Bonds and Angles if ($opts['chartGeom']) { setProgress($tasks, 'geomValidation'); // updates the progress display if running as a background job $geomfile = "{$rawDir}/{$model['prefix']}geomvalidation.data"; runValidationReport($infile, $geomfile, $model['stats']['use_cdl']); //$protfile = "$rawDir/$model[prefix]protvalidation.data"; //runValidationReport($infile, $protfile, "protein"); //$rnafile = "$rawDir/$model[prefix]rnavalidation.data"; //runValidationReport($infile, $rnafile, "rna"); //$validate_bond = loadValidationBondReport($protfile,"protein"); //if (is_array($validate_bond)) $validate_bond = array_merge(loadValidationBondReport($geomfile, "protein"), loadValidationBondReport($geomfile, "rna")); if (count($validate_bond) == 0) { $validate_bond = null; } $validate_angle = array_merge(loadValidationAngleReport($geomfile, "protein"), loadValidationAngleReport($geomfile, "rna")); if (count($validate_angle) == 0) { $validate_angle = null; } } //}}} //}}} Run programs and offer kins to user //{{{ Run all-atom contact programs and offer kins to user // Clashes if ($opts['chartClashlist']) { $startTime = time(); setProgress($tasks, 'clashlist'); // updates the progress display if running as a background job $outfile = "{$chartDir}/{$model['prefix']}clashlist.txt"; #runClashlist($infile, $outfile, $reduce_blength); runClashscore($infile, $outfile, $reduce_blength); #$clash = loadClashlist($outfile); $clash = loadClashscore($outfile); //$clashPct = runClashStats($model['stats']['resolution'], $clash['scoreAll'], $clash['scoreBlt40']); $tasks['clashlist'] .= " - <a href='viewtext.php?{$_SESSION['sessTag']}&file={$outfile}&mode=plain' target='_blank'>preview</a>\n"; setProgress($tasks, 'clashlist'); // so the preview link is visible echo "chartClashlist ran for " . (time() - $startTime) . " seconds\n"; } //}}} Run all-atom contact programs and offer kins to user //{{{ Run real-space correlation $model['raw_rscc_name'] = "{$model['parent']}_raw.rscc"; $model['rscc_name'] = "{$model['parent']}.rscc"; $rscc_out = "{$xrayDir}/{$model['parent']}.rscc"; $rscc_prequel_out = "{$xrayDir}/{$model['parent']}_prequel.rscc"; if ($opts['chartHoriz']) { $startTime = time(); setProgress($tasks, 'runRSCC'); runRscc($infile, $mtz_file, $rscc_out, $rscc_prequel_out); echo "runRscc ran for " . (time() - $startTime) . " seconds\n"; echo $mtz_file; echo isset($mtz_file); } //}}} //{{{ Report on improvements (that could be) made by MolProbity $improveText = ""; if ($opts['chartImprove'] && ($clash || $rota)) { $startTime = time(); setProgress($tasks, 'improve'); // updates the progress display if running as a background job $altpdb = mpTempfile("tmp_altH_pdb_"); $mainClashscore = $clash ? $clash['scoreAll'] : 0; $mainRotaCount = $rota ? count(findRotaOutliers($rota)) : 0; $improvementList = array(); if ($model['isBuilt']) { $altInpath = $modelDir . '/' . $_SESSION['models'][$model['parent']]['pdb']; reduceNoBuild($altInpath, $altpdb, $reduce_blength); // Rotamers $outfile = mpTempfile("tmp_rotamer_"); runRotamer($altpdb, $outfile); $altrota = loadRotamer($outfile); $altRotaCount = count(findRotaOutliers($altrota)); if ($altRotaCount > $mainRotaCount) { if ($altRotaCount - $mainRotaCount > 1) { $improvementList[] = "fixed " . ($altRotaCount - $mainRotaCount) . " bad rotamers"; } else { $improvementList[] = "fixed " . ($altRotaCount - $mainRotaCount) . " bad rotamer"; } } unlink($outfile); // Clashes $outfile = mpTempfile("tmp_clashlist_"); #runClashlist($altpdb, $outfile, $reduce_blength); runClashscore($altpdb, $outfile, $reduce_blength); #$altclash = loadClashlist($outfile); $altclash = loadClashscore($outfile); if ($altclash['scoreAll'] - $mainClashscore >= 0.005) { //0.005 is the smallest change that will still be reported by the sprintf("%.2f") below $improvementList[] = "improved your clashscore by " . sprintf("%.2f", $altclash['scoreAll'] - $mainClashscore) . " points"; } unlink($outfile); if (count($improvementList) > 0) { $improveText .= "<div class='feature'>By adding H to this model and allowing Asn/Gln/His flips, you have already "; $improveText .= implode(" and ", $improvementList); $improveText .= ". <br /><b>Make sure you download the modified PDB to take advantage of these improvements! <br />NOTE: Atom positions have changed, so refinement to idealize geometry is necessary.</b></div>\n"; } } elseif ($mainClashscore > 0 || $mainRotaCount > 0) { if ($model['parent']) { $altInpath = $_SESSION['models'][$model['parent']]['pdb']; } else { $altInpath = $model['pdb']; } $altInpath = "{$modelDir}/{$altInpath}"; reduceBuild($altInpath, $altpdb, $reduce_blength); if ($mainRotaCount > 0) { $outfile = mpTempfile("tmp_rotamer_"); runRotamer($altpdb, $outfile); $altrota = loadRotamer($outfile); $altRotaCount = count(findRotaOutliers($altrota)); if ($altRotaCount < $mainRotaCount) { $improvementList[] = "fix " . ($mainRotaCount - $altRotaCount) . " bad rotamers"; } unlink($outfile); } if ($mainClashscore > 0) { $outfile = mpTempfile("tmp_clashlist_"); #runClashlist($altpdb, $outfile, $reduce_blength); runClashscore($altpdb, $outfile, $reduce_blength); #$altclash = loadClashlist($outfile); $altclash = loadClashscore($outfile); if ($mainClashscore - $altclash['scoreAll'] >= 0.005) { //0.005 is the smallest change that will still be reported by the sprintf("%.2f") below $improvementList[] = "improve your clashscore by " . sprintf("%.2f", $mainClashscore - $altclash['scoreAll']) . " points"; } unlink($outfile); } if (count($improvementList) > 0) { $improveText .= "<div class='feature'>By adding H to this model and allowing Asn/Gln/His flips, we could <i>automatically</i> "; $improveText .= implode(" and ", $improvementList); $improveText .= ".</div>\n"; } } unlink($altpdb); echo "chart Improve ran for " . (time() - $startTime) . " seconds\n"; } //}}} Report on improvements (that could be) made by by MolProbity //{{{ Build multi-criterion chart, kinemage, horizontal, chart if ($opts['doCharts']) { $startTime = time(); if ($opts['chartMulti']) { setProgress($tasks, 'multichart'); // updates the progress display if running as a background job } else { setProgress($tasks, 'chartsummary'); } $outfile = "{$rawDir}/{$model['prefix']}multi.table"; $snapfile = "{$chartDir}/{$model['prefix']}multi.html"; $resout = "{$rawDir}/{$model['prefix']}multi_res.table"; writeMulticritChart($infile, $outfile, $snapfile, $resout, $clash, $rama, $rota, $cbdev, $pperp, $suites, $validate_bond, $validate_angle, $cablam, $omega, !$opts['chartNotJustOut'], $opts['chartMulti'], $opts['chartAltloc']); if ($opts['chartMulti']) { $tasks['multichart'] .= " - <a href='viewtable.php?{$_SESSION['sessTag']}&file={$outfile}' target='_blank'>preview</a>\n"; setProgress($tasks, 'multichart'); // so the preview link is visible } else { $tasks['chartsummary'] .= " - <a href='viewtable.php?{$_SESSION['sessTag']}&file={$outfile}' target='_blank'>preview</a>\n"; setProgress($tasks, 'chartsummary'); // so the preview link is visible } if ($opts['chartHoriz']) { setProgress($tasks, 'charthoriz'); $horiz_table_file = "{$rawDir}/{$model['prefix']}horiz.table"; writeHorizontalChart($resout, $rscc_out, $outfile, $horiz_table_file, $rscc_prequel_out); } if ($opts['chartCoot']) { setProgress($tasks, 'cootchart'); $outfile = "{$chartDir}/{$model['prefix']}multi-coot.scm"; $outfile_py = "{$chartDir}/{$model['prefix']}multi-coot.py"; #makeCootMulticritChart($infile, $outfile, $clash, $rama, $rota, $cbdev, $pperp); makeCootClusteredChart($infile, $outfile, $outfile_py, $clash, $rama, $rota, $cbdev, $pperp); } echo "do Charts ran for " . (time() - $startTime) . " seconds\n"; } if ($opts['doKinemage']) { $startTime = time(); setProgress($tasks, 'multikin'); // updates the progress display if running as a background job $mcKinOpts = array('ribbons' => $opts['kinRibbons'], 'Bscale' => $opts['kinBfactor'], 'Qscale' => $opts['kinOccupancy'], 'altconf' => $opts['kinAltConfs'], 'rama' => $opts['kinRama'], 'rota' => $opts['kinRota'], 'geom' => $opts['kinGeom'], 'cbdev' => $opts['kinCBdev'], 'omega' => $opts['kinOmega'], 'cablam' => $opts['kinCablamLow'], 'pperp' => $opts['kinBaseP'], 'clashdots' => $opts['kinClashes'], 'hbdots' => $opts['kinHbonds'], 'vdwdots' => $opts['kinContacts']); $outfile = "{$kinDir}/{$model['prefix']}multi.kin"; $viewRes = array(); //echo "kinForceViews = ".$opts['kinForceViews']."\n"; if ($opts['kinForceViews']) { //echo "Ran calcLocalBadness\n"; $viewRes = array_keys(calcLocalBadness($infile, 10, $clash, $rama, $rota, $cbdev, $pperp)); } makeMulticritKin2(array($infile), $outfile, $mcKinOpts, $viewRes); // EXPERIMENTAL: gzip compress large multikins if (filesize($outfile) > MP_KIN_GZIP_THRESHOLD) { destructiveGZipFile($outfile); } echo "do Kinemage ran for " . (time() - $startTime) . " seconds\n"; } //}}} Build multi-criterion chart, kinemage //{{{ Low-resolution-specific analyses //Low-res kinemage is being simplified and merged into main kinemage //if($opts['doLowRes']) //{ // if($opts['kinCablamLow'] || $opts['other']) // { // $startTime = time(); // setProgress($tasks, 'lowResKin'); // $lowResKinOpts = array(//first column is opts, second column sets true-false // 'ribbons' => $opts['kinRibbons'],//pass pdb w/HELIX+SHEET for this // 'rama' => $opts['kinRama'], // 'geom' => $opts['kinGeom'], // 'cbdev' => $opts['kinCBdev'], // 'omega' => $opts['kinOmega'], // 'cablam' => $opts['kinCablamLow'], // 'clashdots' => $opts['kinClashes'] // ); // $outfile = "$kinDir/$model[prefix]low_multi.kin"; // $cablamSecStrucFile = "$modelDir/$model[prefix]cablam_sec_struc_records.pdb"; // //$viewRes = array(); //Used with opts[kinForceViews], not necessary argument for makeMulticritKin2 // makeMulticritKinLowRes(array($infile), $outfile, $cablamSecStrucFile, $lowResKinOpts); // if(filesize($outfile) > MP_KIN_GZIP_THRESHOLD) destructiveGZipFile($outfile); // echo "do low-res Kinemage ran for ".(time() - $startTime)." seconds\n"; // } //} //}}} //{{{ Create REMARK 40 and insert into PDB file //if(is_array($clash) || is_array($rama) || is_array($rota)) //{ // setProgress($tasks, 'remark40'); // updates the progress display if running as a background job // $remark40 = makeRemark40($clash, $rama, $rota); // replacePdbRemark($infile, $remark40, 40); //} //}}} Create REMARK 40 and insert into PDB file //{{{ Create lab notebook entry $entry = ""; if (is_array($clash) || is_array($rama) || is_array($rota) || is_array($cbdev) || is_array($pperp) || is_array($suites)) { $entry .= "<h3>Summary statistics</h3>\n"; $entry .= makeSummaryStatsTable($model['stats']['resolution'], $clash, $rama, $rota, $cbdev, $pperp, $suites, $validate_bond, $validate_angle, $cablam, $omega); } $entry .= $improveText; if ($opts['doKinemage'] || $opts['doCharts']) { $entry .= "<h3>Multi-criterion visualizations</h3>\n"; $entry .= "<div class='indent'>\n"; $entry .= "<table width='100%' border='0'><tr valign='top'>\n"; if ($opts['doKinemage']) { $entry .= "<td>" . linkAnyFile("{$model['prefix']}multi.kin", "Kinemage", "img/multikin.jpg") . "</td>\n"; } if ($opts['doCharts']) { $entry .= "<td>" . linkAnyFile("{$model['prefix']}multi.table", "Chart", "img/multichart.jpg") . "</td>\n"; if ($opts['chartCoot']) { $entry .= "<td>" . linkAnyFile("{$model['prefix']}multi-coot.scm", "To-do list for Coot", "img/multichart-coot.jpg") . "<br><small><i>Open this in Coot 0.1.2 or later using Calculate | Run Script...</i></small></td>\n"; #$entry .= "<td>".linkAnyFile("$model[prefix]multi-coot.py", "To-do list for Coot Python", "img/multichart-coot.jpg")."<br><small><i>Open this in Coot 0.1.2 or later using Calculate | Run Script...</i></small></td>\n"; } if ($opts['chartHoriz']) { $entry .= "<td>" . linkAnyFile("{$model['prefix']}horiz.table", "Horizontal Chart", "img/multichart_horiz.jpg") . "</td>\n"; } } //if($opts['doLowRes']) { // if($opts['kinCablamLow'] || $opts['other']) { // $entry .= "<td>".linkAnyFile("$model[prefix]low_multi.kin", "LowRes MultiKin", "img/low_multikin.jpg")."</td>\n"; // } //} $entry .= "</tr></table>\n"; $entry .= "</div>\n"; } if ($opts['chartClashlist'] || $opts['chartRama'] || $opts['chartCBdev'] || $opts['chartSuite']) { $entry .= "<h3>Single-criterion visualizations</h3>"; $entry .= "<ul>\n"; if ($opts['chartClashlist']) { $entry .= "<li>" . linkAnyFile("{$model['prefix']}clashlist.txt", "Clash list") . "</li>\n"; } if ($opts['chartRama']) { $entry .= "<li>" . linkAnyFile("{$model['prefix']}rama.kin", "Ramachandran plot kinemage") . "</li>\n"; $entry .= "<li>" . linkAnyFile("{$model['prefix']}rama.pdf", "Ramachandran plot PDF") . "</li>\n"; } if ($opts['chartCBdev']) { $entry .= "<li>" . linkAnyFile("{$model['prefix']}cbetadev.kin", "Cβ deviation scatter plot") . "</li>\n"; } if ($opts['chartSuite']) { $entry .= "<li>" . linkAnyFile("{$model['prefix']}suitename.txt", "RNA backbone report") . "</li>\n"; $entry .= "<li>" . linkAnyFile("{$model['prefix']}suitestring.txt", "RNA backbone conformation \"sequence\"") . "</li>\n"; $entry .= "<li>" . linkAnyFile("{$model['prefix']}suitename.kin", "RNA backbone multi-D plot of conformations") . "</li>\n"; } $entry .= "</ul>\n"; } if ($remark40) { $entry .= "<h3>REMARK 40</h3>"; $url = "{$modelURL}/{$model['pdb']}"; $entry .= "You can <a href='{$url}'>download your PDB file with REMARK 40</a> inserted, or the same <a href='download_trimmed.php?{$_SESSION['sessTag']}&file={$infile}'> without hydrogens</a>.\n"; $entry .= "<p><pre>{$remark40}</pre></p>"; } //}}} Create lab notebook entry setProgress($tasks, null); // everything is finished return $entry; }
/** * $infiles array of single model PDB files to process * $outfile will be overwritten with a kinemage */ function writeMultimodelChart($infiles, $outfile) { $infiles = array_values($infiles); // re-indexes from 0 ... n-1 $clashes = array(); $clashOuts = array(); $clashCount = array(); $rotas = array(); $rotaOuts = array(); $rotaCount = array(); $ramas = array(); $ramaOuts = array(); $ramaCount = array(); $tmpfile = mpTempfile(); for ($i = 0; $i < count($infiles); $i++) { runClashlist($infiles[$i], $tmpfile); $clashes[$i] = loadClashlist($tmpfile); $clashOuts[$i] = findClashOutliers($clashes[$i]); foreach ($clashOuts[$i] as $cnit => $junk) { $clashCount[$cnit] += 1; } runRotamer($infiles[$i], $tmpfile); $rotas[$i] = loadRotamer($tmpfile); $rotaOuts[$i] = findRotaOutliers($rotas[$i]); foreach ($rotaOuts[$i] as $cnit => $junk) { $rotaCount[$cnit] += 1; } runRamachandran($infiles[$i], $tmpfile); $ramas[$i] = loadRamachandran($tmpfile); $ramaOuts[$i] = findRamaOutliers($ramas[$i]); foreach ($ramaOuts[$i] as $cnit => $junk) { $ramaCount[$cnit] += 1; } } $allRes = array_values(listResidues($infiles[0])); // for now, assume all files have same res $out = fopen($outfile, 'wb'); fwrite($out, "@kinemage 1\n"); fwrite($out, "@flatland\n"); fwrite($out, "@group {models} animate collapsable\n"); fwrite($out, "@labellist {res names}\n"); for ($j = 0; $j < count($allRes); $j++) { fwrite($out, "{" . $allRes[$j] . "} 0 -{$j} 0\n"); } fwrite($out, "@balllist {grid} radius= 0.02 nohighlight color= gray\n"); for ($j = 0; $j < count($allRes); $j++) { for ($i = 0; $i < count($infiles); $i++) { fwrite($out, "{} " . (-$i - 1) . " -{$j} 0\n"); } } for ($i = 0; $i < count($infiles); $i++) { fwrite($out, "@subgroup {" . basename($infiles[$i]) . "} dominant\n"); fwrite($out, "@ringlist {clashes} master= {clashes} radius= 0.3 width= 2 color= hotpink\n"); for ($j = 0; $j < count($allRes); $j++) { if ($clashOuts[$i][$allRes[$j]]) { fwrite($out, "{" . $allRes[$j] . "} " . (-$i - 1) . " -{$j} 0\n"); } } fwrite($out, "@ringlist {rotamers} master= {rotamers} radius= 0.1 width= 2 color= gold\n"); for ($j = 0; $j < count($allRes); $j++) { if ($rotaOuts[$i][$allRes[$j]]) { fwrite($out, "{" . $allRes[$j] . "} " . (-$i - 1) . " -{$j} 0\n"); } } fwrite($out, "@ringlist {Ramachandran} master= {Ramachandran} radius= 0.2 width= 2 color= green\n"); for ($j = 0; $j < count($allRes); $j++) { if ($ramaOuts[$i][$allRes[$j]]) { fwrite($out, "{" . $allRes[$j] . "} " . (-$i - 1) . " -{$j} 0\n"); } } } fwrite($out, "@group {criteria (rings)} animate collapsable\n"); fwrite($out, "@labellist {res names}\n"); for ($j = 0; $j < count($allRes); $j++) { fwrite($out, "{" . $allRes[$j] . "} 0 -{$j} " . -0.1 * $i . "\n"); } for ($i = 0; $i < count($infiles); $i++) { fwrite($out, "@subgroup {" . basename($infiles[$i]) . "} dominant\n"); $xpos = 0; fwrite($out, "@ringlist {clashes} radius= " . 0.5 * ($i + 1) / count($infiles) . " width= 1 color= hotpink\n"); $xpos -= 1.5; for ($j = 0; $j < count($allRes); $j++) { if ($clashOuts[$i][$allRes[$j]]) { fwrite($out, "{" . $allRes[$j] . "} {$xpos} -{$j} " . -0.1 * $i . "\n"); } } fwrite($out, "@ringlist {rotamers} radius= " . 0.5 * ($i + 1) / count($infiles) . " width= 1 color= gold\n"); $xpos -= 1.5; for ($j = 0; $j < count($allRes); $j++) { if ($rotaOuts[$i][$allRes[$j]]) { fwrite($out, "{" . $allRes[$j] . "} {$xpos} -{$j} " . -0.1 * $i . "\n"); } } fwrite($out, "@ringlist {Ramachandran} radius= " . 0.5 * ($i + 1) / count($infiles) . " width= 1 color= green\n"); $xpos -= 1.5; for ($j = 0; $j < count($allRes); $j++) { if ($ramaOuts[$i][$allRes[$j]]) { fwrite($out, "{" . $allRes[$j] . "} {$xpos} -{$j} " . -0.1 * $i . "\n"); } } } fwrite($out, "@group {criteria (lines)} animate collapsable\n"); fwrite($out, "@labellist {res names}\n"); for ($j = 0; $j < count($allRes); $j++) { fwrite($out, "{" . $allRes[$j] . "} 0 -{$j} " . -0.1 * $i . "\n"); } $xpos = 0; fwrite($out, "@vectorlist {clashes} color= hotpink\n"); $xpos -= 1; writeMultimodelChart_bars($out, $allRes, $clashCount, count($infiles), $xpos); fwrite($out, "@vectorlist {rotamers} color= gold\n"); $xpos -= 1; writeMultimodelChart_bars($out, $allRes, $rotaCount, count($infiles), $xpos); fwrite($out, "@vectorlist {Ramachandran} color= green\n"); $xpos -= 1; writeMultimodelChart_bars($out, $allRes, $ramaCount, count($infiles), $xpos); fwrite($out, "@group {criteria (worms)} animate collapsable\n"); fwrite($out, "@labellist {res names}\n"); for ($j = 0; $j < count($allRes); $j++) { fwrite($out, "{" . $allRes[$j] . "} 0 -{$j} " . -0.1 * $i . "\n"); } $xpos = 0; fwrite($out, "@trianglelist {clashes} color= hotpink\n"); $xpos -= 1; writeMultimodelChart_boxes($out, $allRes, $clashCount, count($infiles), $xpos); fwrite($out, "@trianglelist {rotamers} color= gold\n"); $xpos -= 1; writeMultimodelChart_boxes($out, $allRes, $rotaCount, count($infiles), $xpos); fwrite($out, "@trianglelist {Ramachandran} color= green\n"); $xpos -= 1; writeMultimodelChart_boxes($out, $allRes, $ramaCount, count($infiles), $xpos); fclose($out); }
function makeChartKin($pdbname, $ChartKin) { $caption = "caption goes here"; $out = fopen($ChartKin, 'w'); fwrite($out, "@kinemage \n"); fwrite($out, " \n"); fwrite($out, " \n"); fwrite($out, "@onewidth \n"); fwrite($out, "@viewid {Overview} \n"); fwrite($out, "@zoom 1.00 \n"); fwrite($out, "@zslab 200 \n"); fwrite($out, "@ztran 0 \n"); fwrite($out, "@center -16.500 -11.500 0.122 \n"); fwrite($out, "@matrix \n"); fwrite($out, "1.000000 -0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 -0.000000 1.000000 \n"); fwrite($out, "@master {Rotamer Outliers} \n"); fwrite($out, "@master {Rotamer % Outliers} \n"); fwrite($out, "@master {Global Measure Chart} \n"); fwrite($out, "@master {Residue Chart} \n"); fwrite($out, "@labellist {label} color= white master= {Global Measure Chart} nobutton \n"); fwrite($out, "{Resolution or Constrains per Residue}100.000 -30.000 0.000 \n"); fwrite($out, "{Value} -30.000 125.000 30.000 \n"); fwrite($out, "@vectorlist {edge} color= gray width= 1 master= {Global Measure Chart} nobutton \n"); fwrite($out, "{plot edge}P 0.000 250.000 0.000 \n"); fwrite($out, "{plot edge}0.000 0.000 0.000 \n"); fwrite($out, "{plot edge}250.000 0.000 0.000 \n"); fwrite($out, "{plot edge}250.000 250.000 0.000 \n"); fwrite($out, "{plot edge}0.000 250.000 0.000 \n"); fwrite($out, "@labellist {label} color= white master= {Residue Chart} nobutton \n"); fwrite($out, "{Model} 30.000 -30.000 -125.000 \n"); fwrite($out, "{Residue Number} -125.000 -30.000 30.000 \n"); fwrite($out, "@vectorlist {edge} color= gray width= 1 master= {Residue Chart} nobutton \n"); fwrite($out, "{plot edge}P -250.000 0.000 -250.000 \n"); fwrite($out, "{plot edge}0.000 0.000 -250.000 \n"); fwrite($out, "{plot edge}0.000 0.000 0.000 \n"); fwrite($out, "{plot edge}-250.000 0.000 0.000 \n"); fwrite($out, "{plot edge}-250.000 0.000 -250.000 \n"); fwrite($out, "@vectorlist {residue} color= gray width= 1 master= {Residue Chart} nobutton \n"); fwrite($out, "{tick}P 0.000 0.000 0.000 \n"); fwrite($out, "{\"}0.000 0.000 10.000 \n"); fwrite($out, "{\"}P -5.000 0.000 0.000 \n"); fwrite($out, "{\"}-5.000 0.000 5.000 \n"); fwrite($out, "{\"}P -10.000 0.000 0.000 \n"); fwrite($out, "{\"}-10.000 0.000 10.000 \n"); fwrite($out, "{\"}P -15.000 0.000 0.000 \n"); fwrite($out, "{\"}-15.000 0.000 5.000 \n"); fwrite($out, "{\"}P -20.000 0.000 0.000 \n"); fwrite($out, "{\"}-20.000 0.000 10.000 \n"); fwrite($out, "{\"}P -25.000 0.000 0.000 \n"); fwrite($out, "{\"}-25.000 0.000 5.000 \n"); fwrite($out, "{\"}P -30.000 0.000 0.000 \n"); fwrite($out, "{\"}-30.000 0.000 10.000 \n"); fwrite($out, "{\"}P -35.000 0.000 0.000 \n"); fwrite($out, "{\"}-35.000 0.000 5.000 \n"); fwrite($out, "{\"}P -40.000 0.000 0.000 \n"); fwrite($out, "{\"}-40.000 0.000 10.000 \n"); fwrite($out, "{\"}P -45.000 0.000 0.000 \n"); fwrite($out, "{\"}-45.000 0.000 5.000 \n"); fwrite($out, "{\"}P -50.000 0.000 0.000 \n"); fwrite($out, "{\"}-50.000 0.000 10.000 \n"); fwrite($out, "{\"}P -55.000 0.000 0.000 \n"); fwrite($out, "{\"}-55.000 0.000 5.000 \n"); fwrite($out, "{\"}P -60.000 0.000 0.000 \n"); fwrite($out, "{\"}-60.000 0.000 10.000 \n"); fwrite($out, "{\"}P -65.000 0.000 0.000 \n"); fwrite($out, "{\"}-65.000 0.000 5.000 \n"); fwrite($out, "{\"}P -70.000 0.000 0.000 \n"); fwrite($out, "{\"}-70.000 0.000 10.000 \n"); fwrite($out, "{\"}P -75.000 0.000 0.000 \n"); fwrite($out, "{\"}-75.000 0.000 5.000 \n"); fwrite($out, "{\"}P -80.000 0.000 0.000 \n"); fwrite($out, "{\"}-80.000 0.000 10.000 \n"); fwrite($out, "{\"}P -85.000 0.000 0.000 \n"); fwrite($out, "{\"}-85.000 0.000 5.000 \n"); fwrite($out, "{\"}P -90.000 0.000 0.000 \n"); fwrite($out, "{\"}-90.000 0.000 10.000 \n"); fwrite($out, "{\"}P -95.000 0.000 0.000 \n"); fwrite($out, "{\"}-95.000 0.000 5.000 \n"); fwrite($out, "{\"}P -100.000 0.000 0.000 \n"); fwrite($out, "{\"}-100.000 0.000 10.000 \n"); fwrite($out, "{\"}P -105.000 0.000 0.000 \n"); fwrite($out, "{\"}-105.000 0.000 5.000 \n"); fwrite($out, "{\"}P -110.000 0.000 0.000 \n"); fwrite($out, "{\"}-110.000 0.000 10.000 \n"); fwrite($out, "{\"}P -115.000 0.000 0.000 \n"); fwrite($out, "{\"}-115.000 0.000 5.000 \n"); fwrite($out, "{\"}P -120.000 0.000 0.000 \n"); fwrite($out, "{\"}-120.000 0.000 10.000 \n"); fwrite($out, "{\"}P -125.000 0.000 0.000 \n"); fwrite($out, "{\"}-125.000 0.000 5.000 \n"); fwrite($out, "{\"}P -130.000 0.000 0.000 \n"); fwrite($out, "{\"}-130.000 0.000 10.000 \n"); fwrite($out, "{\"}P -135.000 0.000 0.000 \n"); fwrite($out, "{\"}-135.000 0.000 5.000 \n"); fwrite($out, "{\"}P -140.000 0.000 0.000 \n"); fwrite($out, "{\"}-140.000 0.000 10.000 \n"); fwrite($out, "{\"}P -145.000 0.000 0.000 \n"); fwrite($out, "{\"}-145.000 0.000 5.000 \n"); fwrite($out, "{\"}P -150.000 0.000 0.000 \n"); fwrite($out, "{\"}-150.000 0.000 10.000 \n"); fwrite($out, "{\"}P -155.000 0.000 0.000 \n"); fwrite($out, "{\"}-155.000 0.000 5.000 \n"); fwrite($out, "{\"}P -160.000 0.000 0.000 \n"); fwrite($out, "{\"}-160.000 0.000 10.000 \n"); fwrite($out, "{\"}P -165.000 0.000 0.000 \n"); fwrite($out, "{\"}-165.000 0.000 5.000 \n"); fwrite($out, "{\"}P -170.000 0.000 0.000 \n"); fwrite($out, "{\"}-170.000 0.000 10.000 \n"); fwrite($out, "{\"}P -175.000 0.000 0.000 \n"); fwrite($out, "{\"}-175.000 0.000 5.000 \n"); fwrite($out, "{\"}P -180.000 0.000 0.000 \n"); fwrite($out, "{\"}-180.000 0.000 10.000 \n"); fwrite($out, "{\"}P -185.000 0.000 0.000 \n"); fwrite($out, "{\"}-185.000 0.000 5.000 \n"); fwrite($out, "{\"}P -190.000 0.000 0.000 \n"); fwrite($out, "{\"}-190.000 0.000 10.000 \n"); fwrite($out, "{\"}P -195.000 0.000 0.000 \n"); fwrite($out, "{\"}-195.000 0.000 5.000 \n"); fwrite($out, "{\"}P -200.000 0.000 0.000 \n"); fwrite($out, "{\"}-200.000 0.000 10.000 \n"); fwrite($out, "{\"}P -205.000 0.000 0.000 \n"); fwrite($out, "{\"}-205.000 0.000 5.000 \n"); fwrite($out, "{\"}P -210.000 0.000 0.000 \n"); fwrite($out, "{\"}-210.000 0.000 10.000 \n"); fwrite($out, "{\"}P -215.000 0.000 0.000 \n"); fwrite($out, "{\"}-215.000 0.000 5.000 \n"); fwrite($out, "{\"}P -220.000 0.000 0.000 \n"); fwrite($out, "{\"}-220.000 0.000 10.000 \n"); fwrite($out, "{\"}P -225.000 0.000 0.000 \n"); fwrite($out, "{\"}-225.000 0.000 5.000 \n"); fwrite($out, "{\"}P -230.000 0.000 0.000 \n"); fwrite($out, "{\"}-230.000 0.000 10.000 \n"); fwrite($out, "{\"}P -235.000 0.000 0.000 \n"); fwrite($out, "{\"}-235.000 0.000 5.000 \n"); fwrite($out, "{\"}P -240.000 0.000 0.000 \n"); fwrite($out, "{\"}-240.000 0.000 10.000 \n"); fwrite($out, "{\"}P -245.000 0.000 0.000 \n"); fwrite($out, "{\"}-245.000 0.000 5.000 \n"); fwrite($out, "{\"}P -250.000 0.000 0.000 \n"); fwrite($out, "{\"}-250.000 0.000 10.000 \n"); fwrite($out, "@vectorlist {Model} color= gray width= 1 master= {Residue Chart} nobutton \n"); fwrite($out, "{tick}P 0.000 0.000 0.000 \n"); fwrite($out, "{\"}10.000 0.000 0.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -10.000 \n"); fwrite($out, "{\"}5.000 0.000 -10.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -20.000 \n"); fwrite($out, "{\"}5.000 0.000 -20.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -30.000 \n"); fwrite($out, "{\"}5.000 0.000 -30.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -40.000 \n"); fwrite($out, "{\"}5.000 0.000 -40.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -50.000 \n"); fwrite($out, "{\"}10.000 0.000 -50.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -60.000 \n"); fwrite($out, "{\"}5.000 0.000 -60.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -70.000 \n"); fwrite($out, "{\"}5.000 0.000 -70.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -80.000 \n"); fwrite($out, "{\"}5.000 0.000 -80.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -90.000 \n"); fwrite($out, "{\"}5.000 0.000 -90.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -100.000 \n"); fwrite($out, "{\"}10.000 0.000 -100.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -110.000 \n"); fwrite($out, "{\"}5.000 0.000 -110.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -120.000 \n"); fwrite($out, "{\"}5.000 0.000 -120.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -130.000 \n"); fwrite($out, "{\"}5.000 0.000 -130.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -140.000 \n"); fwrite($out, "{\"}5.000 0.000 -140.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -150.000 \n"); fwrite($out, "{\"}10.000 0.000 -150.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -160.000 \n"); fwrite($out, "{\"}5.000 0.000 -160.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -170.000 \n"); fwrite($out, "{\"}5.000 0.000 -170.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -180.000 \n"); fwrite($out, "{\"}10.000 0.000 -180.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -190.000 \n"); fwrite($out, "{\"}5.000 0.000 -190.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -200.000 \n"); fwrite($out, "{\"}10.000 0.000 -200.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -210.000 \n"); fwrite($out, "{\"}5.000 0.000 -210.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -220.000 \n"); fwrite($out, "{\"}5.000 0.000 -220.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -230.000 \n"); fwrite($out, "{\"}5.000 0.000 -230.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -240.000 \n"); fwrite($out, "{\"}5.000 0.000 -240.000 \n"); fwrite($out, "{\"}P 0.000 0.000 -250.000 \n"); fwrite($out, "{\"}10.000 0.000 -250.000 \n"); //for each pdb and iterate //in the beginning.. there was a model! $modelcounter = 1; foreach ($pdbname as $pdb) { //overall stats needed for each pdb file // crystallographic resolution of the model $stats = pdbstat($pdb); $resolution = $stats['resolution']; /* $ConstPerRes = // NMR constraints per Residue in the model */ //number of res in the model $numRes = $stats['residues']; // plotting of rotamer outliers along for each model along vs. residue number fwrite($out, "@group {" . basename($pdb, ".pdb") . "} animate dominant \n"); // plot of rotamer outliers fwrite($out, "@balllist {Rotamer Outliers} color= white radius= 0.5 master= {Rotamer Outliers} nohilite \n"); // create unique temp files in current directory $tmp1 = tempnam(MP_BASE_DIR . "/tmp", 'graphtemp'); // calculations for rotamer data runRotamer($pdb, $tmp1); $rota = loadrotamer($tmp1); //plotting rotamer outliers, determining the x (res), y (score), and z (model) values //followed by writing them out in the balllist $RotaOut = findRotaOutliers($rota); // $RotaOut is the the list of outliers and their scores foreach ($RotaOut as $ResName => $score) { $x = $rota[$ResName]['resNum'] * -1.0; $y = round($rota[$ResName]['scorePct'], 2); $z = $modelcounter * -10.0; // if x = 0, go to next one... if ($x == 0) { continue; } fwrite($out, "{" . basename($pdb, ".pdb") . " " . $ResName . "}{$x} {$y} {$z} \n"); } // plotting % rotamer outlier data // x is what you plot against, resolution / restraints per res etc // y is the percentage of rotamer outliers in the entire model // plots the model $numRotaOut = count(findRotaOutliers($rota)); // can include a factor here $percentoutlier = round($numRotaOut / $numRes * 100, 2); // multiplication by 100 is the scaleing 'fudge' factor $x = $resolution * 100; // -10.00 another scaling factor $z = $modelcounter * -10.0; fwrite($out, "@balllist {Rotamer % Outliers} color= white radius= 1.0 master= {Rotamer % Outliers} nohilite \n"); fwrite($out, "{" . basename($pdb, ".pdb") . " " . $resolution . "A , " . $percentoutlier . "%" . "} {$x} {$percentoutlier} {$z} \n"); unlink($tmp1); //change the Z number which gets multiplied (and hereafter we added another) $modelcounter = $modelcounter + 1; //end of the for each loop going through the PDB files } fclose($out); }