/* * Copyright (C) 1998 by Southwest Research Institute (SwRI) * * All rights reserved under U.S. Copyright Law and International Conventions. * * The development of this Software was supported by contracts NAG5-3148, * NAG5-6855, NAS8-36840, NAG5-2323, and NAG5-7043 issued on behalf of * the United States Government by its National Aeronautics and Space * Administration. Southwest Research Institute grants to the Government, * and others acting on its behalf, a paid-up nonexclusive, irrevocable, * worldwide license to reproduce, prepare derivative works, and perform * publicly and display publicly, by or on behalf of the Government. * Other than those rights granted to the United States Government, no part * of this Software may be reproduced in any form or by any means, electronic * or mechanical, including photocopying, without permission in writing from * Southwest Research Institute. All inquiries should be addressed to: * * Director of Contracts * Southwest Research Institute * P. O. Drawer 28510 * San Antonio, Texas 78228-0510 * * * Use of this Software is governed by the terms of the end user license * agreement, if any, which accompanies or is included with the Software * (the "License Agreement"). An end user will be unable to install any * Software that is accompanied by or includes a License Agreement, unless * the end user first agrees to the terms of the License Agreement. Except * as set forth in the applicable License Agreement, any further copying, * reproduction or distribution of this Software is expressly prohibited. * Installation assistance, product support and maintenance, if any, of the * Software is available from SwRI and/or the Third Party Providers, as the * case may be. * * Disclaimer of Warranty * * SOFTWARE IS WARRANTED, IF AT ALL, IN ACCORDANCE WITH THESE TERMS OF THE * LICENSE AGREEMENT. UNLESS OTHERWISE EXPLICITLY STATED, THIS SOFTWARE IS * PROVIDED "AS IS", IS EXPERIMENTAL, AND IS FOR NON-COMMERCIAL USE ONLY, * AND ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT * SUCH DISCLAIMERS ARE HELD TO BE LEGALLY INVALID. * * Limitation of Liability * * SwRI SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED AS A RESULT OF USING, * MODIFYING, CONTRIBUTING, COPYING, DISTRIBUTING, OR DOWNLOADING THIS * SOFTWARE. IN NO EVENT SHALL SwRI BE LIABLE FOR ANY INDIRECT, PUNITIVE, * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGE (INCLUDING LOSS OF BUSINESS, * REVENUE, PROFITS, USE, DATA OR OTHER ECONOMIC ADVANTAGE) HOWEVER IT ARISES, * WHETHER FOR BREACH OF IN TORT, EVEN IF SwRI HAS BEEN PREVIOUSLY ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. YOU HAVE SOLE RESPONSIBILITY FOR ADEQUATE * PROTECTION AND BACKUP OF DATA AND/OR EQUIPMENT USED IN CONNECTION WITH THE * SOFTWARE AND WILL NOT MAKE A CLAIM AGAINST SwRI FOR LOST DATA, RE-RUN TIME, * INACCURATE OUTPUT, WORK DELAYS OR LOST PROFITS RESULTING FROM THE USE OF * THIS SOFTWARE. YOU AGREE TO HOLD SwRI HARMLESS FROM, AND YOU COVENANT NOT * TO SUE SwRI FOR, ANY CLAIMS BASED ON USING THE SOFTWARE. * * Local Laws: Export Control * * You acknowledge and agree this Software is subject to the U.S. Export * Administration Laws and Regulations. Diversion of such Software contrary * to U.S. law is prohibited. You agree that none of the Software, nor any * direct product therefrom, is being or will be acquired for, shipped, * transferred, or reexported, directly or indirectly, to proscribed or * embargoed countries or their nationals, nor be used for nuclear activities, * chemical biological weapons, or missile projects unless authorized by U.S. * Government. Proscribed countries are set forth in the U.S. Export * Administration Regulations. Countries subject to U.S embargo are: Cuba, * Iran, Iraq, Libya, North Korea, Syria, and the Sudan. This list is subject * to change without further notice from SwRI, and you must comply with the * list as it exists in fact. You certify that you are not on the U.S. * Department of Commerce's Denied Persons List or affiliated lists or on the * U.S. Department of Treasury's Specially Designated Nationals List. You agree * to comply strictly with all U.S. export laws and assume sole responsibilities * for obtaining licenses to export or reexport as may be required. * * General * * These Terms represent the entire understanding relating to the use of the * Software and prevail over any prior or contemporaneous, conflicting or * additional, communications. SwRI can revise these Terms at any time * without notice by updating this posting. * * Trademarks * * The SwRI logo is a trademark of SwRI in the United States and other countries. * */ #ident "@(#) theta_bins.c 1.23 05/08/19 SwRI" #include #include "ret_codes.h" #include "gen_defs.h" #include "libtrec_idfs.h" /******************************************************************************* * * * IR_CALC_THETA_BINS SUBROUTINE * * * * DESCRIPTION * * This routine is called in order to determine the number of unique theta * * ranges (bins) defined for the virtual instrument being processed. If the * * virtual instrument does not contain initial and final elevation field of * * view constants, theta averaging can not be performed; therefore, the * * arrays that holds the start and stop theta values are set to NO_MEMORY, * * the indexes for each sensor indicating which bin the data is associated * * with is set to a unique value for each sensor used and the number of theta * * bins is set to zero. If the elevation field of view constants are defined,* * the number of unique theta ranges (bins) is determined, space is allocated * * to hold the start / stop values for each theta bin and, as a final step, * * the theta bins are ordered in increasing angle value. * * * * INPUT VARIABLES * * None * * * * USAGE * * x = ir_calc_theta_bins () * * * * NECESSARY SUBPROGRAMS * * sizeof () the size of the specified object in bytes * * realloc() reallocates previously allocated memory * * malloc() allocates memory * * ir_order_theta_bins () orders the theta bins into increasing angle * * values, both starting and ending values * * * * EXTERNAL VARIABLES * * struct general_info ginfo structure that holds information concerning * * the experiment that is being processed * * SDDAS_UINT ir_tmp_bytes number of bytes allocated for scratch space * * void *ir_tmp_space scratch space for various uses * * * * INTERNAL VARIABLES * * struct experiment_info *ex a pointer to the structure that holds * * specific experiment information * * struct collapse_data *cptr pointer to the collapse_data structure * * being processed * * reg SDDAS_FLOAT *fptr pointer to floating point values * * reg SDDAS_FLOAT *stop_ptr loop termination variable * * register SDDAS_SHORT i, sen looping variables * * reg SDDAS_SHORT start_loop index into the angle values for the sensors * * SDDAS_FLOAT start_theta the starting theta angle being compared * * against (base value) * * SDDAS_FLOAT stop_theta the ending theta angle being compared * * against (base value) * * SDDAS_FLOAT diff_start starting theta angle for the sensor * * SDDAS_FLOAT diff_stop ending theta angle for the sensor * * SDDAS_FLOAT az_ang_offset azimuthal angle offset for comparison * * size_t bytes the number of bytes to allocate * * size_t num_bytes_sfloat the number of bytes needed for a SDDAS_FLOAT* * SDDAS_LONG offset indexing variable * * SDDAS_SHORT ret_val the value returned by the called routine * * SDDAS_SHORT num_bins the number of unique theta bins * * SDDAS_SHORT *chk_tbin array indicating which unique theta bin * * each sensor is associated with * * SDDAS_CHAR start_ind index to get to the starting theta constants* * SDDAS_CHAR stop_ind index to get to the ending theta constants * * SDDAS_BOOL same_az_ang_offset flag indicating all sensors have the same * * azimuthal angle offset constant values * * char more_data flag indicating if all theta combos have * * been identified * * void *tmp_ptr pointer which holds address passed back by * * the call to the MALLOC routine * * * * SUBSYSTEM * * Display Level * * * ******************************************************************************/ SDDAS_SHORT ir_calc_theta_bins (void) { extern struct general_info ginfo; extern SDDAS_UINT ir_tmp_bytes; extern void *ir_tmp_space; struct experiment_info *ex; struct collapse_data *cptr; register SDDAS_FLOAT *fptr, *stop_ptr; register SDDAS_SHORT i, start_loop, sen; SDDAS_FLOAT start_theta, stop_theta, diff_start, diff_stop, az_ang_offset; size_t bytes, num_bytes_sfloat; SDDAS_LONG offset; SDDAS_SHORT ret_val, num_bins, *chk_tbin; SDDAS_CHAR start_ind, stop_ind; SDDAS_BOOL same_az_ang_offset; char more_data; void *tmp_ptr; /**************************************************************************/ /* Check to see if initial and final elevation constants are defined for */ /* the combination being processed. Both constants must exist. */ /**************************************************************************/ ex = ginfo.expt; cptr = ex->collapse_ptr; start_ind = stop_ind = -1; /*************************************************************************/ /* Space is always allocated for start and stop theta values. Values */ /* are initialized to -1.0 and should be reset if constants exist. */ /*************************************************************************/ if (*(ex->constants + (2 * ex->num_sensor)) >= 0.0) start_ind = 2; if (*(ex->constants + (3 * ex->num_sensor)) >= 0.0) stop_ind = 3; /*************************************************************************/ /* If both constants aren't defined, no theta averaging. Data is */ /* processed as individual sensor information. */ /*************************************************************************/ if (start_ind == -1 || stop_ind == -1) { cptr->theta_bins = 0; cptr->start_theta = NO_MEMORY; cptr->stop_theta = NO_MEMORY; /*********************************************************************/ /* Since no theta angles, memory is allocated on a per sensor basis.*/ /*********************************************************************/ for (sen = 0; sen < ex->num_sensor; ++sen) *(cptr->sensor_bin + sen) = sen; } else { /***********************************************************************/ /* Allocate space for flags that will help determine the number of */ /* unique theta angle bins. Initialize flags to indicate check all */ /* sensor's theta ranges. */ /***********************************************************************/ bytes = ex->num_sensor * sizeof (SDDAS_SHORT); if (bytes > ir_tmp_bytes) { if ((tmp_ptr = realloc (ir_tmp_space, bytes)) == NO_MEMORY) return (THETA_CHK_MALLOC); ir_tmp_space = tmp_ptr; ir_tmp_bytes = (SDDAS_UINT) bytes; } chk_tbin = (SDDAS_SHORT *) ir_tmp_space; for (i = 0; i < ex->num_sensor; ++i) *(chk_tbin + i) = -1; /***********************************************************************/ /* There must be at least one bin (all sensors would have same start- */ /* stop theta angle values). Use the first sensor's values as a base */ /* for determining the number of unique bins. All index values */ /* need to start at 0 (num_bins - 1). */ /***********************************************************************/ num_bins = 1; start_theta = *(ex->constants + (start_ind * ex->num_sensor)); stop_theta = *(ex->constants + (stop_ind * ex->num_sensor)); *(chk_tbin + 0) = num_bins - 1; start_loop = 1; /***********************************************************************/ /* Continue until all unique sets have been identified. */ /***********************************************************************/ do { /********************************************************************/ /* Compare the angle values for those sensors that have yet to be */ /* associated with a specific start-stop theta bin. */ /********************************************************************/ for (i = start_loop; i < ex->num_sensor; ++i) { if (*(chk_tbin + i) == -1) { diff_start = *(ex->constants + (start_ind * ex->num_sensor) + i); diff_stop = *(ex->constants + (stop_ind * ex->num_sensor) + i); if (diff_start == start_theta && diff_stop == stop_theta) *(chk_tbin + i) = num_bins - 1; } } /********************************************************************/ /* Find the next comparison set of values. By definition, all */ /* sensors PRIOR to the comparison sensor have been associated */ /* with a previous theta range (no need to re-examine the sensors).*/ /********************************************************************/ for (more_data = 0, i = start_loop; i < ex->num_sensor; ++i) { if (*(chk_tbin + i) == -1) { ++num_bins; start_theta= *(ex->constants + (start_ind * ex->num_sensor) + i); stop_theta = *(ex->constants + (stop_ind * ex->num_sensor) + i); *(chk_tbin + i) = num_bins - 1; more_data = (i == ex->num_sensor - 1) ? 0 : 1; start_loop = i + 1; break; } } } while (more_data); /**********************************************************************/ /* Duplicate theta ranges defined by 1 or more sensors? */ /**********************************************************************/ if (num_bins != ex->num_sensor) { /*********************************************************************/ /* In order to overcome the "duplicate theta range" problem, only */ /* bin by theta ranges IF all sensors have the same azimuthal angle */ /* offset constant values, if constant id 2 is defined. If constant*/ /* id 2 is not defined, all values are initialized to 0.0, so code */ /* would say okay to bin by theta ranges. */ /*********************************************************************/ fptr = ex->constants; stop_ptr = ex->constants + ex->num_sensor; az_ang_offset = *fptr; ++fptr; same_az_ang_offset = sTrue; for (; fptr < stop_ptr; ++fptr) if (*fptr != az_ang_offset) { same_az_ang_offset = sFalse; break; } /**********************************************************************/ /* If azimuthal angle offsets are not the same, no theta binning. */ /* Data is processed as individual sensor information. But need to */ /* know this is the situation so that theta averaging can still */ /* transpire. */ /**********************************************************************/ if (same_az_ang_offset == sFalse) cptr->theta_bins = (-1 * num_bins); else cptr->theta_bins = num_bins; } /**********************************************************************/ /* All sensors have unique theta ranges. */ /**********************************************************************/ else cptr->theta_bins = num_bins; /**********************************************************************/ /* Allocate the space to hold the unique start and stop theta values.*/ /**********************************************************************/ num_bytes_sfloat = sizeof (SDDAS_FLOAT); bytes = (num_bins * num_bytes_sfloat) + (num_bins * num_bytes_sfloat); if ((tmp_ptr = malloc (bytes)) == NO_MEMORY) return (THETA_BIN_MALLOC); cptr->base_theta = tmp_ptr; /* Cast base_theta to char * since void * and offset is in bytes. */ cptr->start_theta = (SDDAS_FLOAT *) cptr->base_theta; offset = num_bins * num_bytes_sfloat; cptr->stop_theta = (SDDAS_FLOAT *) ((SDDAS_CHAR *) cptr->base_theta + offset); ret_val = ir_order_theta_bins (chk_tbin, start_ind, stop_ind); if (ret_val != ALL_OKAY) return (ret_val); } return (ALL_OKAY); }