// //----------------------------------------------------------------------- /// @copyright /// (c) Copyright 2008 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. /// //----------------------------------------------------------------------- /// /// @file SunSensorCalc.cpp /// /// @author John Burton /// /// @date Thu Jan 17 14:08:25 2008 /// //----------------------------------------------------------------------- // //----------------------------------------------------------------------- // Include Files: //----------------------------------------------------------------------- // #include #include #include "SunSensorCalc.h" #include "EdgeModel.h" #include "EdgeLocation.h" #include "DriftCorrection.h" #include "GATS_Utilities.hpp" // //----------------------------------------------------------------------- // Defines and Macros: //----------------------------------------------------------------------- // // //----------------------------------------------------------------------- // Global Variables: //----------------------------------------------------------------------- // static const double CSUM_INT = 347.00; // Center Sum integration time (us) static const double XROI_INT = 467.67; // X Edge ROI integration time (us) static const double YROI_INT = 456.83; // Y Edge ROI integration time (us) static const double MISSING = -1e24; static const double EDGE_FACTOR = 0.198847; static const double FIXED2FLOAT = 32.0; static const double ARCMIN_TO_RADIANS = M_PI / (double)10800.0; //static double det_el = 636.15625; // now in units of pixels static double det_el = 639.039083; // now in units of pixels static double det_az = 518.46875; // now in units of pixels // //----------------------------------------------------------------------- // Class Methods: //----------------------------------------------------------------------- // void SunSensorCalc::initNames(void) { SunSensorTimeGrid_.setName("SolarImageTimes"); ScienceTimeGrid_.setName("SS_ScienceTimeGrid"); Track_Low_X_.setName("SolarTrackXLow"); Track_High_X_.setName("SolarTrackXHigh"); Track_Low_Y_.setName("SolarTrackYLow"); Track_High_Y_.setName("SolarTrackYHigh"); SolarHighEl_.setName("SolarHighElevationEdge"); SolarLowEl_.setName("SolarLowElevationEdge"); SolarHighAz_.setName("SolarHighAzimuthEdge"); SolarLowAz_.setName("SolarLowAzimuthEdge"); SolarExtent_.setName("SolarExtent"); DetectorAz_.setName("DetectorLockdown_AZ"); DetectorEl_.setName("DetectorLockdown_EL"); RecordType_.setName("SolarTrackRecordType"); CenterOffsets_.setName("SolarCenterSumsOffsets"); NormalizedSolarExtent_.setName("NormalizedSolarExtent"); SumsData_.setName("SolarSums"); LocsVect_.setName("SolarSumsLocations"); CenterSumsVect_.setName("SolarCenterSums"); CenterRowsVect_.setName("SolarCenterRows"); CenterAvesVect_.setName("CenterAveragePixelValues"); AvePixVect_.setName("AveragePixelValues"); CenterOffsetsVect_.setName("SolarCenterSumsOffsetsVect"); QualityOfFit_.setName("SunSensorQualityOfFit"); zImpact_.setName("ImpactAltitude"); } EventVar SunSensorCalc::cleanupTransmission(EventVar &trans, EventVar &ia) { EventVar tmptrans(trans); for(int i=0; i= 0.35)&&(ia[i] < 0.37)) { double y = 18.5 - 50.0 * ia[i]; tmptrans[i] = y + (1-y)*tmptrans[i]; } } tmptrans = tmptrans.Smooth(21); tmptrans = tmptrans.Smooth(21); return tmptrans; } double SunSensorCalc::calcMaxIntensity(void) { double tmp = 0.0; double maxint = 0.0; EventVar avepix; valarray good = ((SunSensorTimeGrid_ >= 60.0) && (SunSensorTimeGrid_ <= 80.0)); for(int i=0; i tmp) ? maxint : tmp; } return maxint; } SunSensorCalc::SunSensorCalc(Event& L0, Event& L1, Event& Tmp, ConfigFile& cf, std::string Section) { cf_ = cf; section_ = Section; srssflag_ = L0.getSRSSFlag(); EventVarVect intSums; EventVartempExtent; EventVarVect tmpTrans; EventVarVect tmpImpact; Tmp.getEventVar("SolarImageTimes", SunSensorTimeGrid_); Tmp.getEventVar("SS_ScienceTimeGrid", ScienceTimeGrid_); Tmp.getEventVar("SS_CompositeTransmission", tmpTrans); Tmp.getEventVar("SS_CompositeImpactAngles", tmpImpact); Tmp.getEventVar("SS_TopEdgeImpactAngle", TopEdgeImpactAngle_); Tmp.getEventVar("SS_BottomEdgeImpactAngle", BottomEdgeImpactAngle_); Tmp.getEventVar("AveragePixelValues", AvePixVect_); Tmp.getEventVar("SolarSumsLocations", LocsVect_); Tmp.getEventVar("SolarTrackXLow", Track_Low_X_); Tmp.getEventVar("SolarTrackXHigh", Track_High_X_); Tmp.getEventVar("SolarTrackYLow", Track_Low_Y_); Tmp.getEventVar("SolarTrackYHigh", Track_High_Y_); Tmp.getEventVar("SolarCenterSums", CenterSumsVect_); Tmp.getEventVar("CenterAveragePixelValues", CenterAvesVect_); L1.getEventVar("zImpact", zImpact_); L1.getEventVar("L1_SolarExtent", tempExtent); TrueSolarExtent_ = tempExtent[0]; Tmp.getEventVar("SolarExtent", tempExtent); tempExtent.setName("FromFPACorrection"); SolarExtentCompare_.addEventVar(tempExtent); valarray valid = (tmpTrans[0] > MISSING); Transmission_ = tmpTrans[0][valid]; ImpactAngle_ = tmpImpact[0][valid]; Transmission_ = cleanupTransmission(Transmission_,ImpactAngle_); // Transmission_.Plot("Transmission Vs. Impact Angle","",ImpactAngle_); eventNumber_ = L0.getEventNumber(); MaxAveIntensity = calcMaxIntensity(); if(cf_.GetFlag(section_,"DebugPrint")) { std::cerr << "SunSensorTimeGrid_.size() = " << SunSensorTimeGrid_.size() << "\n"; std::cerr << "ScienceTimeGrid_.size() = " << ScienceTimeGrid_.size() << "\n"; std::cerr << "Transmission_.size() = " << Transmission_.size() << "\n"; std::cerr << "ImpactAngle_.size() = " << ImpactAngle_.size() << "\n"; std::cerr << "zImpact_.size() = " << zImpact_.size() << "\n"; std::cerr << "TopEdgeImpactAngle_.size() = " << TopEdgeImpactAngle_.size() << "\n"; std::cerr << "BottomEdgeImpactAngle_.size() = " << BottomEdgeImpactAngle_.size() << "\n"; std::cerr << "AvePixVect_.size() = " << AvePixVect_.size() << "\n"; std::cerr << "LocsVect_.size() = " << LocsVect_.size() << "\n"; std::cerr << "AvePixVect_[0].size() = " << AvePixVect_[0].size() << "\n"; std::cerr << "LocsVect_[0].size() = " << LocsVect_[0].size() << "\n"; std::cerr << "Track_Low_Y_.size() = " << Track_Low_Y_.size() << "\n"; std::cerr << "Track_High_Y_.size() = " << Track_High_Y_.size() << "\n"; std::cerr << "CenterSumsVect_.size() = " << CenterSumsVect_.size() << "\n"; std::cerr << "CenterAvesVect_.size() = " << CenterAvesVect_.size() << "\n"; } if(cf_.GetFlag(section_,"WriteScienceEdgeImpactAngle")) { std::ofstream outfile; std::string fname = "ScienceEdgeImpactAngle" + GATS_Utilities::ConvertToString(eventNumber_) + ".dat"; outfile.open(fname.c_str(),std::ofstream::out); int len = ScienceTimeGrid_.size(); for(int i=0;i diff; diff = BottomEdgeImpactAngle_ - TopEdgeImpactAngle_; // diff.Plot("Difference in Impact Angle","Bottom Edge - Top Edge"); if(cf_.GetFlag(section_,"WriteSunSensorEdgeImpactAngle")) { std::ofstream outfile; std::string fname = "SunSensorEdgeImpactAngle" + GATS_Utilities::ConvertToString(eventNumber_) + ".dat"; outfile.open(fname.c_str(),std::ofstream::out); EventVar timegrid; int len = SunSensorTimeGrid_.size(); for(int i=0;i sample(nrows); EventVar XAxis(0.0,(double)(nrows-1),1.0); if(!cf_.GetFlag(section_,"FullElevationScanCalibrationEvent")) { for(int i=0; i Vals(nelem); EventVar Locs(nelem); EventVar EdgeData; QualityOfFit_.resize(nsamp); // EdgeModel SolarEdge(cf_,section_); double maxia = ImpactAngle_.max(); if(cf_.GetFlag(section_,"WriteEdgeRegressionParams")) { fname = "./EdgeRegressionParams_" + GATS_Utilities::ConvertToString(eventNumber_) + ".dat"; outfile.open(fname.c_str(),std::ofstream::out); } // SolarEdge.setTransmissionModel(ImpactAngle_,Transmission_); for(int i=0; i 2564) if(!cf_.GetFlag(section_,"FullElevationScanCalibrationEvent") && eventNumber_ > 2564) { Track_Low_X_[i] = EdgeData[0]; Track_High_X_[i] = EdgeData[1]; QualityOfFit_[i] = EdgeData[2]; } if(cf_.GetFlag(section_,"WriteEdgeRegressionParams")) { outfile << i; for(int j=3; j<10; j++) outfile << ", " << EdgeData[j]; outfile << "\n"; } if(cf_.GetFlag(section_,"WriteSampleModelData")) { std::ofstream fitfile; std::string name = "./SampleData/Model_" + GATS_Utilities::ConvertToString(i) + ".dat"; fitfile.open(name.c_str(),std::ofstream::out); for(int j=0; jtemp; temp = Track_High_X_ - Track_Low_X_; temp.Plot("Diff",""); } } EventVar SunSensorCalc::calcEdgeIntensity(EventVar& edge) { EventVar tmpIA; EventVar tmpTrans; tmpTrans = Transmission_.VInterpol(ImpactAngle_,edge,1); tmpTrans = tmpTrans.VInterpol(ScienceTimeGrid_,SunSensorTimeGrid_); tmpTrans = tmpTrans * EDGE_FACTOR; return tmpTrans; } void SunSensorCalc::transformCoordinates(Event &SD) { std::string fname; std::string Xname = "X_Pixel_Spacing"; std::string Xfile = "X_MappingFile"; std::string Yname = "Y_Pixel_Spacing"; std::string Yfile = "Y_MappingFile"; std::string det_az_name; std::string det_el_name; if(srssflag_ == 'r') { det_az_name = "Detector_lockdown_az_SR"; det_el_name = "Detector_lockdown_el_SR"; } else if(srssflag_ == 's') { det_az_name = "Detector_lockdown_az_SS"; det_el_name = "Detector_lockdown_el_SS"; } else { det_az_name = "Detector_lockdown_az"; det_el_name = "Detector_lockdown_el"; } EventVar X_Mapping(Xname,511.0,-512.0,-1.0); EventVar Y_Mapping(Yname,-511.0,512.0,1.0); if(SD.EventVarExists(Xname)) SD.getEventVar(Xname,X_Mapping); else { if(cf_.ValidEntry(section_,Xfile)) { fname = cf_.GetStr(section_,Xfile); std::cerr << "Reading " << fname << std::endl; X_Mapping.readVar(fname); } X_Mapping = X_Mapping * ARCMIN_TO_RADIANS; SD.addEventVar(X_Mapping); } if(SD.EventVarExists(Yname)) SD.getEventVar(Yname,Y_Mapping); else { if(cf_.ValidEntry(section_,Yfile)) { fname = cf_.GetStr(section_,Yfile); std::cerr << "Reading " << fname << std::endl; Y_Mapping.readVar(fname); } Y_Mapping = Y_Mapping * ARCMIN_TO_RADIANS; SD.addEventVar(Y_Mapping); } if(cf_.ValidEntry(section_,det_az_name)) det_az = cf_.GetReal(section_,det_az_name); if(cf_.ValidEntry(section_,det_el_name)) det_el = cf_.GetReal(section_,det_el_name); det_az = Y_Mapping.Interpol_ndx(det_az); det_el = X_Mapping.Interpol_ndx(det_el); SolarHighEl_ = X_Mapping.VInterpol_ndx(Track_Low_X_); SolarLowEl_ = X_Mapping.VInterpol_ndx(Track_High_X_); SolarHighAz_ = Y_Mapping.VInterpol_ndx(Track_High_Y_); SolarLowAz_ = Y_Mapping.VInterpol_ndx(Track_Low_Y_); for (int i=0; i SunCenterAz; SunCenterAz = (SolarLowAz_ + SolarHighAz_) / 2.0; DetectorAz_ = (SunCenterAz - det_az) * TrueSolarExtent_ / MeasuredExoExtentAz_; DetectorEl_ = (SolarHighEl_ - det_el) * TrueSolarExtent_ / MeasuredExoExtentEl_; } void SunSensorCalc::determineCenterSumsElevation(void) { for(int i = 0; i tmp; EventVar timegrid; EventVar lowel; SolarExtent_ = SolarHighEl_ - SolarLowEl_; SolarExtentAz_ = SolarHighAz_ - SolarLowAz_; valarray good = ((zImpact_ >= 100.0) && (zImpact_ <= 140.0)); tmp = SolarExtent_[good]; MeasuredExoExtentEl_ = tmp.Mean(); tmp = SolarExtentAz_[good]; MeasuredExoExtentAz_ = tmp.Mean(); EventVar mstd; SolarExtent_.setName("SolarExtent"); // SolarExtentCompare_.addEventVar(SolarExtent_); NormalizedSolarExtent_ = SolarExtent_ / MeasuredExoExtentEl_; if(cf_.GetFlag(section_,"PlotCompareSolarExtent")) { EventVar tmpp(SolarExtent_); tmpp.setName("Model"); SolarExtentCompare_.addEventVar(SolarExtent_); str = "Event " + GATS_Utilities::ConvertToString(eventNumber_); // SolarExtentCompare_.Plot("Solar Extent",str); } if(cf_.GetFlag(section_,"PlotSolarExtent")) SolarExtent_.Plot("SolarExtent",""); } void SunSensorCalc::doDriftCorrection(void) { DriftCorrection dc; dc.doLinearFit(SolarExtent_,zImpact_,SunSensorTimeGrid_); SolarExtent_ = dc.doDriftCorrection(TrueSolarExtent_); NormalizedSolarExtent_ = SolarExtent_ / TrueSolarExtent_; if(cf_.GetFlag(section_,"PlotCompareSolarExtent")) { EventVar tmpp(SolarExtent_); tmpp.setName("DriftCorrected"); SolarExtentCompare_.addEventVar(SolarExtent_); std::string str = "Event " + GATS_Utilities::ConvertToString(eventNumber_); SolarExtentCompare_.Plot("SolarExtent::doDriftCorrection",str); } } void SunSensorCalc::adjustToScienceTimeStamp(Event& L1) { std::string str, tmpstr; std::stringstream oss; double SS_TimeShift = 0.0; std::string offset_name; if(srssflag_ == 'r') offset_name = "SunSensorTimeShift_SR"; else if(srssflag_ == 's') offset_name = "SunSensorTimeShift_SS"; else offset_name = "SunSensorTimeShift"; if(cf_.ValidEntry(section_,offset_name)) SS_TimeShift = cf_.GetReal(section_,offset_name); oss << eventNumber_; str = "Event " + oss.str(); EventVar xloc_ts, csum_ts, hiy_ts, loy_ts, xsum_ts; xloc_ts = SunSensorTimeGrid_ - SS_TimeShift; csum_ts = SunSensorTimeGrid_ - SS_TimeShift; hiy_ts = SunSensorTimeGrid_ - SS_TimeShift; loy_ts = SunSensorTimeGrid_ - SS_TimeShift; xsum_ts = SunSensorTimeGrid_ - SS_TimeShift; SolarHighEl_ = SolarHighEl_.VInterpol(xloc_ts, ScienceTimeGrid_); SolarLowEl_ = SolarLowEl_.VInterpol (xloc_ts, ScienceTimeGrid_); SolarHighAz_ = SolarHighAz_.VInterpol(hiy_ts, ScienceTimeGrid_); SolarLowAz_ = SolarLowAz_.VInterpol (loy_ts, ScienceTimeGrid_); SolarExtent_ = SolarExtent_.VInterpol(xloc_ts, ScienceTimeGrid_); NormalizedSolarExtent_ = NormalizedSolarExtent_.VInterpol(xloc_ts, ScienceTimeGrid_); DetectorAz_ = DetectorAz_.VInterpol (xloc_ts, ScienceTimeGrid_); DetectorEl_ = DetectorEl_.VInterpol (xloc_ts, ScienceTimeGrid_); CenterAvesVect_ = CenterAvesVect_.VInterpol(csum_ts,ScienceTimeGrid_); } void SunSensorCalc::copyDataToEvent(Event& eventObj) { initNames(); eventObj.replaceEventVar(ScienceTimeGrid_); eventObj.replaceEventVar(Track_Low_X_); eventObj.replaceEventVar(Track_High_X_); eventObj.replaceEventVar(Track_Low_Y_); eventObj.replaceEventVar(Track_High_Y_); eventObj.replaceEventVar(SolarHighEl_); eventObj.replaceEventVar(SolarLowEl_); eventObj.replaceEventVar(SolarHighAz_); eventObj.replaceEventVar(SolarLowAz_); eventObj.replaceEventVar(SolarExtent_); eventObj.replaceEventVar(DetectorEl_); eventObj.replaceEventVar(DetectorAz_); eventObj.replaceEventVar(SunSensorTimeGrid_); eventObj.replaceEventVar(NormalizedSolarExtent_); eventObj.replaceEventVar(CenterAvesVect_); eventObj.replaceEventVar(CenterSumsVect_); eventObj.addEventVar(QualityOfFit_); } void SunSensorCalc::correctCenterSumsLocations() { std::stringstream oss; std::string str, tmpstr; std::map > CenterAveMap; std::map > CenterOffsetMap; std::map >::iterator iter; std::vector rowvect; int nvars = CenterAvesVect_.size(); int len = SunSensorTimeGrid_.size(); valarray good = ((SunSensorTimeGrid_ >= 70.0) && (SunSensorTimeGrid_ <= 71.0)); EventVar Rows; EventVar Aves; EventVar Offs; EventVar tmp(len); int row; CenterOffsets_.resize(nvars); for(int j=0; j timegrid; timegrid = (grid > 0) ? ScienceTimeGrid_ : SunSensorTimeGrid_; int len = timegrid.size(); for(int i=0;i