File: MvGribDecoder.cc

package info (click to toggle)
metview 5.3.0-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 44,932 kB
  • sloc: cpp: 211,811; ansic: 33,467; xml: 3,942; sh: 2,942; yacc: 1,183; fortran: 762; lex: 761; perl: 700; python: 340; f90: 236; makefile: 92
file content (134 lines) | stat: -rw-r--r-- 4,045 bytes parent folder | download | duplicates (2)
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
/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include <MvRequestUtil.hpp>
#include <fdyntime.h>

#include "MvGribDecoder.h"
#include "MatchingInfo.h"
#include "ObjectList.h"

// =====================================================
// class GribDecoderFactory - builds  decoders
//

class GribDecoderFactory : public DecoderFactory
{
        // Virtual Constructor - Builds a new GribDecoder
	virtual Decoder* Build ( const MvRequest& inRequest ) 
		{ return new GribDecoder ( inRequest ); }

public:
	GribDecoderFactory() : DecoderFactory("GribDecoder") {}
};

static GribDecoderFactory gribDecoderFactoryInstance;

//=======================================================
//
// Methods for the GribDecoder class
//
GribDecoder::GribDecoder( const MvRequest& dataUnitRequest ):
	Decoder(dataUnitRequest),
	fieldSet_(dataUnitRequest),
	fieldSetIterator_(fieldSet_)
{
	// Empty
}

GribDecoder::~GribDecoder()
{
	// Empty
}

// Read Next Data
//
// -- Goes to the next data and returns the offset (data size)
// -- Grib decoder only reads one field
bool
GribDecoder::ReadNextData ()
{
	currentField_ = fieldSetIterator_(); // Read next data
	if  ( !currentField_ )
		return false;

	// Expand the field
	// MvFieldExpander expand(currentField);
	metadataRequest_ = currentField_.getRequest();

	// Get Offset
	offset_ = currentField_.getOffset();
	
	return true;
}

// Create MatchingInfo
// Retrieve the matching request
MatchingInfo
GribDecoder::CreateMatchingInfo ()
{
	const char* ident = metadataRequest_("IDENT");
	MvRequest matchingRequest ("MATCHING_INFO");

	matchingRequest ( "PARAM" ) = metadataRequest_("PARAM");
	SetIfValue ( matchingRequest, "LEVEL", metadataRequest_("LEVELIST") );

	// XXX this might not be necessary since we're not interested in
	// IDENT for identifying satellite images anymore.
	if (ident != NULL)
		matchingRequest ("IDENT") = ident; 

	// For hindcast, data, we use HDATE, not DATE, so check this first
	long date = (long)metadataRequest_("HDATE");
	if (date == 0) date = (long)metadataRequest_("DATE");

	TDynamicTime matchTime(date, (long)metadataRequest_("TIME"));

	// Take the step into account when generating the matching time
	matchTime.ChangeByHours( MvField::stepRangeDecoder(metadataRequest_("STEP")) );
	char buf[50];
	sprintf(buf,"%ddd",matchTime.GetYear(),matchTime.GetMonth(), matchTime.GetDay() );
	matchingRequest("DATE") = buf;
	sprintf(buf,"dd",matchTime.GetHour(),matchTime.GetMin() );
	matchingRequest("TIME") = buf;

	// we will later need to decide whether to apply automatic scaling or not
	//ir matchingRequest("DERIVED") = metadataRequest_("DERIVED");

   // Is it an image field?
   const char* repres = metadataRequest_("REPRES");
   if ( ObjectList::IsImage( repres ) ) 
      matchingRequest( "DATA_TYPE" ) = "IMAGE";
   else
   {
      // Get parameter name
      const size_t cMaxBuf = 99;
      char acc0[cMaxBuf+1];
      size_t nsize = cMaxBuf;

      field* ff = currentField_.libmars_field();
      grib_get_string( ff->handle, "shortName", acc0, &nsize );
      matchingRequest ( "PARAM" ) = acc0;
      matchingRequest( "DATA_TYPE" ) = "GRIB";

      // Has this parameter a companion?
      string pair,mode;
      bool first_companion;
      ObjectList::GetCompanion( string(acc0), pair, mode, first_companion );
      if ( pair != "no_pair" )
      {
         matchingRequest ( "MY_COMPANION" ) = pair.c_str();
         matchingRequest ( "FIRST_COMPANION" ) = first_companion;
         if ( !mode.empty() )
            matchingRequest ( "WIND_MODE" ) = mode.c_str();
      }
   }

   return MatchingInfo( matchingRequest );
}