QGpCompatibility/CompatInversionReport.h
Go to the documentation of this file.
00001 /***************************************************************************
00002 **
00003 **  This file is part of QGpCompatibility.
00004 **
00005 **  This file may be distributed and/or modified under the terms of the
00006 **  GNU General Public License version 2 or 3 as published by the Free
00007 **  Software Foundation and appearing in the file LICENSE.GPL included
00008 **  in the packaging of this file.
00009 **
00010 **  This file is distributed in the hope that it will be useful, but WITHOUT
00011 **  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 **  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
00013 **  more details.
00014 **
00015 **  You should have received a copy of the GNU General Public License
00016 **  along with this program. If not, see <http://www.gnu.org/licenses/>.
00017 **
00018 **  See http://www.geopsy.org for more information.
00019 **
00020 **  Created : 2003-05-22
00021 **  Authors:
00022 **    Marc Wathelet
00023 **    Marc Wathelet (ULg, Liège, Belgium)
00024 **    Marc Wathelet (LGIT, Grenoble, France)
00025 **
00026 ***************************************************************************/
00027 
00028 #ifndef INVERSIONREPORT_H
00029 #define INVERSIONREPORT_H
00030 
00031 #include <QGpCoreWave.h>
00032 
00033 #include "QGpCompatibilityDLLExport.h"
00034 
00035 namespace QGpCompatibility {
00036 
00037 class CompatMultiModalFrequency;
00038 class CompatEllipticity;
00039 class CompatEllipticityData;
00040 class CompatMultiModalCurves;
00041 class CompatDispersion;
00042 class CompatDispersionData;
00043 
00044 class QGPCOMPATIBILITY_EXPORT CompatInversionReport
00045 {
00046   //-----------------------------------------------------------------------------------------------------------------------------
00047   //
00048   //  1st part: general
00049   //
00050   //-----------------------------------------------------------------------------------------------------------------------------
00051 public:
00052   // Constructor: open file
00053   CompatInversionReport(bool isWrite, QString reportFile, QString naInFile=QString::null, int nModels=0);
00054   // Destructor: close filecd ../
00055   virtual ~CompatInversionReport();
00056   // Static function to test if report is ready to be opened
00057   static bool isReady(QString reportFile);
00058   // Test if file is an inversion report
00059   static bool isRightFormat(QString reportFile);
00060   bool isValid() {return _valid;}
00061   // Test whether this class is of type className
00062   virtual bool isA(const char * className);
00063   // Name of this class
00064   const char * className() {return "CompatInversionReport";}
00065   // Test format flag at beginning of file
00066   bool isRightFormat();
00067   // Checks if two report have the same parameters
00068   bool isSameParameter(const CompatInversionReport * otherModels) const;
00069   
00070   void writeHeader();
00071   void setNFromNaIn(QString naInfile);
00072   // Block types to allow block testing
00073   enum BlockType {Parameters, Omegas, DispersionGoal, ModelDispersion, AutocorrGoal,
00074                   EllipticityGoal, FKMaxGoal, Information, Unknown, RefraGoal};
00075   //
00076   enum paramID {H, Vs, Vp, Rho, Depth, ExpGrad, ModeStdDev, NAParam};
00077   // Return the block type of block n�2
00078   BlockType reportType();
00079   void addParameter(paramID which,int layer);
00080   void addEllipticityGoal(CompatEllipticityData * ell);
00081   void modifyEllipticityGoal(CompatEllipticityData * ell);
00082   // Modify the cost value for model i 
00083   void setCostValue(int imodel,double costValue);
00084   
00085   bool startWritingBlock(int index,BlockType wantedType);
00086   bool startWritingBlock(BlockType type);
00087   void endWritingBlock();
00088   bool startReadingBlock(int index,BlockType wantedType);
00089   /* Flush the buffers (usefull to call when reading is blocked)
00090     Introduced to solve a bug noticed 2003-02-10 */
00091   void flush();
00092   // Change the flushed state
00093   void setFlushed(bool s) {_flushed=s;}
00094   // Load model (and its cost function) given by its index and makes it the current one
00095   bool loadModel(int modelIndex=-1);
00096   void loadNAModel(int modelIndex=-1);
00097   // Load next model (and its cost function) given by its index and makes it the current one
00098   bool loadNextModel();
00099   // Get only the cost value from a model
00100   double loadCostValue(int modelIndex);
00101   // load the measured ellipticity curve into a new data class (may be null if there's no ellipticity)
00102   CompatEllipticityData * loadEllipticityGoal();
00103   // Returns the name of a parameter given by its index (don't forget to delete char)
00104   QString parameterName(int paramIndex);
00105   // Returns the value of parameter given by its index in the current model
00106   double getParamValue(int paramIndex);
00107   paramID getParamType(int paramIndex) {return _paramAddresses[paramIndex].which;}
00108   // Returns the current model
00109   Seismic1DModel *  currentModel();
00110   // Returns the current NA model
00111   float *  currentNAModel();
00112   // Returns the value of the cost function for the current model
00113   double currentCost() {return _currentCost;}
00114   // Returns the value of the ID for the current model
00115   int getID() {return _currentID;}
00116   /*
00117      Returns the curve of best fit point versus num models from index startIndex
00118      startIndex is modified and will contain the index of the first model not checked
00119      by getBestFit
00120   */
00121   QVector<Point> * getBestFits(QVector<Point>& curve,
00122                                        int& startIndex,double& minCostValue,
00123                                        int& generatedModels);
00124   /* Just returns the model index of best model
00125     */
00126   int getBestFit();
00127   void getNAParam(int& itmax, int& nsi, int& ns, int& nr);
00128   
00129   int currentID() {return _currentID;}
00130   int dimension() {return _nd;}
00131   int countModels();
00132   void maxOmegasCount(int& dispCount, int& ellCount);
00133   int currentLoadingIndex() {return _currentIndex;}
00134   
00135   QString reportName();
00136   QString reportFileName();
00137   
00138 protected:
00139   // Boolean set to true is correclty opened report
00140   bool _valid;
00141   // Report Stream
00142   QDataStream _s;
00143   // Number of models really inside (all modes)
00144   int _trueN;
00145   // Index of current model just loaded (read mode)
00146   int _currentIndex;
00147   // Number of blocks, number of models=_n-HEADER_BLOCKS_COUNT
00148   int _n;
00149   // Number of parameters
00150   int _nd;
00151   void setMaxOmegasCount(int dispCount, int ellCount);
00152   int _maxDispOmegaCount;
00153   int _maxEllOmegaCount;
00154   // Parameters table
00155   struct paramAddress
00156   {
00157     paramID which;
00158     int layer;
00159   };
00160   paramAddress * _paramAddresses;
00161   // Last Layered Model loaded from stream
00162   Seismic1DModel * _currentModel;
00163   // Last cost value loaded from stream
00164   double _currentCost;
00165   // Last NA model loaded from stream (version 4)
00166   float * _currentNAModel;
00167   // Last ellipticity object loaded from stream
00168   CompatEllipticity * _currentEllipticity;
00169   // Temp offset in file (used by startWritingBlock(), endWritingBlock(), startReadingBlock())
00170   qint64 _ptrStart;
00171   // Offset table loaded on opening the file to speed up and avoid swap
00172   qint64 * _offsetTable;
00173   // Loads the list of parameters in memory
00174   bool loadParamAddresses();
00175   // Greatest unique ID, ready for next model (writing)
00176   // ID of currently load model (reading)
00177   // Usefull when models are sorted in file, or filtered to keep track of initial
00178   // number in file (when generated)
00179   int _currentID;
00180   // Name of the report
00181   QString _fileName;
00182   // initialize current model object
00183   bool initCurrentModel();
00184   // initialize current dispersion object
00185   bool initCurrentEllipticity();
00186   /* When reading this file while another process is also accessing it in writing mode
00187     it is sometimes usefull to flush the reading buffer but it is time consuming.
00188     When has been flushed it is useless to flush again and again while there's no more 
00189     model added. So this flag is set to true when flushed and returns to false when new models
00190     are added. Inside this only flush() set it to true. Other objetcts are free
00191     to set it as they want. */
00192   bool _flushed;
00193   // Number of blocks before the inversion results (blocks DispersionModel), set by constructor
00194   int _headerBlocksCount;
00195   // Current version
00196   int _version;
00197   //  Header block indexes (version dependent)
00198   qint64 _blockParam, _blockOmegas, _blockGoal, _blockEll;
00199   void writeNAModel(float * naModel);
00200   //-----------------------------------------------------------------------------------------------------------------------------
00201   //
00202   //  2nd part: specific to dispersion curve
00203   //
00204   //-----------------------------------------------------------------------------------------------------------------------------
00205 public:
00206   // Checks if two report have the same omegas
00207   bool isSameOmegas(const CompatInversionReport * otherModels) const;
00208   // Checks if two report have the same goal dispersion
00209   bool isSameGoalDispersion(CompatInversionReport * otherModels);
00210   void addOmegas(CompatMultiModalFrequency * omegas);
00211   void addDispersionGoal(CompatDispersionData * rms);
00212   /*
00213      Re-writing over the existing goal curves, extrem caution may be observe to
00214      the size of the new CompatRMS: it must be exactly the same structure as the
00215      one added with addDispersionGoal(), only some changes in the values are tolerated
00216   */
00217   void modifyDispersionGoal(CompatDispersionData * rms);
00218   // Add all block in one time
00219   void addModel(const Seismic1DModel * model, float * naModel,
00220                 const CompatDispersion * disp,
00221                 double cost, int modelID=-1);
00222   // Add all block in one time
00223   void addModel(const Seismic1DModel * model, float * naModel,
00224                 const CompatDispersion * disp,
00225                 const CompatEllipticity * ell,
00226                 double cost, int modelID=-1);
00227   // load the model, the cost and the dispersion curve
00228   bool loadDispersion(int modelIndex);
00229   // Same as above except that it loads the dispersion curve in a given dispersion object
00230   bool loadDispersion(CompatDispersion * disp, CompatEllipticity * ell,int modelIndex);
00231   // load the measured dispersion curve into a new data class
00232   CompatDispersionData * loadDispersionGoal();
00233   // Returns the dispersion of current model
00234   CompatDispersion * currentDispersion();
00235   // Returns the ellipticity of current model (may be null if there's no ellipticity)
00236   CompatEllipticity * currentEllipticity();
00237   int omegasCount();
00238   int modesCount();
00239   // Compute statistical parameter on calculated dispersion curves
00240   void statDispersion(int ipoint,int imode,int start_model,int end_model,
00241                       double& mean, double& stddev);
00242 protected:
00243   // Last dispersion object loaded from stream
00244   CompatMultiModalCurves * _currentDispersion;
00245   // initialize current dispersion object
00246   virtual bool initCurrentDispersion();
00247 };
00248 
00249 } // namespace QGpCompatibility
00250 
00251 #include "CompatDispersion.h"
00252 
00253 namespace QGpCompatibility {
00254 
00255 inline CompatDispersion * CompatInversionReport::currentDispersion()
00256 {
00257   TRACE;
00258   if(!_currentDispersion) initCurrentDispersion();
00259   return (CompatDispersion *)_currentDispersion;
00260 }
00261 
00262 inline CompatEllipticity * CompatInversionReport::currentEllipticity()
00263 {
00264   TRACE;
00265   if(!_currentDispersion) initCurrentDispersion();
00266   return _currentEllipticity;
00267 }
00268 
00269 inline int CompatInversionReport::omegasCount()
00270 {
00271   TRACE;
00272   if(!_currentDispersion) initCurrentDispersion();
00273   return _currentDispersion->omegasCount();
00274 }
00275 
00276 inline int CompatInversionReport::modesCount()
00277 {
00278   TRACE;
00279   if(!_currentDispersion) initCurrentDispersion();
00280   return _currentDispersion->modesCount();  
00281 }
00282 
00283 inline bool CompatInversionReport::isSameOmegas(const CompatInversionReport * otherModels) const
00284 {
00285   TRACE;
00286   return _currentDispersion->isSameOmegas(otherModels->_currentDispersion);
00287 }
00288 
00289 inline bool CompatInversionReport::startReadingBlock(int index,BlockType wantedType)
00290 {
00291   TRACE;
00292   if(index>=_trueN) {
00293     fprintf(stderr,"Model index out of range, max=%i, index=%i\n",_trueN-1,index);
00294     return false;
00295   }
00296   _s.device()->seek(_offsetTable[index]);
00297   int blockType=0;
00298   _s >> blockType;
00299   return (blockType==wantedType);
00300 }
00301 
00302 inline void CompatInversionReport::writeNAModel(float * naModel)
00303 {
00304   TRACE;
00305   if(naModel)
00306     _s.writeRawData((char *)naModel,_nd*sizeof(float));
00307   else {
00308     double * tmp=new double [_nd];
00309     _s.writeRawData((char *)tmp,_nd*sizeof(float));
00310     delete [] tmp;
00311   }
00312 }
00313 
00314 } // namespace QGpCompatibility
00315 
00316 #endif // COMPATINVERSIONREPORT_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines