/* ionosphere residuals ------------------------------------------------------*/ static int res_iono(const obsd_t *obs, int n, const nav_t *nav, const double *rs, const double *rr, const double *pos, const double *azel, const pcv_t *pcv, const ekf_t *ekf, double *phw, double *v, double *H, double *R) { double *sig,P1,P2,L1,L2,c_iono=1.0-SQR(lam[1]/lam[0]); double LG,PG,antdel[3]={0},dant[NFREQ]={0}; int i,j,nv=0,sat; sig=mat(1,2*n); for (i=0;i<n;i++) { if (!raw_obs(obs+i,nav,&P1,&P2,&L1,&L2)||azel[i*2+1]<MIN_EL) continue; sat=obs[i].sat; /* ionosphere-LC model */ LG=-c_iono*ekf->x[II(sat)]+ekf->x[IB(sat)]; PG= c_iono*ekf->x[II(sat)]+nav->cbias[sat-1][0]; /* receiver antenna phase center offset and variation */ if (pcv) { antmodel(pcv,antdel,azel+i*2,dant); LG+=dant[0]-dant[1]; PG+=dant[0]-dant[1]; } /* phase windup correction */ windupcorr(obs[i].time,rs+i*6,rr,phw+obs[i].sat-1); LG+=(lam[0]-lam[1])*phw[obs[i].sat-1]; /* residuals of ionosphere (geometriy-free) LC */ v[nv ]=(L1-L2)-LG; #if 0 v[nv+1]=(P1-P2)-PG; #else v[nv+1]=0.0; #endif for (j=0;j<ekf->nx*2;j++) H[ekf->nx*nv+j]=0.0; H[ekf->nx*nv +II(sat)]=-c_iono; H[ekf->nx*nv +IB(sat)]=1.0; H[ekf->nx*(nv+1)+II(sat)]=c_iono; sig[nv ]=sig_err(azel+i*2); sig[nv+1]=RATIO_ERR*sig[nv]; nv+=2; } for (i=0;i<nv;i++) for (j=0;j<nv;j++) { R[i+j*nv]=i==j?SQR(sig[i]):0.0; } free(sig); return nv; }
/** convert range of spectra starting from initial spectra startSpectra into MD *events *@param startSpectra -- initial spectra number to begin conversion from * * @returns -- number of events added to the workspace. */ size_t ConvToMDHistoWS::conversionChunk(size_t startSpectra) { size_t nAddedEvents(0), nBufEvents(0); // cache global variable locally bool ignoreZeros(m_ignoreZeros); const size_t specSize = this->m_InWS2D->blocksize(); // preprocessed detectors associate each spectra with a detector (position) size_t nValidSpectra = m_NSpectra; // create local unit conversion class UnitsConversionHelper localUnitConv(m_UnitConversion); // local coordinatres initiated by the global coordinates which do not depend // on detector std::vector<coord_t> locCoord(m_Coord); // allocate temporary buffer for MD Events data std::vector<float> sig_err(2 * m_bufferSize); // array for signal and error. std::vector<uint16_t> run_index( m_bufferSize); // Buffer run index for each event std::vector<uint32_t> det_ids( m_bufferSize); // Buffer of det Id-s for each event std::vector<coord_t> allCoord(m_NDims * m_bufferSize); // MD events coordinates buffer size_t n_coordinates = 0; size_t nSpectraToProcess = startSpectra + m_spectraChunk; if (nSpectraToProcess > nValidSpectra) nSpectraToProcess = nValidSpectra; // External loop over the spectra: for (size_t i = startSpectra; i < nSpectraToProcess; ++i) { size_t iSpctr = m_detIDMap[i]; int32_t det_id = m_detID[i]; const MantidVec &X = m_InWS2D->readX(iSpctr); const MantidVec &Signal = m_InWS2D->readY(iSpctr); const MantidVec &Error = m_InWS2D->readE(iSpctr); // calculate the coordinates which depend on detector posision if (!m_QConverter->calcYDepCoordinates(locCoord, i)) continue; // skip y outside of the range; bool histogram(true); if (X.size() == Signal.size()) histogram = false; // convert units localUnitConv.updateConversion(i); std::vector<double> XtargetUnits; XtargetUnits.resize(X.size()); if (histogram) { double xm1 = localUnitConv.convertUnits(X[0]); for (size_t j = 1; j < XtargetUnits.size(); j++) { double xm = localUnitConv.convertUnits(X[j]); XtargetUnits[j - 1] = 0.5 * (xm + xm1); xm1 = xm; } XtargetUnits[XtargetUnits.size() - 1] = xm1; // just in case, should not be used } else for (size_t j = 0; j < XtargetUnits.size(); j++) XtargetUnits[j] = localUnitConv.convertUnits(X[j]); //=> START INTERNAL LOOP OVER THE "TIME" for (size_t j = 0; j < specSize; ++j) { double signal = Signal[j]; // drop NaN events if (isNaN(signal)) continue; // drop 0 -value signals if necessary. if (ignoreZeros && (signal == 0.)) continue; double errorSq = Error[j] * Error[j]; if (!m_QConverter->calcMatrixCoord(XtargetUnits[j], locCoord, signal, errorSq)) continue; // skip ND outside the range // ADD RESULTING EVENTS TO THE BUFFER // coppy all data into data buffer for future transformation into events; sig_err[2 * nBufEvents + 0] = float(signal); sig_err[2 * nBufEvents + 1] = float(errorSq); run_index[nBufEvents] = m_RunIndex; det_ids[nBufEvents] = det_id; for (size_t ii = 0; ii < m_NDims; ii++) allCoord[n_coordinates++] = locCoord[ii]; // calculate number of events nBufEvents++; if (nBufEvents >= m_bufferSize) { m_OutWSWrapper->addMDData(sig_err, run_index, det_ids, allCoord, nBufEvents); nAddedEvents += nBufEvents; // reset buffer counts n_coordinates = 0; nBufEvents = 0; } } // end spectra loop } // end detectors loop; if (nBufEvents > 0) { m_OutWSWrapper->addMDData(sig_err, run_index, det_ids, allCoord, nBufEvents); nAddedEvents += nBufEvents; nBufEvents = 0; } return nAddedEvents; }