/** @file SunSensorRecord.cpp @brief Source code file for the SunSensorRecord Class, which contains the data for 1 Sun Sensor reading @class SunSensorRecord @brief SunSensorRecord contains one record of the SOFIE Sun Sensor data @author John Burton @date Tue Dec 05 09:17:10 2006 @copyright (©) Copyright 2006 by GATS, Inc., 11864 Canon Blvd, Suite 101, Newport News VA 23606 All Rights Reserved. No part of this software or publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise without the prior written permission of GATS, Inc. */ // //----------------------------------------------------------------------- // Include Files: //----------------------------------------------------------------------- // #include #include #include #include #include #include "Event.h" #include "EventVar.h" #include "SunSensorRecord.h" // //----------------------------------------------------------------------- // Global Variables: //----------------------------------------------------------------------- // // //----------------------------------------------------------------------- // Class Methods: //----------------------------------------------------------------------- // void SunSensorRecord::init() { type_ = BADDATA; track_timestamp_ = 0.0; pixel_timestamp_ = 0.0; corr_lo_X_ = 0.0; corr_hi_X_ = 0.0; corr_lo_Y_ = 0.0; corr_hi_Y_ = 0.0; solar_extent_ = 0.0; solar_hi_el_ = 0.0; solar_lo_el_ = 0.0; solar_hi_az_ = 0.0; solar_lo_az_ = 0.0; detector_lockdown_az_ = 0.0; detector_lockdown_el_ = 0.0; sums_ = new EventVar(0.0,ALL_SUMS_LEN); locs_ = new EventVar(0,ALL_SUMS_LEN); ave_pix_vals_ = new EventVar(0.0,ALL_SUMS_LEN); center_ave_pix_vals_ = new EventVar(0.0,CTR_SUMS_LEN); center_sums_ = new EventVar(0.0,CTR_SUMS_LEN); center_sums_rows_ = new EventVar(0,CTR_SUMS_LEN); center_sums_X_ = new EventVar(0.0,CTR_SUMS_LEN); center_sums_el_ = new EventVar(0.0,CTR_SUMS_LEN); center_sums_rel_el_ = new EventVar(0.0,CTR_SUMS_LEN); } void SunSensorRecord::clear() { type_ = BADDATA; track_timestamp_ = 0.0; pixel_timestamp_ = 0.0; corr_lo_X_ = 0.0; corr_hi_X_ = 0.0; corr_lo_Y_ = 0.0; corr_hi_Y_ = 0.0; solar_extent_ = 0.0; sums_->resize(0); locs_->resize(0); ave_pix_vals_->resize(0); center_ave_pix_vals_->resize(0); center_sums_->resize(0); center_sums_rows_->resize(0); center_sums_X_->resize(0); center_sums_el_->resize(0); center_sums_rel_el_->resize(0); } SunSensorRecord::SunSensorRecord() { init(); } SunSensorRecord::SunSensorRecord(double tts, double lox, double hix, double loy, double hiy) { double midx = (lox + hix) / 2.0; double midy = (loy + hiy) / 2.0; double ctrx = ((lox * 32.0) + 4279) / 32.0; init(); track_timestamp_ = tts; lowX_ = new SunSensorRegion(lox,midy,X_ROI); highX_ = new SunSensorRegion(hix,midy,X_ROI); lowY_ = new SunSensorRegion(midx,loy,Y_ROI); highY_ = new SunSensorRegion(midx,hiy,Y_ROI); center_ = new SunSensorRegion(ctrx,midy,C_ROI); } SunSensorRecord::SunSensorRecord(double tts, double lox, double hix, double loy, double hiy, double pts, EventVar &sums) { double midx = (lox + hix) / 2.0; double midy = (loy + hiy) / 2.0; double ctrx = ((lox * 32.0) + 4279) / 32.0; EventVar lxsums,hxsums,lysums,hysums,ctsums; lxsums = sums[std::slice(0,7,1)]; hxsums = sums[std::slice(7,7,1)]; lysums = sums[std::slice(14,5,1)]; hysums = sums[std::slice(19,5,1)]; ctsums = sums[std::slice(24,7,1)]; init(); lowX_ = new SunSensorRegion(lox,midy,lxsums,X_ROI); highX_ = new SunSensorRegion(hix,midy,hxsums,X_ROI); lowY_ = new SunSensorRegion(midx,loy,lysums,Y_ROI); highY_ = new SunSensorRegion(midx,hiy,hysums,Y_ROI); center_ = new SunSensorRegion(ctrx,midy,ctsums,C_ROI); track_timestamp_ = tts; pixel_timestamp_ = pts; sums_->copy(sums); corr_lo_X_ = lowX_->d_getXCenter(); corr_hi_X_ = highX_->d_getXCenter(); corr_lo_Y_ = lowY_->d_getYCenter(); corr_hi_Y_ = highY_->d_getYCenter(); } SunSensorRecord::SunSensorRecord(double tts, double lox, double hix, double loy, double hiy, double pts, EventVar &sums, int status) { double midx = (lox + hix) / 2.0; double midy = (loy + hiy) / 2.0; double ctrx = ((lox * 32.0) + 4279) / 32.0; EventVar lxsums,hxsums,lysums,hysums,ctsums; lxsums = sums[std::slice(0,7,1)]; hxsums = sums[std::slice(7,7,1)]; lysums = sums[std::slice(14,5,1)]; hysums = sums[std::slice(19,5,1)]; ctsums = sums[std::slice(24,7,1)]; init(); lowX_ = new SunSensorRegion(lox,midy,lxsums,X_ROI); highX_ = new SunSensorRegion(hix,midy,hxsums,X_ROI); lowY_ = new SunSensorRegion(midx,loy,lysums,Y_ROI); highY_ = new SunSensorRegion(midx,hiy,hysums,Y_ROI); center_ = new SunSensorRegion(ctrx,midy,ctsums,C_ROI); //std::cout << ctrx << " " << tts << std::endl; track_timestamp_ = tts; pixel_timestamp_ = pts; status_ = status; sums_->copy(sums); corr_lo_X_ = lowX_->d_getXCenter(); corr_hi_X_ = highX_->d_getXCenter(); corr_lo_Y_ = lowY_->d_getYCenter(); corr_hi_Y_ = highY_->d_getYCenter(); //exit(23); } SunSensorRecord::~SunSensorRecord() { delete lowX_; delete highX_; delete lowY_; delete highY_; delete center_; delete sums_; delete locs_; delete center_sums_; delete center_sums_rows_; delete center_sums_X_; delete center_sums_el_; delete center_sums_rel_el_; delete center_ave_pix_vals_; delete ave_pix_vals_; lowX_ = NULL; highX_ = NULL; lowY_ = NULL; highY_ = NULL; center_ = NULL; sums_ = NULL; locs_ = NULL; center_sums_ = NULL; center_sums_rows_ = NULL; center_sums_X_ = NULL; center_sums_el_ = NULL; center_sums_rel_el_ = NULL; center_ave_pix_vals_ = NULL; ave_pix_vals_ = NULL; } void SunSensorRecord::setSums(EventVar &sums) { sums_->copy(sums); } void SunSensorRecord::getSums(EventVar &sums) { sums.copy(*sums_); } void SunSensorRecord::getAvePixVals(EventVar &aves) { aves.copy(*ave_pix_vals_); } void SunSensorRecord::getCenterAvePixVals(EventVar &aves) { aves.copy(*center_ave_pix_vals_); } void SunSensorRecord::getCenterSums(EventVar &sums) { sums.copy(*center_sums_); } void SunSensorRecord::writeFlatFieldData(std::ofstream& outfile, int event_n) { int i; if(outfile.is_open()) { outfile << event_n << " "; outfile << track_timestamp_ << " "; outfile << lowX_->d_getXCenter() << " "; outfile << highX_->d_getXCenter() << " "; outfile << lowY_->d_getYCenter() << " "; outfile << highY_->d_getYCenter() << " "; outfile << pixel_timestamp_; for (i=0; isize();i++) { outfile << " " << (*sums_)[i]; } outfile << std::endl; } } int SunSensorRecord::detectType() { if (status_ < 0xA000) type_ = BADDATA; else if ((*sums_)[0] == 0xFEED) type_ = PIXELS; else type_ = SUMS; return type_; } void SunSensorRecord::doFlatField(EventVar &rel_resp, std::ofstream& outfile, int en) { double X,Y; int i,j; EventVar Sum; EventVar Loc; EventVar Ave; if (type_ == PIXELS) { writeFlatFieldData(outfile, en); } else if (type_ == SUMS) { i = 0; // // Low X Sum // lowX_->correctSums(rel_resp); Ave = lowX_->getAveIntensity(); Sum = lowX_->getSums(); Loc = lowX_->getLocs(); for(j=0;j<7;j++) { (*ave_pix_vals_)[i] = Ave[j]; (*locs_)[i] = Loc[j]; (*sums_)[i++] = Sum[j]; } // // High X Sum // highX_->correctSums(rel_resp); Ave = highX_->getAveIntensity(); Sum = highX_->getSums(); Loc = highX_->getLocs(); for(j=0;j<7;j++) { (*ave_pix_vals_)[i] = Ave[j]; (*locs_)[i] = Loc[j]; (*sums_)[i++] = Sum[j]; } // // Low Y Sum // lowY_->correctSums(rel_resp); Ave = lowY_->getAveIntensity(); Sum = lowY_->getSums(); Loc = lowY_->getLocs(); for(j=0;j<5;j++) { (*ave_pix_vals_)[i] = Ave[j]; (*locs_)[i] = Loc[j]; (*sums_)[i++] = Sum[j]; } // // High Y Sum // highY_->correctSums(rel_resp); Ave = highY_->getAveIntensity(); Sum = highY_->getSums(); Loc = highY_->getLocs(); for(j=0;j<5;j++) { (*ave_pix_vals_)[i] = Ave[j]; (*locs_)[i] = Loc[j]; (*sums_)[i++] = Sum[j]; } // // Center Sum // center_->correctSums(rel_resp); Ave = center_->getAveIntensity(); Sum = center_->getSums(); Loc = center_->getLocs(); for(j=0;j<7;j++) { (*center_ave_pix_vals_)[j] = Ave[j]; (*ave_pix_vals_)[i] = Ave[j]; (*locs_)[i] = Loc[j]; (*center_sums_)[j] = Sum[j]; (*sums_)[i++] = Sum[j]; } } } void SunSensorRecord::doIntegrationTimeCorrection(int en) { double X,Y; int i,j; EventVar Sum; EventVar Loc; EventVar Ave; double val; // // Everything is scaled relative to XROI integration times // Fudge factor corrects center integration times for events // before 10732 double CROI_INT = 456.67; // Center Sum integration time (us) double XROI_INT = 467.67; // X Edge ROI integration time (us) double YROI_INT = 456.83; // Y Edge ROI integration time (us) // double FUDGE = 1.0693; // Empirical fudge factor double FUDGE = 1.0; // Empirical fudge factor if(en < 2565) CROI_INT = 456.67; else if(en < 10733) CROI_INT = 347.00; else CROI_INT = 249.00; double factor; if (type_ == SUMS) { i = 0; // // Low X Sum // factor = 1.0; lowX_->correctIntegration(factor); Ave = lowX_->getAveIntensity(); for(j=0;j<7;j++) { (*ave_pix_vals_)[i++] = Ave[j]; } // // High X Sum // factor = 1.0; highX_->correctIntegration(factor); Ave = highX_->getAveIntensity(); for(j=0;j<7;j++) { (*ave_pix_vals_)[i++] = Ave[j]; } // // Low Y Sum // factor = XROI_INT / YROI_INT; lowY_->correctIntegration(factor); Ave = lowY_->getAveIntensity(); for(j=0;j<5;j++) { (*ave_pix_vals_)[i++] = Ave[j]; } // // High Y Sum // factor = XROI_INT / YROI_INT; highY_->correctIntegration(factor); Ave = highY_->getAveIntensity(); for(j=0;j<5;j++) { (*ave_pix_vals_)[i++] = Ave[j]; } // // Center Sum // factor = XROI_INT / CROI_INT; center_->correctIntegration(factor); Ave = center_->getAveIntensity(); if(en > 10732) { for(j=0;j<7;j++) { (*ave_pix_vals_)[i++] = Ave[j]; (*center_ave_pix_vals_)[j] = Ave[j]; } } else { for(j=0;j<7;j++) { val = (Ave[j] > 1031) ? (Ave[j] * 1.25695 - 265.097) : Ave[j]; (*ave_pix_vals_)[i++] = val; (*center_ave_pix_vals_)[j] = val; } } } } // // Correct Edge Locations // void SunSensorRecord::correctEdgeLocations() { int X,Y,i,j; EventVar Sum; EventVar Ave; double threshold; double ctr_int; // // Temporary - Until we have a better Edge correction routine // if (type_ == PIXELS) { // // PIXELS data, not SUMS data, so we have to use the tracking data // corr_lo_X_ = lowX_->d_getXCenter(); corr_hi_X_ = highX_->d_getXCenter(); corr_lo_Y_ = lowY_->d_getYCenter(); corr_hi_Y_ = highY_->d_getYCenter(); } else { // // Temporary - Until we have a better Edge correction routine // // Possible edge correction method - // get maximum sum value from center sums, calculate max pixel value // determine max and min sum value for each set of edge sums. is 25% of // center sum max within the min-max range of edge sums? calculate edge // be 25% of center sum max. If not, determine a new threshold value // based on center sum max // Ave = center_->getAveIntensity(); // threshold = Ave.max(); ctr_int = Ave.max(); threshold = 0.145 * (Ave.max()); // threshold = 0.25 * (Ave.max()); lowX_->correctEdge(threshold); highX_->correctEdge(threshold); threshold = 0.145 * (Ave.Mean()); // threshold = 0.25 * (Ave.Mean()); lowY_->correctEdge(threshold); highY_->correctEdge(threshold); corr_lo_X_ = lowX_->getEdge(); corr_hi_X_ = highX_->getEdge(); corr_lo_Y_ = lowY_->getEdge(); corr_hi_Y_ = highY_->getEdge(); } } void SunSensorRecord::determineCenterSumsLocation() { if (type_ != BADDATA) { EventVar xloc = center_->getLocs(); if(xloc.size() != center_sums_X_->size()) { std::cerr << "Houston, we have a problem - xloc.size() != center_sums_X_.size()"; std::cerr << xloc.size() << " != " << center_sums_X_->size() << std::endl; } for(int i=0;isize();i++) { (*center_sums_X_)[i] = (double)xloc[i]; (*center_sums_rows_)[i] = xloc[i]; } } } void SunSensorRecord::transformCoordinateSystem(EventVar &xmap, EventVar &ymap) { if (type_ != BADDATA) { solar_hi_el_ = xmap.Interpol_ndx(corr_lo_X_); solar_lo_el_ = xmap.Interpol_ndx(corr_hi_X_); solar_lo_az_ = ymap.Interpol_ndx(corr_lo_Y_); solar_hi_az_ = ymap.Interpol_ndx(corr_hi_Y_); for(int i = 0; isize(); i++) (*center_sums_el_)[i] = xmap.Interpol_ndx((*center_sums_X_)[i]); } } void SunSensorRecord::determineDetectorLockDownPosition(double det_az, double det_el) { double sun_center_az; if(type_ != BADDATA) { sun_center_az = (solar_lo_az_ + solar_hi_az_) / 2.0; detector_lockdown_az_ = sun_center_az - det_az; detector_lockdown_el_ = solar_hi_el_ - det_el; } } void SunSensorRecord::determineCenterSumsElevation(double det_el) { if(type_ != BADDATA) { for(int i = 0; isize(); i++) (*center_sums_rel_el_)[i] = det_el - (*center_sums_el_)[i]; } } void SunSensorRecord::determineSolarExtent() { if(type_ != BADDATA) { solar_extent_ = solar_hi_el_ - solar_lo_el_; } } void SunSensorRecord::correctNonLinearity(EventVar &Intensity, EventVar &Counts) { int i = 0; int j; EventVar Ave; // // Low X Sum // lowX_->correctIntensities(Intensity,Counts); Ave = lowX_->getAveIntensity(); for(j=0;j<7;j++) { (*ave_pix_vals_)[i++] = Ave[j]; } // // High X Sum // highX_->correctIntensities(Intensity,Counts); Ave = highX_->getAveIntensity(); for(j=0;j<7;j++) { (*ave_pix_vals_)[i++] = Ave[j]; } // // Low Y Sum // lowY_->correctIntensities(Intensity,Counts); Ave = lowY_->getAveIntensity(); for(j=0;j<5;j++) { (*ave_pix_vals_)[i++] = Ave[j]; } // // High Y Sum // highY_->correctIntensities(Intensity,Counts); Ave = highY_->getAveIntensity(); for(j=0;j<5;j++) { (*ave_pix_vals_)[i++] = Ave[j]; } // // Center Sum // center_->correctIntensities(Intensity,Counts); Ave = center_->getAveIntensity(); for(j=0;j<7;j++) { (*ave_pix_vals_)[i++] = Ave[j]; (*center_ave_pix_vals_)[j] = Ave[j]; } } // //void SunSensorRecord::clear() //{ // init(); // pixels.resize(0); //}