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:
<?php
namespace DispatchModule;
class ResultSet {
public $data = array();
public $totalCount = 0;
public $id;
private $first = TRUE;
public function getTotalCount() {
return $this->totalCount;
}
public function setTotalCount($totalCount) {
$this->totalCount = $totalCount;
}
public function addSequence(\DispatchModule\Sequence $sequence) {
foreach ($this->data as $seq) {
if ($sequence->accession == $seq->accession && $sequence->startPosition == $seq->startPosition && $sequence->stopPosition == $seq->stopPosition) {
$this->mergeSequences($seq, $sequence);
return;
}
}
$this->data[] = $sequence;
}
private function join(\DispatchModule\ResultSet $set = null, $merge = 3) {
if (is_null($set)) {
return;
}
if ($this->first && empty($this->data)) {
$this->first = FALSE;
$this->data = $set->getData();
} else {
$notToMerge = array();
$oldData = $this->data;
$this->data = array();
foreach ($oldData as $oldSeq) {
$merged = false;
foreach ($set->data as $seq) {
if ($seq->accession == $oldSeq->accession && $seq->startPosition == $oldSeq->startPosition && $seq->stopPosition == $oldSeq->stopPosition) {
$this->mergeSequences($oldSeq, $seq);
$this->data[] = $oldSeq;
$merged = true;
if (!isset($notToMerge[$seq->accession . ':' . $seq->startPosition . ':' . $seq->stopPosition])) {
$notToMerge[$seq->accession . ':' . $seq->startPosition . ':' . $seq->stopPosition] = $seq;
}
}
}
if (($merge & 2) > 0 && !$merged) {
$this->data[] = $oldSeq;
}
}
if (($merge & 1) > 0) {
foreach ($set->data as $seq) {
if (!isset($notToMerge[$seq->accession . ':' . $seq->startPosition . ':' . $seq->stopPosition])) {
$this->data[] = $seq;
}
}
}
}
}
public function add(\DispatchModule\ResultSet $set = null) {
$this->join($set, 3);
}
public function intersect(\DispatchModule\ResultSet $set = null) {
$this->join($set, 0);
}
public function leftJoin(\DispatchModule\ResultSet $set = null) {
$this->join($set, 2);
}
public function getData() {
return $this->data;
}
public function getDataAndCount() {
$array = $this->data;
$last = array("count" => $this->getTotalCount());
if (isset($this->id) && !empty($this->id)) {
$last["search_id"] = $this->id;
}
$array[] = $last;
return $array;
}
public function sortByScore() {
usort($this->data, $this->build_cmpSequences());
}
private function build_cmpSequences() {
return function (\DispatchModule\Sequence $a, \DispatchModule\Sequence $b) {
$aScores = self::score($a);
$bScores = self::score($b);
for ($i=0; $i < min(count($aScores), count($bScores)); $i++) {
if ($aScores[$i] != $bScores[$i]) {
return ($aScores[$i] < $bScores[$i]) ? 1 : -1;
}
}
if (count($aScores) != count($bScores)) {
return (count($aScores) < count($bScores)) ? 1 : -1;
}
if (($a->stopPosition - $a->startPosition) !== ($b->stopPosition - $b->startPosition)) {
return (($a->stopPosition - $a->startPosition) > ($b->stopPosition - $b->startPosition)) ? -1 : 1;
}
$res = strcmp($a->accession, $b->accession);
if ($res !== 0) {
return ($res < 0) ? -1 : 1;
}
if ($a->startPosition !== $b->startPosition) {
return ($a->startPosition < $b->startPosition) ? -1 : 1;
}
if ($a->stopPosition !== $b->stopPosition) {
return ($a->stopPosition < $b->stopPosition) ? -1 : 1;
}
return 0;
};
}
private static function score(\DispatchModule\Sequence $sequence) {
$scores = array();
foreach ($sequence->matches as $match) {
$scores[] = $match->getScore();
}
rsort($scores);
return $scores;
}
public function sortScores() {
foreach ($this->data as $seq) {
usort($seq->matches, array("\DispatchModule\ResultSet", "cmpMatches"));
}
}
private static function cmpMatches(\DispatchModule\BaseMatch $a, \DispatchModule\BaseMatch $b) {
if ($a->getScore() == $b->getScore()) {
return 0;
}
return ($a->getScore() < $b->getScore()) ? 1 : -1;
}
public function mergeSequences(\DispatchModule\Sequence &$oldSequence, \DispatchModule\Sequence $newSequence) {
$params = get_object_vars($newSequence);
foreach ($params as $propertyName => $propertyValue) {
if (is_null($oldSequence->$propertyName) || empty($oldSequence->$propertyName)) {
$oldSequence->$propertyName = $propertyValue;
} else if (is_array($oldSequence->$propertyName) && isset($newSequence->$propertyName)
&& !empty($newSequence->$propertyName)) {
$oldSequence->$propertyName = array_merge($oldSequence->$propertyName, $newSequence->$propertyName);
}
}
}
}