#include <cstdio> // ssmiclass begun 5/5/2004 Robert Grumbine // Purpose is to transition to having a class for ssmi processing, // rather than requiring C-only codes // 4 February 2009: add member functions polarization, gradient, differences, qc, show // Copied over to begin ssmi-s class #ifndef SSMISUCLASS_INCLUDE #define SSMISUCLASS_INCLUDE #ifndef POINTSH #include "points.h" #endif #ifndef PARAMSH #include "params.h" #endif /* Maximum observed latitude = */ #define SSMISU_MAX_LATITUDE 87.5 /* Define the characteristics of the data file structure */ #define NORBITS 1 #define NSCANS 64 /* Structures which relate to bufr decoding */ typedef struct { int kwrit; float latitude, longitude; int sftg, posn; float t91v, t91h; } short_bufr; typedef struct { int scan_counter; float latitude, longitude; int surface_type; int position_num; float t19v, t19h, t22v, t37v, t37h, t91v, t91h; short_bufr hires[3]; } bufr_point; typedef struct { int satno, year, month, day, hour, mins, secs, scan_no; bufr_point full[NSCANS]; } bufr_line; /* Declare BUFR function prototypes */ extern int process_bufr(bufr_line *b); extern int check_bufr(bufr_line *b); extern int check_short_bufr(short_bufr *b); extern void zero_bufr(bufr_line *b, int i); /* define field numbers */ #define T19V 0 #define T19H 1 #define T22V 2 #define T37V 3 #define T37H 4 #define T91V 5 #define T91H 6 #define T150H 7 #define CONC_BAR 8 #define BAR_CONC 9 #define COUNT 10 #define HIRES_CONC 11 #define WEATHER_COUNT 12 // 4 Feb 2009 RG note: want to do something stable about the flag values // used in processing -- LAND, ... typedef struct { unsigned int t19v : 16; unsigned int t19h : 16; unsigned int t22v : 16; unsigned int t37v : 16; unsigned int t37h : 16; unsigned int t91v : 16; unsigned int t91h : 16; unsigned int t150h : 16; unsigned int conc_bar : 8; unsigned int bar_conc : 8; unsigned int count : 8; unsigned int hires_conc : 8; unsigned int weather_count : 8; unsigned int old_conc : 8; } ssmisu; typedef struct { unsigned int t19v : 24; unsigned int t19h : 24; unsigned int t22v : 24; unsigned int t37v : 24; unsigned int t37h : 24; unsigned int t91v : 24; unsigned int t91h : 24; unsigned int t150h : 24; unsigned int conc_bar : 16; unsigned int hires_bar : 16; unsigned int count : 8; unsigned int weather_count : 8; unsigned int old_conc_bar : 16; } ssmisu_tmp; class ssmisupt { public: ssmisu obs; ssmisupt(); operator double(); ssmisupt(ssmisupt &); ssmisupt & operator=(ssmisupt &); // Added 4 February 2009, after versions in 28 Jul 2000 experiment point3<float> polarization(); point3<float> gradient(); point3<float> differences(); int qc(); void show(); // Future: To add, after methods in ssmisuclass.operations.h // ssmisupt & operator=(int ); }; ssmisupt::ssmisupt() { obs.t19v = 0; obs.t19h = 0; obs.t22v = 0; obs.t37v = 0; obs.t37h = 0; obs.t91v = 0; obs.t91h = 0; obs.conc_bar = 0; obs.bar_conc = 0; obs.count = 0; obs.hires_conc = 0; obs.weather_count = 0; } ssmisupt::operator double() { return (double) obs.conc_bar; } ssmisupt::ssmisupt(ssmisupt &x) { obs.t19v = x.obs.t19v; obs.t19h = x.obs.t19h; obs.t22v = x.obs.t22v; obs.t37v = x.obs.t37v; obs.t37h = x.obs.t37h; obs.t91v = x.obs.t91v; obs.t91h = x.obs.t91h; obs.conc_bar = x.obs.conc_bar; obs.bar_conc = x.obs.bar_conc; obs.count = x.obs.count; obs.hires_conc = x.obs.hires_conc; obs.weather_count = x.obs.weather_count; } ssmisupt & ssmisupt::operator=(ssmisupt &x) { obs.t19v = x.obs.t19v; obs.t19h = x.obs.t19h; obs.t22v = x.obs.t22v; obs.t37v = x.obs.t37v; obs.t37h = x.obs.t37h; obs.t91v = x.obs.t91v; obs.t91h = x.obs.t91h; obs.conc_bar = x.obs.conc_bar; obs.bar_conc = x.obs.bar_conc; obs.count = x.obs.count; obs.hires_conc = x.obs.hires_conc; obs.weather_count = x.obs.weather_count; return *this; } // Added 4 February 2009, after versions in 28 Jul 2000 experiment void ssmisupt::show() { printf("ssmisupt %5d %5d %5d %5d %5d %5d %5d %3d %3d\n", obs.t19v, obs.t19h,obs.t22v, obs.t37v, obs.t37h, obs.t91v, obs.t91h, obs.conc_bar, obs.bar_conc); } int ssmisupt::qc() { int ret=0; // If not a data point, don't worry if (obs.conc_bar == LAND || obs.conc_bar == WEATHER || obs.conc_bar == COAST || obs.conc_bar == NO_DATA || obs.bar_conc == LAND || obs.bar_conc == WEATHER || obs.bar_conc == COAST || obs.bar_conc == NO_DATA ) { return ret; } if (obs.t19v < 50*100 || obs.t19v > 300*100) { ret += 1; } if (obs.t19h < 50*100 || obs.t19h > 300*100) { ret += 1; } if (obs.t22v < 50*100 || obs.t22v > 300*100) { ret += 1; } if (obs.t37v < 50*100 || obs.t37v > 300*100) { ret += 1; } if (obs.t37h < 50*100 || obs.t37h > 300*100) { ret += 1; } if (obs.t91v < 50*100 || obs.t91v > 300*100) { ret += 1; } if (obs.t91h < 50*100 || obs.t91h > 300*100) { ret += 1; } return ret; } point3<float> ssmisupt::gradient() { point3<float> x; x.i = (float) obs.t22v / (float) obs.t19v; x.j = (float) obs.t37v / (float) obs.t19v; x.k = (float) obs.t91v / (float) obs.t19v; return x; } point3<float> ssmisupt::polarization() { point3<float> x; x.i = (float) obs.t19v / (float) obs.t19h; x.j = (float) obs.t37v / (float) obs.t37h; x.k = (float) obs.t91v / (float) obs.t91h; return x; } point3<float> ssmisupt::differences() { point3<float> x; x.i = (float) obs.t19v - (float) obs.t19h; x.j = (float) obs.t37v - (float) obs.t37h; x.k = (float) obs.t91v - (float) obs.t91h; return x; } #endif