/* * 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 "@(#) fill_theta.c 1.22 05/08/19 SwRI" #include #include "ret_codes.h" #include "user_defs.h" #include "gen_defs.h" #include "libtrec_idfs.h" /******************************************************************************* * * * FILL_THETA_MATRIX SUBROUTINE * * * * DESCRIPTION * * This routine is called to fill in the theta data matrix with the data * * that is returned in the specified buffer. All sensors that contain data * * in the specified buffer are processed. The data buffers are those that * * are returned by either the FILL_DATA or SWEEP_DATA routine. If the user * * is not collapsing over the PHI dimension, but is collapsing over the THETA * * dimension, this routine should be called after the buffers are filled by * * the FILL_DATA or SWEEP_DATA routine. There is one data set for each * * different data level (unit) requested. The sensors are associated with a * * theta bin. A check is made concerning the bin status array to determine * * if the data is to be stored "=" or summed "+=". The bin status value can * * be either 0 if no previous data has been placed into the bin element or * * can be set to a negative value by the collapsing routine to indicate that * * the data has been used (old data). In these two cases, the bin should be * * replaced. If the bin status value is a positive value, that indicates * * that the current data should be added to the data that exists in the theta * * bin. * * * * INPUT VARIABLES * * SDDAS_ULONG data_key key which uniquely identifies the data set * * being processed * * SDDAS_CHAR *exten filename extension for the data to be used * * SDDAS_USHORT vnum version number to be associated with this * * combination (allows for multiple opens) * * SDDAS_SHORT num_sen the number of sensors processed * * SDDAS_SHORT *sen_numbers an array that holds the sensor number(s) * * for which data is being returned * * SDDAS_FLOAT *ret_data an array that holds the data values in the * * buffers (data for all sensors) * * SDDAS_FLOAT *ret_frac an array that holds the normalization factors * * SDDAS_CHAR *ret_bin an array that holds the bin status values * * SDDAS_SHORT *num_units an array that holds the number of data sets * * to bypass to get to the data for the * * specified sensor * * SDDAS_CHAR cur_buf the buffer being processed (0 - 4) * * SDDAS_SHORT sen_units number of units or data levels sub-buffers * * defined for the sensor in question * * * * USAGE * * x = fill_theta_matrix (data_key, exten, vnum, num_sen, sen_numbers, * * ret_data, ret_frac, ret_bin, num_units, cur_buf, sen_units) * * * * NECESSARY SUBPROGRAMS * * ir_locate_ex() determines if requested combination has * * already been pand points to the * * correct structure allocated for the combo * * ir_clear_theta_matrix () clears all theta bins * * abs() returns the absolute value of a number * * * * EXTERNAL VARIABLES * * struct general_info ginfo structure that holds information concerning * * the experiment that is being processed * * * * INTERNAL VARIABLES * * struct experiment_info a pointer to the structure that holds * * *ex specific experiment information * * struct fill_data *fptr pointer to the fill_data structure being * * processed * * struct fill_sensor *sptr pointer to the fill_sensor structure being * * processed * * struct collapse_data pointer to the collapse_data structure * * *cptr being processed * * struct bin_info *bptr a pointer to the structure holding sweep * * binning information * * reg SDDAS_FLOAT *dptr pointer to data matrix being manipulated * * reg SDDAS_FLOAT *data_ptr pointer to data in the buffer being processed * * reg SDDAS_FLOAT *tfrac pointer to the normalization factors * * reg SDDAS_CHAR *bin_stat_3d pointer to the bin status array * * reg SDDAS_CHAR *bin_stat_buf pointer to the bin_status factors for the * * buffer being processed * * reg SDDAS_SHORT unit, cnt looping variables to process all data levels * * for all samples returned * * SDDAS_FLOAT *base_3d_data pointer to the first unit being processed for * * the theta bin of interest * * SDDAS_FLOAT *base_buf_data pointer to the first buffer for the sensor * * being processed * * SDDAS_FLOAT *base_buf_frac pointer to the first block of normalization * * factors for the sensor being processed * * SDDAS_LONG offset_theta offset to get to the beginning of the data * * matrix for the theta bin being processed * * SDDAS_LONG offset_3d_unit offset to get to the beginning of the 3D * * matrix for the data level being processed * * SDDAS_LONG offset_buf_unit offset to get to the beginning of the data * * buffer for the data level being processed * * SDDAS_LONG offset_buffer offset to get to the first units sub-buffer * * for the buffer being processed * * SDDAS_LONG from_start offset to get to the data of interest * * SDDAS_SHORT sensor the sensor being processed * * SDDAS_SHORT sen_index looping variable to process all sensors data * * in the buffer being processed * * SDDAS_SHORT index index variable * * SDDAS_SHORT num_theta the number of theta columns * * SDDAS_SHORT ret_val holds called routine status flags * * SDDAS_SHORT num_buffers number of buffers returned by FILL_DATA or * * SWEEP_DATA * * SDDAS_CHAR *base_bin pointer to the beginning of the bin status * * array for the theta bin being processed * * SDDAS_CHAR *base_buf_bin pointer to the bin status factors for the * * first buffer for the sensor being processed * * char reset_called flag indicating if LOCATE_EX was called * * * * SUBSYSTEM * * Display Level * * * ******************************************************************************/ SDDAS_SHORT fill_theta_matrix (SDDAS_ULONG data_key, SDDAS_CHAR *exten, SDDAS_USHORT vnum, SDDAS_SHORT num_sen, SDDAS_SHORT *sen_numbers, SDDAS_FLOAT *ret_data, SDDAS_FLOAT *ret_frac, SDDAS_CHAR *ret_bin, SDDAS_SHORT *num_units, SDDAS_CHAR cur_buf, SDDAS_SHORT sen_units) { extern struct general_info ginfo; struct experiment_info *ex; struct fill_data *fptr; struct fill_sensor *sptr; struct collapse_data *cptr; struct bin_info *bptr; register SDDAS_FLOAT *dptr, *data_ptr, *tfrac; register SDDAS_CHAR *bin_stat_3d, *bin_stat_buf; register SDDAS_SHORT unit, cnt; SDDAS_FLOAT *base_3d_data, *base_buf_data, *base_buf_frac; SDDAS_LONG offset_theta, offset_3d_unit, offset_buf_unit, offset_buffer; SDDAS_LONG from_start; SDDAS_SHORT sensor, sen_index, index, num_theta; SDDAS_SHORT ret_val, num_buffers; SDDAS_CHAR *base_bin, *base_buf_bin; char reset_called; /*************************************************************************/ /* Check to see if the combination being processed has been processed */ /* before. If not, an error condition - probably didn't call FILE_OPEN. */ /* Since ir_locate_ex() is called by more than one routine, return an */ /* error code that indicates which calling routine resulted in the error.*/ /* Since a 0 is passed for the last parameter, the only possible error is*/ /* that the requested combination was not found among processed combos. */ /*************************************************************************/ if (!ginfo.called_locate) { ret_val = ir_locate_ex (data_key, exten, vnum, 0); if (ret_val != ALL_OKAY) return (FILL_THETA_NOT_FOUND); ginfo.called_locate = 1; reset_called = 1; } else reset_called = 0; /************************************************************************/ /* Set pointers to the memory allocated to process the current sensor, */ /* with index used to get to the correct sensor offset. */ /************************************************************************/ ex = ginfo.expt; bptr = ex->bin_ptr; fptr = ex->fill_arrays; cptr = ex->collapse_ptr; /************************************************************************/ /* There is no buffer status array for SWEEP_DATA, but there is for */ /* FILL_DATA. */ /************************************************************************/ num_buffers = (fptr->buf_stat == NO_MEMORY) ? 1 : NUM_BUFFERS; /************************************************************************/ /* Check if memory for collapsing over multi-dimension data exists. */ /************************************************************************/ if (ex->collapse_ptr == NO_MEMORY) { if (reset_called) ginfo.called_locate = 0; return (FILL_THETA_COLLAPSE); } /***********************************************************************/ /* Clear out the whole theta matrix if interleaving is not to be */ /* performed. */ /***********************************************************************/ if (!cptr->interleave) ir_clear_theta_matrix (); /***********************************************************************/ /* Loop over all sensors returned for this buffer being processed. */ /***********************************************************************/ num_theta = (cptr->theta_bins <= 0) ? ex->num_sensor : cptr->theta_bins; for (sen_index = 0; sen_index < num_sen; ++sen_index) { if (*(sen_numbers + sen_index) != -1) { /*******************************************************************/ /* Set pointers to the correct element for this sensor. */ /*******************************************************************/ sensor = *(sen_numbers + sen_index); for (cnt = 0, index = 0; cnt < sensor; ++cnt) index += *(ex->sensors_needed + cnt); /********************************************************************/ /* For the collapsing to work correctly, all sensors must process */ /* the same number of data levels (same units). */ /********************************************************************/ sptr = ex->fill_sen_ptr + *(fptr->ind_fill_sen + index); if (sptr->num_units != cptr->num_units) { if (reset_called) ginfo.called_locate = 0; return (THETA_DIFF_UNITS); } /******************************************************************/ /* Set the pointer to the start of the correct data block for */ /* the sensor being processed. NUM_UNITS indicates the number */ /* of units (data levels) to bypass to get to the data for the */ /* sensor in question. */ /******************************************************************/ from_start = num_buffers * *(num_units + sen_index) * bptr->num_bins; base_buf_data = ret_data + from_start; base_buf_frac = ret_frac + from_start; base_buf_bin = ret_bin + from_start; /*******************************************************************/ /* Readjust the pointers to point to the buffer being accessed. */ /* SEN_UNITS is the number of units (data levels) for the sensor. */ /* Each buffer has this many unit sub-buffers associated with it. */ /* This points at the first unit sub-buffer. This needs to be */ /* done for FILL_DATA processing only. */ /*******************************************************************/ if (fptr->buf_stat != NO_MEMORY) { offset_buffer = cur_buf * sen_units * bptr->num_bins; base_buf_data += offset_buffer; base_buf_frac += offset_buffer; base_buf_bin += offset_buffer; } /******************************************************************/ /* Set the pointer to the start of the correct data block that */ /* holds the data to be collapsed over for theta. Get to the */ /* correct theta bin for the sensor being processed. */ /******************************************************************/ if (cptr->theta_bins < 0) { offset_theta = sensor * bptr->num_bins; base_3d_data = cptr->data_3d_separate + offset_theta; } else { offset_theta = *(cptr->sensor_bin + sensor) * bptr->num_bins; base_3d_data = cptr->data_3d_binned + offset_theta; } base_bin = *(cptr->bin_stat_ptr + 0) + offset_theta; /******************************************************************/ /* Process all units (data levels). */ /******************************************************************/ for (unit = 0; unit < sptr->num_units; ++unit) { /*****************************************************************/ /* Set pointers to the correct units sub-buffer for the buffer */ /* being processed. */ /*****************************************************************/ offset_buf_unit = unit * bptr->num_bins; data_ptr = base_buf_data + offset_buf_unit; tfrac = base_buf_frac + offset_buf_unit; bin_stat_buf = base_buf_bin + offset_buf_unit; offset_3d_unit = unit * (bptr->num_bins * num_theta); dptr = base_3d_data + offset_3d_unit; bin_stat_3d = base_bin + offset_3d_unit; /***************************************************************/ /* Loop over all elements in the sweep. */ /***************************************************************/ for (cnt = 0; cnt < bptr->num_bins; ++cnt) { /*************************************************************/ /* The bin status value will be zero if the bin is to be */ /* replaced or will be set to a negative value by the */ /* collapsing routine to indicate that the bin previously */ /* was filled. */ /*************************************************************/ if (*(bin_stat_3d + cnt) <= 0) { /************************************************************/ /* The status value from FILL_DATA() and SWEEP_DATA() will */ /* be set to 1 if a legitimate value was placed into the */ /* bin. Normalize the value prior to storage. */ /************************************************************/ if (*(bin_stat_buf + cnt) == 1) { *(dptr + cnt) = *(data_ptr + cnt) / *(tfrac + cnt); *(bin_stat_3d + cnt) = 1; } /************************************************************/ /* The status will be set to 0 if no data for this bin was */ /* found OR if the data was outside the cutoff range. */ /* Replace data value only if the second case transpired. */ /* This is necessary since many sensors could map to the */ /* same theta bin, in which case, the integration routines */ /* would need to know that the bin was found. */ /************************************************************/ else { if (*(data_ptr + cnt) > 0) *(dptr + cnt) = *(data_ptr + cnt); *(bin_stat_3d + cnt) = 0; } } /************************************************************/ /* Do not add in OUTSIDE_MIN or OUTSIDE_MAX values, which */ /* are identified with a status value of 0. */ /************************************************************/ else if (*(bin_stat_buf + cnt) != 0) *(dptr + cnt) += *(data_ptr + cnt) / *(tfrac + cnt); } } } } if (reset_called) ginfo.called_locate = 0; return (ALL_OKAY); }