hysplitcdump.i.hh 3.96 KB
Newer Older
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
#include <string>
#include "radixbug/bug.hh"
#include "radixio/eafstream.hh"
#include "radixio/hysplitcdump.hh"
namespace radix
{

template<typename data_type>
HysplitCDump<data_type>::HysplitCDump(data_type container)
{
    mData = container;
}

template<typename data_type>
bool HysplitCDump<data_type>::read_from(const std::string& file)
{
    bool result = false;
    eafstream fstr(file.c_str()
                      , std::ios::in | std::ios::binary);
    if(fstr.is_open() == false)
    {
        return result;
    }
    // big endian
    fstr.setReverseBytes(true);
    // read fortran header
    fstr.readHeader();
    std::string id = fstr.readString(4);
    mData->setId(id);
    int packing, year, month, day, hour, forecastHour, numLocations;
    fstr >> year
            >> month
            >> day
            >> hour
            >> forecastHour
            >> numLocations
            >> packing;
    fstr.readFooter();
    mData->setDateTime(year, month, day, hour, forecastHour);

    float lat, lon, z;
    int minutes;
    // for the number of locations
    for( int i = 0; i < numLocations; ++i)
    {
        fstr.readHeader();
        fstr >> year
                >> month
                >> day
                >> hour
                >> lat
                >> lon
                >> z
                >> minutes;
        mData->addLocation(year, month, day, hour, lat, lon, z, minutes);
        fstr.readFooter();
    }

    int numLat, numLon;
    float deltaLat, deltaLon, cLat, cLon;
    fstr.readHeader();
    fstr >> numLat
            >> numLon
            >> deltaLat
            >> deltaLon
            >> cLat
            >> cLon;
    fstr.readFooter();
    mData->setNumLat(numLat);
    mData->setNumLon(numLon);
    mData->setDeltaLat(deltaLat);
    mData->setDeltaLon(deltaLon);
    mData->setCornerLat(cLat);
    mData->setCornerLon(cLon);

    fstr.readHeader();
    int numLevels;
    fstr >> numLevels;
    for(int i = 0; i < numLevels; ++i)
    {
        int level;
        fstr >> level;
        mData->addLevel(level);
    }
    fstr.readFooter();

    fstr.readHeader();
    int numPollutants;
    fstr >> numPollutants;
    for(int i = 0; i < numPollutants; ++i)
    {
        std::string pol;
        pol = fstr.readString(4);
        mData->addPollutant(pol);
    }
    fstr.readFooter();


    // infinite loop over observation times
    for(; fstr.good();)
    {
        fstr.readHeader();
        fstr >> year
                >> month
                >> day
                >> hour
                >> minutes
                >> forecastHour;
        fstr.readFooter();
        mData->addStartTime(year, month, day, hour, minutes, forecastHour);

        fstr.readHeader();
        fstr >> year
                >> month
                >> day
                >> hour
                >> minutes
                >> forecastHour;
        fstr.readFooter();
        mData->addEndTime(year, month, day, hour, minutes, forecastHour);

        for(int i = 0; i < numPollutants; ++i)
        {
            for(int j = 0; j < numLevels; ++j)
            {
                fstr.readHeader();
                std::string pollutant;
                int z;
                int nxyp;
                if(packing)
                {
                    pollutant = fstr.readString(4);
                    fstr >> z >> nxyp;
                    mData->setNumNonZeroPoints(i,j,nxyp);
                    for(int np = 0; np < nxyp; ++np)
                    {
                        short xi = fstr.readShort();
                        short yi = fstr.readShort();
                        float c = fstr.readFloat();
                        mData->addPoint(i,j,np,xi,yi,c);
                    }
                } // if packing is enabled
                fstr.readFooter();
                fstr.peek(); // peek ahead to check file integrity
            } // loop over num levels
        } // loop num pollutants
    } // infinite loop over output times
    return result;
} // HysplitCDump::read_from

} // namespace radix