Changeset 11091 in ntrip
- Timestamp:
- Oct 16, 2026, 11:22:26 AM (17 hours ago)
- Location:
- trunk/BNC/src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/BNC/src/bnchelp.html
r11087 r11091 5138 5138 signal (or to another common signal, if the stream lacks it), are compared with 5139 5139 <ul> 5140 <li>each other AC separately (one vote per AC, own AC left out, combinations not voting), with the RMS of 5141 the differences and the number of DCBs with opposite sign (only DCBs of at least 0.3 m are used for the 5142 sign). A stream is reported to use the opposite sign if it has the opposite sign for most DCBs to more than 5143 half of at least two other ACs - with only two ACs, it cannot be decided which one is wrong. Satellites 5144 with DCBs deviating from the median of at least 3 other ACs are listed,</li> 5140 <li>each other solution separately (see 'CONSENSUS' below; also the other solutions of the own AC, 5141 combinations not voting), with the RMS of the differences and the number of DCBs with opposite sign (only 5142 DCBs of at least 0.3 m are used for the sign). A stream is reported to use the opposite sign if it has the 5143 opposite sign for most DCBs to more than half of at least two solutions of other ACs - with only two ACs, it 5144 cannot be decided which one is wrong. Satellites with DCBs deviating from the median of at least 3 5145 solutions of other ACs are listed,</li> 5145 5146 <li>the selected 'QC Reference' stream instead, if it is not 'CONSENSUS',</li> 5146 5147 <li>the 'QC Bias File', if specified.</li> … … 5152 5153 gets errors of twice the biases, e.g. 5153 5154 <pre> 5154 G code biases compared with the other ACs (DCBs to C1W): BKG RMS 2.17 m, opposite sign 48/49; CNE RMS 2.44 m, opposite sign 98/1015155 G code biases with the opposite sign of 2 of 2 other ACs (BKG CNE) - SINEX sign convention instead of the SSR one?5155 G code biases compared with the other solutions (DCBs to C1W): BKG00 RMS 2.17 m, opposite sign 48/49; CNE00 RMS 2.44 m, opposite sign 98/101 5156 G code biases with the opposite sign of 2 of 2 solutions of other ACs (BKG00 CNE00) - SINEX sign convention instead of the SSR one? 5156 5157 G code biases compared with Bias SINEX file CAS1MGXRAP_01D_01D_DCB.BSX (DCBs to C1W, 32 satellites, 141 DCBs): RMS of the differences 2.401 m, opposite sign for 106 of 107 DCBs (|DCB| >= 0.3 m) 5157 5158 </pre> … … 5191 5192 </p> 5192 5193 <ul> 5193 <li>'CONSENSUS' (default): per satellite the median of the other analysis centers (at least two). All decoded 5194 streams contribute, also those not selected under 'QC Streams' (except the excluded ones). An AC with several 5195 streams (IGS-SSR and RTCM-SSR format, APC and CoM) has one vote, the median of its streams; the AC is derived 5196 from the stream name (e.g. 'CNE' from 'SSRA00CNE1'). A stream is compared without the streams of its own AC. 5194 <li>'CONSENSUS' (default): per satellite the median of the solutions of the other analysis centers (at least 5195 two). All decoded streams contribute, also those not selected under 'QC Streams' (except the excluded ones). A 5196 solution is the AC and the two digits of the stream name, e.g. 'GFZ00' for SSRA00GFZ0, SSRA00GFZ1, SSRC00GFZ0 5197 and SSRC00GFZ1, and 'GFZ01' for SSRA01GFZ0 (OSB streams like OSBC00WHU1 belong to the solution 'WHU00'). The 5198 streams of a solution (IGS-SSR and RTCM-SSR format, APC and CoM) have one vote, the median of its streams; 5199 different solutions of an AC vote separately. A stream is compared without all solutions of its own AC, as 5200 these are not independent (same software and models). 5197 5201 Combination products ('INTERNAL' and the IGS combinations '...IGS.') do not vote, as they are derived from the 5198 5202 ACs, but are compared with the consensus. A single erroneous AC does not affect the consensus, and no -
trunk/BNC/src/ssrQc.cpp
r11087 r11091 172 172 173 173 // Analysis center of a stream: the 3 characters of the AC in mountpoints 174 // like SSRA00CNE1, otherwise the stream name itself 174 // like SSRA00CNE1 or OSBC00WHU1, otherwise the stream name itself 175 175 //////////////////////////////////////////////////////////////////////////// 176 176 QString t_ssrQc::acOf(const QString& staID) { 177 static const QRegularExpression re("^ SSR[AC][0-9]{2}([A-Z0-9]{3})[0-9]$");177 static const QRegularExpression re("^(?:SSR|OSB)[AC][0-9]{2}([A-Z0-9]{3})[0-9]$"); 178 178 QRegularExpressionMatch mm = re.match(staID); 179 179 return mm.hasMatch() ? mm.captured(1) : staID; 180 } 181 182 // Solution of an AC: AC and the two digits of the mountpoint, e.g. GFZ00 for 183 // SSRA00GFZ0/SSRC00GFZ1 and GFZ01 for SSRA01GFZ0; the streams of a solution 184 // (formats, APC/CoM) have one vote in the consensus 185 //////////////////////////////////////////////////////////////////////////// 186 QString t_ssrQc::solOf(const QString& staID) { 187 static const QRegularExpression re("^(?:SSR|OSB)[AC]([0-9]{2})([A-Z0-9]{3})[0-9]$"); 188 QRegularExpressionMatch mm = re.match(staID); 189 return mm.hasMatch() ? mm.captured(2) + mm.captured(1) : staID; 190 } 191 192 // AC of a solution (GFZ01 -> GFZ) 193 //////////////////////////////////////////////////////////////////////////// 194 QString t_ssrQc::acOfSol(const QString& sol) { 195 static const QRegularExpression re("^([A-Z0-9]{3})[0-9]{2}$"); 196 QRegularExpressionMatch mm = re.match(sol); 197 return mm.hasMatch() ? mm.captured(1) : sol; 180 198 } 181 199 … … 505 523 } 506 524 if (_reference == "CONSENSUS") { 507 if (!votes(sta) || acOf(sta) == acOf(staID) || (!onlyAC.isEmpty() && acOf(sta) != onlyAC)) { 525 if (!votes(sta)) { 526 continue; 527 } 528 if (onlyAC.isEmpty() ? (acOf(sta) == acOf(staID)) 529 : (solOf(sta) != onlyAC || solOf(sta) == solOf(staID))) { 508 530 continue; 509 531 } … … 521 543 for (auto it = bb.constBegin(); it != bb.constEnd(); ++it) { 522 544 if (it.key() != base) { 523 acDcbs[ acOf(sta)][it.key()].append(bb[base] - it.value());545 acDcbs[solOf(sta)][it.key()].append(bb[base] - it.value()); 524 546 } 525 547 } … … 668 690 QSet<QString> acs; 669 691 for (auto itS = _cbLast.constBegin(); itS != _cbLast.constEnd(); ++itS) { 670 if (itS.key() != staID && votes(itS.key()) && acOf(itS.key()) !=acOf(staID)) {671 acs.insert( acOf(itS.key()));692 if (itS.key() != staID && votes(itS.key()) && solOf(itS.key()) != solOf(staID)) { 693 acs.insert(solOf(itS.key())); 672 694 } 673 695 } … … 683 705 continue; 684 706 } 685 numACs++;686 707 bases.unite(cc.bases); 687 708 items << QString("%1 RMS %2 m, opposite sign %3/%4").arg(ac).arg(cc.rms(), 0, 'f', 2) 688 709 .arg(cc.numOpp).arg(cc.numSign); 689 if (cc.opposite()) { 690 oppACs << ac; 691 } 692 } 693 if (numACs > 0) { 710 // the sign rule counts the solutions of other ACs only 711 if (acOfSol(ac) != acOf(staID)) { 712 numACs++; 713 if (cc.opposite()) { 714 oppACs << ac; 715 } 716 } 717 } 718 if (!items.isEmpty()) { 694 719 QStringList ll = bases.values(); 695 720 ll.sort(); 696 lines << QString("code biases compared with the other ACs (DCBs to %1): %2").arg(ll.join("/")).arg(items.join("; "));721 lines << QString("code biases compared with the other solutions (DCBs to %1): %2").arg(ll.join("/")).arg(items.join("; ")); 697 722 if (numACs >= 2 && oppACs.size() > numACs / 2) { 698 lines << QString("code biases with the opposite sign of %1 of %2 other ACs (%3) - " 723 lines << QString("code biases with the opposite sign of %1 of %2 solutions of other ACs (%3) - " 699 724 "SINEX sign convention instead of the SSR one?") 700 725 .arg(oppACs.size()).arg(numACs).arg(oppACs.join(" ")); 701 726 } 702 deviating(compare(1, QString()), QString("the median of the other ACs (at least %1 ACs)").arg(MIN_VOTE));727 deviating(compare(1, QString()), QString("the median of the other ACs (at least %1 solutions)").arg(MIN_VOTE)); 703 728 } 704 729 } … … 828 853 if (!votes(oo) || !crd[oo].contains(prn) || !crd[oo][prn].clkOK) continue; 829 854 if (useOff && !off.contains(oo)) continue; 830 perAC[ acOf(oo)] << crd[oo][prn].clk - (useOff ? off[oo] : 0.0);855 perAC[solOf(oo)] << crd[oo][prn].clk - (useOff ? off[oo] : 0.0); 831 856 } 832 857 QMap<QString, double> res; … … 879 904 while (itA.hasNext()) { 880 905 itA.next(); 881 if ( itA.key() != ownAC) clks << itA.value();906 if (acOfSol(itA.key()) != ownAC) clks << itA.value(); 882 907 } 883 908 // orbits: per AC the median of its streams with the same reference point … … 887 912 const t_satCrd& rc = crd[oo][prn]; 888 913 if (rc.refPoint != sc.refPoint || sc.refPoint == '?') continue; 889 for (int ii = 0; ii < 3; ii++) perAC[ii][ acOf(oo)] << rc.xx[ii];914 for (int ii = 0; ii < 3; ii++) perAC[ii][solOf(oo)] << rc.xx[ii]; 890 915 } 891 916 for (const QString& ac : perAC[0].keys()) { -
trunk/BNC/src/ssrQc.h
r11087 r11091 86 86 bool votes(const QString& staID) const; 87 87 static QString acOf(const QString& staID); 88 static QString solOf(const QString& staID); // AC solution, e.g. GFZ00, GFZ01 89 static QString acOfSol(const QString& sol); 88 90 89 91 // Stream comparison: every CMP_SAMPL seconds, the orbits and clocks of each
Note:
See TracChangeset
for help on using the changeset viewer.
