27
27
#include " TextVisitor.h"
28
28
#include " expat.h"
29
29
30
+ #include < algorithm>
31
+ #include < set>
32
+ #include < string>
33
+ #include < vector>
34
+
30
35
using namespace magics ;
31
36
32
37
map<int , bool > multilevels_;
@@ -52,7 +57,7 @@ class BufrSubType : public map<string, string> {
52
57
class BufrFamily : public map <string, BufrSubType> {
53
58
public:
54
59
BufrFamily (const string&);
55
- ~BufrFamily (){};
60
+ ~BufrFamily () {};
56
61
57
62
void currentType (const map<string, string>& def) { type_ = def.find (" value" )->second ; }
58
63
@@ -176,7 +181,7 @@ static void XMLCALL character(void* userData, const char* s, int len) {
176
181
177
182
BufrIdentifiers::BufrIdentifiers (int centre) : centre_(centre) {
178
183
ostringstream file, deffile;
179
- file << buildSharePath (" bufr_" + to_string (centre) + " .xml" );
184
+ file << buildSharePath (" bufr_" + to_string (centre) + " .xml" );
180
185
deffile << buildSharePath (" bufr_98.xml" );
181
186
char buf[BUFSIZ];
182
187
XML_Parser parser = XML_ParserCreate (NULL );
@@ -293,9 +298,9 @@ class BufrAccessor {
293
298
BufrAccessor (const string& descriptor) : descriptor_(descriptor) {
294
299
init ();
295
300
auto token = translator_.find (descriptor_);
296
- eccodes_ = (token == translator_.end ()) ? descriptor_ : token->second ;
301
+ eccodes_ = (token == translator_.end ()) ? descriptor_ : token->second ;
297
302
}
298
- virtual ~BufrAccessor (){};
303
+ virtual ~BufrAccessor () {};
299
304
virtual void operator ()(const ObsDecoder&, MvObs&, string&) const {}
300
305
virtual void operator ()(const ObsDecoder&, MvObs& obs, double & val) const { val = obs.value (eccodes_); }
301
306
virtual void print () {}
@@ -311,7 +316,7 @@ map<string, string> BufrAccessor::translator_;
311
316
class BufrMultiValueAccessor : public BufrAccessor {
312
317
public:
313
318
BufrMultiValueAccessor (const string& descriptor, int index) : BufrAccessor(descriptor), index_(index) {}
314
- virtual ~BufrMultiValueAccessor (){};
319
+ virtual ~BufrMultiValueAccessor () {};
315
320
virtual void operator ()(const ObsDecoder&, MvObs& obs, double & val) const {
316
321
const BufrIdentifiers& table = BufrIdentTable::get (obs.originatingCentre ());
317
322
val = obs.valueByOccurrence (index_, descriptor_);
@@ -381,7 +386,7 @@ class BufrHighCloudHeightAccessor : public BufrMultiValueAccessor {
381
386
class BufrTypeAccessor : public BufrAccessor {
382
387
public:
383
388
BufrTypeAccessor () { descriptor_ = " type" ; };
384
- virtual ~BufrTypeAccessor (){};
389
+ virtual ~BufrTypeAccessor () {};
385
390
void operator ()(const ObsDecoder&, MvObs& obs, string& val) const {
386
391
val = obs.messageType ();
387
392
@@ -459,7 +464,7 @@ class BufrMultiLevelAccessor : public BufrAccessor {
459
464
void operator ()(const ObsDecoder& decoder, MvObs& obs, double & val) const {
460
465
const BufrIdentifiers& table = BufrIdentTable::get (obs.originatingCentre ());
461
466
int type = obs.messageType ();
462
-
467
+
463
468
map<int , bool >::const_iterator multilevel = multilevels_.find (type);
464
469
if (multilevel == multilevels_.end ()) {
465
470
MagLog::warning () << " BufrMultiLevelAccessor> Unknown observation type [" << val << " ]\n " ;
@@ -468,7 +473,7 @@ class BufrMultiLevelAccessor : public BufrAccessor {
468
473
if (type == 0 || type == 1 ) {
469
474
// surface data
470
475
val = obs.value (surface_);
471
- if ( val == kBufrMissingValue ) {
476
+ if (val == kBufrMissingValue ) {
472
477
// Trying the descriptor for multilevel: some centres are using it for surface.
473
478
val = obs.value (altitude_);
474
479
}
@@ -492,8 +497,43 @@ class BufrMultiLevelAccessor : public BufrAccessor {
492
497
493
498
class BufrGeopotentialAccessor : public BufrMultiLevelAccessor {
494
499
public:
495
- BufrGeopotentialAccessor () : BufrMultiLevelAccessor(" geopotential" ) {}
500
+ BufrGeopotentialAccessor () : BufrMultiLevelAccessor(" geopotential" ) {
501
+ keys_ = {" geopotential" , " nonCoordinateGeopotential" , " nonCoordinateGeopotentialHeight" };
502
+ heightKeys_ = {" nonCoordinateGeopotentialHeight" };
503
+ }
504
+
496
505
virtual ~BufrGeopotentialAccessor () {}
506
+
507
+ void operator ()(const ObsDecoder& decoder, MvObs& obs, double & val) const {
508
+ const BufrIdentifiers& table = BufrIdentTable::get (obs.originatingCentre ());
509
+ int type = obs.messageType ();
510
+
511
+ map<int , bool >::const_iterator multilevel = multilevels_.find (type);
512
+ if (multilevel == multilevels_.end ()) {
513
+ MagLog::warning () << " BufrMultiLevelAccessor> Unknown observation type [" << val << " ]\n " ;
514
+ val = kBufrMissingValue ;
515
+ }
516
+
517
+ if (type != 0 && type != 1 && type != 4 && type != 5 ) {
518
+ for (auto key : keys_) {
519
+ val = obs.valueByPressureLevel (decoder.level_ , key);
520
+ // std::cout << "level: " << decoder.level_ << " key: " << key << " val: " << val << std::endl;
521
+ if (val != kBufrMissingValue ) {
522
+ if (heightKeys_.find (key) != heightKeys_.end ()) {
523
+ val *= 9.81 ;
524
+ }
525
+ return ;
526
+ }
527
+ };
528
+ }
529
+
530
+ BufrMultiLevelAccessor::operator ()(decoder, obs, val);
531
+ }
532
+
533
+
534
+ protected:
535
+ std::vector<std::string> keys_;
536
+ std::set<std::string> heightKeys_;
497
537
};
498
538
499
539
class BufrTemperatureAccessor : public BufrMultiLevelAccessor {
@@ -670,7 +710,6 @@ void ObsDecoder::customisedPoints(const Transformation& transformation, const st
670
710
671
711
map<string, BufrAccessor*> accessors;
672
712
for (std::set<string>::const_iterator token = tokens.begin (); token != tokens.end (); ++token) {
673
-
674
713
try {
675
714
BufrAccessor* accessor = SimpleObjectMaker<BufrAccessor>::create (*token);
676
715
accessors.insert (make_pair (*token, accessor));
@@ -679,7 +718,6 @@ void ObsDecoder::customisedPoints(const Transformation& transformation, const st
679
718
BufrAccessor* accessor = new BufrAccessor (*token);
680
719
accessors.insert (make_pair (*token, accessor));
681
720
}
682
-
683
721
}
684
722
685
723
// Create the type accessor!
0 commit comments