Handle missing antenna pattern file

This commit is contained in:
Gareth Evans
2017-02-22 18:55:47 +00:00
parent 1a4f4bd226
commit 0b495ad094
3 changed files with 272 additions and 271 deletions

536
inputs.cc
View File

@@ -659,7 +659,7 @@ char LoadSDF(char *name)
return return_value;
}
void LoadPAT(char *filename)
int LoadPAT(char *filename)
{
/* This function reads and processes antenna pattern (.az
and .el) files that correspond in name to previously
@@ -696,38 +696,57 @@ void LoadPAT(char *filename)
/* Load .az antenna pattern file */
fd = fopen(azfile, "r");
if( (fd = fopen(azfile, "r")) == NULL )
return errno;
if (fd != NULL) {
/* Clear azimuth pattern array */
/* Clear azimuth pattern array */
for (x = 0; x <= 360; x++) {
azimuth[x] = 0.0;
read_count[x] = 0;
for (x = 0; x <= 360; x++) {
azimuth[x] = 0.0;
read_count[x] = 0;
}
/* Read azimuth pattern rotation
in degrees measured clockwise
from true North. */
if (fgets(string, 254, fd) == NULL) {
//fprintf(stderr,"Azimuth read error\n");
//exit(0);
}
pointer = strchr(string, ';');
if (pointer != NULL)
*pointer = 0;
sscanf(string, "%f", &rotation);
/* Read azimuth (degrees) and corresponding
normalized field radiation pattern amplitude
(0.0 to 1.0) until EOF is reached. */
if (fgets(string, 254, fd) == NULL) {
//fprintf(stderr,"Azimuth read error\n");
//exit(0);
}
pointer = strchr(string, ';');
if (pointer != NULL)
*pointer = 0;
sscanf(string, "%f %f", &az, &amplitude);
do {
x = (int)rintf(az);
if (x >= 0 && x <= 360 && fd != NULL) {
azimuth[x] += amplitude;
read_count[x]++;
}
/* Read azimuth pattern rotation
in degrees measured clockwise
from true North. */
if (fgets(string, 254, fd) == NULL) {
//fprintf(stderr,"Azimuth read error\n");
//exit(0);
}
pointer = strchr(string, ';');
if (pointer != NULL)
*pointer = 0;
sscanf(string, "%f", &rotation);
/* Read azimuth (degrees) and corresponding
normalized field radiation pattern amplitude
(0.0 to 1.0) until EOF is reached. */
if (fgets(string, 254, fd) == NULL) {
//fprintf(stderr,"Azimuth read error\n");
//exit(0);
// exit(0);
}
pointer = strchr(string, ';');
@@ -736,265 +755,244 @@ void LoadPAT(char *filename)
sscanf(string, "%f %f", &az, &amplitude);
do {
x = (int)rintf(az);
} while (feof(fd) == 0);
if (x >= 0 && x <= 360 && fd != NULL) {
azimuth[x] += amplitude;
read_count[x]++;
}
fclose(fd);
if (fgets(string, 254, fd) == NULL) {
//fprintf(stderr,"Azimuth read error\n");
// exit(0);
}
pointer = strchr(string, ';');
/* Handle 0=360 degree ambiguity */
if (pointer != NULL)
*pointer = 0;
sscanf(string, "%f %f", &az, &amplitude);
} while (feof(fd) == 0);
fclose(fd);
/* Handle 0=360 degree ambiguity */
if ((read_count[0] == 0) && (read_count[360] != 0)) {
read_count[0] = read_count[360];
azimuth[0] = azimuth[360];
}
if ((read_count[0] != 0) && (read_count[360] == 0)) {
read_count[360] = read_count[0];
azimuth[360] = azimuth[0];
}
/* Average pattern values in case more than
one was read for each degree of azimuth. */
for (x = 0; x <= 360; x++) {
if (read_count[x] > 1)
azimuth[x] /= (float)read_count[x];
}
/* Interpolate missing azimuths
to completely fill the array */
last_index = -1;
next_index = -1;
for (x = 0; x <= 360; x++) {
if (read_count[x] != 0) {
if (last_index == -1)
last_index = x;
else
next_index = x;
}
if (last_index != -1 && next_index != -1) {
valid1 = azimuth[last_index];
valid2 = azimuth[next_index];
span = next_index - last_index;
delta = (valid2 - valid1) / (float)span;
for (y = last_index + 1; y < next_index; y++)
azimuth[y] = azimuth[y - 1] + delta;
last_index = y;
next_index = -1;
}
}
/* Perform azimuth pattern rotation
and load azimuth_pattern[361] with
azimuth pattern data in its final form. */
for (x = 0; x < 360; x++) {
y = x + (int)rintf(rotation);
if (y >= 360)
y -= 360;
azimuth_pattern[y] = azimuth[x];
}
azimuth_pattern[360] = azimuth_pattern[0];
got_azimuth_pattern = 255;
if ((read_count[0] == 0) && (read_count[360] != 0)) {
read_count[0] = read_count[360];
azimuth[0] = azimuth[360];
}
if ((read_count[0] != 0) && (read_count[360] == 0)) {
read_count[360] = read_count[0];
azimuth[360] = azimuth[0];
}
/* Average pattern values in case more than
one was read for each degree of azimuth. */
for (x = 0; x <= 360; x++) {
if (read_count[x] > 1)
azimuth[x] /= (float)read_count[x];
}
/* Interpolate missing azimuths
to completely fill the array */
last_index = -1;
next_index = -1;
for (x = 0; x <= 360; x++) {
if (read_count[x] != 0) {
if (last_index == -1)
last_index = x;
else
next_index = x;
}
if (last_index != -1 && next_index != -1) {
valid1 = azimuth[last_index];
valid2 = azimuth[next_index];
span = next_index - last_index;
delta = (valid2 - valid1) / (float)span;
for (y = last_index + 1; y < next_index; y++)
azimuth[y] = azimuth[y - 1] + delta;
last_index = y;
next_index = -1;
}
}
/* Perform azimuth pattern rotation
and load azimuth_pattern[361] with
azimuth pattern data in its final form. */
for (x = 0; x < 360; x++) {
y = x + (int)rintf(rotation);
if (y >= 360)
y -= 360;
azimuth_pattern[y] = azimuth[x];
}
azimuth_pattern[360] = azimuth_pattern[0];
got_azimuth_pattern = 255;
/* Read and process .el file */
fd = fopen(elfile, "r");
if( (fd = fopen(elfile, "r")) == NULL )
return errno;
if (fd != NULL) {
for (x = 0; x <= 10000; x++) {
el_pattern[x] = 0.0;
read_count[x] = 0;
for (x = 0; x <= 10000; x++) {
el_pattern[x] = 0.0;
read_count[x] = 0;
}
/* Read mechanical tilt (degrees) and
tilt azimuth in degrees measured
clockwise from true North. */
if (fgets(string, 254, fd) == NULL) {
//fprintf(stderr,"Tilt read error\n");
//exit(0);
}
pointer = strchr(string, ';');
if (pointer != NULL)
*pointer = 0;
sscanf(string, "%f %f", &mechanical_tilt, &tilt_azimuth);
/* Read elevation (degrees) and corresponding
normalized field radiation pattern amplitude
(0.0 to 1.0) until EOF is reached. */
if (fgets(string, 254, fd) == NULL) {
//fprintf(stderr,"Ant elevation read error\n");
//exit(0);
}
pointer = strchr(string, ';');
if (pointer != NULL)
*pointer = 0;
sscanf(string, "%f %f", &elevation, &amplitude);
while (feof(fd) == 0) {
/* Read in normalized radiated field values
for every 0.01 degrees of elevation between
-10.0 and +90.0 degrees */
x = (int)rintf(100.0 * (elevation + 10.0));
if (x >= 0 && x <= 10000) {
el_pattern[x] += amplitude;
read_count[x]++;
}
/* Read mechanical tilt (degrees) and
tilt azimuth in degrees measured
clockwise from true North. */
if (fgets(string, 254, fd) == NULL) {
//fprintf(stderr,"Tilt read error\n");
//exit(0);
if (fgets(string, 254, fd) != NULL) {
pointer = strchr(string, ';');
}
pointer = strchr(string, ';');
if (pointer != NULL)
*pointer = 0;
sscanf(string, "%f %f", &mechanical_tilt, &tilt_azimuth);
/* Read elevation (degrees) and corresponding
normalized field radiation pattern amplitude
(0.0 to 1.0) until EOF is reached. */
if (fgets(string, 254, fd) == NULL) {
//fprintf(stderr,"Ant elevation read error\n");
//exit(0);
}
pointer = strchr(string, ';');
if (pointer != NULL)
*pointer = 0;
sscanf(string, "%f %f", &elevation, &amplitude);
while (feof(fd) == 0) {
/* Read in normalized radiated field values
for every 0.01 degrees of elevation between
-10.0 and +90.0 degrees */
x = (int)rintf(100.0 * (elevation + 10.0));
if (x >= 0 && x <= 10000) {
el_pattern[x] += amplitude;
read_count[x]++;
}
if (fgets(string, 254, fd) != NULL) {
pointer = strchr(string, ';');
}
if (pointer != NULL)
*pointer = 0;
sscanf(string, "%f %f", &elevation, &amplitude);
}
fclose(fd);
/* Average the field values in case more than
one was read for each 0.01 degrees of elevation. */
for (x = 0; x <= 10000; x++) {
if (read_count[x] > 1)
el_pattern[x] /= (float)read_count[x];
}
/* Interpolate between missing elevations (if
any) to completely fill the array and provide
radiated field values for every 0.01 degrees of
elevation. */
last_index = -1;
next_index = -1;
for (x = 0; x <= 10000; x++) {
if (read_count[x] != 0) {
if (last_index == -1)
last_index = x;
else
next_index = x;
}
if (last_index != -1 && next_index != -1) {
valid1 = el_pattern[last_index];
valid2 = el_pattern[next_index];
span = next_index - last_index;
delta = (valid2 - valid1) / (float)span;
for (y = last_index + 1; y < next_index; y++)
el_pattern[y] =
el_pattern[y - 1] + delta;
last_index = y;
next_index = -1;
}
}
/* Fill slant_angle[] array with offset angles based
on the antenna's mechanical beam tilt (if any)
and tilt direction (azimuth). */
if (mechanical_tilt == 0.0) {
for (x = 0; x <= 360; x++)
slant_angle[x] = 0.0;
}
else {
tilt_increment = mechanical_tilt / 90.0;
for (x = 0; x <= 360; x++) {
xx = (float)x;
y = (int)rintf(tilt_azimuth + xx);
while (y >= 360)
y -= 360;
while (y < 0)
y += 360;
if (x <= 180)
slant_angle[y] =
-(tilt_increment * (90.0 - xx));
if (x > 180)
slant_angle[y] =
-(tilt_increment * (xx - 270.0));
}
}
slant_angle[360] = slant_angle[0]; /* 360 degree wrap-around */
for (w = 0; w <= 360; w++) {
tilt = slant_angle[w];
/** Convert tilt angle to
an array index offset **/
y = (int)rintf(100.0 * tilt);
/* Copy shifted el_pattern[10001] field
values into elevation_pattern[361][1001]
at the corresponding azimuth, downsampling
(averaging) along the way in chunks of 10. */
for (x = y, z = 0; z <= 1000; x += 10, z++) {
for (sum = 0.0, a = 0; a < 10; a++) {
b = a + x;
if (b >= 0 && b <= 10000)
sum += el_pattern[b];
if (b < 0)
sum += el_pattern[0];
if (b > 10000)
sum += el_pattern[10000];
}
elevation_pattern[w][z] = sum / 10.0;
}
}
got_elevation_pattern = 255;
}
fclose(fd);
/* Average the field values in case more than
one was read for each 0.01 degrees of elevation. */
for (x = 0; x <= 10000; x++) {
if (read_count[x] > 1)
el_pattern[x] /= (float)read_count[x];
}
/* Interpolate between missing elevations (if
any) to completely fill the array and provide
radiated field values for every 0.01 degrees of
elevation. */
last_index = -1;
next_index = -1;
for (x = 0; x <= 10000; x++) {
if (read_count[x] != 0) {
if (last_index == -1)
last_index = x;
else
next_index = x;
}
if (last_index != -1 && next_index != -1) {
valid1 = el_pattern[last_index];
valid2 = el_pattern[next_index];
span = next_index - last_index;
delta = (valid2 - valid1) / (float)span;
for (y = last_index + 1; y < next_index; y++)
el_pattern[y] =
el_pattern[y - 1] + delta;
last_index = y;
next_index = -1;
}
}
/* Fill slant_angle[] array with offset angles based
on the antenna's mechanical beam tilt (if any)
and tilt direction (azimuth). */
if (mechanical_tilt == 0.0) {
for (x = 0; x <= 360; x++)
slant_angle[x] = 0.0;
}
else {
tilt_increment = mechanical_tilt / 90.0;
for (x = 0; x <= 360; x++) {
xx = (float)x;
y = (int)rintf(tilt_azimuth + xx);
while (y >= 360)
y -= 360;
while (y < 0)
y += 360;
if (x <= 180)
slant_angle[y] =
-(tilt_increment * (90.0 - xx));
if (x > 180)
slant_angle[y] =
-(tilt_increment * (xx - 270.0));
}
}
slant_angle[360] = slant_angle[0]; /* 360 degree wrap-around */
for (w = 0; w <= 360; w++) {
tilt = slant_angle[w];
/** Convert tilt angle to
an array index offset **/
y = (int)rintf(100.0 * tilt);
/* Copy shifted el_pattern[10001] field
values into elevation_pattern[361][1001]
at the corresponding azimuth, downsampling
(averaging) along the way in chunks of 10. */
for (x = y, z = 0; z <= 1000; x += 10, z++) {
for (sum = 0.0, a = 0; a < 10; a++) {
b = a + x;
if (b >= 0 && b <= 10000)
sum += el_pattern[b];
if (b < 0)
sum += el_pattern[0];
if (b > 10000)
sum += el_pattern[10000];
}
elevation_pattern[w][z] = sum / 10.0;
}
}
got_elevation_pattern = 255;
for (x = 0; x <= 360; x++) {
for (y = 0; y <= 1000; y++) {
if (got_elevation_pattern)

View File

@@ -5,7 +5,7 @@
int LoadSDF_SDF(char *name, int winfiles);
char LoadSDF(char *name, int winfiles);
void LoadPAT(char *filename);
int LoadPAT(char *filename);
void LoadSignalColors(struct site xmtr);
void LoadLossColors(struct site xmtr);
void LoadDBMColors(struct site xmtr);

View File

@@ -1218,7 +1218,10 @@ int main(int argc, char *argv[])
strncpy(mapfile, argv[z], 253);
strncpy(tx_site[0].name, "Tx", 2);
strncpy(tx_site[0].filename, argv[z], 253);
LoadPAT(argv[z]);
if( (result = LoadPAT(argv[z])) != 0 ){
fprintf(stderr,"Error reading antenna pattern file\n");
exit(result);
}
} else if (z <= y && argv[z][0] && argv[z][0] == '-' && argv[z][1] == '\0' ) {
/* Handle writing image data to stdout */
to_stdout = true;